示例#1
0
END_TEST

/* --------------------------------------------------------------------------------------------- */

START_TEST (test_vfs_parse_ls_lga_reorder)
{
    size_t filepos = 0;
    struct vfs_s_entry *ent1, *ent2, *ent3;
    int i;

    vfs_parse_ls_lga_init();

    ent1 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    i = ent1->ino->st.st_nlink;
    if (! vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09      build_root1",
    &ent1->ino->st, &ent1->name, &ent1->ino->linkname, &filepos))
    {
        fail ("An error occured while parse ls output");
        return;
    }
    vfs_s_store_filename_leading_spaces (ent1, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent1);


    ent2 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    i = ent2->ino->st.st_nlink;
    if (! vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09    build_root2",
    &ent2->ino->st, &ent2->name, &ent2->ino->linkname, &filepos))
    {
        fail ("An error occured while parse ls output");
        return;
    }
    vfs_s_store_filename_leading_spaces (ent2, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent2);

    ent3 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    i = ent3->ino->st.st_nlink;
    if (! vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09 ..",
    &ent3->ino->st, &ent3->name, &ent3->ino->linkname, &filepos))
    {
        fail ("An error occured while parse ls output");
        return;
    }
    vfs_s_store_filename_leading_spaces (ent3, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent3);

    vfs_s_normalize_filename_leading_spaces (vfs_root_inode, vfs_parse_ls_lga_get_final_spaces ());

    fail_unless(strcmp(ent1->name, "     build_root1") == 0, "\nactual '%s'\nnot equal to '%s'\n", ent1->name, "     build_root1");
    fail_unless(strcmp(ent2->name, "   build_root2") == 0, "\nactual '%s'\nnot equal to '%s'\n", ent2->name, "   build_root2");
}
示例#2
0
/* *INDENT-OFF* */
END_PARAMETRIZED_TEST
/* *INDENT-ON* */

/* --------------------------------------------------------------------------------------------- */

/* @Test */
/* *INDENT-OFF* */
START_TEST (test_vfs_parse_ls_lga_reorder)
/* *INDENT-ON* */
{
    /* given */
    size_t filepos = 0;
    struct vfs_s_entry *ent1, *ent2, *ent3;

    vfs_parse_ls_lga_init ();

    /* init ent1 */
    ent1 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    vfs_parse_ls_lga
        ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09      build_root1", &ent1->ino->st,
         &ent1->name, &ent1->ino->linkname, &filepos);
    vfs_s_store_filename_leading_spaces (ent1, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent1);


    /* init ent2 */
    ent2 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09    build_root2",
                      &ent2->ino->st, &ent2->name, &ent2->ino->linkname, &filepos);
    vfs_s_store_filename_leading_spaces (ent2, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent2);

    /* init ent3 */
    ent3 = vfs_s_generate_entry (&vfs_test_ops1, NULL, vfs_root_inode, 0);
    vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09 ..",
                      &ent3->ino->st, &ent3->name, &ent3->ino->linkname, &filepos);
    vfs_s_store_filename_leading_spaces (ent3, filepos);
    vfs_s_insert_entry (&vfs_test_ops1, vfs_root_inode, ent3);

    /* when */
    vfs_s_normalize_filename_leading_spaces (vfs_root_inode, vfs_parse_ls_lga_get_final_spaces ());

    /* then */
    mctest_assert_str_eq (ent1->name, "     build_root1");
    mctest_assert_str_eq (ent2->name, "   build_root2");
}
示例#3
0
文件: direntry.c 项目: dborca/mc
/* We were asked to create entries automagically */
static struct vfs_s_entry *
vfs_s_automake (struct vfs_class *me, struct vfs_s_inode *dir, char *path, int flags)
{
    struct vfs_s_entry *res;
    char *sep = strchr (path, PATH_SEP);
    
    if (sep)
	    *sep = 0;
    res = vfs_s_generate_entry (me, path, dir, flags & FL_MKDIR ? (0777 | S_IFDIR) : 0777);
    vfs_s_insert_entry (me, dir, res);

    if (sep)
	    *sep = PATH_SEP;

    return res;
}
示例#4
0
文件: direntry.c 项目: dborca/mc
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;
}
示例#5
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;
}
/*
 * Return 1 for success, 0 if the checksum is bad, EOF on eof,
 * 2 for a record full of zeros (EOF marker).
 *
 */
