Forgot to remove some more .s strings and do a rename in order to prevent compiler...
[midnight-commander.git] / src / execute.c
blob35b4d4b6e1a3828f6fa58bbcb905022246b35728
1 /* Execution routines for GNU Midnight Commander
2 Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 #include <config.h>
20 #include <signal.h>
22 #include <mhl/memory.h>
23 #include <mhl/string.h>
25 #include "global.h"
26 #include "tty.h"
27 #include "win.h"
28 #include "key.h"
29 #include "main.h"
30 #include "cons.saver.h"
31 #include "subshell.h"
32 #include "layout.h"
33 #include "dialog.h"
34 #include "wtools.h"
35 #include "execute.h"
38 static void
39 edition_post_exec (void)
41 do_enter_ca_mode ();
43 /* FIXME: Missing on slang endwin? */
44 reset_prog_mode ();
45 flushinp ();
47 keypad (stdscr, TRUE);
48 mc_raw_mode ();
49 channels_up ();
50 enable_mouse ();
51 if (alternate_plus_minus)
52 application_keypad_mode ();
56 static void
57 edition_pre_exec (void)
59 if (clear_before_exec)
60 clr_scr ();
61 else {
62 if (!(console_flag || xterm_flag))
63 printf ("\n\n");
66 channels_down ();
67 disable_mouse ();
69 reset_shell_mode ();
70 keypad (stdscr, FALSE);
71 endwin ();
73 numeric_keypad_mode ();
75 /* on xterms: maybe endwin did not leave the terminal on the shell
76 * screen page: do it now.
78 * Do not move this before endwin: in some systems rmcup includes
79 * a call to clear screen, so it will end up clearing the shell screen.
81 do_exit_ca_mode ();
85 /* Set up the terminal before executing a program */
86 static void
87 pre_exec (void)
89 use_dash (0);
90 edition_pre_exec ();
94 static void
95 do_execute (const char *shell, const char *command, int flags)
97 #ifdef HAVE_SUBSHELL_SUPPORT
98 char *new_dir = NULL;
99 #endif /* HAVE_SUBSHELL_SUPPORT */
101 #ifdef USE_VFS
102 char *old_vfs_dir = 0;
104 if (!vfs_current_is_local ())
105 old_vfs_dir = g_strdup (vfs_get_current_dir ());
106 #endif /* USE_VFS */
108 save_cwds_stat ();
109 pre_exec ();
110 if (console_flag)
111 handle_console (CONSOLE_RESTORE);
113 if (!use_subshell && command && !(flags & EXECUTE_INTERNAL)) {
114 printf ("%s%s\n", prompt, command);
115 fflush (stdout);
117 #ifdef HAVE_SUBSHELL_SUPPORT
118 if (use_subshell && !(flags & EXECUTE_INTERNAL)) {
119 do_update_prompt ();
121 /* We don't care if it died, higher level takes care of this */
122 #ifdef USE_VFS
123 invoke_subshell (command, VISIBLY, old_vfs_dir ? 0 : &new_dir);
124 #else
125 invoke_subshell (command, VISIBLY, &new_dir);
126 #endif /* !USE_VFS */
127 } else
128 #endif /* HAVE_SUBSHELL_SUPPORT */
129 my_system (flags, shell, command);
131 if (!(flags & EXECUTE_INTERNAL)) {
132 if ((pause_after_run == pause_always
133 || (pause_after_run == pause_on_dumb_terminals && !xterm_flag
134 && !console_flag)) && !quit
135 #ifdef HAVE_SUBSHELL_SUPPORT
136 && subshell_state != RUNNING_COMMAND
137 #endif /* HAVE_SUBSHELL_SUPPORT */
139 printf (_("Press any key to continue..."));
140 fflush (stdout);
141 mc_raw_mode ();
142 get_key_code (0);
143 printf ("\r\n");
144 fflush (stdout);
146 if (console_flag) {
147 if (output_lines && keybar_visible) {
148 putchar ('\n');
149 fflush (stdout);
154 if (console_flag)
155 handle_console (CONSOLE_SAVE);
156 edition_post_exec ();
158 #ifdef HAVE_SUBSHELL_SUPPORT
159 if (new_dir)
160 do_possible_cd (new_dir);
162 #endif /* HAVE_SUBSHELL_SUPPORT */
164 #ifdef USE_VFS
165 if (old_vfs_dir) {
166 mc_chdir (old_vfs_dir);
167 g_free (old_vfs_dir);
169 #endif /* USE_VFS */
171 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
172 update_xterm_title_path ();
174 do_refresh ();
175 use_dash (TRUE);
179 /* Executes a command */
180 void
181 shell_execute (const char *command, int flags)
183 char *cmd = NULL;
185 if (flags & EXECUTE_HIDE) {
186 cmd = g_strconcat (" ", command, (char *) NULL);
187 flags ^= EXECUTE_HIDE;
190 #ifdef HAVE_SUBSHELL_SUPPORT
191 if (use_subshell)
192 if (subshell_state == INACTIVE)
193 do_execute (shell, cmd ? cmd : command, flags | EXECUTE_AS_SHELL);
194 else
195 message (D_ERROR, MSG_ERROR,
196 _(" The shell is already running a command "));
197 else
198 #endif /* HAVE_SUBSHELL_SUPPORT */
199 do_execute (shell, cmd ? cmd : command, flags | EXECUTE_AS_SHELL);
201 g_free (cmd);
205 void
206 exec_shell (void)
208 do_execute (shell, 0, 0);
212 void
213 toggle_panels (void)
215 #ifdef HAVE_SUBSHELL_SUPPORT
216 char *new_dir = NULL;
217 char **new_dir_p;
218 #endif /* HAVE_SUBSHELL_SUPPORT */
220 channels_down ();
221 disable_mouse ();
222 if (clear_before_exec)
223 clr_scr ();
224 if (alternate_plus_minus)
225 numeric_keypad_mode ();
226 #ifndef HAVE_SLANG
227 /* With slang we don't want any of this, since there
228 * is no mc_raw_mode supported
230 reset_shell_mode ();
231 noecho ();
232 #endif /* !HAVE_SLANG */
233 keypad (stdscr, FALSE);
234 endwin ();
235 do_exit_ca_mode ();
236 mc_raw_mode ();
237 if (console_flag)
238 handle_console (CONSOLE_RESTORE);
240 #ifdef HAVE_SUBSHELL_SUPPORT
241 if (use_subshell) {
242 new_dir_p = vfs_current_is_local ()? &new_dir : NULL;
243 if (invoke_subshell (NULL, VISIBLY, new_dir_p))
244 quiet_quit_cmd (); /* User did `exit' or `logout': quit MC quietly */
245 } else
246 #endif /* HAVE_SUBSHELL_SUPPORT */
248 if (output_starts_shell) {
249 fprintf (stderr,
250 _("Type `exit' to return to the Midnight Commander"));
251 fprintf (stderr, "\n\r\n\r");
253 my_system (EXECUTE_INTERNAL, shell, NULL);
254 } else
255 get_key_code (0);
257 if (console_flag)
258 handle_console (CONSOLE_SAVE);
260 do_enter_ca_mode ();
262 reset_prog_mode ();
263 keypad (stdscr, TRUE);
265 /* Prevent screen flash when user did 'exit' or 'logout' within
266 subshell */
267 if (quit)
268 return;
270 enable_mouse ();
271 channels_up ();
272 if (alternate_plus_minus)
273 application_keypad_mode ();
275 #ifdef HAVE_SUBSHELL_SUPPORT
276 if (use_subshell) {
277 load_prompt (0, 0);
278 if (new_dir)
279 do_possible_cd (new_dir);
280 if (console_flag && output_lines)
281 show_console_contents (output_start_y,
282 LINES - keybar_visible - output_lines -
283 1, LINES - keybar_visible - 1);
285 #endif /* HAVE_SUBSHELL_SUPPORT */
287 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
288 update_xterm_title_path ();
289 do_refresh ();
293 static void
294 do_suspend_cmd (void)
296 pre_exec ();
298 if (console_flag && !use_subshell)
299 handle_console (CONSOLE_RESTORE);
301 #ifdef SIGTSTP
303 struct sigaction sigtstp_action;
305 /* Make sure that the SIGTSTP below will suspend us directly,
306 without calling ncurses' SIGTSTP handler; we *don't* want
307 ncurses to redraw the screen immediately after the SIGCONT */
308 sigaction (SIGTSTP, &startup_handler, &sigtstp_action);
310 kill (getpid (), SIGTSTP);
312 /* Restore previous SIGTSTP action */
313 sigaction (SIGTSTP, &sigtstp_action, NULL);
315 #endif /* SIGTSTP */
317 if (console_flag && !use_subshell)
318 handle_console (CONSOLE_SAVE);
320 edition_post_exec ();
324 void
325 suspend_cmd (void)
327 save_cwds_stat ();
328 do_suspend_cmd ();
329 update_panels (UP_OPTIMIZE, UP_KEEPSEL);
330 do_refresh ();
335 * Execute command on a filename that can be on VFS.
336 * Errors are reported to the user.
338 void
339 execute_with_vfs_arg (const char *command, const char *filename)
341 char *localcopy;
342 char *fn;
343 struct stat st;
344 time_t mtime;
346 /* Simplest case, this file is local */
347 if (!filename || vfs_file_is_local (filename)) {
348 do_execute (command, filename, EXECUTE_INTERNAL);
349 return;
352 /* FIXME: Creation of new files on VFS is not supported */
353 if (!*filename)
354 return;
356 localcopy = mc_getlocalcopy (filename);
357 if (localcopy == NULL) {
358 message (D_ERROR, MSG_ERROR, _(" Cannot fetch a local copy of %s "),
359 filename);
360 return;
364 * filename can be an entry on panel, it can be changed by executing
365 * the command, so make a copy. Smarter VFS code would make the code
366 * below unnecessary.
368 fn = g_strdup (filename);
369 mc_stat (localcopy, &st);
370 mtime = st.st_mtime;
371 do_execute (command, localcopy, EXECUTE_INTERNAL);
372 mc_stat (localcopy, &st);
373 mc_ungetlocalcopy (fn, localcopy, mtime != st.st_mtime);
374 g_free (localcopy);
375 g_free (fn);