Exemplo n.º 1
0
/*
 * Run the "file" command on the local file.
 * Return 1 if the data is valid, 0 otherwise, -1 for fatal errors.
 */
static int
get_file_type_local (const char *filename, char *buf, int buflen)
{
    int read_bytes = 0;

    char *tmp = name_quote (filename, 0);
    char *command = g_strconcat (FILE_CMD, tmp, (char *) NULL);
    FILE *f = popen (command, "r");

    g_free (tmp);
    g_free (command);
    if (f != NULL) {
#ifdef __QNXNTO__
	if (setvbuf (f, NULL, _IOFBF, 0) != 0) {
	    (void)pclose (f);
	    return -1;
	}
#endif
	read_bytes = (fgets (buf, buflen, f)
		      != NULL);
	if (read_bytes == 0)
	    buf[0] = 0;
	pclose (f);
    } else {
	return -1;
    }

    return (read_bytes > 0);
}
Exemplo n.º 2
0
Arquivo: ext.c Projeto: inso/mc
static int
get_file_encoding_local (const vfs_path_t * filename_vpath, char *buf, int buflen)
{
    char *tmp, *lang, *args;
    int ret;

    tmp = name_quote (vfs_path_get_last_path_str (filename_vpath), 0);
    lang = name_quote (autodetect_codeset, 0);
    args = g_strconcat (" -L", lang, " -i ", tmp, (char *) NULL);

    ret = get_popen_information ("enca", args, buf, buflen);

    g_free (args);
    g_free (lang);
    g_free (tmp);

    return ret;
}
Exemplo n.º 3
0
Arquivo: command.c Projeto: V07D/mc
void
command_insert (WInput * in, const char *text, gboolean insert_extra_space)
{
    char *quoted_text;

    quoted_text = name_quote (text, TRUE);
    input_insert (in, quoted_text, insert_extra_space);
    g_free (quoted_text);
}
Exemplo n.º 4
0
Arquivo: ext.c Projeto: inso/mc
static int
get_file_type_local (const vfs_path_t * filename_vpath, char *buf, int buflen)
{
    char *tmp;
    int ret;

    tmp = name_quote (vfs_path_get_last_path_str (filename_vpath), 0);
    ret = get_popen_information (FILE_CMD, tmp, buf, buflen);
    g_free (tmp);

    return ret;
}
Exemplo n.º 5
0
Arquivo: fish.c Projeto: dborca/mc
static int fish_symlink (struct vfs_class *me, const char *setto, const char *path)
{
    char *qsetto;
    PREFIX
    qsetto = name_quote (setto, 0);
    g_snprintf(buf, sizeof(buf),
            "#SYMLINK %s /%s\n"
	    "ln -s %s /%s 2>/dev/null\n"
	    "echo '### 000'\n",
	    qsetto, rpath, qsetto, rpath);
    g_free (qsetto);
    POSTFIX(OPT_FLUSH);
}
Exemplo n.º 6
0
/* *INDENT-OFF* */
START_PARAMETRIZED_TEST (quote_percent_test, data_source1)
/* *INDENT-ON* */
{
    /* given */
    char *actual_string;

    /* when */
    actual_string = name_quote (data->input_string, data->input_quote_percent);

    /* then */
    mctest_assert_str_eq (actual_string, data->expected_string);

    g_free (actual_string);
}
Exemplo n.º 7
0
Arquivo: fish.c Projeto: dborca/mc
static int
fish_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset)
{
    char *name;
    char *quoted_name;
    if (offset)
        ERRNOR (E_NOTSUPP, 0);
    name = vfs_s_fullpath (me, fh->ino);
    if (!name)
	return 0;
    quoted_name = name_quote (name, 0);
    g_free (name);
    name = quoted_name;
    fh->u.fish.append = 0;
    offset = fish_command (me, FH_SUPER, WANT_STRING,
		"#RETR /%s\n"
		"if dd if=/%s of=/dev/null bs=1 count=1 2>/dev/null; then\n"
		"ls -ln /%s 2>/dev/null | (\n"
		  "read p l u g s r\n"
		  "echo \"$s\"\n"
		")\n"
		"echo '### 100'\n"
		"cat /%s\n"
		"echo '### 200'\n"
		"else\n"
		"echo '### 500'\n"
		"fi\n",
		name, name, name, name );
    g_free (name);
    if (offset != PRELIM) ERRNOR (E_REMOTE, 0);
    fh->linear = LS_LINEAR_OPEN;
    fh->u.fish.got = 0;
#if SIZEOF_OFF_T > SIZEOF_INT
    if (sscanf( reply_str, "%llu", &fh->u.fish.total )!=1)
#else
    if (sscanf( reply_str, "%u", &fh->u.fish.total )!=1)
#endif
	ERRNOR (E_REMOTE, 0);
    return 1;
}
Exemplo n.º 8
0
/*
 * Run the "file" command on the local file.
 * Return 1 if the data is valid, 0 otherwise, -1 for fatal errors.
 */
