Пример #1
0
/* @After */
static void
teardown (void)
{
    vfs_s_free_entry (&vfs_test_ops1, vfs_root_entry);
    vfs_shut ();
    str_uninit_strings ();
}
Пример #2
0
static void
vfs_s_free_inode (struct vfs_class *me, struct vfs_s_inode *ino)
{
    if (!ino)
	vfs_die ("Don't pass NULL to me");

    /* ==0 can happen if freshly created entry is deleted */
    if (ino->st.st_nlink <= 1){
	while (ino->subdir){
	    vfs_s_free_entry (me, ino->subdir);
	}

	CALL (free_inode) (me, ino);
	g_free (ino->linkname);
	if (ino->localname){
	    unlink (ino->localname);
	    g_free(ino->localname);
	}
	total_inodes--;
	ino->super->ino_usage--;
	g_free(ino);
    } else ino->st.st_nlink--;
}
Пример #3
0
static struct vfs_s_entry *
vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
			 const char *a_path, int follow, int flags)
{
    struct vfs_s_entry *ent = NULL;
    char * const path = g_strdup (a_path);
    struct vfs_s_entry *retval = NULL;

    if (root->super->root != root)
	vfs_die ("We have to use _real_ root. Always. Sorry.");

    canonicalize_pathname (path);

    if (!(flags & FL_DIR)) {
	char *dirname, *name, *save;
	struct vfs_s_inode *ino;
	split_dir_name (me, path, &dirname, &name, &save);
	ino =
	    vfs_s_find_inode (me, root->super, dirname, follow,
			      flags | FL_DIR);
	if (save)
	    *save = PATH_SEP;
	retval = vfs_s_find_entry_tree (me, ino, name, follow, flags);
	g_free (path);
	return retval;
    }

    for (ent = root->subdir; ent != NULL; ent = ent->next)
	if (!strcmp (ent->name, path))
	    break;

    if (ent && (!(MEDATA->dir_uptodate) (me, ent->ino))) {
#if 1
	print_vfs_message (_("Directory cache expired for %s"), path);
#endif
	vfs_s_free_entry (me, ent);
	ent = NULL;
    }

    if (!ent) {
	struct vfs_s_inode *ino;

	ino =
	    vfs_s_new_inode (me, root->super,
			     vfs_s_default_stat (me, S_IFDIR | 0755));
	ent = vfs_s_new_entry (me, path, ino);
	if ((MEDATA->dir_load) (me, ino, path) == -1) {
	    vfs_s_free_entry (me, ent);
	    g_free (path);
	    return NULL;
	}
	vfs_s_insert_entry (me, root, ent);

	for (ent = root->subdir; ent != NULL; ent = ent->next)
	    if (!strcmp (ent->name, path))
		break;
    }
    if (!ent)
	vfs_die ("find_linear: success but directory is not there\n");

#if 0
    if (!vfs_s_resolve_symlink (me, ent, follow)) {
    	g_free (path);
	return NULL;
    }
#endif
    g_free (path);
    return ent;
}
Пример #4
0
Файл: fish.c Проект: dborca/mc
static int
fish_dir_load(struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
{
    struct vfs_s_super *super = dir->super;
    char buffer[8192];
    struct vfs_s_entry *ent = NULL;
    FILE *logfile;
    char *quoted_path;

    logfile = MEDATA->logfile;

    print_vfs_message(_("fish: Reading directory %s..."), remote_path);

    gettimeofday(&dir->timestamp, NULL);
    dir->timestamp.tv_sec += fish_directory_timeout;
    quoted_path = name_quote (remote_path, 0);
    fish_command (me, super, NONE,
	    /* XXX no -L here, unless -L in RETR; otherwise we'll be inconsistent */
	    /* XXX The trailing slash is needed to accomodate directory symlinks */
	    "#LIST /%s\n"
	    "ls -lan /%s/ 2>/dev/null | grep '^[^cbt]' | (\n"
	      "while read p l u g s m d y n; do\n"
	        "echo \"P$p $u.$g\nS$s\nd$m $d $y\n:$n\n\"\n"
	      "done\n"
	    ")\n"
	    "ls -lan /%s/ 2>/dev/null | grep '^[cb]' | (\n"
	      "while read p l u g a i m d y n; do\n"
	        "echo \"P$p $u.$g\nE$a$i\nd$m $d $y\n:$n\n\"\n"
	      "done\n"
	    ")\n"
	    "echo '### 200'\n",
	    remote_path, quoted_path, quoted_path);
    g_free (quoted_path);
    ent = vfs_s_generate_entry(me, NULL, dir, 0);
    while (1) {
	int res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), SUP.sockr); 
	if ((!res) || (res == EINTR)) {
	    vfs_s_free_entry(me, ent);
	    me->verrno = ECONNRESET;
	    goto error;
	}
	if (logfile) {
	    fputs (buffer, logfile);
            fputs ("\n", logfile);
	    fflush (logfile);
	}
	if (!strncmp(buffer, "### ", 4))
	    break;
	if ((!buffer[0])) {
	    if (ent->name) {
#define ST ent->ino->st
		if (S_ISLNK(ST.st_mode) && ent->ino->linkname == NULL) {
		    /* Symlink, without 'L' reply.  We assume the name has this form
		     * <pathname of link> -> <contents of link> and that size is the
		     * number of characters in <contents of link>
		     */
		    const char *lsep = " -> ";
		    const int lsep_len = strlen(lsep);
		    int real_len = strlen(ent->name) - ST.st_size - lsep_len;
		    if (real_len > 0 && !strncmp(ent->name + real_len, lsep, lsep_len)) {
			ent->ino->linkname = g_strdup(ent->name + real_len + lsep_len);
			ent->name[real_len] = '\0';
		    } else {
			ST.st_mode = 0;
		    }
		}
		vfs_s_insert_entry(me, dir, ent);
		ent = vfs_s_generate_entry(me, NULL, dir, 0);
	    }
	    continue;
	}

	switch(buffer[0]) {
	case ':': {
		      if (!strcmp(buffer+1, ".") || !strcmp(buffer+1, ".."))
			  break;  /* We'll do . and .. ourself */
		      ent->name = g_strdup(buffer+1); 
		      break;
	          }
	case 'S':
#ifdef HAVE_ATOLL
	    ST.st_size = (off_t) atoll (buffer+1);
#else
	    ST.st_size = (off_t) atof (buffer+1);
#endif
	    break;
	case 'P': {
	    size_t skipped;

	    if (vfs_parse_filemode (buffer + 1, &skipped, &ST.st_mode)) {
		/*if (S_ISLNK(ST.st_mode))
		    ST.st_mode = 0; XXX we'll deal with it, eventually */
	    }
	    break;
	}
	case 'd': {
		      vfs_split_text(buffer+1);
		      if (!vfs_parse_filedate(0, &ST.st_ctime))
			  break;
		      ST.st_atime = ST.st_mtime = ST.st_ctime;
		  }
	          break;
	case 'D': {
	              struct tm tim;
		      if (sscanf(buffer+1, "%d %d %d %d %d %d", &tim.tm_year, &tim.tm_mon, 
				 &tim.tm_mday, &tim.tm_hour, &tim.tm_min, &tim.tm_sec) != 6)
			  break;
		      ST.st_atime = ST.st_mtime = ST.st_ctime = mktime(&tim);
	          }
	          break;
	case 'E': {
	              int maj, min;
	              if (sscanf(buffer+1, "%d,%d", &maj, &min) != 2)
			  break;
#ifdef HAVE_STRUCT_STAT_ST_RDEV
		      ST.st_rdev = makedev (maj, min);
#endif
	          }
	case 'L': ent->ino->linkname = g_strdup(buffer+1);
	          break;
	}
    }
    
    vfs_s_free_entry (me, ent);
    me->verrno = E_REMOTE;
    if (fish_decode_reply(buffer+4, 0) == COMPLETE) {
	g_free (SUP.cwdir);
	SUP.cwdir = g_strdup (remote_path);
	print_vfs_message (_("%s: done."), me->name);
	return 0;
    }

error:
    print_vfs_message (_("%s: failure"), me->name);
    return 1;
}