From 511321bcfdc8c340dedbd26ba173602f3258befb Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Mon, 27 Oct 2003 01:26:18 +0000 Subject: [PATCH] =?UTF-8?q?*=20direntry.c=20(vfs=5Fs=5Fadd=5Fdots):=20Remo?= =?UTF-8?q?ve.=20=20Fix=20all=20callers.=20(vfs=5Fs=5Ffree=5Finode):=20Rem?= =?UTF-8?q?ove=20support=20for=20"."=20and=20".."=20entries.=20*=20ftpfs.c?= =?UTF-8?q?=20(dir=5Fload):=20Likewise.=20Support=20for=20"."=20and=20".."?= =?UTF-8?q?=20entries=20was=20a=20hack=20that=20could=20make=20the=20cache?= =?UTF-8?q?=20non-traversible=20from=20inodes=20to=20the=20root=20and=20ca?= =?UTF-8?q?use=20infinite=20loop=20in=20vfs=5Fs=5Ffullpath().=20Reported?= =?UTF-8?q?=20by=20Fr=E9d=E9ric=20L.=20W.=20Meunier=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vfs/ChangeLog | 10 ++++ vfs/cpio.c | 4 -- vfs/direntry.c | 21 +-------- vfs/ftpfs.c | 118 ++++++++++++++++-------------------------------- vfs/tar.c | 3 +- vfs/xdirentry.h | 2 - 6 files changed, 52 insertions(+), 106 deletions(-) diff --git a/vfs/ChangeLog b/vfs/ChangeLog index 49067462d..8f8ce25fb 100644 --- a/vfs/ChangeLog +++ b/vfs/ChangeLog @@ -1,3 +1,13 @@ +2003-10-26 Pavel Roskin + + * direntry.c (vfs_s_add_dots): Remove. Fix all callers. + (vfs_s_free_inode): Remove support for "." and ".." entries. + * ftpfs.c (dir_load): Likewise. + Support for "." and ".." entries was a hack that could make the + cache non-traversible from inodes to the root and cause infinite + loop in vfs_s_fullpath(). + Reported by Frédéric L. W. Meunier + 2003-10-25 Pavel Roskin * tar.h: Merge into tar.c, as it doesn't provide any external diff --git a/vfs/cpio.c b/vfs/cpio.c index e0004c90d..1ca17e7ef 100644 --- a/vfs/cpio.c +++ b/vfs/cpio.c @@ -168,7 +168,6 @@ static int cpio_open_cpio_file(struct vfs_class *me, struct vfs_s_super *super, root->st.st_nlink++; root->st.st_dev = MEDATA->rdev++; - vfs_s_add_dots(me, root, NULL); super->root = root; CPIO_SEEK_SET(super, 0); @@ -479,9 +478,6 @@ static int cpio_create_entry(struct vfs_class *me, struct vfs_s_super *super, st entry = vfs_s_new_entry(me, tn, inode); vfs_s_insert_entry(me, root, entry); - if(S_ISDIR(stat->st_mode)) - vfs_s_add_dots(me, inode, root); - if(S_ISLNK(stat->st_mode)) { inode->linkname = g_malloc(stat->st_size + 1); if(mc_read(super->u.arch.fd, inode->linkname, stat->st_size) < stat->st_size) { diff --git a/vfs/direntry.c b/vfs/direntry.c index d313d3a5b..fc123e6b1 100644 --- a/vfs/direntry.c +++ b/vfs/direntry.c @@ -103,7 +103,6 @@ vfs_s_free_inode (struct vfs_class *me, struct vfs_s_inode *ino) void vfs_s_free_entry (struct vfs_class *me, struct vfs_s_entry *ent) { - int is_dot = 0; if (ent->prevp){ /* It is possible that we are deleting freshly created entry */ *ent->prevp = ent->next; if (ent->next) @@ -111,12 +110,11 @@ vfs_s_free_entry (struct vfs_class *me, struct vfs_s_entry *ent) } if (ent->name){ - is_dot = (!strcmp (ent->name, ".")) || (!strcmp (ent->name, "..")); g_free (ent->name); ent->name = NULL; } - if (!is_dot && ent->ino){ + if (ent->ino){ ent->ino->ent = NULL; vfs_s_free_inode (me, ent->ino); ent->ino = NULL; @@ -163,21 +161,6 @@ vfs_s_default_stat (struct vfs_class *me, mode_t mode) return &st; } -void -vfs_s_add_dots (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_inode *parent) -{ - struct vfs_s_entry *dot, *dotdot; - - if (!parent) - parent = dir; - dot = vfs_s_new_entry (me, ".", dir); - dotdot = vfs_s_new_entry (me, "..", parent); - vfs_s_insert_entry (me, dir, dot); - vfs_s_insert_entry (me, dir, dotdot); - dir->st.st_nlink--; - parent->st.st_nlink--; /* We do not count "." and ".." into nlinks */ -} - struct vfs_s_entry * vfs_s_generate_entry (struct vfs_class *me, char *name, struct vfs_s_inode *parent, mode_t mode) { @@ -186,8 +169,6 @@ vfs_s_generate_entry (struct vfs_class *me, char *name, struct vfs_s_inode *pare st = vfs_s_default_stat (me, mode); inode = vfs_s_new_inode (me, parent->super, st); - if (S_ISDIR (mode)) - vfs_s_add_dots (me, inode, parent); return vfs_s_new_entry (me, name, inode); } diff --git a/vfs/ftpfs.c b/vfs/ftpfs.c index c9c26dc2b..e8a1e5e50 100644 --- a/vfs/ftpfs.c +++ b/vfs/ftpfs.c @@ -1174,47 +1174,49 @@ dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path) struct vfs_s_entry *ent; struct vfs_s_super *super = dir->super; int sock, num_entries = 0; -#ifdef FIXME_LATER - int has_symlinks = 0; -#endif char buffer[BUF_8K]; int cd_first; - + cd_first = ftpfs_first_cd_then_ls || (SUP.strict == RFC_STRICT) || (strchr (remote_path, ' ') != NULL); -again: - print_vfs_message(_("ftpfs: Reading FTP directory %s... %s%s"), remote_path, - SUP.strict == RFC_STRICT ? _("(strict rfc959)") : "", - cd_first ? _("(chdir first)") : ""); + again: + print_vfs_message (_("ftpfs: Reading FTP directory %s... %s%s"), + remote_path, + SUP.strict == + RFC_STRICT ? _("(strict rfc959)") : "", + cd_first ? _("(chdir first)") : ""); if (cd_first) { - char *p; + char *p; - p = translate_path (me, super, remote_path); + p = translate_path (me, super, remote_path); - if (ftpfs_chdir_internal (me, super, p) != COMPLETE) { + if (ftpfs_chdir_internal (me, super, p) != COMPLETE) { g_free (p); - my_errno = ENOENT; - print_vfs_message(_("ftpfs: CWD failed.")); + my_errno = ENOENT; + print_vfs_message (_("ftpfs: CWD failed.")); return -1; - } + } g_free (p); } - gettimeofday(&dir->timestamp, NULL); + gettimeofday (&dir->timestamp, NULL); dir->timestamp.tv_sec += ftpfs_directory_timeout; - if (SUP.strict == RFC_STRICT) - sock = open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0); + if (SUP.strict == RFC_STRICT) + sock = open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0); else if (cd_first) /* Dirty hack to avoid autoprepending / to . */ /* Wu-ftpd produces strange output for '/' if 'LIST -la .' used */ - sock = open_data_connection (me, super, "LIST -la", 0, TYPE_ASCII, 0); + sock = + open_data_connection (me, super, "LIST -la", 0, TYPE_ASCII, 0); else { /* Trailing "/." is necessary if remote_path is a symlink */ char *path = concat_dir_and_file (remote_path, "."); - sock = open_data_connection (me, super, "LIST -la", path, TYPE_ASCII, 0); + sock = + open_data_connection (me, super, "LIST -la", path, TYPE_ASCII, + 0); g_free (path); } @@ -1224,104 +1226,64 @@ again: /* Clear the interrupt flag */ enable_interrupt_key (); -#if 1 - { - /* added 20001006 by gisburn - * add dots '.' and '..'. This must be _executed_ before scanning the dir as the - * code below may jump directly into error handling code (without executing - * remaining code). And C doesn't have try {...} finally {}; :-) - */ - struct vfs_s_inode *parent = dir->ent->dir; - - if( parent==NULL ) - parent = dir; - - ent = vfs_s_generate_entry(me, ".", dir, 0); - ent->ino->st=dir->st; - num_entries++; - vfs_s_insert_entry(me, dir, ent); - - ent = vfs_s_generate_entry(me, "..", parent, 0); - ent->ino->st=parent->st; - num_entries++; - vfs_s_insert_entry(me, dir, ent); - } -#endif - while (1) { int i; - int res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), sock); + int res = + vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), + sock); if (!res) break; if (res == EINTR) { me->verrno = ECONNRESET; close (sock); - disable_interrupt_key(); - get_reply(me, SUP.sock, NULL, 0); + disable_interrupt_key (); + get_reply (me, SUP.sock, NULL, 0); print_vfs_message (_("%s: failure"), me->name); return -1; } - if (MEDATA->logfile){ + if (MEDATA->logfile) { fputs (buffer, MEDATA->logfile); - fputs ("\n", MEDATA->logfile); + fputs ("\n", MEDATA->logfile); fflush (MEDATA->logfile); } - ent = vfs_s_generate_entry(me, NULL, dir, 0); + ent = vfs_s_generate_entry (me, NULL, dir, 0); i = ent->ino->st.st_nlink; - if (!vfs_parse_ls_lga (buffer, &ent->ino->st, &ent->name, &ent->ino->linkname)) { + if (!vfs_parse_ls_lga + (buffer, &ent->ino->st, &ent->name, &ent->ino->linkname)) { vfs_s_free_entry (me, ent); continue; } - ent->ino->st.st_nlink = i; /* Ouch, we need to preserve our counts :-( */ + ent->ino->st.st_nlink = i; /* Ouch, we need to preserve our counts :-( */ num_entries++; - if ((!strcmp(ent->name, ".")) || (!strcmp (ent->name, ".."))) { - g_free (ent->name); - ent->name = NULL; /* Ouch, vfs_s_free_entry "knows" about . and .. being special :-( */ - vfs_s_free_entry (me, ent); - continue; - } - - vfs_s_insert_entry(me, dir, ent); + vfs_s_insert_entry (me, dir, ent); } - /* vfs_s_add_dots(me, dir, NULL); - FIXME This really should be here; but we need to provide correct parent. - Disabled for now, please fix it. Pavel - */ - close(sock); + close (sock); me->verrno = E_REMOTE; if ((get_reply (me, SUP.sock, NULL, 0) != COMPLETE) || !num_entries) - goto fallback; + goto fallback; if (SUP.strict == RFC_AUTODETECT) SUP.strict = RFC_DARING; -#ifdef FIXME_LATER - if (has_symlinks) { - if (resolve_symlinks) - resolve_symlink(me, super, dcache); - else - dcache->symlink_status = FTPFS_UNRESOLVED_SYMLINKS; - } -#endif print_vfs_message (_("%s: done."), me->name); return 0; -fallback: + fallback: if (SUP.strict == RFC_AUTODETECT) { - /* It's our first attempt to get a directory listing from this - server (UNIX style LIST command) */ + /* It's our first attempt to get a directory listing from this + server (UNIX style LIST command) */ SUP.strict = RFC_STRICT; /* I hate goto, but recursive call needs another 8K on stack */ /* return dir_load (me, dir, remote_path); */ cd_first = 1; goto again; } - print_vfs_message(_("ftpfs: failed; nowhere to fallback to")); - ERRNOR(-1, EACCES); + print_vfs_message (_("ftpfs: failed; nowhere to fallback to")); + ERRNOR (-1, EACCES); } static int diff --git a/vfs/tar.c b/vfs/tar.c index 9c0571df1..5203cf597 100644 --- a/vfs/tar.c +++ b/vfs/tar.c @@ -18,7 +18,7 @@ License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Namespace: vfs_tarfs_ops */ +/* Namespace: init_tarfs */ #include #include @@ -242,7 +242,6 @@ static int tar_open_archive (struct vfs_class *me, char *name, struct vfs_s_supe root->st.st_nlink++; root->st.st_dev = MEDATA->rdev++; - vfs_s_add_dots (me, root, NULL); archive->root = root; return result; diff --git a/vfs/xdirentry.h b/vfs/xdirentry.h index cc930f0f0..da0f1cf9e 100644 --- a/vfs/xdirentry.h +++ b/vfs/xdirentry.h @@ -161,8 +161,6 @@ void vfs_s_insert_entry (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_entry *ent); struct stat *vfs_s_default_stat (struct vfs_class *me, mode_t mode); -void vfs_s_add_dots (struct vfs_class *me, struct vfs_s_inode *dir, - struct vfs_s_inode *parent); struct vfs_s_entry *vfs_s_generate_entry (struct vfs_class *me, char *name, struct vfs_s_inode *parent, mode_t mode);