static int read_header (vfs *me, vfs_s_super *archive, int tard)
{
    register int i;
    register long sum, signed_sum, recsum;
    register char *p;
    register union record *header;
    char **longp;
    char *bp, *data;
    int size, written;
    static char *next_long_name = NULL, *next_long_link = NULL;
    char *current_file_name, *current_link_name;

  recurse:

    header = get_next_record (archive, tard);
    if (NULL == header)
	return EOF;

    recsum = from_oct (8, header->header.chksum);

    sum = 0; signed_sum = 0;
    p = header->charptr;
    for (i = sizeof (*header); --i >= 0;) {
	        /*
		 * We can't use unsigned char here because of old compilers,
		 * e.g. V7.
		 */
	signed_sum += *p;
	sum += 0xFF & *p++;
    }

    /* Adjust checksum to count the "chksum" field as blanks. */
    for (i = sizeof (header->header.chksum); --i >= 0;) {
	sum -= 0xFF & header->header.chksum[i];
	signed_sum -= (char) header->header.chksum[i];
    }
    sum += ' ' * sizeof header->header.chksum;
    signed_sum += ' ' * sizeof header->header.chksum;

    if (sum == 8 * ' ') {
	/*
	 * This is a zeroed record...whole record is 0's except
	 * for the 8 blanks we faked for the checksum field.
	 */
	return 2;
    }
    if (sum != recsum && signed_sum != recsum)
	return 0;
    
    /*
     * linkflag on BSDI tar (pax) always '\000'
     */
    if(header->header.linkflag == '\000' &&
       strlen(header->header.arch_name) &&
       header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
	header->header.linkflag = LF_DIR;
    
     /*
     * Good record.  Decode file size and return.
     */
    if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR)
	hstat.st_size = 0;	/* Links 0 size on tape */
    else
	hstat.st_size = from_oct (1 + 12, header->header.size);

    header->header.arch_name[NAMSIZ - 1] = '\0';
    if (header->header.linkflag == LF_LONGNAME
	|| header->header.linkflag == LF_LONGLINK) {
	longp = ((header->header.linkflag == LF_LONGNAME)
		 ? &next_long_name
		 : &next_long_link);

	if (*longp)
	    free (*longp);
	bp = *longp = (char *) xmalloc (hstat.st_size, "Tar: Long name");

	for (size = hstat.st_size;
	     size > 0;
	     size -= written) {
	    data = get_next_record (archive, tard)->charptr;
	    if (data == NULL) {
		message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
		return 0;
	    }
	    written = RECORDSIZE;
	    if (written > size)
		written = size;

	    bcopy (data, bp, written);
	    bp += written;
	}
#if 0
	if (hstat.st_size > 1)
	    bp [hstat.st_size - 1] = 0;	/* just to make sure */
#endif
	goto recurse;
    } else {
	struct stat st;
	struct vfs_s_entry *entry;
	struct vfs_s_inode *inode, *parent;
	long data_position;
	char *p, *q;
	int len;
	int isdir = 0;

	current_file_name = (next_long_name
			     ? next_long_name
			     : strdup (header->header.arch_name));
	len = strlen (current_file_name);
	if (current_file_name[len - 1] == '/') {
	    current_file_name[len - 1] = 0;
	    isdir = 1;
	}

	current_link_name = (next_long_link
			     ? next_long_link
			     : strdup (header->header.arch_linkname));
	len = strlen (current_link_name);
	if (len && current_link_name [len - 1] == '/')
	    current_link_name[len - 1] = 0;

	next_long_link = next_long_name = NULL;

	data_position = current_tar_position;
	
	p = strrchr (current_file_name, '/');
	if (p == NULL) {
	    p = current_file_name;
	    q = current_file_name + strlen (current_file_name); /* "" */
	} else {
	    *(p++) = 0;
	    q = current_file_name;
	}

	parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR);
	if (parent == NULL) {
	    message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
	    return 0;
	}

	if (header->header.linkflag == LF_LINK) {
	    parent = vfs_s_find_inode (me, archive->root, current_link_name, LINK_NO_FOLLOW, 0);
	    if (parent == NULL) {
	        message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
	    } else {
	        inode = parent;
		entry = vfs_s_new_entry(me, p, inode);
		vfs_s_insert_entry(me, parent, entry);
		free (current_link_name);
		goto done;
	    }
	}

	fill_stat_from_header (me, &st, header);
	inode = vfs_s_new_inode (me, archive, &st);

	inode->u.tar.data_offset = data_position;
	if (*current_link_name)
	    inode->linkname = current_link_name;
	entry = vfs_s_new_entry (me, p, inode);

	vfs_s_insert_entry (me, parent, entry);
	free (current_file_name);

    done:
	if (header->header.isextended) {
	    while (get_next_record (archive, tard)->ext_hdr.isextended);
	    inode->u.tar.data_offset = current_tar_position;
	}
	return 1;
    }
}