FBUF * f_open (const char *filename, int flags) { int fd; FBUF *fs; fs = f_dopen(0); if (fs == NULL) { return NULL; } fs->name = g_strdup(filename); if (!fs->name) { f_free(fs); return NULL; } if (vfs_file_is_local(filename)) { fd = open(filename, flags); } else { fd = -1; fs->data = mc_getlocalcopy(filename); if (fs->data) { fs->flags = FILE_FLAG_COPY; fd = open(fs->data, flags); } } if (fd < 0) { f_free(fs); return NULL; } fs->fd = fd; return fs; }
static gboolean execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath, time_t * mtime) { struct stat st; /* Simplest case, this file is local */ if ((filename_vpath == NULL && vfs_file_is_local (vfs_get_raw_current_dir ())) || vfs_file_is_local (filename_vpath)) return TRUE; /* FIXME: Creation of new files on VFS is not supported */ if (filename_vpath == NULL) return FALSE; *localcopy_vpath = mc_getlocalcopy (filename_vpath); if (*localcopy_vpath == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot fetch a local copy of %s"), vfs_path_as_str (filename_vpath)); return FALSE; } mc_stat (*localcopy_vpath, &st); *mtime = st.st_mtime; return TRUE; }
static char * exec_get_file_name (const vfs_path_t * filename_vpath) { if (!do_local_copy) return quote_func (vfs_path_get_last_path_str (filename_vpath), 0); if (localfilecopy_vpath == NULL) { struct stat mystat; localfilecopy_vpath = mc_getlocalcopy (filename_vpath); if (localfilecopy_vpath == NULL) return NULL; mc_stat (localfilecopy_vpath, &mystat); localmtime = mystat.st_mtime; } return quote_func (vfs_path_get_last_path_str (localfilecopy_vpath), 0); }
/* * Execute command on a filename that can be on VFS. * Errors are reported to the user. */ void execute_with_vfs_arg (const char *command, const char *filename) { char *localcopy; char *fn; struct stat st; time_t mtime; /* Simplest case, this file is local */ if (!filename || vfs_file_is_local (filename)) { do_execute (command, filename, EXECUTE_INTERNAL); return; } /* FIXME: Creation of new files on VFS is not supported */ if (!*filename) return; localcopy = mc_getlocalcopy (filename); if (localcopy == NULL) { message (1, MSG_ERROR, _(" Cannot fetch a local copy of %s "), filename); return; } /* * filename can be an entry on panel, it can be changed by executing * the command, so make a copy. Smarter VFS code would make the code * below unnecessary. */ fn = g_strdup (filename); mc_stat (localcopy, &st); mtime = st.st_mtime; do_execute (command, localcopy, EXECUTE_INTERNAL); mc_stat (localcopy, &st); mc_ungetlocalcopy (fn, localcopy, mtime != st.st_mtime); g_free (localcopy); g_free (fn); }
static void exec_extension (const char *filename, const char *data, int *move_dir, int start_line) { char *file_name; int cmd_file_fd; FILE *cmd_file; char *cmd = NULL; int expand_prefix_found = 0; int parameter_found = 0; char prompt[80]; int run_view = 0; int def_hex_mode = default_hex_mode, changed_hex_mode = 0; int def_nroff_flag = default_nroff_flag, changed_nroff_flag = 0; int written_nonspace = 0; int is_cd = 0; char buffer[1024]; char *p = 0; char *localcopy = NULL; int do_local_copy; time_t localmtime = 0; struct stat mystat; quote_func_t quote_func = name_quote; g_return_if_fail (filename != NULL); g_return_if_fail (data != NULL); /* Avoid making a local copy if we are doing a cd */ if (!vfs_file_is_local (filename)) do_local_copy = 1; else do_local_copy = 0; /* * All commands should be run in /bin/sh regardless of user shell. * To do that, create temporary shell script and run it. * Sometimes it's not needed (e.g. for %cd and %view commands), * but it's easier to create it anyway. */ cmd_file_fd = mc_mkstemps (&file_name, "mcext", 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); prompt[0] = 0; for (; *data && *data != '\n'; data++) { if (parameter_found) { if (*data == '}') { char *parameter; parameter_found = 0; parameter = input_dialog (_(" Parameter "), prompt, ""); if (!parameter) { /* User canceled */ fclose (cmd_file); unlink (file_name); if (localcopy) { mc_ungetlocalcopy (filename, localcopy, 0); g_free (localcopy); } g_free (file_name); return; } fputs (parameter, cmd_file); written_nonspace = 1; g_free (parameter); } else { size_t len = strlen (prompt); if (len < sizeof (prompt) - 1) { prompt[len] = *data; prompt[len + 1] = 0; } } } else if (expand_prefix_found) { expand_prefix_found = 0; if (*data == '{') parameter_found = 1; else { int i = check_format_view (data); char *v; if (i) { data += i - 1; run_view = 1; } else if ((i = check_format_cd (data)) > 0) { is_cd = 1; quote_func = fake_name_quote; do_local_copy = 0; p = buffer; data += i - 1; } else if ((i = check_format_var (data, &v)) > 0 && v) { fputs (v, cmd_file); g_free (v); data += i; } else { char *text; if (*data == 'f') { if (do_local_copy) { localcopy = mc_getlocalcopy (filename); if (localcopy == NULL) { fclose (cmd_file); unlink (file_name); g_free (file_name); return; } mc_stat (localcopy, &mystat); localmtime = mystat.st_mtime; text = (*quote_func) (localcopy, 0); } else { text = (*quote_func) (filename, 0); } } else text = expand_format (NULL, *data, !is_cd); if (!is_cd) fputs (text, cmd_file); else { strcpy (p, text); p = strchr (p, 0); } g_free (text); written_nonspace = 1; } } } else { if (*data == '%') expand_prefix_found = 1; else { if (*data != ' ' && *data != '\t') written_nonspace = 1; if (is_cd) *(p++) = *data; else fputc (*data, cmd_file); } } } /* for */ /* * Make the script remove itself when it finishes. * Don't do it for the viewer - it may need to rerun the script, * so we clean up after calling view(). */ if (!run_view) { fprintf (cmd_file, "\n/bin/rm -f %s\n", file_name); } fclose (cmd_file); if ((run_view && !written_nonspace) || is_cd) { unlink (file_name); g_free (file_name); file_name = NULL; } else { /* Set executable flag on the command file ... */ chmod (file_name, S_IRWXU); /* ... but don't rely on it - run /bin/sh explicitly */ cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); } if (run_view) { altered_hex_mode = 0; altered_nroff_flag = 0; if (def_hex_mode != default_hex_mode) changed_hex_mode = 1; if (def_nroff_flag != default_nroff_flag) changed_nroff_flag = 1; /* If we've written whitespace only, then just load filename * into view */ if (written_nonspace) { view (cmd, filename, move_dir, start_line); unlink (file_name); } else { view (0, filename, move_dir, start_line); } if (changed_hex_mode && !altered_hex_mode) default_hex_mode = def_hex_mode; if (changed_nroff_flag && !altered_nroff_flag) default_nroff_flag = def_nroff_flag; repaint_screen (); } else if (is_cd) { char *q; *p = 0; p = buffer; /* while (*p == ' ' && *p == '\t') * p++; */ /* Search last non-space character. Start search at the end in order not to short filenames containing spaces. */ q = p + strlen (p) - 1; while (q >= p && (*q == ' ' || *q == '\t')) q--; q[1] = 0; do_cd (p, cd_parse_command); } else { shell_execute (cmd, EXECUTE_INTERNAL); if (console_flag) { handle_console (CONSOLE_SAVE); if (output_lines && keybar_visible) { show_console_contents (output_start_y, LINES - keybar_visible - output_lines - 1, LINES - keybar_visible - 1); } } } g_free (file_name); g_free (cmd); if (localcopy) { mc_stat (localcopy, &mystat); mc_ungetlocalcopy (filename, localcopy, localmtime != mystat.st_mtime); g_free (localcopy); } }
/* * Invoke the "file" command on the file and match its output against PTR. * have_type is a flag that is set if we already have tried to determine * the type of that file. * Return 1 for match, 0 for no match, -1 errors. */ static int regex_check_type (const char *filename, const char *ptr, int *have_type) { int found = 0; /* Following variables are valid if *have_type is 1 */ static char content_string[2048]; static int content_shift = 0; static int got_data = 0; if (!use_file_to_check_type) { return 0; } if (!*have_type) { char *realname; /* name used with "file" */ char *localfile; /* Don't repeate even unsuccessful checks */ *have_type = 1; localfile = mc_getlocalcopy (filename); if (!localfile) return -1; realname = localfile; got_data = get_file_type_local (localfile, content_string, sizeof (content_string)); mc_ungetlocalcopy (filename, localfile, 0); if (got_data > 0) { char *pp; /* Paranoid termination */ content_string[sizeof (content_string) - 1] = 0; if ((pp = strchr (content_string, '\n')) != 0) *pp = 0; if (!strncmp (content_string, realname, strlen (realname))) { /* Skip "realname: " */ content_shift = strlen (realname); if (content_string[content_shift] == ':') { /* Solaris' file prints tab(s) after ':' */ for (content_shift++; content_string[content_shift] == ' ' || content_string[content_shift] == '\t'; content_shift++); } } } else { /* No data */ content_string[0] = 0; } g_free (realname); } if (got_data == -1) { return -1; } if (content_string[0] && regexp_match (ptr, content_string + content_shift, match_regex)) { found = 1; } return found; }
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, ¤t_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; }
static gboolean regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, int *have_type, gboolean case_insense, GError ** error) { gboolean found = FALSE; /* Following variables are valid if *have_type is 1 */ static char content_string[2048]; #ifdef HAVE_CHARSET static char encoding_id[21]; /* CSISO51INISCYRILLIC -- 20 */ #endif static size_t content_shift = 0; static int got_data = 0; if (!use_file_to_check_type) return FALSE; if (*have_type == 0) { vfs_path_t *localfile_vpath; const char *realname; /* name used with "file" */ #ifdef HAVE_CHARSET int got_encoding_data; #endif /* HAVE_CHARSET */ /* Don't repeate even unsuccessful checks */ *have_type = 1; localfile_vpath = mc_getlocalcopy (filename_vpath); if (localfile_vpath == NULL) { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Cannot fetch a local copy of %s"), vfs_path_as_str (filename_vpath))); return FALSE; } realname = vfs_path_get_last_path_str (localfile_vpath); #ifdef HAVE_CHARSET got_encoding_data = is_autodetect_codeset_enabled ? get_file_encoding_local (localfile_vpath, encoding_id, sizeof (encoding_id)) : 0; if (got_encoding_data > 0) { char *pp; int cp_id; pp = strchr (encoding_id, '\n'); if (pp != NULL) *pp = '\0'; cp_id = get_codepage_index (encoding_id); if (cp_id == -1) cp_id = default_source_codepage; do_set_codepage (cp_id); } #endif /* HAVE_CHARSET */ mc_ungetlocalcopy (filename_vpath, localfile_vpath, FALSE); got_data = get_file_type_local (localfile_vpath, content_string, sizeof (content_string)); if (got_data > 0) { char *pp; size_t real_len; pp = strchr (content_string, '\n'); if (pp != NULL) *pp = '\0'; real_len = strlen (realname); if (strncmp (content_string, realname, real_len) == 0) { /* Skip "realname: " */ content_shift = real_len; if (content_string[content_shift] == ':') { /* Solaris' file prints tab(s) after ':' */ for (content_shift++; content_string[content_shift] == ' ' || content_string[content_shift] == '\t'; content_shift++) ; } } } else { /* No data */ content_string[0] = '\0'; } vfs_path_free (localfile_vpath); } if (got_data == -1) { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Pipe failed"))); return FALSE; } if (content_string[0] != '\0') { mc_search_t *search; search = mc_search_new (ptr, -1); if (search != NULL) { search->search_type = MC_SEARCH_T_REGEX; search->is_case_sensitive = !case_insense; found = mc_search_run (search, content_string + content_shift, 0, -1, NULL); mc_search_free (search); } else { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Regular expression error"))); } } return found; }
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 */ }