root/src/execute.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. edition_post_exec
  2. edition_pre_exec
  3. do_possible_cd
  4. do_suspend_cmd
  5. execute_prepare_with_vfs_arg
  6. execute_cleanup_with_vfs_arg
  7. execute_get_opts_from_cfg
  8. execute_get_external_cmd_opts_from_config
  9. do_executev
  10. do_execute
  11. pre_exec
  12. post_exec
  13. shell_execute
  14. toggle_subshell
  15. execute_suspend
  16. execute_with_vfs_arg
  17. execute_external_editor_or_viewer

   1 /*
   2    Execution routines for GNU Midnight Commander
   3 
   4    Copyright (C) 2003-2019
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Slava Zanko <slavazanko@gmail.com>, 2013
   9 
  10    This file is part of the Midnight Commander.
  11 
  12    The Midnight Commander is free software: you can redistribute it
  13    and/or modify it under the terms of the GNU General Public License as
  14    published by the Free Software Foundation, either version 3 of the License,
  15    or (at your option) any later version.
  16 
  17    The Midnight Commander is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21 
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  24  */
  25 
  26 /** \file  execute.c
  27  *  \brief Source: execution routines
  28  */
  29 
  30 #include <config.h>
  31 
  32 #include <signal.h>
  33 #include <string.h>
  34 #include <sys/stat.h>
  35 #include <sys/time.h>
  36 
  37 #include "lib/global.h"
  38 
  39 #include "lib/tty/tty.h"
  40 #include "lib/tty/key.h"
  41 #include "lib/tty/win.h"
  42 #include "lib/vfs/vfs.h"
  43 #include "lib/mcconfig.h"
  44 #include "lib/util.h"
  45 #include "lib/strutil.h"        /* str_replace_all_substrings() */
  46 #include "lib/widget.h"
  47 
  48 #include "filemanager/midnight.h"
  49 #include "filemanager/layout.h" /* use_dash() */
  50 #include "consaver/cons.saver.h"
  51 #ifdef ENABLE_SUBSHELL
  52 #include "subshell/subshell.h"
  53 #endif
  54 #include "setup.h"              /* clear_before_exec */
  55 
  56 #include "execute.h"
  57 
  58 /*** global variables ****************************************************************************/
  59 
  60 int pause_after_run = pause_on_dumb_terminals;
  61 
  62 /*** file scope macro definitions ****************************************************************/
  63 
  64 /*** file scope type declarations ****************************************************************/
  65 
  66 /*** file scope variables ************************************************************************/
  67 
  68 /*** file scope functions ************************************************************************/
  69 
  70 void do_execute (const char *shell, const char *command, int flags);
  71 void do_executev (const char *shell, int flags, char *const argv[]);
  72 char *execute_get_external_cmd_opts_from_config (const char *command,
  73                                                  const vfs_path_t * filename_vpath,
  74                                                  long start_line);
  75 
  76 /* --------------------------------------------------------------------------------------------- */
  77 
  78 static void
  79 edition_post_exec (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  80 {
  81     tty_enter_ca_mode ();
  82 
  83     /* FIXME: Missing on slang endwin? */
  84     tty_reset_prog_mode ();
  85     tty_flush_input ();
  86 
  87     tty_keypad (TRUE);
  88     tty_raw_mode ();
  89     channels_up ();
  90     enable_mouse ();
  91     enable_bracketed_paste ();
  92     if (mc_global.tty.alternate_plus_minus)
  93         application_keypad_mode ();
  94 }
  95 
  96 /* --------------------------------------------------------------------------------------------- */
  97 
  98 static void
  99 edition_pre_exec (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 100 {
 101     if (clear_before_exec)
 102         clr_scr ();
 103     else
 104     {
 105         if (!(mc_global.tty.console_flag != '\0' || mc_global.tty.xterm_flag))
 106             printf ("\n\n");
 107     }
 108 
 109     channels_down ();
 110     disable_mouse ();
 111     disable_bracketed_paste ();
 112 
 113     tty_reset_shell_mode ();
 114     tty_keypad (FALSE);
 115     tty_reset_screen ();
 116 
 117     numeric_keypad_mode ();
 118 
 119     /* on xterms: maybe endwin did not leave the terminal on the shell
 120      * screen page: do it now.
 121      *
 122      * Do not move this before endwin: in some systems rmcup includes
 123      * a call to clear screen, so it will end up clearing the shell screen.
 124      */
 125     tty_exit_ca_mode ();
 126 }
 127 
 128 /* --------------------------------------------------------------------------------------------- */
 129 
 130 #ifdef ENABLE_SUBSHELL
 131 static void
 132 do_possible_cd (const vfs_path_t * new_dir_vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 133 {
 134     if (!do_cd (new_dir_vpath, cd_exact))
 135         message (D_ERROR, _("Warning"), "%s",
 136                  _("The Commander can't change to the directory that\n"
 137                    "the subshell claims you are in. Perhaps you have\n"
 138                    "deleted your working directory, or given yourself\n"
 139                    "extra access permissions with the \"su\" command?"));
 140 }
 141 #endif /* ENABLE_SUBSHELL */
 142 
 143 /* --------------------------------------------------------------------------------------------- */
 144 
 145 static void
 146 do_suspend_cmd (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 147 {
 148     pre_exec ();
 149 
 150     if (mc_global.tty.console_flag != '\0' && !mc_global.tty.use_subshell)
 151         handle_console (CONSOLE_RESTORE);
 152 
 153 #ifdef SIGTSTP
 154     {
 155         struct sigaction sigtstp_action;
 156 
 157         memset (&sigtstp_action, 0, sizeof (sigtstp_action));
 158         /* Make sure that the SIGTSTP below will suspend us directly,
 159            without calling ncurses' SIGTSTP handler; we *don't* want
 160            ncurses to redraw the screen immediately after the SIGCONT */
 161         sigaction (SIGTSTP, &startup_handler, &sigtstp_action);
 162 
 163         kill (getpid (), SIGTSTP);
 164 
 165         /* Restore previous SIGTSTP action */
 166         sigaction (SIGTSTP, &sigtstp_action, NULL);
 167     }
 168 #endif /* SIGTSTP */
 169 
 170     if (mc_global.tty.console_flag != '\0' && !mc_global.tty.use_subshell)
 171         handle_console (CONSOLE_SAVE);
 172 
 173     edition_post_exec ();
 174 }
 175 
 176 /* --------------------------------------------------------------------------------------------- */
 177 
 178 static gboolean
 179 execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
     /* [previous][next][first][last][top][bottom][index][help]  */
 180                               time_t * mtime)
 181 {
 182     struct stat st;
 183 
 184     /* Simplest case, this file is local */
 185     if ((filename_vpath == NULL && vfs_file_is_local (vfs_get_raw_current_dir ()))
 186         || vfs_file_is_local (filename_vpath))
 187         return TRUE;
 188 
 189     /* FIXME: Creation of new files on VFS is not supported */
 190     if (filename_vpath == NULL)
 191         return FALSE;
 192 
 193     *localcopy_vpath = mc_getlocalcopy (filename_vpath);
 194     if (*localcopy_vpath == NULL)
 195     {
 196         message (D_ERROR, MSG_ERROR, _("Cannot fetch a local copy of %s"),
 197                  vfs_path_as_str (filename_vpath));
 198         return FALSE;
 199     }
 200 
 201     mc_stat (*localcopy_vpath, &st);
 202     *mtime = st.st_mtime;
 203     return TRUE;
 204 }
 205 
 206 /* --------------------------------------------------------------------------------------------- */
 207 
 208 static void
 209 execute_cleanup_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
     /* [previous][next][first][last][top][bottom][index][help]  */
 210                               time_t * mtime)
 211 {
 212     if (*localcopy_vpath != NULL)
 213     {
 214         struct stat st;
 215 
 216         /*
 217          * filename can be an entry on panel, it can be changed by executing
 218          * the command, so make a copy.  Smarter VFS code would make the code
 219          * below unnecessary.
 220          */
 221         mc_stat (*localcopy_vpath, &st);
 222         mc_ungetlocalcopy (filename_vpath, *localcopy_vpath, *mtime != st.st_mtime);
 223         vfs_path_free (*localcopy_vpath);
 224         *localcopy_vpath = NULL;
 225     }
 226 }
 227 
 228 /* --------------------------------------------------------------------------------------------- */
 229 
 230 static char *
 231 execute_get_opts_from_cfg (const char *command, const char *default_str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 232 {
 233     char *str_from_config;
 234 
 235     str_from_config =
 236         mc_config_get_string_raw (mc_global.main_config, CONFIG_EXT_EDITOR_VIEWER_SECTION, command,
 237                                   NULL);
 238 
 239     if (str_from_config == NULL)
 240     {
 241         mc_config_t *cfg;
 242 
 243         cfg = mc_config_init (global_profile_name, TRUE);
 244         if (cfg == NULL)
 245             return g_strdup (default_str);
 246 
 247         str_from_config =
 248             mc_config_get_string_raw (cfg, CONFIG_EXT_EDITOR_VIEWER_SECTION, command, default_str);
 249 
 250         mc_config_deinit (cfg);
 251     }
 252 
 253     return str_from_config;
 254 }
 255 
 256 /* --------------------------------------------------------------------------------------------- */
 257 /*** public functions ****************************************************************************/
 258 /* --------------------------------------------------------------------------------------------- */
 259 
 260 char *
 261 execute_get_external_cmd_opts_from_config (const char *command, const vfs_path_t * filename_vpath,
     /* [previous][next][first][last][top][bottom][index][help]  */
 262                                            long start_line)
 263 {
 264     char *str_from_config, *return_str;
 265     char *parameter;
 266 
 267     if (filename_vpath == NULL)
 268         return g_strdup ("");
 269 
 270     parameter = g_shell_quote (vfs_path_get_last_path_str (filename_vpath));
 271 
 272     if (start_line <= 0)
 273         return parameter;
 274 
 275     str_from_config = execute_get_opts_from_cfg (command, "%filename");
 276 
 277     return_str = str_replace_all (str_from_config, "%filename", parameter);
 278     g_free (parameter);
 279     g_free (str_from_config);
 280     str_from_config = return_str;
 281 
 282     parameter = g_strdup_printf ("%ld", start_line);
 283     return_str = str_replace_all (str_from_config, "%lineno", parameter);
 284     g_free (parameter);
 285     g_free (str_from_config);
 286 
 287     return return_str;
 288 }
 289 
 290 /* --------------------------------------------------------------------------------------------- */
 291 
 292 void
 293 do_executev (const char *shell, int flags, char *const argv[])
     /* [previous][next][first][last][top][bottom][index][help]  */
 294 {
 295 #ifdef ENABLE_SUBSHELL
 296     vfs_path_t *new_dir_vpath = NULL;
 297 #endif /* ENABLE_SUBSHELL */
 298 
 299     vfs_path_t *old_vfs_dir_vpath = NULL;
 300 
 301     if (!vfs_current_is_local ())
 302         old_vfs_dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
 303 
 304     if (mc_global.mc_run_mode == MC_RUN_FULL)
 305         save_cwds_stat ();
 306     pre_exec ();
 307     if (mc_global.tty.console_flag != '\0')
 308         handle_console (CONSOLE_RESTORE);
 309 
 310     if (!mc_global.tty.use_subshell && *argv != NULL && (flags & EXECUTE_INTERNAL) == 0)
 311     {
 312         printf ("%s%s\n", mc_prompt, *argv);
 313         fflush (stdout);
 314     }
 315 #ifdef ENABLE_SUBSHELL
 316     if (mc_global.tty.use_subshell && (flags & EXECUTE_INTERNAL) == 0)
 317     {
 318         do_update_prompt ();
 319 
 320         /* We don't care if it died, higher level takes care of this */
 321         invoke_subshell (*argv, VISIBLY, old_vfs_dir_vpath != NULL ? NULL : &new_dir_vpath);
 322     }
 323     else
 324 #endif /* ENABLE_SUBSHELL */
 325         my_systemv_flags (flags, shell, argv);
 326 
 327     if ((flags & EXECUTE_INTERNAL) == 0)
 328     {
 329         if ((pause_after_run == pause_always
 330              || (pause_after_run == pause_on_dumb_terminals && !mc_global.tty.xterm_flag
 331                  && mc_global.tty.console_flag == '\0')) && quit == 0
 332 #ifdef ENABLE_SUBSHELL
 333             && subshell_state != RUNNING_COMMAND
 334 #endif /* ENABLE_SUBSHELL */
 335             )
 336         {
 337             printf ("%s", _("Press any key to continue..."));
 338             fflush (stdout);
 339             tty_raw_mode ();
 340             get_key_code (0);
 341             printf ("\r\n");
 342             fflush (stdout);
 343         }
 344         if (mc_global.tty.console_flag != '\0' && output_lines != 0 && mc_global.keybar_visible)
 345         {
 346             putchar ('\n');
 347             fflush (stdout);
 348         }
 349     }
 350 
 351     if (mc_global.tty.console_flag != '\0')
 352         handle_console (CONSOLE_SAVE);
 353     edition_post_exec ();
 354 
 355 #ifdef ENABLE_SUBSHELL
 356     if (new_dir_vpath != NULL)
 357     {
 358         do_possible_cd (new_dir_vpath);
 359         vfs_path_free (new_dir_vpath);
 360     }
 361 
 362 #endif /* ENABLE_SUBSHELL */
 363 
 364     if (old_vfs_dir_vpath != NULL)
 365     {
 366         mc_chdir (old_vfs_dir_vpath);
 367         vfs_path_free (old_vfs_dir_vpath);
 368     }
 369 
 370     if (mc_global.mc_run_mode == MC_RUN_FULL)
 371     {
 372         update_panels (UP_OPTIMIZE, UP_KEEPSEL);
 373         update_xterm_title_path ();
 374     }
 375 
 376     do_refresh ();
 377     use_dash (TRUE);
 378 }
 379 
 380 /* --------------------------------------------------------------------------------------------- */
 381 
 382 void
 383 do_execute (const char *shell, const char *command, int flags)
     /* [previous][next][first][last][top][bottom][index][help]  */
 384 {
 385     GPtrArray *args_array;
 386 
 387     args_array = g_ptr_array_new ();
 388     g_ptr_array_add (args_array, (char *) command);
 389     g_ptr_array_add (args_array, NULL);
 390 
 391     do_executev (shell, flags, (char *const *) args_array->pdata);
 392 
 393     g_ptr_array_free (args_array, TRUE);
 394 }
 395 
 396 /* --------------------------------------------------------------------------------------------- */
 397 
 398 /** Set up the terminal before executing a program */
 399 
 400 void
 401 pre_exec (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 402 {
 403     use_dash (FALSE);
 404     edition_pre_exec ();
 405 }
 406 
 407 /* --------------------------------------------------------------------------------------------- */
 408 /** Hide the terminal after executing a program */
 409 void
 410 post_exec (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 411 {
 412     edition_post_exec ();
 413     use_dash (TRUE);
 414     repaint_screen ();
 415 }
 416 
 417 /* --------------------------------------------------------------------------------------------- */
 418 /* Executes a command */
 419 
 420 void
 421 shell_execute (const char *command, int flags)
     /* [previous][next][first][last][top][bottom][index][help]  */
 422 {
 423     char *cmd = NULL;
 424 
 425     if (flags & EXECUTE_HIDE)
 426     {
 427         cmd = g_strconcat (" ", command, (char *) NULL);
 428         flags ^= EXECUTE_HIDE;
 429     }
 430 
 431 #ifdef ENABLE_SUBSHELL
 432     if (mc_global.tty.use_subshell)
 433     {
 434         if (subshell_state == INACTIVE)
 435             do_execute (mc_global.shell->path, cmd ? cmd : command, flags | EXECUTE_AS_SHELL);
 436         else
 437             message (D_ERROR, MSG_ERROR, "%s", _("The shell is already running a command"));
 438     }
 439     else
 440 #endif /* ENABLE_SUBSHELL */
 441         do_execute (mc_global.shell->path, cmd ? cmd : command, flags | EXECUTE_AS_SHELL);
 442 
 443     g_free (cmd);
 444 }
 445 
 446 /* --------------------------------------------------------------------------------------------- */
 447 
 448 void
 449 toggle_subshell (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 450 {
 451     static gboolean message_flag = TRUE;
 452 
 453 #ifdef ENABLE_SUBSHELL
 454     vfs_path_t *new_dir_vpath = NULL;
 455 #endif /* ENABLE_SUBSHELL */
 456 
 457     SIG_ATOMIC_VOLATILE_T was_sigwinch = 0;
 458 
 459     if (!(mc_global.tty.xterm_flag || mc_global.tty.console_flag != '\0'
 460           || mc_global.tty.use_subshell || output_starts_shell))
 461     {
 462         if (message_flag)
 463             message (D_ERROR, MSG_ERROR,
 464                      _("Not an xterm or Linux console;\nthe panels cannot be toggled."));
 465         message_flag = FALSE;
 466         return;
 467     }
 468 
 469     channels_down ();
 470     disable_mouse ();
 471     disable_bracketed_paste ();
 472     if (clear_before_exec)
 473         clr_scr ();
 474     if (mc_global.tty.alternate_plus_minus)
 475         numeric_keypad_mode ();
 476 #ifndef HAVE_SLANG
 477     /* With slang we don't want any of this, since there
 478      * is no raw_mode supported
 479      */
 480     tty_reset_shell_mode ();
 481 #endif /* !HAVE_SLANG */
 482     tty_noecho ();
 483     tty_keypad (FALSE);
 484     tty_reset_screen ();
 485     tty_exit_ca_mode ();
 486     tty_raw_mode ();
 487     if (mc_global.tty.console_flag != '\0')
 488         handle_console (CONSOLE_RESTORE);
 489 
 490 #ifdef ENABLE_SUBSHELL
 491     if (mc_global.tty.use_subshell)
 492     {
 493         vfs_path_t **new_dir_p;
 494 
 495         new_dir_p = vfs_current_is_local ()? &new_dir_vpath : NULL;
 496         invoke_subshell (NULL, VISIBLY, new_dir_p);
 497     }
 498     else
 499 #endif /* ENABLE_SUBSHELL */
 500     {
 501         if (output_starts_shell)
 502         {
 503             fputs (_("Type 'exit' to return to the Midnight Commander"), stderr);
 504             fputs ("\n\r\n\r", stderr);
 505 
 506             my_system (EXECUTE_INTERNAL, mc_global.shell->path, NULL);
 507         }
 508         else
 509             get_key_code (0);
 510     }
 511 
 512     if (mc_global.tty.console_flag != '\0')
 513         handle_console (CONSOLE_SAVE);
 514 
 515     tty_enter_ca_mode ();
 516 
 517     tty_reset_prog_mode ();
 518     tty_keypad (TRUE);
 519 
 520     /* Prevent screen flash when user did 'exit' or 'logout' within
 521        subshell */
 522     if ((quit & SUBSHELL_EXIT) != 0)
 523     {
 524         /* User did 'exit' or 'logout': quit MC */
 525         if (quiet_quit_cmd ())
 526             return;
 527 
 528         quit = 0;
 529 #ifdef ENABLE_SUBSHELL
 530         /* restart subshell */
 531         if (mc_global.tty.use_subshell)
 532             init_subshell ();
 533 #endif /* ENABLE_SUBSHELL */
 534     }
 535 
 536     enable_mouse ();
 537     enable_bracketed_paste ();
 538     channels_up ();
 539     if (mc_global.tty.alternate_plus_minus)
 540         application_keypad_mode ();
 541 
 542     /* HACK:
 543      * Save sigwinch flag that will be reset in mc_refresh() called via update_panels().
 544      * There is some problem with screen redraw in ncurses-based mc in this situation.
 545      */
 546     was_sigwinch = tty_got_winch ();
 547     tty_flush_winch ();
 548 
 549 #ifdef ENABLE_SUBSHELL
 550     if (mc_global.tty.use_subshell)
 551     {
 552         if (mc_global.mc_run_mode == MC_RUN_FULL)
 553         {
 554             do_load_prompt ();
 555             if (new_dir_vpath != NULL)
 556                 do_possible_cd (new_dir_vpath);
 557             if (mc_global.tty.console_flag != '\0' && output_lines)
 558                 show_console_contents (output_start_y,
 559                                        LINES - mc_global.keybar_visible - output_lines -
 560                                        1, LINES - mc_global.keybar_visible - 1);
 561         }
 562         else if (new_dir_vpath != NULL && mc_chdir (new_dir_vpath) != -1)
 563             vfs_setup_cwd ();
 564     }
 565 
 566     vfs_path_free (new_dir_vpath);
 567 #endif /* ENABLE_SUBSHELL */
 568 
 569     if (mc_global.mc_run_mode == MC_RUN_FULL)
 570     {
 571         update_panels (UP_OPTIMIZE, UP_KEEPSEL);
 572         update_xterm_title_path ();
 573     }
 574 
 575     if (was_sigwinch != 0 || tty_got_winch ())
 576         dialog_change_screen_size ();
 577     else
 578         repaint_screen ();
 579 }
 580 
 581 /* --------------------------------------------------------------------------------------------- */
 582 
 583 /* event callback */
 584 gboolean
 585 execute_suspend (const gchar * event_group_name, const gchar * event_name,
     /* [previous][next][first][last][top][bottom][index][help]  */
 586                  gpointer init_data, gpointer data)
 587 {
 588     (void) event_group_name;
 589     (void) event_name;
 590     (void) init_data;
 591     (void) data;
 592 
 593     if (mc_global.mc_run_mode == MC_RUN_FULL)
 594         save_cwds_stat ();
 595     do_suspend_cmd ();
 596     if (mc_global.mc_run_mode == MC_RUN_FULL)
 597         update_panels (UP_OPTIMIZE, UP_KEEPSEL);
 598     do_refresh ();
 599 
 600     return TRUE;
 601 }
 602 
 603 /* --------------------------------------------------------------------------------------------- */
 604 
 605 /**
 606  * Execute command on a filename that can be on VFS.
 607  * Errors are reported to the user.
 608  */
 609 
 610 void
 611 execute_with_vfs_arg (const char *command, const vfs_path_t * filename_vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 612 {
 613     vfs_path_t *localcopy_vpath = NULL;
 614     const vfs_path_t *do_execute_vpath;
 615     time_t mtime;
 616 
 617     if (!execute_prepare_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime))
 618         return;
 619 
 620     do_execute_vpath = (localcopy_vpath == NULL) ? filename_vpath : localcopy_vpath;
 621 
 622     do_execute (command, vfs_path_get_last_path_str (do_execute_vpath), EXECUTE_INTERNAL);
 623 
 624     execute_cleanup_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime);
 625 }
 626 
 627 /* --------------------------------------------------------------------------------------------- */
 628 /**
 629  * Execute external editor or viewer.
 630  *
 631  * @param command editor/viewer to run
 632  * @param filename_vpath path for edit/view
 633  * @param start_line cursor will be placed at the 'start_line' position after opening file
 634  *        if start_line is 0 or negative, no start line will be passed to editor/viewer
 635  */
 636 
 637 void
 638 execute_external_editor_or_viewer (const char *command, const vfs_path_t * filename_vpath,
     /* [previous][next][first][last][top][bottom][index][help]  */
 639                                    long start_line)
 640 {
 641     vfs_path_t *localcopy_vpath = NULL;
 642     const vfs_path_t *do_execute_vpath;
 643     char *extern_cmd_options;
 644     time_t mtime = 0;
 645 
 646     if (!execute_prepare_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime))
 647         return;
 648 
 649     do_execute_vpath = (localcopy_vpath == NULL) ? filename_vpath : localcopy_vpath;
 650 
 651     extern_cmd_options =
 652         execute_get_external_cmd_opts_from_config (command, do_execute_vpath, start_line);
 653 
 654     if (extern_cmd_options != NULL)
 655     {
 656         char **argv_cmd_options;
 657         int argv_count;
 658 
 659         if (g_shell_parse_argv (extern_cmd_options, &argv_count, &argv_cmd_options, NULL))
 660         {
 661             do_executev (command, EXECUTE_INTERNAL, argv_cmd_options);
 662             g_strfreev (argv_cmd_options);
 663         }
 664         else
 665             do_executev (command, EXECUTE_INTERNAL, NULL);
 666 
 667         g_free (extern_cmd_options);
 668     }
 669 
 670     execute_cleanup_with_vfs_arg (filename_vpath, &localcopy_vpath, &mtime);
 671 }
 672 
 673 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */