static char * exec_expand_format (char symbol, gboolean is_result_quoted) { char *text; text = expand_format (NULL, symbol, TRUE); if (is_result_quoted && text != NULL) { char *quoted_text; quoted_text = g_strdup_printf ("\"%s\"", text); g_free (text); text = quoted_text; } return text; }
static char * exec_get_export_variables (const vfs_path_t * filename_vpath) { char *text; GString *export_vars_string; size_t i; /* *INDENT-OFF* */ struct { const char symbol; const char *name; } export_variables[] = { {'p', "MC_EXT_BASENAME"}, {'d', "MC_EXT_CURRENTDIR"}, {'s', "MC_EXT_SELECTED"}, {'t', "MC_EXT_ONLYTAGGED"}, {'\0', NULL} }; /* *INDENT-ON* */ text = exec_get_file_name (filename_vpath); if (text == NULL) return NULL; export_vars_string = g_string_new ("MC_EXT_FILENAME="); g_string_append_printf (export_vars_string, "%s\nexport MC_EXT_FILENAME\n", text); g_free (text); for (i = 0; export_variables[i].name != NULL; i++) { text = expand_format (NULL, export_variables[i].symbol, TRUE); if (text != NULL) { g_string_append_printf (export_vars_string, "%s=%s\nexport %s\n", export_variables[i].name, text, export_variables[i].name); g_free (text); } } return g_string_free (export_vars_string, FALSE); }
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); } }
/* 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); }
static char * exec_make_shell_string (const char *lc_data, const vfs_path_t * filename_vpath) { GString *shell_string; char lc_prompt[80] = "\0"; gboolean parameter_found = FALSE; gboolean expand_prefix_found = FALSE; shell_string = g_string_new (""); for (; *lc_data != '\0' && *lc_data != '\n'; lc_data++) { if (parameter_found) { if (*lc_data == '}') { char *parameter; parameter_found = FALSE; parameter = input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, "", INPUT_COMPLETE_NONE); if (parameter == NULL) { /* User canceled */ g_string_free (shell_string, TRUE); exec_cleanup_file_name (filename_vpath, FALSE); return NULL; } g_string_append (shell_string, parameter); written_nonspace = TRUE; g_free (parameter); } else { size_t len = strlen (lc_prompt); if (len < sizeof (lc_prompt) - 1) { lc_prompt[len] = *lc_data; lc_prompt[len + 1] = '\0'; } } } else if (expand_prefix_found) { expand_prefix_found = FALSE; if (*lc_data == '{') parameter_found = TRUE; else { int i; char *v; i = check_format_view (lc_data); if (i != 0) { lc_data += i - 1; run_view = TRUE; } else { i = check_format_cd (lc_data); if (i > 0) { is_cd = TRUE; quote_func = fake_name_quote; do_local_copy = FALSE; pbuffer = buffer; lc_data += i - 1; } else { i = check_format_var (lc_data, &v); if (i > 0 && v != NULL) { g_string_append (shell_string, v); g_free (v); lc_data += i; } else { char *text; if (*lc_data != 'f') text = expand_format (NULL, *lc_data, !is_cd); else { text = exec_get_file_name (filename_vpath); if (text == NULL) { g_string_free (shell_string, TRUE); return NULL; } } if (!is_cd) g_string_append (shell_string, text); else { strcpy (pbuffer, text); pbuffer = strchr (pbuffer, 0); } g_free (text); written_nonspace = TRUE; } } } } } else if (*lc_data == '%') expand_prefix_found = TRUE; else { if (*lc_data != ' ' && *lc_data != '\t') written_nonspace = TRUE; if (is_cd) *(pbuffer++) = *lc_data; else g_string_append_c (shell_string, *lc_data); } } /* for */ return g_string_free (shell_string, FALSE); }
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); }
static cb_ret_t enter (WInput * lc_cmdline) { char *cmd = lc_cmdline->buffer; if (!command_prompt) return MSG_HANDLED; /* Any initial whitespace should be removed at this point */ while (*cmd == ' ' || *cmd == '\t' || *cmd == '\n') cmd++; if (!*cmd) return MSG_HANDLED; if (strncmp (cmd, "cd ", 3) == 0 || strcmp (cmd, "cd") == 0) { do_cd_command (cmd); input_clean (lc_cmdline); return MSG_HANDLED; } else if (strcmp (cmd, "exit") == 0) { input_assign_text (lc_cmdline, ""); if (!quiet_quit_cmd ()) return MSG_NOT_HANDLED; } else { GString *command; size_t i; if (!vfs_current_is_local ()) { message (D_ERROR, MSG_ERROR, _("Cannot execute commands on non-local filesystems")); return MSG_NOT_HANDLED; } #ifdef ENABLE_SUBSHELL /* Check this early before we clean command line * (will be checked again by shell_execute) */ if (mc_global.tty.use_subshell && subshell_state != INACTIVE) { message (D_ERROR, MSG_ERROR, _("The shell is already running a command")); return MSG_NOT_HANDLED; } #endif command = g_string_sized_new (32); for (i = 0; cmd[i] != '\0'; i++) { if (cmd[i] != '%') g_string_append_c (command, cmd[i]); else { char *s; s = expand_format (NULL, cmd[++i], TRUE); g_string_append (command, s); g_free (s); } } input_clean (lc_cmdline); shell_execute (command->str, 0); g_string_free (command, TRUE); #ifdef ENABLE_SUBSHELL if ((quit & SUBSHELL_EXIT) != 0) { if (quiet_quit_cmd ()) return MSG_HANDLED; quit = 0; /* restart subshell */ if (mc_global.tty.use_subshell) init_subshell (); } if (mc_global.tty.use_subshell) do_load_prompt (); #endif } return MSG_HANDLED; }
/* 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); }