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); } }
void setup_panels (void) { int start_y; int promptl; /* the prompt len */ if (console_flag){ int minimum; if (output_lines < 0) output_lines = 0; height = LINES - keybar_visible - command_prompt - menubar_visible - output_lines - message_visible; if (message_visible && xterm_hintbar && xterm_flag) height++; minimum = MINHEIGHT * (1 + horizontal_split); if (height < minimum){ output_lines -= minimum - height; height = minimum; } } else { height = LINES - menubar_visible - command_prompt - keybar_visible - message_visible; if (message_visible && xterm_hintbar && xterm_flag) height++; } check_split (); start_y = menubar_visible; /* The column computing is defered until panel_do_cols */ if (horizontal_split){ widget_set_size (panels [0].widget, start_y, 0, first_panel_size, 0); widget_set_size (panels [1].widget, start_y+first_panel_size, 0, height-first_panel_size, 0); } else { int first_x = first_panel_size; widget_set_size (panels [0].widget, start_y, 0, height, 0); widget_set_size (panels [1].widget, start_y, first_x, height, 0); } panel_do_cols (0); panel_do_cols (1); promptl = strlen (prompt); widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); if (command_prompt) { widget_set_size (&cmdline->input.widget, LINES-1-keybar_visible, promptl, 1, COLS-promptl-(keybar_visible ? 0 : 1)); winput_set_origin (&cmdline->input, promptl, COLS-promptl-(keybar_visible ? 0 : 1)); widget_set_size (&the_prompt->widget, LINES-1-keybar_visible, 0, 1, promptl); } else { widget_set_size (&cmdline->input.widget, 0, 0, 0, 0); winput_set_origin (&cmdline->input, 0, 0); widget_set_size (&the_prompt->widget, LINES, COLS, 0, 0); } widget_set_size (&the_bar->widget, LINES-1, 0, 1, COLS); the_bar->visible = keybar_visible; /* Output window */ if (console_flag && output_lines){ output_start_y = LINES -command_prompt-keybar_visible- output_lines; show_console_contents (output_start_y, LINES-output_lines-keybar_visible-1, LINES-keybar_visible-1); } if (message_visible && (!xterm_hintbar || !xterm_flag)) widget_set_size (&the_hint->widget, height+start_y, 0, 1,COLS); else widget_set_size (&the_hint->widget, 0, 0, 0, 0); load_hint (); }
static vfs_path_t * exec_extension (void *target, const vfs_path_t * filename_vpath, const char *lc_data, int start_line) { char *shell_string, *export_variables; vfs_path_t *script_vpath = NULL; int cmd_file_fd; FILE *cmd_file; char *cmd = NULL; g_return_val_if_fail (lc_data != NULL, NULL); pbuffer = NULL; localmtime = 0; quote_func = name_quote; run_view = FALSE; is_cd = FALSE; written_nonspace = FALSE; /* Avoid making a local copy if we are doing a cd */ do_local_copy = !vfs_file_is_local (filename_vpath); shell_string = exec_make_shell_string (lc_data, filename_vpath); if (shell_string == NULL) goto ret; if (is_cd) { exec_extension_cd (); g_free (shell_string); goto ret; } /* * 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 (&script_vpath, "mcext", SCRIPT_SUFFIX); if (cmd_file_fd == -1) { message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"), unix_error_string (errno)); goto ret; } cmd_file = fdopen (cmd_file_fd, "w"); fputs ("#! /bin/sh\n\n", cmd_file); export_variables = exec_get_export_variables (filename_vpath); if (export_variables != NULL) { fprintf (cmd_file, "%s\n", export_variables); g_free (export_variables); } fputs (shell_string, cmd_file); g_free (shell_string); /* * 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", vfs_path_as_str (script_vpath)); fclose (cmd_file); if ((run_view && !written_nonspace) || is_cd) { exec_cleanup_script (script_vpath); script_vpath = NULL; } else { /* Set executable flag on the command file ... */ mc_chmod (script_vpath, S_IRWXU); /* ... but don't rely on it - run /bin/sh explicitly */ cmd = g_strconcat ("/bin/sh ", vfs_path_as_str (script_vpath), (char *) NULL); } if (run_view) { /* If we've written whitespace only, then just load filename into view */ if (!written_nonspace) exec_extension_view (target, NULL, filename_vpath, start_line); else exec_extension_view (target, cmd, filename_vpath, start_line); } else { shell_execute (cmd, EXECUTE_INTERNAL); if (mc_global.tty.console_flag != '\0') { handle_console (CONSOLE_SAVE); if (output_lines && mc_global.keybar_visible) show_console_contents (output_start_y, LINES - mc_global.keybar_visible - output_lines - 1, LINES - mc_global.keybar_visible - 1); } } g_free (cmd); exec_cleanup_file_name (filename_vpath, TRUE); ret: return script_vpath; }
void setup_panels (void) { int start_y; if (mc_global.tty.console_flag != '\0') { int minimum; if (output_lines < 0) output_lines = 0; height = LINES - mc_global.keybar_visible - (command_prompt ? 1 : 0) - menubar_visible - output_lines - mc_global.message_visible; minimum = MINHEIGHT * (1 + panels_layout.horizontal_split); if (height < minimum) { output_lines -= minimum - height; height = minimum; } } else { height = LINES - menubar_visible - (command_prompt ? 1 : 0) - mc_global.keybar_visible - mc_global.message_visible; } check_split (&panels_layout); start_y = menubar_visible; /* The column computing is deferred until panel_do_cols */ if (panels_layout.horizontal_split) { widget_set_size (panels[0].widget, start_y, 0, panels_layout.top_panel_size, 0); widget_set_size (panels[1].widget, start_y + panels_layout.top_panel_size, 0, height - panels_layout.top_panel_size, 0); } else { widget_set_size (panels[0].widget, start_y, 0, height, 0); widget_set_size (panels[1].widget, start_y, panels_layout.left_panel_size, height, 0); } panel_do_cols (0); panel_do_cols (1); widget_set_size (WIDGET (the_menubar), 0, 0, 1, COLS); if (command_prompt) { #ifdef ENABLE_SUBSHELL if (!mc_global.tty.use_subshell || !do_load_prompt ()) #endif setup_cmdline (); } else { widget_set_size (WIDGET (cmdline), 0, 0, 0, 0); widget_set_size (WIDGET (the_prompt), LINES, COLS, 0, 0); } widget_set_size (WIDGET (the_bar), LINES - 1, 0, mc_global.keybar_visible, COLS); buttonbar_set_visible (the_bar, mc_global.keybar_visible); /* Output window */ if (mc_global.tty.console_flag != '\0' && output_lines) { output_start_y = LINES - (command_prompt ? 1 : 0) - mc_global.keybar_visible - output_lines; show_console_contents (output_start_y, LINES - output_lines - mc_global.keybar_visible - 1, LINES - mc_global.keybar_visible - 1); } if (mc_global.message_visible) widget_set_size (WIDGET (the_hint), height + start_y, 0, 1, COLS); else widget_set_size (WIDGET (the_hint), 0, 0, 0, 0); update_xterm_title_path (); }
void setup_panels (void) { int start_y; int promptl; /* the prompt len */ if (mc_global.tty.console_flag) { int minimum; if (output_lines < 0) output_lines = 0; height = LINES - mc_global.keybar_visible - command_prompt - menubar_visible - output_lines - mc_global.message_visible; minimum = MINHEIGHT * (1 + horizontal_split); if (height < minimum) { output_lines -= minimum - height; height = minimum; } } else { height = LINES - menubar_visible - command_prompt - mc_global.keybar_visible - mc_global.message_visible; } check_split (); start_y = menubar_visible; /* The column computing is defered until panel_do_cols */ if (horizontal_split) { widget_set_size (panels[0].widget, start_y, 0, first_panel_size, 0); widget_set_size (panels[1].widget, start_y + first_panel_size, 0, height - first_panel_size, 0); } else { int first_x = first_panel_size; widget_set_size (panels[0].widget, start_y, 0, height, 0); widget_set_size (panels[1].widget, start_y, first_x, height, 0); } panel_do_cols (0); panel_do_cols (1); promptl = str_term_width1 (mc_prompt); widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); if (command_prompt) { widget_set_size (&cmdline->widget, LINES - 1 - mc_global.keybar_visible, promptl, 1, COLS - promptl); input_set_origin (cmdline, promptl, COLS - promptl); widget_set_size (&the_prompt->widget, LINES - 1 - mc_global.keybar_visible, 0, 1, promptl); } else { widget_set_size (&cmdline->widget, 0, 0, 0, 0); input_set_origin (cmdline, 0, 0); widget_set_size (&the_prompt->widget, LINES, COLS, 0, 0); } widget_set_size (&the_bar->widget, LINES - 1, 0, mc_global.keybar_visible, COLS); buttonbar_set_visible (the_bar, mc_global.keybar_visible); /* Output window */ if (mc_global.tty.console_flag && output_lines) { output_start_y = LINES - command_prompt - mc_global.keybar_visible - output_lines; show_console_contents (output_start_y, LINES - output_lines - mc_global.keybar_visible - 1, LINES - mc_global.keybar_visible - 1); } if (mc_global.message_visible) widget_set_size (&the_hint->widget, height + start_y, 0, 1, COLS); else widget_set_size (&the_hint->widget, 0, 0, 0, 0); update_xterm_title_path (); }
void toggle_panels (void) { #ifdef ENABLE_SUBSHELL vfs_path_t *new_dir_vpath = NULL; #endif /* ENABLE_SUBSHELL */ SIG_ATOMIC_VOLATILE_T was_sigwinch = 0; channels_down (); disable_mouse (); disable_bracketed_paste (); if (clear_before_exec) clr_scr (); if (mc_global.tty.alternate_plus_minus) numeric_keypad_mode (); #ifndef HAVE_SLANG /* With slang we don't want any of this, since there * is no raw_mode supported */ tty_reset_shell_mode (); #endif /* !HAVE_SLANG */ tty_noecho (); tty_keypad (FALSE); tty_reset_screen (); do_exit_ca_mode (); tty_raw_mode (); if (mc_global.tty.console_flag != '\0') handle_console (CONSOLE_RESTORE); #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell) { vfs_path_t **new_dir_p; new_dir_p = vfs_current_is_local ()? &new_dir_vpath : NULL; invoke_subshell (NULL, VISIBLY, new_dir_p); } else #endif /* ENABLE_SUBSHELL */ { if (output_starts_shell) { fprintf (stderr, _("Type 'exit' to return to the Midnight Commander")); fprintf (stderr, "\n\r\n\r"); my_system (EXECUTE_INTERNAL, mc_global.tty.shell, NULL); } else get_key_code (0); } if (mc_global.tty.console_flag != '\0') handle_console (CONSOLE_SAVE); do_enter_ca_mode (); tty_reset_prog_mode (); tty_keypad (TRUE); /* Prevent screen flash when user did 'exit' or 'logout' within subshell */ if ((quit & SUBSHELL_EXIT) != 0) { /* User did 'exit' or 'logout': quit MC */ if (quiet_quit_cmd ()) return; quit = 0; #ifdef ENABLE_SUBSHELL /* restart subshell */ if (mc_global.tty.use_subshell) init_subshell (); #endif /* ENABLE_SUBSHELL */ } enable_mouse (); enable_bracketed_paste (); channels_up (); if (mc_global.tty.alternate_plus_minus) application_keypad_mode (); /* HACK: * Save sigwinch flag that will be reset in mc_refresh() called via update_panels(). * There is some problem with screen redraw in ncurses-based mc in this situation. */ was_sigwinch = mc_global.tty.winch_flag; mc_global.tty.winch_flag = 0; #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell) { do_load_prompt (); if (new_dir_vpath != NULL) do_possible_cd (new_dir_vpath); if (mc_global.tty.console_flag != '\0' && output_lines) show_console_contents (output_start_y, LINES - mc_global.keybar_visible - output_lines - 1, LINES - mc_global.keybar_visible - 1); } vfs_path_free (new_dir_vpath); #endif /* ENABLE_SUBSHELL */ if (mc_global.mc_run_mode == MC_RUN_FULL) { update_panels (UP_OPTIMIZE, UP_KEEPSEL); update_xterm_title_path (); } if (was_sigwinch != 0 || mc_global.tty.winch_flag != 0) dialog_change_screen_size (); else repaint_screen (); }
void toggle_panels (void) { #ifdef HAVE_SUBSHELL_SUPPORT char *new_dir = NULL; char **new_dir_p; #endif /* HAVE_SUBSHELL_SUPPORT */ channels_down (); disable_mouse (); if (clear_before_exec) clr_scr (); if (alternate_plus_minus) numeric_keypad_mode (); #ifndef HAVE_SLANG /* With slang we don't want any of this, since there * is no mc_raw_mode supported */ reset_shell_mode (); noecho (); #endif /* !HAVE_SLANG */ keypad (stdscr, FALSE); endwin (); do_exit_ca_mode (); mc_raw_mode (); if (console_flag) handle_console (CONSOLE_RESTORE); #ifdef HAVE_SUBSHELL_SUPPORT if (use_subshell) { new_dir_p = vfs_current_is_local ()? &new_dir : NULL; if (invoke_subshell (NULL, VISIBLY, new_dir_p)) quiet_quit_cmd (); /* User did `exit' or `logout': quit MC quietly */ } else #endif /* HAVE_SUBSHELL_SUPPORT */ { if (output_starts_shell) { fprintf (stderr, _("Type `exit' to return to the Midnight Commander")); fprintf (stderr, "\n\r\n\r"); my_system (EXECUTE_INTERNAL, shell, NULL); } else get_key_code (0); } if (console_flag) handle_console (CONSOLE_SAVE); do_enter_ca_mode (); reset_prog_mode (); keypad (stdscr, TRUE); /* Prevent screen flash when user did 'exit' or 'logout' within subshell */ if (quit) return; enable_mouse (); channels_up (); if (alternate_plus_minus) application_keypad_mode (); #ifdef HAVE_SUBSHELL_SUPPORT if (use_subshell) { load_prompt (0, 0); if (new_dir) do_possible_cd (new_dir); if (console_flag && output_lines) show_console_contents (output_start_y, LINES - keybar_visible - output_lines - 1, LINES - keybar_visible - 1); } #endif /* HAVE_SUBSHELL_SUPPORT */ update_panels (UP_OPTIMIZE, UP_KEEPSEL); update_xterm_title_path (); do_refresh (); }