diff --git a/src/vfs/extfs/extfs.c b/src/vfs/extfs/extfs.c index 1053a07d6..b78b98a0c 100644 --- a/src/vfs/extfs/extfs.c +++ b/src/vfs/extfs/extfs.c @@ -190,31 +190,6 @@ extfs_cmp_archive (const void *a, const void *b) /* --------------------------------------------------------------------------------------------- */ -static void -extfs_make_dots (struct vfs_class *me, struct vfs_s_entry *ent) -{ - struct vfs_s_entry *entry; - struct vfs_s_inode *parent, *inode; - - parent = ent->dir; - inode = ent->ino; - - /* Create "." */ - entry = extfs_entry_new (me, ".", inode); - inode->localname = NULL; - vfs_s_insert_entry (me, inode, entry); - - /* Create ".." */ - if (parent != NULL) - vfs_s_insert_entry (me, parent, extfs_entry_new (me, "..", parent)); - else - vfs_s_insert_entry (me, inode, extfs_entry_new (me, "..", inode)); - - inode->ent = ent; -} - -/* --------------------------------------------------------------------------------------------- */ - static struct vfs_s_entry * extfs_generate_entry (struct extfs_super_t *archive, const char *name, struct vfs_s_inode *parent, mode_t mode) @@ -244,9 +219,6 @@ extfs_generate_entry (struct extfs_super_t *archive, const char *name, struct vf if (parent != NULL) vfs_s_insert_entry (me, parent, entry); - if (S_ISDIR (st.st_mode)) - extfs_make_dots (me, entry); - return entry; } @@ -275,6 +247,8 @@ extfs_find_entry_int (struct vfs_s_inode *dir, const char *name, GSList * list, while ((pent != NULL) && (c != '\0') && (*p != '\0')) { + GList *pl; + q = strchr (p, PATH_SEP); if (q == NULL) q = (char *) name_end; @@ -282,45 +256,37 @@ extfs_find_entry_int (struct vfs_s_inode *dir, const char *name, GSList * list, c = *q; *q = '\0'; - if (!DIR_IS_DOT (p)) + pent = extfs_resolve_symlinks_int (pent, list); + if (pent == NULL) { - if (DIR_IS_DOTDOT (p)) - pent = pent->dir->ent; - else - { - GList *pl; - - pent = extfs_resolve_symlinks_int (pent, list); - if (pent == NULL) - { - *q = c; - return NULL; - } - if (!S_ISDIR (pent->ino->st.st_mode)) - { - *q = c; - notadir = TRUE; - return NULL; - } - - pdir = pent; - pl = g_list_find_custom (pent->ino->subdir, p, vfs_s_entry_compare); - pent = pl != NULL ? VFS_ENTRY (pl->data) : NULL; - if (pent != NULL && q + 1 > name_end) - { - /* Hack: I keep the original semanthic unless q+1 would break in the strchr */ - *q = c; - notadir = !S_ISDIR (pent->ino->st.st_mode); - return pent; - } - - /* When we load archive, we create automagically non-existent directories */ - if (pent == NULL && (flags & FL_MKDIR) != 0) - pent = extfs_generate_entry (super, p, pdir->ino, S_IFDIR | 0777); - if (pent == NULL && (flags & FL_MKFILE) != 0) - pent = extfs_generate_entry (super, p, pdir->ino, S_IFREG | 0666); - } + *q = c; + return NULL; } + + if (!S_ISDIR (pent->ino->st.st_mode)) + { + *q = c; + notadir = TRUE; + return NULL; + } + + pdir = pent; + pl = g_list_find_custom (pent->ino->subdir, p, vfs_s_entry_compare); + pent = pl != NULL ? VFS_ENTRY (pl->data) : NULL; + if (pent != NULL && q + 1 > name_end) + { + /* Hack: I keep the original semanthic unless q+1 would break in the strchr */ + *q = c; + notadir = !S_ISDIR (pent->ino->st.st_mode); + return pent; + } + + /* When we load archive, we create automagically non-existent directories */ + if (pent == NULL && (flags & FL_MKDIR) != 0) + pent = extfs_generate_entry (super, p, pdir->ino, S_IFDIR | 0777); + if (pent == NULL && (flags & FL_MKFILE) != 0) + pent = extfs_generate_entry (super, p, pdir->ino, S_IFREG | 0666); + /* Next iteration */ *q = c; if (c != '\0') @@ -362,6 +328,21 @@ extfs_fill_names (struct vfs_class *me, fill_names_f func) /* --------------------------------------------------------------------------------------------- */ +/* Create this function because VFS_USETMP flag is not used in extfs */ +static void +extfs_free_inode (struct vfs_class *me, struct vfs_s_inode *ino) +{ + (void) me; + + if (ino->localname != NULL) + { + unlink (ino->localname); + MC_PTR_FREE (ino->localname); + } +} + +/* --------------------------------------------------------------------------------------------- */ + static void extfs_free_archive (struct vfs_class *me, struct vfs_s_super *psup) { @@ -517,81 +498,75 @@ extfs_read_archive (FILE * extfsd, struct extfs_super_t *current_archive) q = cfn; } - if (!S_ISDIR (hstat.st_mode) || !(DIR_IS_DOT (p) || DIR_IS_DOTDOT (p))) + if (*q != '\0') { - if (*q != '\0') + pent = extfs_find_entry (super->root, q, FL_MKDIR); + if (pent == NULL) { - pent = extfs_find_entry (super->root, q, FL_MKDIR); - if (pent == NULL) - { - ret = -1; - break; - } + ret = -1; + break; + } + } + + if (pent != NULL) + { + entry = extfs_entry_new (super->me, p, pent->ino); + entry->dir = pent->ino; + pent->ino->subdir = g_list_append (pent->ino->subdir, entry); + } + else + { + entry = extfs_entry_new (super->me, p, super->root); + entry->dir = super->root; + super->root->subdir = g_list_append (super->root->subdir, entry); + } + + if (!S_ISLNK (hstat.st_mode) && (current_link_name != NULL)) + { + pent = extfs_find_entry (super->root, current_link_name, FL_NONE); + if (pent == NULL) + { + ret = -1; + break; } - if (pent != NULL) - { - entry = extfs_entry_new (super->me, p, pent->ino); - entry->dir = pent->ino; - pent->ino->subdir = g_list_append (pent->ino->subdir, entry); - } - else - { - entry = extfs_entry_new (super->me, p, super->root); - entry->dir = super->root; - super->root->subdir = g_list_append (super->root->subdir, entry); - } + pent->ino->st.st_nlink++; + entry->ino = pent->ino; + } + else + { + struct stat st; - if (!S_ISLNK (hstat.st_mode) && (current_link_name != NULL)) - { - pent = extfs_find_entry (super->root, current_link_name, FL_NONE); - if (pent == NULL) - { - ret = -1; - break; - } - - pent->ino->st.st_nlink++; - entry->ino = pent->ino; - } - else - { - struct stat st; - - st.st_ino = super->ino_usage++; - st.st_nlink = 1; - st.st_dev = current_archive->rdev; - st.st_mode = hstat.st_mode; + st.st_ino = super->ino_usage++; + st.st_nlink = 1; + st.st_dev = current_archive->rdev; + st.st_mode = hstat.st_mode; #ifdef HAVE_STRUCT_STAT_ST_RDEV - st.st_rdev = hstat.st_rdev; + st.st_rdev = hstat.st_rdev; #else - st.st_rdev = 0; + st.st_rdev = 0; #endif - st.st_uid = hstat.st_uid; - st.st_gid = hstat.st_gid; - st.st_size = hstat.st_size; - st.st_mtime = hstat.st_mtime; - st.st_atime = hstat.st_atime; - st.st_ctime = hstat.st_ctime; + st.st_uid = hstat.st_uid; + st.st_gid = hstat.st_gid; + st.st_size = hstat.st_size; + st.st_mtime = hstat.st_mtime; + st.st_atime = hstat.st_atime; + st.st_ctime = hstat.st_ctime; - if (current_link_name == NULL || !S_ISLNK (hstat.st_mode)) - { - if (S_ISLNK (hstat.st_mode)) - st.st_mode &= ~S_IFLNK; /* You *DON'T* want to do this always */ - } + if (current_link_name == NULL || !S_ISLNK (hstat.st_mode)) + { + if (S_ISLNK (hstat.st_mode)) + st.st_mode &= ~S_IFLNK; /* You *DON'T* want to do this always */ + } - inode = vfs_s_new_inode (super->me, super, &st); - inode->ent = entry; - entry->ino = inode; + inode = vfs_s_new_inode (super->me, super, &st); + inode->ent = entry; + entry->ino = inode; - if (current_link_name != NULL && S_ISLNK (hstat.st_mode)) - { - VFS_INODE (inode)->linkname = current_link_name; - current_link_name = NULL; - } - - if (S_ISDIR (hstat.st_mode)) - extfs_make_dots (super->me, entry); + if (current_link_name != NULL && S_ISLNK (hstat.st_mode)) + { + VFS_INODE (inode)->linkname = current_link_name; + current_link_name = NULL; } } } @@ -1544,7 +1519,8 @@ extfs_done (struct vfs_class *me) { size_t i; - (void) me; + while (VFS_SUBCLASS (me)->supers != NULL) + me->free ((vfsid) VFS_SUBCLASS (me)->supers->data); if (extfs_plugins == NULL) return; @@ -1611,6 +1587,7 @@ vfs_init_extfs (void) vfs_extfs_ops->mkdir = extfs_mkdir; vfs_extfs_ops->rmdir = extfs_rmdir; vfs_extfs_ops->setctl = extfs_setctl; + extfs_subclass.free_inode = extfs_free_inode; extfs_subclass.free_archive = extfs_free_archive; vfs_register_class (vfs_extfs_ops); } diff --git a/src/vfs/extfs/helpers/README b/src/vfs/extfs/helpers/README index 6a02b167e..5eb2a1091 100644 --- a/src/vfs/extfs/helpers/README +++ b/src/vfs/extfs/helpers/README @@ -80,6 +80,8 @@ means from root of the archive listed). If permissions do not start with l, but number of links is greater than one, then it says that this file should be a hardlinked with the other file. +The result of list command must not contain "." and ".." items. + * Command: copyout archivename storedfilename extractto This should extract from archive archivename the file called