#include #include #include #include #include "vfs.h" /* Initialise op‚rations sur un r‚pertoire virtuel. Un r‚pertoire virtuel est sp‚cifi‚ par le contenu de deux fichier plus le contenu du r‚pertoire lui-mˆme. Le permier fichier repr‚sente l'‚tat initial du r‚pertoire, le deuxiŠme fichier repr‚sente les fichiers qui ont ‚t‚ effac‚s. Le contenu du r‚pertoire virtuel est donc donn‚ par l'‚quation suivante fincl + courant - fexcl. Ce m‚canisme permet de simuler le Translucid File System. Retourne -1 si erreur. */ int filedir_init( FILEDIR *fdir, const char *fincl, /* Fichier contenant une liste … inclure */ const char *fexcl) /* Fichier contenant une liste … exclure */ /* ou NULL */ { strcpy (fdir->fincl,fincl); if (fexcl != NULL){ strcpy (fdir->fexcl,fexcl); }else{ fdir->fexcl[0] = '\0'; } fdir->fincl_nb = -1; /* D‚fŠre la lecture du fichier fincl au */ fdir->incl_files = NULL; return 0; } /* LibŠre espace occup‚ par un FILEDIR */ void filedir_end (FILEDIR *fdir) { int i; VFILE_SPEC *sp = fdir->incl_files; for (i=0; ifincl_nb; i++,sp++){ free (sp->fname); free (sp->relpath); } free (fdir->incl_files); fdir->fincl_nb = -1; /* D‚fŠre la lecture du fichier fincl au */ fdir->incl_files = NULL; } static int cmp_vfile (const void *p1, const void *p2) { VFILE_SPEC *v1 = (VFILE_SPEC *)p1; VFILE_SPEC *v2 = (VFILE_SPEC *)p2; return strcmp(v1->fname,v2->fname); } /* Collecte ou met … jour l'information dans le FILEDIR. Appel‚ avant toute transaction. Ne retourne pas si erreur. L'absence des fichiers fincl et fexcl n'est pas un erreur. Les tables de fichiers sont tri‚es. */ void filedir_setup (FILEDIR *fdir) { int ret = 0; if (fdir->fincl_nb == -1){ int nb = 0; FILE *fin; fin = fopen (fdir->fincl,"r"); if (fin != NULL){ VFILE_SPEC tb[1000]; VFILE_SPEC *pttb = tb; char buf[300]; while (fgets_strip (buf,sizeof(buf)-1,fin,'\\','#',NULL)!=NULL){ strip_end (buf); if (buf[0] != '\0'){ int ok = 0; char path[PATH_MAX]; char *pt = str_copymot (path,buf); pttb->fname = strdup (path); pt = str_skip (pt); if (isdigit (*pt)){ unsigned date = date_a2u(pt); pt = str_skipword (pt); pt = str_skip (pt); if (isdigit(*pt)){ unsigned time = time_a2u(pt); pttb->date = ((unsigned long)date << 16) | time; pt = str_skipword (pt); pt = str_skip (pt); /* Le reste de la ligne contient un path relatif pour localiser le fichier et un numero de version, qui est inutile. */ str_copyword (path,pt); pttb->relpath = strdup (path); ok = 1; pttb++; nb++; } } if (!ok){ fprintf (stderr,"Date invalide, fichier %s\n\t%s\n" ,fdir->fincl,buf); ret = -1; } } } /* Le +1 est la au cas ou nb == 0 */ fdir->incl_files = (VFILE_SPEC *) malloc (nb *sizeof(VFILE_SPEC)+1); hsort (tb,nb,sizeof(VFILE_SPEC),cmp_vfile); memcpy (fdir->incl_files,tb,nb*sizeof(VFILE_SPEC)); fclose (fin); } fdir->fincl_nb = nb; if (fdir->fexcl[0] != '\0'){ fin = fopen (fdir->fexcl,"r"); if (fin != NULL){ char *tbexcl[1000]; int nbexcl = 0; char buf[300]; while (fgets_strip (buf,sizeof(buf)-1,fin,'\\','#',NULL)!=NULL){ char path[PATH_MAX]; char *pt = str_copymot(path,buf); if (pt != NULL) tbexcl[nbexcl++] = strdup (path); } fclose (fin); /* #Specification: repertoires virtuels Le contenu d'un r‚pertoire virtuel est donn‚ par l'‚quation suivante: makefile.dat - makefile.del + contenu r‚el. */ /* On doit maintenant ‚liminer les fichiers qui sont virtuellement ‚limin‚s. */ { int notb = 0; int i; VFILE_SPEC *tbincl = fdir->incl_files; int nbincl = fdir->fincl_nb; tbstr_sort (tbexcl,nbexcl); for (i=0; ifname); if (cmp == 0){ int nbcop = nbincl-(notb+1); free (spc->fname); free (spc->relpath); if (nbcop > 0){ memmove (spc,spc+1,nbcop *sizeof(VFILE_SPEC)); } nbincl--; break; }else if (cmp < 0){ break; } } free (fname); } fdir->fincl_nb = nbincl; } } } } if (ret == -1) exit (-1); } /* Localise un fichier dans table virtuelle. Retourne NULL si trouve pas. */ VFILE_SPEC *filedir_locate (FILEDIR *fdir, const char *fname) { VFILE_SPEC *ret= NULL; filedir_setup(fdir); { VFILE_SPEC *vf = fdir->incl_files; int nb = fdir->fincl_nb; int i; for (i=0; ifname); if (cmp==0){ ret = vf; break; }else if (cmp < 0){ break; } } } return ret; } int filedir_unlink (FILEDIR *fdir, const char *name) { int ret = -1; VFILE_SPEC *spc; int notb, nbincl; filedir_setup (fdir); spc = fdir->incl_files; nbincl = fdir->fincl_nb; for (notb = 0 ; notb < nbincl; notb++,spc++){ int cmp = strcmp(name,spc->fname); if (cmp == 0){ int nbcop = nbincl-(notb+1); free (spc->fname); free (spc->relpath); if (nbcop > 0){ memmove (spc,spc+1,nbcop *sizeof(VFILE_SPEC)); } fdir->fincl_nb--; ret = 0; break; }else if (cmp < 0){ break; } } return ret; }