1
1

* 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 Frdric L. W. Meunier <lists1@pervalidus.net>
Этот коммит содержится в:
Pavel Roskin 2003-10-27 01:26:18 +00:00
родитель 290426d17a
Коммит 511321bcfd
6 изменённых файлов: 52 добавлений и 106 удалений

Просмотреть файл

@ -1,3 +1,13 @@
2003-10-26 Pavel Roskin <proski@gnu.org>
* 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 <lists1@pervalidus.net>
2003-10-25 Pavel Roskin <proski@gnu.org>
* tar.h: Merge into tar.c, as it doesn't provide any external

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <config.h>
#include <sys/types.h>
@ -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;

Просмотреть файл

@ -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);