Пример #1
0
int
invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath)
{
    char *pcwd;

    /* Make the MC terminal transparent */
    tcsetattr (STDOUT_FILENO, TCSANOW, &raw_mode);

    /* Make the subshell change to MC's working directory */
    if (new_dir_vpath != NULL)
        do_subshell_chdir (current_panel->cwd_vpath, TRUE, TRUE);

    if (command == NULL)        /* The user has done "C-o" from MC */
    {
        if (subshell_state == INACTIVE)
        {
            subshell_state = ACTIVE;
            /* FIXME: possibly take out this hack; the user can
               re-play it by hitting C-hyphen a few times! */
            if (subshell_ready)
                write_all (mc_global.tty.subshell_pty, " \b", 2);       /* Hack to make prompt reappear */
        }
    }
    else                        /* MC has passed us a user command */
    {
        if (how == QUIETLY)
            write_all (mc_global.tty.subshell_pty, " ", 1);
        /* FIXME: if command is long (>8KB ?) we go comma */
        write_all (mc_global.tty.subshell_pty, command, strlen (command));
        write_all (mc_global.tty.subshell_pty, "\n", 1);
        subshell_state = RUNNING_COMMAND;
        subshell_ready = FALSE;
    }

    feed_subshell (how, FALSE);

    {
        char *cwd_str;

        cwd_str = vfs_path_to_str (current_panel->cwd_vpath);
        pcwd = vfs_translate_path_n (cwd_str);
        g_free (cwd_str);
    }

    if (new_dir_vpath != NULL && subshell_alive && strcmp (subshell_cwd, pcwd))
        *new_dir_vpath = vfs_path_from_str (subshell_cwd);      /* Make MC change to the subshell's CWD */
    g_free (pcwd);

    /* Restart the subshell if it has died by SIGHUP, SIGQUIT, etc. */
    while (!subshell_alive && quit == 0 && mc_global.tty.use_subshell)
        init_subshell ();

    prompt_pos = 0;

    return quit;
}
Пример #2
0
/** If it actually changed the directory it returns true */
void
do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt)
{
    char *pcwd;

    pcwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_RECODE);

    if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0))
    {
        /* We have to repaint the subshell prompt if we read it from
         * the main program.  Please note that in the code after this
         * if, the cd command that is sent will make the subshell
         * repaint the prompt, so we don't have to paint it. */
        if (update_prompt)
            do_update_prompt ();
        g_free (pcwd);
        return;
    }

    /* The initial space keeps this out of the command history (in bash
       because we set "HISTCONTROL=ignorespace") */
    write_all (mc_global.tty.subshell_pty, " cd ", 4);

    if (vpath != NULL)
    {
        char *translate;

        translate = vfs_translate_path_n (vfs_path_as_str (vpath));
        if (translate != NULL)
        {
            GString *temp;

            temp = subshell_name_quote (translate);
            write_all (mc_global.tty.subshell_pty, temp->str, temp->len);
            g_string_free (temp, TRUE);

            g_free (translate);
        }
        else
        {
            write_all (mc_global.tty.subshell_pty, ".", 1);
        }
    }
    else
    {
        write_all (mc_global.tty.subshell_pty, "/", 1);
    }
    write_all (mc_global.tty.subshell_pty, "\n", 1);

    subshell_state = RUNNING_COMMAND;
    feed_subshell (QUIETLY, FALSE);

    if (subshell_alive)
    {
        int bPathNotEq = strcmp (subshell_cwd, pcwd);

        if (bPathNotEq && subshell_type == TCSH)
        {
            char rp_subshell_cwd[PATH_MAX];
            char rp_current_panel_cwd[PATH_MAX];

            char *p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd);
            char *p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd);

            if (p_subshell_cwd == NULL)
                p_subshell_cwd = subshell_cwd;
            if (p_current_panel_cwd == NULL)
                p_current_panel_cwd = pcwd;
            bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd);
        }

        if (bPathNotEq && !DIR_IS_DOT (pcwd))
        {
            char *cwd;

            cwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_PASSWORD);
            vfs_print_message (_("Warning: Cannot change to %s.\n"), cwd);
            g_free (cwd);
        }
    }

    update_subshell_prompt = FALSE;

    g_free (pcwd);
    /* Make sure that MC never stores the CWD in a silly format */
    /* like /usr////lib/../bin, or the strcmp() above will fail */
}
Пример #3
0
/** If it actually changed the directory it returns true */
void
do_subshell_chdir (const char *directory, gboolean update_prompt, gboolean reset_prompt)
{
    char *pcwd;
    char *temp;
    char *translate;

    pcwd = vfs_translate_path_n (current_panel->cwd);

    if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0))
    {
        /* We have to repaint the subshell prompt if we read it from
         * the main program.  Please note that in the code after this
         * if, the cd command that is sent will make the subshell
         * repaint the prompt, so we don't have to paint it. */
        if (update_prompt)
            do_update_prompt ();
        g_free (pcwd);
        return;
    }

    /* The initial space keeps this out of the command history (in bash
       because we set "HISTCONTROL=ignorespace") */
    write_all (mc_global.tty.subshell_pty, " cd ", 4);
    if (*directory)
    {
        translate = vfs_translate_path_n (directory);
        if (translate)
        {
            temp = subshell_name_quote (translate);
            if (temp)
            {
                write_all (mc_global.tty.subshell_pty, temp, strlen (temp));
                g_free (temp);
            }
            else
            {
                /* Should not happen unless the directory name is so long
                   that we don't have memory to quote it.  */
                write_all (mc_global.tty.subshell_pty, ".", 1);
            }
            g_free (translate);
        }
        else
        {
            write_all (mc_global.tty.subshell_pty, ".", 1);
        }
    }
    else
    {
        write_all (mc_global.tty.subshell_pty, "/", 1);
    }
    write_all (mc_global.tty.subshell_pty, "\n", 1);

    subshell_state = RUNNING_COMMAND;
    feed_subshell (QUIETLY, FALSE);

    if (subshell_alive)
    {
        int bPathNotEq = strcmp (subshell_cwd, pcwd);

        if (bPathNotEq && subshell_type == TCSH)
        {
            char rp_subshell_cwd[PATH_MAX];
            char rp_current_panel_cwd[PATH_MAX];

            char *p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd);
            char *p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd);

            if (p_subshell_cwd == NULL)
                p_subshell_cwd = subshell_cwd;
            if (p_current_panel_cwd == NULL)
                p_current_panel_cwd = pcwd;
            bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd);
        }

        if (bPathNotEq && strcmp (pcwd, "."))
        {
            char *cwd = strip_password (g_strdup (pcwd), 1);
            fprintf (stderr, _("Warning: Cannot change to %s.\n"), cwd);
            g_free (cwd);
        }
    }

    if (reset_prompt)
        prompt_pos = 0;
    update_subshell_prompt = FALSE;

    g_free (pcwd);
    /* Make sure that MC never stores the CWD in a silly format */
    /* like /usr////lib/../bin, or the strcmp() above will fail */
}