/[mc]/mc/vfs/direntry.c
ViewVC logotype

Diff of /mc/vfs/direntry.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.57 by proskin, Thu Dec 26 02:21:43 2002 UTC revision 1.75 by proski, Thu Oct 16 23:58:44 2003 UTC
# Line 25  Line 25 
25   * archive/site is simply "". Beware. */   * archive/site is simply "". Beware. */
26    
27  #include <config.h>  #include <config.h>
28    #include <errno.h>
29    
30  #include "utilvfs.h"  #include "utilvfs.h"
31  #include "xdirentry.h"  #include "xdirentry.h"
# Line 34  Line 35 
35    
36  static volatile int total_inodes = 0, total_entries = 0;  static volatile int total_inodes = 0, total_entries = 0;
37    
38  vfs_s_inode *  struct vfs_s_inode *
39  vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat)  vfs_s_new_inode (struct vfs_class *me, struct vfs_s_super *super, struct stat *initstat)
40  {  {
41      vfs_s_inode *ino;      struct vfs_s_inode *ino;
42    
43      ino = g_new0 (vfs_s_inode, 1);      ino = g_new0 (struct vfs_s_inode, 1);
44      if (!ino)      if (!ino)
45          return NULL;          return NULL;
46    
# Line 58  vfs_s_new_inode (vfs *me, vfs_s_super *s Line 59  vfs_s_new_inode (vfs *me, vfs_s_super *s
59      return ino;      return ino;
60  }  }
61    
62  vfs_s_entry *  struct vfs_s_entry *
63  vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)  vfs_s_new_entry (struct vfs_class *me, char *name, struct vfs_s_inode *inode)
64  {  {
65      vfs_s_entry *entry;      struct vfs_s_entry *entry;
66    
67      entry = g_new0 (struct vfs_s_entry, 1);      entry = g_new0 (struct vfs_s_entry, 1);
68      total_entries++;      total_entries++;
# Line 77  vfs_s_new_entry (vfs *me, char *name, vf Line 78  vfs_s_new_entry (vfs *me, char *name, vf
78  }  }
79    
80  static void  static void
81  vfs_s_free_inode (vfs *me, vfs_s_inode *ino)  vfs_s_free_inode (struct vfs_class *me, struct vfs_s_inode *ino)
82  {  {
83      if (!ino)      if (!ino)
84          vfs_die ("Don't pass NULL to me");          vfs_die ("Don't pass NULL to me");
# Line 101  vfs_s_free_inode (vfs *me, vfs_s_inode * Line 102  vfs_s_free_inode (vfs *me, vfs_s_inode *
102  }  }
103    
104  void  void
105  vfs_s_free_entry (vfs *me, vfs_s_entry *ent)  vfs_s_free_entry (struct vfs_class *me, struct vfs_s_entry *ent)
106  {  {
107      int is_dot = 0;      int is_dot = 0;
108      if (ent->prevp){    /* It is possible that we are deleting freshly created entry */      if (ent->prevp){    /* It is possible that we are deleting freshly created entry */
# Line 127  vfs_s_free_entry (vfs *me, vfs_s_entry * Line 128  vfs_s_free_entry (vfs *me, vfs_s_entry *
128  }  }
129    
130  void  void
131  vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent)  vfs_s_insert_entry (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_entry *ent)
132  {  {
133      vfs_s_entry **ep;      struct vfs_s_entry **ep;
134    
135      for (ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next))      for (ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next))
136          ;          ;
# Line 142  vfs_s_insert_entry (vfs *me, vfs_s_inode Line 143  vfs_s_insert_entry (vfs *me, vfs_s_inode
143  }  }
144    
145  struct stat *  struct stat *
146  vfs_s_default_stat (vfs *me, mode_t mode)  vfs_s_default_stat (struct vfs_class *me, mode_t mode)
147  {  {
148      static struct stat st;      static struct stat st;
149      int myumask;      int myumask;
# Line 164  vfs_s_default_stat (vfs *me, mode_t mode Line 165  vfs_s_default_stat (vfs *me, mode_t mode
165  }  }
166    
167  void  void
168  vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent)  vfs_s_add_dots (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_inode *parent)
169  {  {
170      struct vfs_s_entry *dot, *dotdot;      struct vfs_s_entry *dot, *dotdot;
171    
# Line 179  vfs_s_add_dots (vfs *me, vfs_s_inode *di Line 180  vfs_s_add_dots (vfs *me, vfs_s_inode *di
180  }  }
181    
182  struct vfs_s_entry *  struct vfs_s_entry *
183  vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, mode_t mode)  vfs_s_generate_entry (struct vfs_class *me, char *name, struct vfs_s_inode *parent, mode_t mode)
184  {  {
185      struct vfs_s_inode *inode;      struct vfs_s_inode *inode;
186      struct stat *st;      struct stat *st;
# Line 193  vfs_s_generate_entry (vfs *me, char *nam Line 194  vfs_s_generate_entry (vfs *me, char *nam
194  }  }
195    
196  /* We were asked to create entries automagically */  /* We were asked to create entries automagically */
197  vfs_s_entry *  static struct vfs_s_entry *
198  vfs_s_automake (vfs *me, vfs_s_inode *dir, char *path, int flags)  vfs_s_automake (struct vfs_class *me, struct vfs_s_inode *dir, char *path, int flags)
199  {  {
200      struct vfs_s_entry *res;      struct vfs_s_entry *res;
201      char *sep = strchr (path, PATH_SEP);      char *sep = strchr (path, PATH_SEP);
# Line 210  vfs_s_automake (vfs *me, vfs_s_inode *di Line 211  vfs_s_automake (vfs *me, vfs_s_inode *di
211      return res;      return res;
212  }  }
213    
214    /* If the entry is a symlink, find the entry for its target */
215    static struct vfs_s_entry *
216    vfs_s_resolve_symlink (struct vfs_class *me, struct vfs_s_entry *entry,
217                           char *path, int follow)
218    {
219        char *linkname;
220        char *fullname = NULL;
221        struct vfs_s_entry *target;
222    
223        if (follow == LINK_NO_FOLLOW)
224            return entry;
225        if (follow == 0)
226            ERRNOR (ELOOP, NULL);
227        if (!entry)
228            ERRNOR (ENOENT, NULL);
229        if (!S_ISLNK (entry->ino->st.st_mode))
230            return entry;
231    
232        linkname = entry->ino->linkname;
233        if (linkname == NULL)
234            ERRNOR (EFAULT, NULL);
235    
236        /* make full path from relative */
237        if (*linkname != PATH_SEP) {
238            char *fullpath = vfs_s_fullpath (me, entry->dir);
239            fullname = g_strdup_printf ("%s/%s", fullpath, linkname);
240            linkname = fullname;
241            g_free (fullpath);
242        }
243    
244        target =
245            (MEDATA->find_entry) (me, entry->dir->super->root, linkname,
246                                  follow - 1, 0);
247        g_free (fullname);
248        return target;
249    }
250    
251  /*  /*
252   * Follow > 0: follow links, serves as loop protect,   * Follow > 0: follow links, serves as loop protect,
253   *       == -1: do not follow links   *       == -1: do not follow links
254   */   */
255  vfs_s_entry *  struct vfs_s_entry *
256  vfs_s_find_entry_tree (vfs *me, vfs_s_inode *root, char *path, int follow, int flags)  vfs_s_find_entry_tree (struct vfs_class *me, struct vfs_s_inode *root,
257                           char *path, int follow, int flags)
258  {  {
259      unsigned int pseg;      unsigned int pseg;
260      vfs_s_entry *ent = NULL;      struct vfs_s_entry *ent = NULL;
261      char p[MC_MAXPATHLEN] = "";      char p[MC_MAXPATHLEN] = "";
262    
263      while (root){      if (strlen(path) >= MC_MAXPATHLEN)
264            return NULL;
265    
266        while (root) {
267          int t;          int t;
268    
269          while (*path == PATH_SEP)       /* Strip leading '/' */          while (*path == PATH_SEP)       /* Strip leading '/' */
270              path++;              path++;
271    
272          if (!path [0])          if (!path[0])
273              return ent;              return ent;
274    
275          for (pseg = 0; path[pseg] && path[pseg] != PATH_SEP; pseg++)          for (pseg = 0; path[pseg] && path[pseg] != PATH_SEP; pseg++);
                 ;  
276    
277          strcat (p, PATH_SEP_STR);          strcat (p, PATH_SEP_STR);
278          strncpy (p + (t = strlen (p)), path, pseg);          strncpy (p + (t = strlen (p)), path, pseg);
279          p[t + pseg] = '\0';          p[t + pseg] = '\0';
280    
281          for (ent = root->subdir; ent != NULL; ent = ent->next)          for (ent = root->subdir; ent != NULL; ent = ent->next)
282              if (strlen (ent->name) == pseg && (!strncmp (ent->name, path, pseg)))              if (strlen (ent->name) == pseg
283                    && (!strncmp (ent->name, path, pseg)))
284                  /* FOUND! */                  /* FOUND! */
285                  break;                  break;
286    
287          if (!ent && (flags & (FL_MKFILE | FL_MKDIR)))          if (!ent && (flags & (FL_MKFILE | FL_MKDIR)))
288              ent = vfs_s_automake (me, root, path, flags);              ent = vfs_s_automake (me, root, path, flags);
289          if (!ent) ERRNOR (ENOENT, NULL);          if (!ent)
290                ERRNOR (ENOENT, NULL);
291          path += pseg;          path += pseg;
292  /* here we must follow leading directories always; only the actual file is optional */          /* here we must follow leading directories always;
293          if (!(ent = vfs_s_resolve_symlink (me, ent, p, strchr (path, PATH_SEP) ? LINK_FOLLOW : follow)))             only the actual file is optional */
294            ent =
295                vfs_s_resolve_symlink (me, ent, p,
296                                       strchr (path,
297                                               PATH_SEP) ? LINK_FOLLOW :
298                                       follow);
299            if (!ent)
300              return NULL;              return NULL;
301          root = ent->ino;          root = ent->ino;
302      }      }
# Line 256  vfs_s_find_entry_tree (vfs *me, vfs_s_in Line 305  vfs_s_find_entry_tree (vfs *me, vfs_s_in
305  }  }
306    
307  static void  static void
308  split_dir_name (vfs *me, char *path, char **dir, char **name, char **save)  split_dir_name (struct vfs_class *me, char *path, char **dir, char **name, char **save)
309  {  {
310      char *s;      char *s;
311      s = strrchr (path, PATH_SEP);      s = strrchr (path, PATH_SEP);
# Line 272  split_dir_name (vfs *me, char *path, cha Line 321  split_dir_name (vfs *me, char *path, cha
321      }      }
322  }  }
323    
324  vfs_s_entry *  struct vfs_s_entry *
325  vfs_s_find_entry_linear (vfs *me, vfs_s_inode *root, char *path, int follow, int flags)  vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root, char *path, int follow, int flags)
326  {  {
327      vfs_s_entry* ent = NULL;      struct vfs_s_entry* ent = NULL;
328    
329      if (root->super->root != root)      if (root->super->root != root)
330          vfs_die ("We have to use _real_ root. Always. Sorry." );          vfs_die ("We have to use _real_ root. Always. Sorry." );
# Line 284  vfs_s_find_entry_linear (vfs *me, vfs_s_ Line 333  vfs_s_find_entry_linear (vfs *me, vfs_s_
333    
334      if (!(flags & FL_DIR)){      if (!(flags & FL_DIR)){
335          char *dirname, *name, *save;          char *dirname, *name, *save;
336          vfs_s_inode *ino;          struct vfs_s_inode *ino;
337          split_dir_name (me, path, &dirname, &name, &save);          split_dir_name (me, path, &dirname, &name, &save);
338          ino = vfs_s_find_inode (me, root, dirname, follow, flags | FL_DIR);          ino = vfs_s_find_inode (me, root, dirname, follow, flags | FL_DIR);
339          if (save)          if (save)
# Line 305  vfs_s_find_entry_linear (vfs *me, vfs_s_ Line 354  vfs_s_find_entry_linear (vfs *me, vfs_s_
354      }      }
355    
356      if (!ent){      if (!ent){
357          vfs_s_inode *ino;          struct vfs_s_inode *ino;
358    
359          ino = vfs_s_new_inode (me, root->super, vfs_s_default_stat (me, S_IFDIR | 0755));          ino = vfs_s_new_inode (me, root->super, vfs_s_default_stat (me, S_IFDIR | 0755));
360          ent = vfs_s_new_entry (me, path, ino);          ent = vfs_s_new_entry (me, path, ino);
# Line 328  vfs_s_find_entry_linear (vfs *me, vfs_s_ Line 377  vfs_s_find_entry_linear (vfs *me, vfs_s_
377      return ent;      return ent;
378  }  }
379    
380  vfs_s_inode *  struct vfs_s_inode *
381  vfs_s_find_inode (vfs *me, vfs_s_inode *root, char *path, int follow, int flags)  vfs_s_find_inode (struct vfs_class *me, struct vfs_s_inode *root, char *path, int follow, int flags)
382  {  {
383      vfs_s_entry *ent;      struct vfs_s_entry *ent;
384      if ((MEDATA->find_entry == vfs_s_find_entry_tree) && (!*path))      if ((MEDATA->find_entry == vfs_s_find_entry_tree) && (!*path))
385          return root;          return root;
386      ent = (MEDATA->find_entry)(me, root, path, follow, flags);      ent = (MEDATA->find_entry)(me, root, path, follow, flags);
# Line 340  vfs_s_find_inode (vfs *me, vfs_s_inode * Line 389  vfs_s_find_inode (vfs *me, vfs_s_inode *
389      return ent->ino;      return ent->ino;
390  }  }
391    
 vfs_s_entry *  
 vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry, char *path, int follow)  
 {  
     char buf[MC_MAXPATHLEN], *linkname;  
   
     if (follow == LINK_NO_FOLLOW)  
         return entry;  
     if (follow == 0)  
         ERRNOR (ELOOP, NULL);  
     if (!entry)  
         ERRNOR (ENOENT, NULL);  
     if (!S_ISLNK (entry->ino->st.st_mode))  
         return entry;  
   
     linkname = entry->ino->linkname;  
   
     if (linkname == NULL)  
         ERRNOR (EFAULT, NULL);  
   
     if (MEDATA->find_entry == vfs_s_find_entry_linear) {  
         if (*linkname == PATH_SEP)  
             return (MEDATA->find_entry) (me, entry->dir->super->root,  
                                          linkname, follow - 1, 0);  
         else {  
             char *fullpath = vfs_s_fullpath (me, entry->dir);  
   
             g_snprintf (buf, sizeof (buf), "%s/%s", fullpath, linkname);  
             g_free (fullpath);  
             return (MEDATA->find_entry) (me, entry->dir->super->root, buf,  
                                          follow - 1, 0);  
         }  
     }  
   
     /* Convert absolute paths to relative ones */  
     if (*linkname == PATH_SEP) {  
         char *p, *q;  
   
         for (p = path, q = entry->ino->linkname; *p == *q; p++, q++);  
         while (*(--q) != PATH_SEP);  
         q++;  
         for (;; p++) {  
             p = strchr (p, PATH_SEP);  
             if (!p) {  
                 strcat (buf, q);  
                 break;  
             }  
             strcat (buf, "..");  
             strcat (buf, PATH_SEP_STR);  
         }  
         linkname = buf;  
     }  
   
     return (MEDATA->find_entry) (me, entry->dir, linkname, follow - 1, 0);  
 }  
   
392  /* Ook, these were functions around directory entries / inodes */  /* Ook, these were functions around directory entries / inodes */
393  /* -------------------------------- superblock games -------------------------- */  /* -------------------------------- superblock games -------------------------- */
394    
395  vfs_s_super *  static struct vfs_s_super *
396  vfs_s_new_super (vfs *me)  vfs_s_new_super (struct vfs_class *me)
397  {  {
398      vfs_s_super *super;      struct vfs_s_super *super;
399    
400      super = g_new0 (struct vfs_s_super, 1);      super = g_new0 (struct vfs_s_super, 1);
401      super->me = me;      super->me = me;
# Line 409  vfs_s_new_super (vfs *me) Line 403  vfs_s_new_super (vfs *me)
403  }  }
404    
405  static void  static void
406  vfs_s_insert_super (vfs *me, vfs_s_super *super)  vfs_s_insert_super (struct vfs_class *me, struct vfs_s_super *super)
407  {  {
408      super->next = MEDATA->supers;      super->next = MEDATA->supers;
409      super->prevp = &MEDATA->supers;      super->prevp = &MEDATA->supers;
# Line 419  vfs_s_insert_super (vfs *me, vfs_s_super Line 413  vfs_s_insert_super (vfs *me, vfs_s_super
413      MEDATA->supers = super;      MEDATA->supers = super;
414  }  }
415    
416  void  static void
417  vfs_s_free_super (vfs *me, vfs_s_super *super)  vfs_s_free_super (struct vfs_class *me, struct vfs_s_super *super)
418  {  {
419      if (super->root){      if (super->root){
420          vfs_s_free_inode (me, super->root);          vfs_s_free_inode (me, super->root);
# Line 453  vfs_s_free_super (vfs *me, vfs_s_super * Line 447  vfs_s_free_super (vfs *me, vfs_s_super *
447  /* ------------------------------------------------------------------------= */  /* ------------------------------------------------------------------------= */
448    
449  static void  static void
450  vfs_s_stamp_me (vfs *me, struct vfs_s_super *psup, char *fs_name)  vfs_s_stamp_me (struct vfs_class *me, struct vfs_s_super *psup, char *fs_name)
451  {  {
452      struct vfs_stamping *parent;      struct vfs_stamping *parent;
453      vfs *v;      struct vfs_class *v;
454    
455      v = vfs_type (fs_name);      v = vfs_get_class (fs_name);
456      if (v == &vfs_local_ops){      if (v->flags & VFSF_LOCAL){
457          parent = NULL;          parent = NULL;
458      } else {      } else {
459          parent = g_new (struct vfs_stamping, 1);          parent = g_new (struct vfs_stamping, 1);
# Line 468  vfs_s_stamp_me (vfs *me, struct vfs_s_su Line 462  vfs_s_stamp_me (vfs *me, struct vfs_s_su
462          parent->id = (*v->getid) (v, fs_name, &(parent->parent));          parent->id = (*v->getid) (v, fs_name, &(parent->parent));
463      }      }
464      vfs_add_noncurrent_stamps (me, (vfsid) psup, parent);      vfs_add_noncurrent_stamps (me, (vfsid) psup, parent);
     vfs_rm_parents (parent);  
465  }  }
466    
467  char *  char *
468  vfs_s_get_path_mangle (vfs *me, char *inname, struct vfs_s_super **archive, int flags)  vfs_s_get_path_mangle (struct vfs_class *me, char *inname, struct vfs_s_super **archive, int flags)
469  {  {
470      char *local, *op, *archive_name;      char *local, *op, *archive_name;
471      int result = -1;      int result = -1;
# Line 518  return_success: Line 511  return_success:
511      return local;      return local;
512  }  }
513    
514  char *  static char *
515  vfs_s_get_path (vfs *me, char *inname, struct vfs_s_super **archive, int flags)  vfs_s_get_path (struct vfs_class *me, const char *inname, struct vfs_s_super **archive, int flags)
516  {  {
517      char *buf = g_strdup( inname );      char *buf = g_strdup( inname );
518      char *res = vfs_s_get_path_mangle (me, buf, archive, flags);      char *res = vfs_s_get_path_mangle (me, buf, archive, flags);
# Line 530  vfs_s_get_path (vfs *me, char *inname, s Line 523  vfs_s_get_path (vfs *me, char *inname, s
523  }  }
524    
525  void  void
526  vfs_s_invalidate (vfs *me, vfs_s_super *super)  vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super)
527  {  {
528      if (!super->want_stale){      if (!super->want_stale){
529          vfs_s_free_inode (me, super->root);          vfs_s_free_inode (me, super->root);
# Line 539  vfs_s_invalidate (vfs *me, vfs_s_super * Line 532  vfs_s_invalidate (vfs *me, vfs_s_super *
532  }  }
533    
534  char *  char *
535  vfs_s_fullpath (vfs *me, vfs_s_inode *ino)  vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino)
536  {  {
537  /* For now, usable only on filesystems with _linear structure */      if (!ino->ent)
     if (MEDATA->find_entry != vfs_s_find_entry_linear)  
         vfs_die ("Implement me!");  
     if (!ino->ent) /* That must be directory... */  
538          ERRNOR (EAGAIN, NULL);          ERRNOR (EAGAIN, NULL);
539    
540      if ((!ino->ent->dir) || (!ino->ent->dir->ent)) /* It must be directory */      if (MEDATA->find_entry != vfs_s_find_entry_linear) {
541          return g_strdup (ino->ent->name);          char *newpath;
542            char *path = g_strdup (ino->ent->name);
543            while (1) {
544                ino = ino->ent->dir;
545                if (ino == ino->super->root)
546                    break;
547                newpath = g_strdup_printf ("%s/%s", ino->ent->name, path);
548                g_free (path);
549                path = newpath;
550            }
551            return path;
552        }
553    
554        /* It must be directory */
555        if ((!ino->ent->dir) || (!ino->ent->dir->ent))
556            return g_strdup (ino->ent->name);
557    
558      return  g_strconcat (ino->ent->dir->ent->name, PATH_SEP_STR,      return g_strconcat (ino->ent->dir->ent->name, PATH_SEP_STR,
559                              ino->ent->name, NULL);                          ino->ent->name, NULL);
560  }  }
561    
562  /* Support of archives */  /* Support of archives */
563  /* ------------------------ readdir & friends ----------------------------- */  /* ------------------------ readdir & friends ----------------------------- */
564    
565  vfs_s_super *vfs_s_super_from_path (vfs *me, char *name)  static struct vfs_s_inode *
566  {  vfs_s_inode_from_path (struct vfs_class *me, char *name, int flags)
     struct vfs_s_super *super;  
   
     if (!vfs_s_get_path_mangle (me, name, &super, 0))  
         return NULL;  
     return super;  
 }  
   
 vfs_s_inode *  
 vfs_s_inode_from_path (vfs *me, char *name, int flags)  
567  {  {
568      struct vfs_s_super *super;      struct vfs_s_super *super;
569      struct vfs_s_inode *ino;      struct vfs_s_inode *ino;
# Line 584  vfs_s_inode_from_path (vfs *me, char *na Line 580  vfs_s_inode_from_path (vfs *me, char *na
580  }  }
581    
582  struct dirhandle {  struct dirhandle {
583      vfs_s_entry *cur;      struct vfs_s_entry *cur;
584      vfs_s_inode *dir;      struct vfs_s_inode *dir;
585  };  };
586    
587  void *  static void *
588  vfs_s_opendir (vfs *me, char *dirname)  vfs_s_opendir (struct vfs_class *me, char *dirname)
589  {  {
590      struct vfs_s_inode *dir;      struct vfs_s_inode *dir;
591      struct dirhandle *info;      struct dirhandle *info;
# Line 612  vfs_s_opendir (vfs *me, char *dirname) Line 608  vfs_s_opendir (vfs *me, char *dirname)
608      return info;      return info;
609  }  }
610    
611  void *  static void *
612  vfs_s_readdir(void *data)  vfs_s_readdir(void *data)
613  {  {
614      static union vfs_dirent dir;      static union vfs_dirent dir;
# Line 634  vfs_s_readdir(void *data) Line 630  vfs_s_readdir(void *data)
630      return (void *) &dir;      return (void *) &dir;
631  }  }
632    
633  int  static int
 vfs_s_telldir (void *data)  
 {  
     struct dirhandle *info = (struct dirhandle *) data;  
     struct vfs_s_entry *cur;  
     int num = 0;  
   
     cur = info->dir->subdir;  
     while (cur!=NULL){  
         if (cur == info->cur)  
             return num;  
         num++;  
         cur = cur->next;  
     }  
     return -1;  
 }  
   
 void  
 vfs_s_seekdir (void *data, int offset)  
 {  
     struct dirhandle *info = (struct dirhandle *) data;  
     int i;  
     info->cur = info->dir->subdir;  
     for (i=0; i<offset; i++)  
         vfs_s_readdir (data);  
 }  
   
 int  
634  vfs_s_closedir (void *data)  vfs_s_closedir (void *data)
635  {  {
636      struct dirhandle *info = (struct dirhandle *) data;      struct dirhandle *info = (struct dirhandle *) data;
# Line 672  vfs_s_closedir (void *data) Line 641  vfs_s_closedir (void *data)
641      return 0;      return 0;
642  }  }
643    
644  int  static int
645  vfs_s_chdir (vfs *me, char *path)  vfs_s_chdir (struct vfs_class *me, char *path)
646  {  {
647      void *data;      void *data;
648      if (!(data = vfs_s_opendir (me, path)))      if (!(data = vfs_s_opendir (me, path)))
# Line 685  vfs_s_chdir (vfs *me, char *path) Line 654  vfs_s_chdir (vfs *me, char *path)
654  /* --------------------------- stat and friends ---------------------------- */  /* --------------------------- stat and friends ---------------------------- */
655    
656  static int  static int
657  vfs_s_internal_stat (vfs *me, char *path, struct stat *buf, int flag)  vfs_s_internal_stat (struct vfs_class *me, char *path, struct stat *buf, int flag)
658  {  {
659      struct vfs_s_inode *ino;      struct vfs_s_inode *ino;
660    
# Line 695  vfs_s_internal_stat (vfs *me, char *path Line 664  vfs_s_internal_stat (vfs *me, char *path
664      return 0;      return 0;
665  }  }
666    
667  int  static int
668  vfs_s_stat (vfs *me, char *path, struct stat *buf)  vfs_s_stat (struct vfs_class *me, char *path, struct stat *buf)
669  {  {
670      return vfs_s_internal_stat (me, path, buf, FL_FOLLOW);      return vfs_s_internal_stat (me, path, buf, FL_FOLLOW);
671  }  }
672    
673  int  static int
674  vfs_s_lstat (vfs *me, char *path, struct stat *buf)  vfs_s_lstat (struct vfs_class *me, char *path, struct stat *buf)
675  {  {
676      return vfs_s_internal_stat (me, path, buf, FL_NONE);      return vfs_s_internal_stat (me, path, buf, FL_NONE);
677  }  }
678    
679  int  static int
680  vfs_s_fstat (void *fh, struct stat *buf)  vfs_s_fstat (void *fh, struct stat *buf)
681  {  {
682      *buf = FH->ino->st;      *buf = FH->ino->st;
683      return 0;      return 0;
684  }  }
685    
686  int  static int
687  vfs_s_readlink (vfs *me, char *path, char *buf, int size)  vfs_s_readlink (struct vfs_class *me, char *path, char *buf, int size)
688  {  {
689      struct vfs_s_inode *ino;      struct vfs_s_inode *ino;
690    
# Line 734  vfs_s_readlink (vfs *me, char *path, cha Line 703  vfs_s_readlink (vfs *me, char *path, cha
703      return strlen (buf);      return strlen (buf);
704  }  }
705    
706  void *  static void *
707  vfs_s_open (vfs *me, char *file, int flags, int mode)  vfs_s_open (struct vfs_class *me, char *file, int flags, int mode)
708  {  {
709      int was_changed = 0;      int was_changed = 0;
710      struct vfs_s_fh *fh;      struct vfs_s_fh *fh;
711      vfs_s_super *super;      struct vfs_s_super *super;
712      char *q;      char *q;
713      struct vfs_s_inode *ino;      struct vfs_s_inode *ino;
714    
# Line 750  vfs_s_open (vfs *me, char *file, int fla Line 719  vfs_s_open (vfs *me, char *file, int fla
719          ERRNOR (EEXIST, NULL);          ERRNOR (EEXIST, NULL);
720      if (!ino){      if (!ino){
721          char *dirname, *name, *save;          char *dirname, *name, *save;
722          vfs_s_entry *ent;          struct vfs_s_entry *ent;
723          vfs_s_inode *dir;          struct vfs_s_inode *dir;
724          int tmp_handle;          int tmp_handle;
725    
726          /* If the filesystem is read-only, disable file creation */          /* If the filesystem is read-only, disable file creation */
# Line 812  vfs_s_open (vfs *me, char *file, int fla Line 781  vfs_s_open (vfs *me, char *file, int fla
781      return fh;      return fh;
782  }  }
783    
784  int  static int
785  vfs_s_read (void *fh, char *buffer, int count)  vfs_s_read (void *fh, char *buffer, int count)
786  {  {
787      int n;      int n;
788      vfs *me = FH_SUPER->me;      struct vfs_class *me = FH_SUPER->me;
789    
790      if (FH->linear == LS_LINEAR_CLOSED)      if (FH->linear == LS_LINEAR_CLOSED)
791          vfs_die ("linear_start() did not set linear_state!");          vfs_die ("linear_start() did not set linear_state!");
# Line 834  vfs_s_read (void *fh, char *buffer, int Line 803  vfs_s_read (void *fh, char *buffer, int
803      return -1;      return -1;
804  }  }
805    
806  int  static int
807  vfs_s_write (void *fh, char *buffer, int count)  vfs_s_write (void *fh, char *buffer, int count)
808  {  {
809      int n;      int n;
810      vfs *me = FH_SUPER->me;      struct vfs_class *me = FH_SUPER->me;
811            
812      if (FH->linear)      if (FH->linear)
813          vfs_die ("no writing to linear files, please");          vfs_die ("no writing to linear files, please");
# Line 854  vfs_s_write (void *fh, char *buffer, int Line 823  vfs_s_write (void *fh, char *buffer, int
823      return 0;      return 0;
824  }  }
825    
826  int  static int
827  vfs_s_lseek (void *fh, off_t offset, int whence)  vfs_s_lseek (void *fh, off_t offset, int whence)
828  {  {
829      off_t size = FH->ino->st.st_size;      off_t size = FH->ino->st.st_size;
# Line 881  vfs_s_lseek (void *fh, off_t offset, int Line 850  vfs_s_lseek (void *fh, off_t offset, int
850      return FH->pos;      return FH->pos;
851  }  }
852    
853  int  static int
854  vfs_s_close (void *fh)  vfs_s_close (void *fh)
855  {  {
856      int res = 0;      int res = 0;
857      vfs *me = FH_SUPER->me;      struct vfs_class *me = FH_SUPER->me;
858    
859      FH_SUPER->fd_usage--;      FH_SUPER->fd_usage--;
860      if (!FH_SUPER->fd_usage){      if (!FH_SUPER->fd_usage){
861          struct vfs_stamping *parent;          struct vfs_stamping *parent;
862          vfs *v;          struct vfs_class *v;
863                    
864          v = vfs_type (FH_SUPER->name);          v = vfs_get_class (FH_SUPER->name);
865          if (v == &vfs_local_ops){          if (v->flags & VFSF_LOCAL) {
866              parent = NULL;              parent = NULL;
867          } else {          } else {
868              parent = g_new (struct vfs_stamping, 1);              parent = g_new (struct vfs_stamping, 1);
# Line 902  vfs_s_close (void *fh) Line 871  vfs_s_close (void *fh)
871              parent->id = (*v->getid) (v, FH_SUPER->name, &(parent->parent));              parent->id = (*v->getid) (v, FH_SUPER->name, &(parent->parent));
872          }          }
873          vfs_add_noncurrent_stamps (me, (vfsid) (FH_SUPER), parent);          vfs_add_noncurrent_stamps (me, (vfsid) (FH_SUPER), parent);
         vfs_rm_parents (parent);  
874      }      }
875      if (FH->linear == LS_LINEAR_OPEN)      if (FH->linear == LS_LINEAR_OPEN)
876          MEDATA->linear_close (me, fh);          MEDATA->linear_close (me, fh);
# Line 927  vfs_s_close (void *fh) Line 895  vfs_s_close (void *fh)
895  }  }
896    
897  int  int
898  vfs_s_retrieve_file (vfs *me, struct vfs_s_inode *ino)  vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino)
899  {  {
900      /* If you want reget, you'll have to open file with O_LINEAR */      /* If you want reget, you'll have to open file with O_LINEAR */
901      off_t total = 0;      off_t total = 0;
# Line 991  vfs_s_retrieve_file (vfs *me, struct vfs Line 959  vfs_s_retrieve_file (vfs *me, struct vfs
959    
960  /* ------------------------------- mc support ---------------------------- */  /* ------------------------------- mc support ---------------------------- */
961    
962  void  static void
963  vfs_s_fill_names (vfs *me, void (*func)(char *))  vfs_s_fill_names (struct vfs_class *me, void (*func)(char *))
964  {  {
965      struct vfs_s_super *a = MEDATA->supers;      struct vfs_s_super *a = MEDATA->supers;
966      char *name;      char *name;
# Line 1005  vfs_s_fill_names (vfs *me, void (*func)( Line 973  vfs_s_fill_names (vfs *me, void (*func)(
973      }      }
974  }  }
975    
976  int  static int
977  vfs_s_ferrno (vfs *me)  vfs_s_ferrno (struct vfs_class *me)
978  {  {
979      return me->verrno;      return me->verrno;
980  }  }
981    
982  void  static char *
983  vfs_s_dump (vfs *me, char *prefix, vfs_s_inode *ino)  vfs_s_getlocalcopy (struct vfs_class *me, char *path)
 {  
     printf ("%s %s %d ", prefix, S_ISDIR (ino->st.st_mode) ? "DIR" : "FILE", ino->st.st_mode);  
     if (!ino->subdir)  
         printf ("FILE\n");  
     else  
     {  
         struct vfs_s_entry *ent;  
         for (ent = ino->subdir; ent ; ent = ent->next){  
             char *s = g_strconcat (prefix, "/", ent->name, NULL);  
             if (ent->name[0] == '.')  
                 printf ("%s IGNORED\n", s);  
             else  
                 vfs_s_dump (me, s, ent->ino);  
             g_free(s);  
         }  
     }  
 }  
   
 char *  
 vfs_s_getlocalcopy (vfs *me, char *path)  
984  {  {
985      struct vfs_s_inode *ino;      struct vfs_s_inode *ino;
986      char buf[MC_MAXPATHLEN];      char buf[MC_MAXPATHLEN];
# Line 1046  vfs_s_getlocalcopy (vfs *me, char *path) Line 994  vfs_s_getlocalcopy (vfs *me, char *path)
994      return g_strdup (ino->localname);      return g_strdup (ino->localname);
995  }  }
996    
997  int  static int
998  vfs_s_setctl (vfs *me, char *path, int ctlop, char *arg)  vfs_s_setctl (struct vfs_class *me, char *path, int ctlop, void *arg)
999  {  {
1000      vfs_s_inode *ino = vfs_s_inode_from_path (me, path, 0);      switch (ctlop) {
1001      if (!ino)      case VFS_SETCTL_STALE_DATA:
1002          return 0;          {
1003      switch (ctlop){              struct vfs_s_inode *ino = vfs_s_inode_from_path (me, path, 0);
1004      case MCCTL_WANT_STALE_DATA:  
1005          ino->super->want_stale = 1;              if (!ino)
1006                    return 0;
1007                if (arg)
1008                    ino->super->want_stale = 1;
1009                else {
1010                    ino->super->want_stale = 0;
1011                    vfs_s_invalidate (me, ino->super);
1012                }
1013                return 1;
1014            }
1015        case VFS_SETCTL_LOGFILE:
1016            MEDATA->logfile = fopen ((char *) arg, "w");
1017          return 1;          return 1;
1018      case MCCTL_NO_STALE_DATA:      case VFS_SETCTL_FLUSH:
1019          ino->super->want_stale = 0;          MEDATA->flush = 1;
         vfs_s_invalidate(me, ino->super);  
1020          return 1;          return 1;
 #if 0   /* FIXME: We should implement these */  
     case MCCTL_REMOVELOCALCOPY:  
         return remove_temp_file (path);  
     case MCCTL_FORGET_ABOUT:  
         my_forget(path);  
         return 0;  
 #endif  
1021      }      }
1022      return 0;      return 0;
1023  }  }
# Line 1074  vfs_s_setctl (vfs *me, char *path, int c Line 1025  vfs_s_setctl (vfs *me, char *path, int c
1025    
1026  /* ----------------------------- Stamping support -------------------------- */  /* ----------------------------- Stamping support -------------------------- */
1027    
1028  vfsid  static vfsid
1029  vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent)  vfs_s_getid (struct vfs_class *me, const char *path, struct vfs_stamping **parent)
1030  {  {
1031      vfs_s_super *archive;      struct vfs_s_super *archive;
1032      vfs *v;      struct vfs_class *v;
1033      char *p;      char *p;
1034      vfsid id;      vfsid id;
1035      struct vfs_stamping *par;      struct vfs_stamping *par;
# Line 1087  vfs_s_getid (vfs *me, char *path, struct Line 1038  vfs_s_getid (vfs *me, char *path, struct
1038      if (!(p = vfs_s_get_path (me, path, &archive, FL_NO_OPEN)))      if (!(p = vfs_s_get_path (me, path, &archive, FL_NO_OPEN)))
1039          return (vfsid) -1;          return (vfsid) -1;
1040      g_free(p);      g_free(p);
1041      v = vfs_type (archive->name);      v = vfs_get_class (archive->name);
1042      id = (*v->getid) (v, archive->name, &par);      id = (*v->getid) (v, archive->name, &par);
1043      if (id != (vfsid)-1){      if (id != (vfsid)-1){
1044          *parent = g_new (struct vfs_stamping, 1);          *parent = g_new (struct vfs_stamping, 1);
# Line 1099  vfs_s_getid (vfs *me, char *path, struct Line 1050  vfs_s_getid (vfs *me, char *path, struct
1050      return (vfsid) archive;          return (vfsid) archive;    
1051  }  }
1052    
1053  int  static int
1054  vfs_s_nothingisopen (vfsid id)  vfs_s_nothingisopen (vfsid id)
1055  {  {
1056    /* Our data structures should survive free of superblock at any time */    /* Our data structures should survive free of superblock at any time */
1057      return 1;      return 1;
1058  }  }
1059    
1060  void  static void
1061  vfs_s_free (vfsid id)  vfs_s_free (vfsid id)
1062  {  {
1063      vfs_s_free_super (((vfs_s_super *)id)->me, (vfs_s_super *)id);      vfs_s_free_super (((struct vfs_s_super *)id)->me, (struct vfs_s_super *)id);
1064    }
1065    
1066    void
1067    vfs_s_init_class (struct vfs_class *vclass)
1068    {
1069        vclass->fill_names = vfs_s_fill_names;
1070        vclass->open = vfs_s_open;
1071        vclass->close = vfs_s_close;
1072        vclass->read = vfs_s_read;
1073        vclass->write = vfs_s_write;
1074        vclass->opendir = vfs_s_opendir;
1075        vclass->readdir = vfs_s_readdir;
1076        vclass->closedir = vfs_s_closedir;
1077        vclass->stat = vfs_s_stat;
1078        vclass->lstat = vfs_s_lstat;
1079        vclass->fstat = vfs_s_fstat;
1080        vclass->readlink = vfs_s_readlink;
1081        vclass->chdir = vfs_s_chdir;
1082        vclass->ferrno = vfs_s_ferrno;
1083        vclass->lseek = vfs_s_lseek;
1084        vclass->getid = vfs_s_getid;
1085        vclass->nothingisopen = vfs_s_nothingisopen;
1086        vclass->free = vfs_s_free;
1087        vclass->getlocalcopy = vfs_s_getlocalcopy;
1088        vclass->setctl = vfs_s_setctl;
1089  }  }
1090    
1091  /* ----------- Utility functions for networked filesystems  -------------- */  /* ----------- Utility functions for networked filesystems  -------------- */
# Line 1139  vfs_s_select_on_two (int fd1, int fd2) Line 1115  vfs_s_select_on_two (int fd1, int fd2)
1115  }  }
1116    
1117  int  int
1118  vfs_s_get_line (vfs *me, int sock, char *buf, int buf_len, char term)  vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char term)
1119  {  {
1120      FILE *logfile = MEDATA->logfile;      FILE *logfile = MEDATA->logfile;
1121      int i, status;      int i, status;
# Line 1172  vfs_s_get_line (vfs *me, int sock, char Line 1148  vfs_s_get_line (vfs *me, int sock, char
1148  }  }
1149    
1150  int  int
1151  vfs_s_get_line_interruptible (vfs *me, char *buffer, int size, int fd)  vfs_s_get_line_interruptible (struct vfs_class *me, char *buffer, int size, int fd)
1152  {  {
1153      int n;      int n;
1154      int i;      int i;

Legend:
Removed from v.1.57  
changed lines
  Added in v.1.75

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26