static int
get_file_type_local (char *filename, char *buf, int buflen)
{
    int read_bytes = 0;

    char *tmp = name_quote (filename, 0);
    char *command = g_strconcat (FILE_CMD, tmp, NULL);
    FILE *f = popen (command, "r");

    g_free (tmp);
    g_free (command);
    if (f != NULL) {
	read_bytes = (fgets (buf, buflen - 1, f)
		      != NULL);
	if (read_bytes == 0)
	    buf[0] = 0;
	pclose (f);
    } else {
	return -1;
    }

    return (read_bytes > 0);
}
Exemplo n.º 9
0
Arquivo: extfs.c Projeto: dborca/mc
static FILE *
extfs_open_archive (int fstype, const char *name, struct archive **pparc)
{
    static dev_t archive_counter = 0;
    FILE *result;
    mode_t mode;
    char *cmd;
    char *mc_extfsdir;
    struct stat mystat;
    struct archive *current_archive;
    struct entry *root_entry;
    char *local_name = NULL, *tmp = 0;
    int uses_archive = extfs_need_archive[fstype];

    if (uses_archive) {
	if (mc_stat (name, &mystat) == -1)
	    return NULL;
	if (!vfs_file_is_local (name)) {
	    local_name = mc_getlocalcopy (name);
	    if (local_name == NULL)
		return NULL;
	}
	tmp = name_quote (name, 0);
    }

    mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
    cmd =
	g_strconcat (mc_extfsdir, extfs_prefixes[fstype], " list ",
		     local_name ? local_name : tmp, (char *) NULL);
    g_free (tmp);
    g_free (mc_extfsdir);
    open_error_pipe ();
    result = popen (cmd, "r");
    g_free (cmd);
    if (result == NULL) {
	close_error_pipe (1, NULL);
	if (local_name) {
	    mc_ungetlocalcopy (name, local_name, 0);
	    g_free(local_name);
	}
	return NULL;
    } 
#ifdef ___QNXNTO__    
    setvbuf (result, NULL, _IONBF, 0);
#endif    

    current_archive = g_new (struct archive, 1);
    current_archive->fstype = fstype;
    current_archive->name = name ? g_strdup (name) : NULL;
    current_archive->local_name = local_name;

    if (local_name != NULL)
	mc_stat (local_name, &current_archive->local_stat);
    current_archive->inode_counter = 0;
    current_archive->fd_usage = 0;
    current_archive->rdev = archive_counter++;
    current_archive->next = first_archive;
    first_archive = current_archive;
    mode = mystat.st_mode & 07777;
    if (mode & 0400)
	mode |= 0100;
    if (mode & 0040)
	mode |= 0010;
    if (mode & 0004)
	mode |= 0001;
    mode |= S_IFDIR;
    root_entry = extfs_generate_entry (current_archive, "/", NULL, mode);
    root_entry->inode->uid = mystat.st_uid;
    root_entry->inode->gid = mystat.st_gid;
    root_entry->inode->atime = mystat.st_atime;
    root_entry->inode->ctime = mystat.st_ctime;
    root_entry->inode->mtime = mystat.st_mtime;
    current_archive->root_entry = root_entry;

    *pparc = current_archive;

    return result;
}
Exemplo n.º 10
0
Arquivo: user.c Projeto: dborca/mc
/* FIXME: recode this routine on version 3.0, it could be cleaner */
static void
execute_menu_command (WEdit *edit_widget, const char *commands)
{
    FILE *cmd_file;
    int  cmd_file_fd;
    int  expand_prefix_found = 0;
    char *parameter = 0;
    int  do_quote = 0;
    char prompt [80];
    int  col;
    char *file_name;
    int run_view = 0;

    /* Skip menu entry title line */
    commands = strchr (commands, '\n');
    if (!commands){
	return;
    }

    cmd_file_fd = mc_mkstemps (&file_name, "mcusr", SCRIPT_SUFFIX);

    if (cmd_file_fd == -1){
	message (1, MSG_ERROR, _(" Cannot create temporary command file \n %s "),
		 unix_error_string (errno));
	return;
    }
    cmd_file = fdopen (cmd_file_fd, "w");
    fputs ("#! /bin/sh\n", cmd_file);
    commands++;
    
    for (col = 0; *commands; commands++){
	if (col == 0) {
	    if (*commands != ' ' && *commands != '\t')
		break;
	    while (*commands == ' ' || *commands == '\t')
	        commands++;
	    if (*commands == 0)
		break;
	}
	col++;
	if (*commands == '\n')
	    col = 0;
	if (parameter){
	    if (*commands == '}'){
		char *tmp;
		*parameter = 0;
		parameter = input_dialog (_(" Parameter "), prompt, INPUT_LAST_TEXT);
		if (!parameter){
		    /* User canceled */
		    fclose (cmd_file);
		    unlink (file_name);
                    g_free (file_name);
		    return;
		}
		if (do_quote) {
    		    fputs (tmp = name_quote (parameter, 0), cmd_file);
		    g_free (tmp);
		} else
		    fputs (parameter, cmd_file);
		g_free (parameter);
		parameter = 0;
	    } else {
		if (parameter < &prompt [sizeof (prompt) - 1]) {
		    *parameter++ = *commands;
		} 
	    }
	} else if (expand_prefix_found){
	    expand_prefix_found = 0;
	    if (isdigit ((unsigned char) *commands)) {
		do_quote = atoi (commands);
		while (isdigit ((unsigned char) *commands))
		    commands++;
	    }
	    if (*commands == '{')
		parameter = prompt;
	    else{
		char *text = expand_format (edit_widget, *commands, do_quote);
		fputs (text, cmd_file);
		g_free (text);
	    }
	} else {
	    if (*commands == '%') {
		int i = check_format_view (commands + 1);
		if (i) {
		    commands += i;
		    run_view = 1;
		} else {
		    do_quote = 1; /* Default: Quote expanded macro */
		    expand_prefix_found = 1;
		}
	    } else
		fputc (*commands, cmd_file);
	}
    }
    fclose (cmd_file);
    chmod (file_name, S_IRWXU);
    if (run_view) {
	run_view = 0;
	mc_internal_viewer (file_name, NULL, &run_view, 0);
#ifdef USE_DLGSWITCH
	dlgswitch_process_pending();
#endif
    } else {
	/* execute the command indirectly to allow execution even
	 * on no-exec filesystems. */
	char *cmd = g_strconcat("/bin/sh ", file_name, (char *)NULL);
	shell_execute (cmd, EXECUTE_HIDE);
	g_free(cmd);
    }
    unlink (file_name);
    g_free (file_name);
}
Exemplo n.º 11
0
static void
execute_menu_command (WEdit * edit_widget, const char *commands, gboolean show_prompt)
{
    FILE *cmd_file;
    int cmd_file_fd;
    int expand_prefix_found = 0;
    char *parameter = 0;
    gboolean do_quote = FALSE;
    char lc_prompt[80];
    int col;
    vfs_path_t *file_name_vpath;
    int run_view = 0;

    /* Skip menu entry title line */
    commands = strchr (commands, '\n');
    if (!commands)
    {
        return;
    }

    cmd_file_fd = mc_mkstemps (&file_name_vpath, "mcusr", SCRIPT_SUFFIX);

    if (cmd_file_fd == -1)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"),
                 unix_error_string (errno));
        vfs_path_free (file_name_vpath);
        return;
    }
    cmd_file = fdopen (cmd_file_fd, "w");
    fputs ("#! /bin/sh\n", cmd_file);
    commands++;

    for (col = 0; *commands; commands++)
    {
        if (col == 0)
        {
            if (*commands != ' ' && *commands != '\t')
                break;
            while (*commands == ' ' || *commands == '\t')
                commands++;
            if (*commands == 0)
                break;
        }
        col++;
        if (*commands == '\n')
            col = 0;
        if (parameter)
        {
            if (*commands == '}')
            {
                *parameter = 0;
                parameter =
                    input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, "",
                                  INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD |
                                  INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_VARIABLES |
                                  INPUT_COMPLETE_USERNAMES);
                if (!parameter || !*parameter)
                {
                    /* User canceled */
                    fclose (cmd_file);
                    mc_unlink (file_name_vpath);
                    vfs_path_free (file_name_vpath);
                    return;
                }
                if (do_quote)
                {
                    char *tmp;

                    tmp = name_quote (parameter, 0);
                    fputs (tmp, cmd_file);
                    g_free (tmp);
                }
                else
                    fputs (parameter, cmd_file);
                g_free (parameter);
                parameter = 0;
            }
            else
            {
                if (parameter < &lc_prompt[sizeof (lc_prompt) - 1])
                {
                    *parameter++ = *commands;
                }
            }
        }
        else if (expand_prefix_found)
        {
            expand_prefix_found = 0;
            if (g_ascii_isdigit ((gchar) * commands))
            {
                do_quote = (atoi (commands) != 0);
                while (g_ascii_isdigit ((gchar) * commands))
                    commands++;
            }
            if (*commands == '{')
                parameter = lc_prompt;
            else
            {
                char *text = expand_format (edit_widget, *commands, do_quote);
                fputs (text, cmd_file);
                g_free (text);
            }
        }
        else
        {
            if (*commands == '%')
            {
                int i = check_format_view (commands + 1);
                if (i)
                {
                    commands += i;
                    run_view = 1;
                }
                else
                {
                    do_quote = TRUE;    /* Default: Quote expanded macro */
                    expand_prefix_found = 1;
                }
            }
            else
                fputc (*commands, cmd_file);
        }
    }
    fclose (cmd_file);
    mc_chmod (file_name_vpath, S_IRWXU);
    if (run_view)
    {
        mcview_viewer (vfs_path_as_str (file_name_vpath), NULL, 0);
        dialog_switch_process_pending ();
    }
    else
    {
        /* execute the command indirectly to allow execution even
         * on no-exec filesystems. */
        char *cmd;

        cmd = g_strconcat ("/bin/sh ", vfs_path_as_str (file_name_vpath), (char *) NULL);
        if (!show_prompt)
        {
            if (system (cmd) == -1)
                message (D_ERROR, MSG_ERROR, "%s", _("Error calling program"));
        }
        else
        {
            shell_execute (cmd, EXECUTE_HIDE);
        }
        g_free (cmd);
    }
    mc_unlink (file_name_vpath);
    vfs_path_free (file_name_vpath);
}
Exemplo n.º 12
0
Arquivo: sfs.c Projeto: dborca/mc
static int
sfs_vfmake (struct vfs_class *me, const char *name, char *cache)
{
    char *inpath, *op;
    int w;
    char pad[10240];
    char *s, *t = pad;
    int was_percent = 0;
    char *pname;	/* name of parent archive */
    char *pqname;	/* name of parent archive, quoted */

    pname = g_strdup (name);
    vfs_split (pname, &inpath, &op);
    if ((w = (*me->which) (me, op)) == -1)
	vfs_die ("This cannot happen... Hopefully.\n");

    if (!(sfs_flags[w] & F_1) && strcmp (pname, "/")) {
	g_free (pname);
	return -1;
    }

    /*    if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
    if (!(sfs_flags[w] & F_NOLOCALCOPY)) {
	s = mc_getlocalcopy (pname);
	if (!s) {
	    g_free (pname);
	    return -1;
	}
	pqname = name_quote (s, 0);
	g_free (s);
    } else {
	pqname = name_quote (pname, 0);
    }
    g_free (pname);

#define COPY_CHAR \
    if ((size_t) (t-pad) > sizeof(pad)) { \
	g_free (pqname); \
	return -1; \
    } \
    else \
	*t++ = *s;

#define COPY_STRING(a) \
    if ((t-pad)+strlen(a)>sizeof(pad)) { \
	g_free (pqname); \
	return -1; \
    } else { \
	strcpy (t, a); \
	t+= strlen(a); \
    }

    for (s = sfs_command[w]; *s; s++) {
	if (was_percent) {

	    const char *ptr = NULL;
	    was_percent = 0;

	    switch (*s) {
	    case '1':
		ptr = pqname;
		break;
	    case '2':
		ptr = op + strlen (sfs_prefix[w]);
		break;
	    case '3':
		ptr = cache;
		break;
	    case '%':
		COPY_CHAR;
		continue;
	    }
	    COPY_STRING (ptr);
	} else {
	    if (*s == '%')
		was_percent = 1;
	    else
		COPY_CHAR;
	}
    }

    g_free (pqname);
    open_error_pipe ();
    if (my_system (EXECUTE_AS_SHELL, "/bin/sh", pad)) {
	close_error_pipe (1, NULL);
	return -1;
    }

    close_error_pipe (0, NULL);
    return 0;			/* OK */
}
Exemplo n.º 13
0
Arquivo: fish.c Projeto: dborca/mc
static int
fish_file_store(struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *localname)
{
    struct vfs_s_super *super = FH_SUPER;
    int n, total;
    char buffer[8192];
    struct stat s;
    int was_error = 0;
    int h;
    char *quoted_name;

    h = open (localname, O_RDONLY);

    if (h == -1)
	ERRNOR (EIO, -1);
    if (fstat(h, &s)<0) {
	close (h);
	ERRNOR (EIO, -1);
    }

    /* First, try this as stor:
     *
     *     ( head -c number ) | ( cat > file; cat >/dev/null )
     *
     *  If `head' is not present on the remote system, `dd' will be used.
     * Unfortunately, we cannot trust most non-GNU `head' implementations
     * even if `-c' options is supported. Therefore, we separate GNU head
     * (and other modern heads?) using `-q' and `-' . This causes another
     * implementations to fail (because of "incorrect options").
     *
     *	Fallback is:
     *
     *	   rest=<number>
     *	   while [ $rest -gt 0 ]
     *	   do
     *	      cnt=`expr \( $rest + 255 \) / 256`
     *	      n=`dd bs=256 count=$cnt | tee -a <target_file> | wc -c`
     *	      rest=`expr $rest - $n`
     *	   done
     *
     *	`dd' was not designed for full filling of input buffers,
     *	and does not report exact number of bytes (not blocks).
     *	Therefore a more complex shell script is needed.
     *
     *	 On some systems non-GNU head writes "Usage:" error report to stdout
     *	instead of stderr. It makes impossible the use of "head || dd"
     *	algorithm for file appending case, therefore just "dd" is used for it.
     */

    print_vfs_message(_("fish: store %s: sending command..."), name );
    quoted_name = name_quote (name, 0);

    /* FIXME: File size is limited to ULONG_MAX */
    if (!fh->u.fish.append)
	n = fish_command (me, super, WAIT_REPLY,
		 "#STOR %lu /%s\n"
		 "echo '### 001'\n"
		 "file=/%s\n"
                 "res=`exec 3>&1\n"
		 "(\n"
		   "head -c %lu -q - || echo DD >&3\n"
		 ") 2>/dev/null | (\n"
		   "cat > \"$file\"\n"
		   "cat > /dev/null\n"
		 ")`; [ \"$res\" = DD ] && {\n"
			"> \"$file\"\n"
			"rest=%lu\n"
			"while [ $rest -gt 0 ]\n"
			"do\n"
			"    cnt=`expr \\( $rest + 255 \\) / 256`\n"
			"    n=`dd bs=256 count=$cnt | tee -a \"$file\" | wc -c`\n"
			"    rest=`expr $rest - $n`\n"
			"done\n"
		 "}; echo '### 200'\n",
		 (unsigned long) s.st_size, name,
		 quoted_name, (unsigned long) s.st_size,
		 (unsigned long) s.st_size);
    else
	n = fish_command (me, super, WAIT_REPLY,
		 "#STOR %lu /%s\n"
		 "echo '### 001'\n"
		 "{\n"
			"file=/%s\n"
			"rest=%lu\n"
			"while [ $rest -gt 0 ]\n"
			"do\n"
			"    cnt=`expr \\( $rest + 255 \\) / 256`\n"
			"    n=`dd bs=256 count=$cnt | tee -a \"$file\" | wc -c`\n"
			"    rest=`expr $rest - $n`\n"
			"done\n"
		 "}; echo '### 200'\n",
		 (unsigned long) s.st_size, name,
		 quoted_name, (unsigned long) s.st_size);

    g_free (quoted_name);
    if (n != PRELIM) {
	close (h);
        ERRNOR(E_REMOTE, -1);
    }
    total = 0;
    
    while (1) {
	int t;
	while ((n = read(h, buffer, sizeof(buffer))) < 0) {
	    if ((errno == EINTR) && got_interrupt())
	        continue;
	    print_vfs_message(_("fish: Local read failed, sending zeros") );
	    close(h);
	    h = open( "/dev/zero", O_RDONLY );
	}
	if (n == 0)
	    break;
    	if ((t = write (SUP.sockw, buffer, n)) != n) {
	    if (t == -1) {
		me->verrno = errno;
	    } else { 
		me->verrno = EIO;
	    }
	    goto error_return;
	}
	disable_interrupt_key();
	total += n;
	print_vfs_message(_("fish: storing %s %d (%lu)"), 
			  was_error ? _("zeros") : _("file"), total,
			  (unsigned long) s.st_size);
    }
    close(h);
    if ((fish_get_reply (me, SUP.sockr, NULL, 0) != COMPLETE) || was_error)
        ERRNOR (E_REMOTE, -1);
    return 0;
error_return:
    close(h);
    fish_get_reply(me, SUP.sockr, NULL, 0);
    return -1;
}
Exemplo n.º 14
0
Arquivo: fish.c Projeto: 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;
}
Exemplo n.º 15
0
/* FIXME: recode this routine on version 3.0, it could be cleaner */
void execute_menu_command (char *s)
{
    char *commands;
    FILE *cmd_file;
    int  cmd_file_fd;
    int  expand_prefix_found = 0;
    int parameter_found = 0;
    int do_quote;
    char prompt [80] = "";
    int  col;
    char *file_name = tmpnam (0);

#ifdef OS2_NT
    /* OS/2 and NT requires the command to end in .cmd */
    file_name = copy_strings (file_name, ".cmd", NULL);
    file_name = "temp.bat";  // $$ fixme

    if ((cmd_file_fd = open (file_name, O_RDWR | O_CREAT | O_TRUNC | O_EXCL
                                                         | O_TEXT, 0600)) == -1){
    message (1, MSG_ERROR, _(" Can't create temporary command file \n %s "),
         unix_error_string (errno));
    return;
    }
#else
    if ((cmd_file_fd = open (file_name, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600)) == -1){
    message (1, MSG_ERROR, _(" Can't create temporary command file \n %s "),
         unix_error_string (errno));
    return;
    }
#endif
    cmd_file = fdopen (cmd_file_fd, "w");
    commands = strchr (s, '\n');
    if (!commands){
    fclose (cmd_file);
    unlink (file_name);
    return;
    }
    commands++;

    for (col = 0; *commands; commands++){
    if (col == 0 && (*commands != ' ' && *commands != '\t'))
        break;
        else if (col == 0)
        while (*commands == ' ' || *commands == '\t')
            commands++;
    col++;
    if (*commands == '\n')
        col = 0;
    if (parameter_found){
        if (*commands == '}'){
        char *parameter;
        char *tmp;
        parameter_found = 0;
        parameter = input_dialog (_(" Parameter "), prompt, "");
        if (!parameter || !*parameter){
            /* User canceled */
            fclose (cmd_file);
            unlink (file_name);
            return;
        }
        if (do_quote) {
                fputs (tmp = name_quote (parameter, 0), cmd_file);
            free (tmp);
        } else
            fputs (parameter, cmd_file);
        free (parameter);
        } else {
        int len = strlen (prompt);

        if (len+1 < sizeof (prompt)){
            prompt [len] = *commands;
            prompt [len+1] = 0;
        } else
            prompt [sizeof (prompt)-1] = 0;
        }
    } else if (expand_prefix_found){
        expand_prefix_found = 0;
        if (isdigit (*commands)) {
        do_quote = atoi (commands);
        for ( ; isdigit (*commands); commands++)
            ;
        }
        if (*commands == '{')
        parameter_found = 1;
        else{
        char *text = expand_format (*commands, do_quote);
        fputs (text, cmd_file);
        free (text);
        }
    } else {
        if (*commands == '%') {
        do_quote = 1; /* Default: Quote expanded macro */
        expand_prefix_found = 1;
        } else
        fputc (*commands, cmd_file);
    }
    }
    fclose (cmd_file);
    chmod (file_name, S_IRWXU);
    execute (file_name);
    unlink (file_name);
}