Пример #1
0
/* *INDENT-OFF* */
START_PARAMETRIZED_TEST (test_path_to_str_flags, test_path_to_str_flags_ds)
/* *INDENT-ON* */
{
    /* given */
    vfs_path_t *vpath;
    char *str_path;

    test_init_vfs ("UTF-8");

    test_subclass1.flags = VFS_S_REMOTE;
    vfs_s_init_class (&vfs_test_ops1, &test_subclass1);
    vfs_test_ops1.name = "testfs1";
    vfs_test_ops1.flags = VFSF_NOLINKS;
    vfs_test_ops1.prefix = "test1";
    vfs_register_class (&vfs_test_ops1);

    /* when */

    vpath = vfs_path_from_str_flags (data->input_path, data->input_from_str_flags);
    str_path = vfs_path_to_str_flags (vpath, 0, data->input_to_str_flags);

    /* then */
    mctest_assert_str_eq (str_path, data->expected_path);

    g_free (str_path);
    vfs_path_free (vpath);
    test_deinit_vfs ();
}
Пример #2
0
Файл: main.c Проект: BrEacK/mc
void
title_path_prepare (char **path, char **login)
{

    char host[BUF_TINY];
    struct passwd *pw = NULL;
    int res = 0;

    *login = NULL;


    *path =
        vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
    res = gethostname (host, sizeof (host));
    if (res)
    {                           /* On success, res = 0 */
        host[0] = '\0';
    }
    else
    {
        host[sizeof (host) - 1] = '\0';
    }
    pw = getpwuid (getuid ());
    if (pw)
    {
        *login = g_strdup_printf ("%s@%s", pw->pw_name, host);
    }
    else
    {
        *login = g_strdup (host);
    }
}
Пример #3
0
Файл: util.c Проект: JBurant/mc
const char *
path_trunc (const char *path, size_t trunc_len)
{
    vfs_path_t *vpath;
    char *secure_path;
    const char *ret;

    vpath = vfs_path_from_str (path);
    secure_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
    vfs_path_free (vpath);

    ret = str_trunc (secure_path, trunc_len);
    g_free (secure_path);

    return ret;
}
Пример #4
0
/* *INDENT-OFF* */
END_PARAMETRIZED_TEST
/* *INDENT-ON* */

/* --------------------------------------------------------------------------------------------- */

/* Relative to panel_correct_path_to_show()  */

/* @Test */
/* *INDENT-OFF* */
START_TEST (test_vpath_to_str_filter)
/* *INDENT-ON* */
{
    /* given */
    vfs_path_t *vpath, *last_vpath;
    char *filtered_path;
    const vfs_path_element_t *path_element;

    /* when */
    vpath = vfs_path_from_str ("/test1://some.host/dir");
    path_element = vfs_path_element_clone (vfs_path_get_by_index (vpath, -1));
    vfs_path_free (vpath);

    last_vpath = vfs_path_new ();
    last_vpath->relative = TRUE;

    vfs_path_add_element (last_vpath, path_element);

    filtered_path = vfs_path_to_str_flags (last_vpath, 0,
                                           VPF_STRIP_HOME | VPF_STRIP_PASSWORD | VPF_HIDE_CHARSET);

    /* then */
    mctest_assert_str_eq (filtered_path, "test1://some.host/dir");

    vfs_path_free (last_vpath);
    g_free (filtered_path);
}
Пример #5
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 */
}
Пример #6
0
/*
 * FIXME: probably it is better to replace this with quick dialog machinery,
 * but actually I'm not familiar with it and have not much time :(
 *   alex
 */
static replace_action_t
overwrite_query_dialog (file_op_context_t * ctx, enum OperationMode mode)
{
#define ADD_RD_BUTTON(i, ypos) \
    add_widget_autopos (ui->replace_dlg, \
                        button_new (ypos, rd_widgets [i].xpos, rd_widgets [i].value, \
                                    NORMAL_BUTTON, rd_widgets [i].text, NULL), \
                        rd_widgets [i].pos_flags, ui->replace_dlg->current->data)

#define ADD_RD_LABEL(i, p1, p2, ypos) \
    g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2); \
    label2 = WIDGET (label_new (ypos, rd_widgets [i].xpos, buffer)); \
    add_widget_autopos (ui->replace_dlg, label2, rd_widgets [i].pos_flags, \
                        ui->replace_dlg->current != NULL ? ui->replace_dlg->current->data : NULL)

    /* dialog sizes */
    const int rd_ylen = 1;
    int rd_xlen = 60;
    int y = 2;
    unsigned long yes_id;

    struct
    {
        const char *text;
        int ypos, xpos;
        widget_pos_flags_t pos_flags;
        int value;              /* 0 for labels */
    } rd_widgets[] =
    {
    /* *INDENT-OFF* */
        /*  0 */
        { N_("Target file already exists!"), 3, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  1 */
        { "%s", 4, 4, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, 0 },
        /*  2 */
        { N_("New     : %s, size %s"), 6, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  3 */
        { N_("Existing: %s, size %s"), 7, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  4 */
        { N_("Overwrite this target?"), 9, 4, WPOS_KEEP_DEFAULT, 0 },
        /*  5 */
        { N_("&Yes"), 9, 28, WPOS_KEEP_DEFAULT, REPLACE_YES },
        /*  6 */
        { N_("&No"), 9, 37, WPOS_KEEP_DEFAULT, REPLACE_NO },
        /*  7 */
        { N_("A&ppend"), 9, 45, WPOS_KEEP_DEFAULT, REPLACE_APPEND },
        /*  8 */
        { N_("&Reget"), 10, 28, WPOS_KEEP_DEFAULT, REPLACE_REGET },
        /*  9 */
        { N_("Overwrite all targets?"), 11, 4, WPOS_KEEP_DEFAULT, 0 },
        /* 10 */
        { N_("A&ll"), 11, 28, WPOS_KEEP_DEFAULT, REPLACE_ALWAYS },
        /* 11 */
        { N_("&Update"), 11, 36, WPOS_KEEP_DEFAULT, REPLACE_UPDATE },
        /* 12 */
        { N_("Non&e"), 11, 47, WPOS_KEEP_DEFAULT, REPLACE_NEVER },
        /* 13 */
        { N_("If &size differs"), 12, 28, WPOS_KEEP_DEFAULT, REPLACE_SIZE },
        /* 14 */
        { N_("&Abort"), 14, 25, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, REPLACE_ABORT }
    /* *INDENT-ON* */
    };

    const size_t num = G_N_ELEMENTS (rd_widgets);
    int *widgets_len;

    file_op_context_ui_t *ui = ctx->ui;

    char buffer[BUF_SMALL];
    char fsize_buffer[BUF_SMALL];
    Widget *label1, *label2;
    const char *title;
    vfs_path_t *stripped_vpath;
    const char *stripped_name;
    char *stripped_name_orig;
    int result;

    widgets_len = g_new0 (int, num);

    if (mode == Foreground)
        title = _("File exists");
    else
        title = _("Background process: File exists");

    stripped_vpath = vfs_path_from_str (ui->replace_filename);
    stripped_name = stripped_name_orig =
        vfs_path_to_str_flags (stripped_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
    vfs_path_free (stripped_vpath);

    {
        size_t i;
        int l1, l2, l, row;
        int stripped_name_len;

        for (i = 0; i < num; i++)
        {
#ifdef ENABLE_NLS
            if (i != 1)         /* skip filename */
                rd_widgets[i].text = _(rd_widgets[i].text);
#endif /* ENABLE_NLS */
            widgets_len[i] = str_term_width1 (rd_widgets[i].text);
        }

        /*
         * longest of "Overwrite..." labels
         * (assume "Target date..." are short enough)
         */
        l1 = max (widgets_len[9], widgets_len[4]);

        /* longest of button rows */
        l = l2 = 0;
        row = 0;
        for (i = 1; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l2 = max (l2, l);
                    l = 0;
                }
                l += widgets_len[i] + 4;
            }

        l2 = max (l2, l);       /* last row */
        rd_xlen = max (rd_xlen, l1 + l2 + 8);
        /* rd_xlen = max (rd_xlen, str_term_width1 (title) + 2); */
        stripped_name_len = str_term_width1 (stripped_name);
        rd_xlen = max (rd_xlen, min (COLS, stripped_name_len + 8));

        /* Now place widgets */
        l1 += 5;                /* start of first button in the row */
        l = l1;
        row = 0;
        for (i = 2; i < num - 1; i++)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l = l1;
                }
                rd_widgets[i].xpos = l;
                l += widgets_len[i] + 4;
            }
    }

    /* FIXME - missing help node */
    ui->replace_dlg =
        dlg_create (TRUE, 0, 0, rd_ylen, rd_xlen, alarm_colors, NULL, NULL, "[Replace]", title,
                    DLG_CENTER);

    /* prompt */
    ADD_RD_LABEL (0, "", "", y++);
    /* file name */
    ADD_RD_LABEL (1, "", "", y++);
    label1 = label2;

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    /* source date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->s_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);
    /* destination date and size */
    size_trunc_len (fsize_buffer, sizeof (fsize_buffer), ui->d_stat->st_size, 0,
                    panels_options.kilobyte_si);
    ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), fsize_buffer, y++);
    rd_xlen = max (rd_xlen, label2->cols + 8);

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (4, 0, 0, y);  /* Overwrite this target? */
    yes_id = ADD_RD_BUTTON (5, y);      /* Yes */
    ADD_RD_BUTTON (6, y);       /* No */

    /* "this target..." widgets */
    if (!S_ISDIR (ui->d_stat->st_mode))
    {
        ADD_RD_BUTTON (7, y++); /* Append */

        if ((ctx->operation == OP_COPY) && (ui->d_stat->st_size != 0)
            && (ui->s_stat->st_size > ui->d_stat->st_size))
            ADD_RD_BUTTON (8, y++);     /* Reget */
    }

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_LABEL (9, 0, 0, y);  /* Overwrite all targets? */
    ADD_RD_BUTTON (10, y);      /* All" */
    ADD_RD_BUTTON (11, y);      /* Update */
    ADD_RD_BUTTON (12, y++);    /* None */
    ADD_RD_BUTTON (13, y++);    /* If size differs */

    add_widget (ui->replace_dlg, hline_new (y++, -1, -1));

    ADD_RD_BUTTON (14, y);      /* Abort */

    label_set_text (LABEL (label1), str_trunc (stripped_name, rd_xlen - 8));
    dlg_set_size (ui->replace_dlg, y + 3, rd_xlen);
    dlg_select_by_id (ui->replace_dlg, yes_id);
    result = dlg_run (ui->replace_dlg);
    dlg_destroy (ui->replace_dlg);

    g_free (widgets_len);
    g_free (stripped_name_orig);

    return (result == B_CANCEL) ? REPLACE_ABORT : (replace_action_t) result;
#undef ADD_RD_LABEL
#undef ADD_RD_BUTTON
}
Пример #7
0
char *
file_mask_dialog (file_op_context_t * ctx, FileOperation operation,
                  gboolean only_one,
                  const char *format, const void *text, const char *def_text, gboolean * do_bg)
{
    size_t fmd_xlen;
    vfs_path_t *vpath;
    int source_easy_patterns = easy_patterns;
    char fmd_buf[BUF_MEDIUM];
    char *dest_dir, *tmp;
    char *def_text_secure;

    if (ctx == NULL)
        return NULL;

    /* unselect checkbox if target filesystem don't support attributes */
    ctx->op_preserve = filegui__check_attrs_on_fs (def_text);
    ctx->stable_symlinks = FALSE;
    *do_bg = FALSE;

    /* filter out a possible password from def_text */
    vpath = vfs_path_from_str_flags (def_text, only_one ? VPF_NO_CANON : VPF_NONE);
    tmp = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
    vfs_path_free (vpath);

    if (source_easy_patterns)
        def_text_secure = strutils_glob_escape (tmp);
    else
        def_text_secure = strutils_regex_escape (tmp);
    g_free (tmp);

    if (only_one)
    {
        int format_len, text_len;
        int max_len;

        format_len = str_term_width1 (format);
        text_len = str_term_width1 (text);
        max_len = COLS - 2 - 6;

        if (format_len + text_len <= max_len)
        {
            fmd_xlen = format_len + text_len + 6;
            fmd_xlen = max (fmd_xlen, 68);
        }
        else
        {
            text = str_trunc ((const char *) text, max_len - format_len);
            fmd_xlen = max_len + 6;
        }

        g_snprintf (fmd_buf, sizeof (fmd_buf), format, (const char *) text);
    }
    else
    {
        fmd_xlen = COLS * 2 / 3;
        fmd_xlen = max (fmd_xlen, 68);
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, *(const int *) text);
    }

    {
        char *source_mask, *orig_mask;
        int val;
        struct stat buf;

        quick_widget_t quick_widgets[] = {
            /* *INDENT-OFF* */
            QUICK_LABELED_INPUT (fmd_buf, input_label_above,
                                 easy_patterns ? "*" : "^(.*)$", "input-def", &source_mask,
                                 NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
            QUICK_START_COLUMNS,
                QUICK_SEPARATOR (FALSE),
            QUICK_NEXT_COLUMN,
                QUICK_CHECKBOX (N_("&Using shell patterns"), &source_easy_patterns, NULL),
            QUICK_STOP_COLUMNS,
            QUICK_LABELED_INPUT (N_("to:"), input_label_above,
                                 def_text_secure, "input2", &dest_dir, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
            QUICK_SEPARATOR (TRUE),
            QUICK_START_COLUMNS,
                QUICK_CHECKBOX (N_("Follow &links"), &ctx->follow_links, NULL),
                QUICK_CHECKBOX (N_("Preserve &attributes"), &ctx->op_preserve, NULL),
            QUICK_NEXT_COLUMN,
                QUICK_CHECKBOX (N_("Di&ve into subdir if exists"), &ctx->dive_into_subdirs, NULL),
                QUICK_CHECKBOX (N_("&Stable symlinks"), &ctx->stable_symlinks, NULL),
            QUICK_STOP_COLUMNS,
            QUICK_START_BUTTONS (TRUE, TRUE),
                QUICK_BUTTON (N_("&OK"), B_ENTER, NULL, NULL),
#ifdef ENABLE_BACKGROUND
                QUICK_BUTTON (N_("&Background"), B_USER, NULL, NULL),
#endif /* ENABLE_BACKGROUND */
                QUICK_BUTTON (N_("&Cancel"), B_CANCEL, NULL, NULL),
            QUICK_END
            /* *INDENT-ON* */
        };

        quick_dialog_t qdlg = {
            -1, -1, fmd_xlen,
            op_names[operation], "[Mask Copy/Rename]",
            quick_widgets, NULL, NULL
        };

      ask_file_mask:
        val = quick_dialog_skip (&qdlg, 4);

        if (val == B_CANCEL)
        {
            g_free (def_text_secure);
            return NULL;
        }

        if (ctx->follow_links)
            ctx->stat_func = mc_stat;
        else
            ctx->stat_func = mc_lstat;

        if (ctx->op_preserve)
        {
            ctx->preserve = TRUE;
            ctx->umask_kill = 0777777;
            ctx->preserve_uidgid = (geteuid () == 0);
        }
        else
        {
            int i2;

            ctx->preserve = ctx->preserve_uidgid = FALSE;
            i2 = umask (0);
            umask (i2);
            ctx->umask_kill = i2 ^ 0777777;
        }

        if ((dest_dir == NULL) || (*dest_dir == '\0'))
        {
            g_free (def_text_secure);
            g_free (source_mask);
            return dest_dir;
        }

        ctx->search_handle = mc_search_new (source_mask, -1, NULL);

        if (ctx->search_handle == NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Invalid source pattern '%s'"), source_mask);
            g_free (dest_dir);
            g_free (source_mask);
            goto ask_file_mask;
        }

        g_free (def_text_secure);
        g_free (source_mask);

        ctx->search_handle->is_case_sensitive = TRUE;
        if (source_easy_patterns)
            ctx->search_handle->search_type = MC_SEARCH_T_GLOB;
        else
            ctx->search_handle->search_type = MC_SEARCH_T_REGEX;

        vpath = vfs_path_from_str (dest_dir);

        ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
        if (ctx->dest_mask == NULL)
            ctx->dest_mask = dest_dir;
        else
            ctx->dest_mask++;
        orig_mask = ctx->dest_mask;
        if (*ctx->dest_mask == '\0'
            || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask)
                && (!only_one
                    || (mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode))))
            || (ctx->dive_into_subdirs
                && ((!only_one && !is_wildcarded (ctx->dest_mask))
                    || (only_one && mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode)))))
            ctx->dest_mask = g_strdup ("\\0");
        else
        {
            ctx->dest_mask = g_strdup (ctx->dest_mask);
            *orig_mask = '\0';
        }
        if (*dest_dir == '\0')
        {
            g_free (dest_dir);
            dest_dir = g_strdup ("./");
        }
        vfs_path_free (vpath);
        if (val == B_USER)
            *do_bg = TRUE;
    }

    return dest_dir;
}
Пример #8
0
Файл: command.c Проект: V07D/mc
void
do_cd_command (char *orig_cmd)
{
    int len;
    int operand_pos = CD_OPERAND_OFFSET;
    const char *cmd;

    /* Any final whitespace should be removed here
       (to see why, try "cd fred "). */
    /* NOTE: I think we should not remove the extra space,
       that way, we can cd into hidden directories */
    /* FIXME: what about interpreting quoted strings like the shell.
       so one could type "cd <tab> M-a <enter>" and it would work. */
    len = strlen (orig_cmd) - 1;
    while (len >= 0 && (orig_cmd[len] == ' ' || orig_cmd[len] == '\t' || orig_cmd[len] == '\n'))
    {
        orig_cmd[len] = 0;
        len--;
    }

    cmd = orig_cmd;
    if (cmd[CD_OPERAND_OFFSET - 1] == 0)
        cmd = "cd ";            /* 0..2 => given text, 3 => \0 */

    /* allow any amount of white space in front of the path operand */
    while (cmd[operand_pos] == ' ' || cmd[operand_pos] == '\t')
        operand_pos++;

    if (get_current_type () == view_tree)
    {
        if (cmd[0] == 0)
        {
            sync_tree (mc_config_get_home_dir ());
        }
        else if (DIR_IS_DOTDOT (cmd + operand_pos))
        {
            if (vfs_path_elements_count (current_panel->cwd_vpath) != 1 ||
                strlen (vfs_path_get_by_index (current_panel->cwd_vpath, 0)->path) > 1)
            {
                vfs_path_t *tmp_vpath = current_panel->cwd_vpath;

                current_panel->cwd_vpath =
                    vfs_path_vtokens_get (tmp_vpath, 0, vfs_path_tokens_count (tmp_vpath) - 1);
                vfs_path_free (tmp_vpath);
            }
            sync_tree (vfs_path_as_str (current_panel->cwd_vpath));
        }
        else if (cmd[operand_pos] == PATH_SEP)
        {
            sync_tree (cmd + operand_pos);
        }
        else
        {
            vfs_path_t *new_vpath;

            new_vpath = vfs_path_append_new (current_panel->cwd_vpath, cmd + operand_pos, NULL);
            sync_tree (vfs_path_as_str (new_vpath));
            vfs_path_free (new_vpath);
        }
    }
    else
    {
        char *path;
        vfs_path_t *q_vpath;
        gboolean ok;

        path = examine_cd (&cmd[operand_pos]);

        if (*path == '\0')
            q_vpath = vfs_path_from_str (mc_config_get_home_dir ());
        else
            q_vpath = vfs_path_from_str_flags (path, VPF_NO_CANON);

        ok = do_cd (q_vpath, cd_parse_command);
        if (!ok)
            ok = handle_cdpath (path);

        if (!ok)
        {
            char *d;

            d = vfs_path_to_str_flags (q_vpath, 0, VPF_STRIP_PASSWORD);
            message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), d,
                     unix_error_string (errno));
            g_free (d);
        }

        vfs_path_free (q_vpath);
        g_free (path);
    }
}
Пример #9
0
/*
 * FIXME: probably it is better to replace this with quick dialog machinery,
 * but actually I'm not familiar with it and have not much time :(
 *   alex
 */
static replace_action_t
overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode)
{
#define ADD_RD_BUTTON(i) \
    add_widget (ui->replace_dlg, \
            button_new (rd_widgets [i].ypos, rd_widgets [i].xpos, rd_widgets [i].value, \
                        NORMAL_BUTTON, rd_widgets [i].text, 0))

#define ADD_RD_LABEL(i, p1, p2) \
    g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2); \
    add_widget (ui->replace_dlg, label_new (rd_widgets [i].ypos, rd_widgets [i].xpos, buffer))

    /* dialog sizes */
    const int rd_ylen = 17;
    int rd_xlen = 60;

    struct
    {
        const char *text;
        int ypos, xpos;
        int value;              /* 0 for labels */
    } rd_widgets[] =
    {
    /* *INDENT-OFF* */
        /*  0 */
        { N_("Target file already exists!"), 3, 4, 0 },
        /*  1 */
        { "%s", 4, 4, 0 },
        /*  2 */ /* cannot use PRIuMAX here; %llu is used instead */
        { N_("Source date: %s, size %llu"), 6, 4, 0 },
        /*  3 */  /* cannot use PRIuMAX here; %llu is used instead */
        { N_("Target date: %s, size %llu"), 7, 4, 0 },
        /*  4 */
        { N_("&Abort"), 14, 25, REPLACE_ABORT },
        /*  5 */
        { N_("If &size differs"), 12, 28, REPLACE_SIZE },
        /*  6 */
        { N_("Non&e"), 11, 47, REPLACE_NEVER },
        /*  7 */
        { N_("&Update"), 11, 36, REPLACE_UPDATE },
        /*  8 */
        { N_("A&ll"), 11, 28, REPLACE_ALWAYS },
        /*  9 */
        { N_("Overwrite all targets?"), 11, 4, 0 },
        /* 10 */
        { N_("&Reget"), 10, 28, REPLACE_REGET },
        /* 11 */
        { N_("A&ppend"), 9, 45, REPLACE_APPEND },
        /* 12 */
        { N_("&No"), 9, 37, REPLACE_NO },
        /* 13 */
        { N_("&Yes"), 9, 28, REPLACE_YES },
        /* 14 */
        { N_("Overwrite this target?"), 9, 4, 0 }
    /* *INDENT-ON* */
    };

    const int num = sizeof (rd_widgets) / sizeof (rd_widgets[0]);
    int *widgets_len;

    FileOpContextUI *ui = ctx->ui;

    char buffer[BUF_SMALL];
    const char *title;
    int stripped_name_len;
    vfs_path_t *stripped_vpath;
    const char *stripped_name;
    char *stripped_name_orig;
    int result;

    widgets_len = g_new0 (int, num);

    if (mode == Foreground)
        title = _("File exists");
    else
        title = _("Background process: File exists");

    stripped_vpath = vfs_path_from_str (ui->replace_filename);
    stripped_name = stripped_name_orig =
        vfs_path_to_str_flags (stripped_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
    vfs_path_free (stripped_vpath);
    stripped_name_len = str_term_width1 (stripped_name);

    {
        int i, l1, l2, l, row;

        for (i = 0; i < num; i++)
        {
#ifdef ENABLE_NLS
            if (i != 1)         /* skip filename */
                rd_widgets[i].text = _(rd_widgets[i].text);
#endif /* ENABLE_NLS */
            widgets_len[i] = str_term_width1 (rd_widgets[i].text);
        }

        /*
         * longest of "Overwrite..." labels
         * (assume "Target date..." are short enough)
         */
        l1 = max (widgets_len[9], widgets_len[14]);

        /* longest of button rows */
        i = num;
        for (row = l = l2 = 0; i--;)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l2 = max (l2, l);
                    l = 0;
                }
                l += widgets_len[i] + 4;
            }

        l2 = max (l2, l);       /* last row */
        rd_xlen = max (rd_xlen, l1 + l2 + 8);
        rd_xlen = max (rd_xlen, str_term_width1 (title) + 2);
        rd_xlen = max (rd_xlen, min (COLS, stripped_name_len + 8));

        /* Now place widgets */
        l1 += 5;                /* start of first button in the row */
        i = num;
        for (l = l1, row = 0; --i > 1;)
            if (rd_widgets[i].value != 0)
            {
                if (row != rd_widgets[i].ypos)
                {
                    row = rd_widgets[i].ypos;
                    l = l1;
                }
                rd_widgets[i].xpos = l;
                l += widgets_len[i] + 4;
            }

        /* Abort button is centered */
        rd_widgets[4].xpos = (rd_xlen - widgets_len[4] - 3) / 2;
    }

    /* FIXME - missing help node */
    ui->replace_dlg =
        create_dlg (TRUE, 0, 0, rd_ylen, rd_xlen, alarm_colors, NULL, NULL, "[Replace]",
                    title, DLG_CENTER | DLG_REVERSE);

    /* prompt -- centered */
    add_widget (ui->replace_dlg,
                label_new (rd_widgets[0].ypos, (rd_xlen - widgets_len[0]) / 2, rd_widgets[0].text));
    /* file name -- centered */
    stripped_name = str_trunc (stripped_name, rd_xlen - 8);
    stripped_name_len = str_term_width1 (stripped_name);
    add_widget (ui->replace_dlg,
                label_new (rd_widgets[1].ypos, (rd_xlen - stripped_name_len) / 2, stripped_name));

    /* source date and size */
    ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), (unsigned long long) ui->s_stat->st_size);
    /* destination date and size */
    ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), (unsigned long long) ui->d_stat->st_size);

    ADD_RD_BUTTON (4);          /* Abort */
    ADD_RD_BUTTON (5);          /* If size differs */
    ADD_RD_BUTTON (6);          /* None */
    ADD_RD_BUTTON (7);          /* Update */
    ADD_RD_BUTTON (8);          /* All" */
    ADD_RD_LABEL (9, 0, 0);     /* Overwrite all targets? */

    /* "this target..." widgets */
    if (!S_ISDIR (ui->d_stat->st_mode))
    {
        if ((ctx->operation == OP_COPY) && (ui->d_stat->st_size != 0)
            && (ui->s_stat->st_size > ui->d_stat->st_size))
            ADD_RD_BUTTON (10); /* Reget */

        ADD_RD_BUTTON (11);     /* Append */
    }
    ADD_RD_BUTTON (12);         /* No */
    ADD_RD_BUTTON (13);         /* Yes */
    ADD_RD_LABEL (14, 0, 0);    /* Overwrite this target? */

    result = run_dlg (ui->replace_dlg);
    destroy_dlg (ui->replace_dlg);

    g_free (widgets_len);
    g_free (stripped_name_orig);

    return (result == B_CANCEL) ? REPLACE_ABORT : (replace_action_t) result;
#undef ADD_RD_LABEL
#undef ADD_RD_BUTTON
}
Пример #10
0
char *
file_mask_dialog (FileOpContext * ctx, FileOperation operation,
                  gboolean only_one,
                  const char *format, const void *text, const char *def_text, gboolean * do_bg)
{
    const size_t FMDY = 13;
    const size_t FMDX = 68;
    size_t fmd_xlen;

    /* buttons */
    const size_t gap = 1;
    size_t b0_len, b2_len;
    size_t b1_len = 0;

    int source_easy_patterns = easy_patterns;
    size_t i, len;
    char fmd_buf[BUF_MEDIUM];
    char *source_mask, *orig_mask, *dest_dir, *tmp;
    char *def_text_secure;
    int val;

    QuickWidget fmd_widgets[] = {
        /* 0 */ QUICK_BUTTON (42, 64, 10, FMDY, N_("&Cancel"), B_CANCEL, NULL),
#ifdef ENABLE_BACKGROUND
        /* 1 */ QUICK_BUTTON (25, 64, 10, FMDY, N_("&Background"), B_USER, NULL),
#define OFFSET 0
#else
#define OFFSET 1
#endif /* ENABLE_BACKGROUND */
        /*  2 - OFFSET */
        QUICK_BUTTON (14, FMDX, 10, FMDY, N_("&OK"), B_ENTER, NULL),
        /*  3 - OFFSET */
        QUICK_CHECKBOX (42, FMDX, 8, FMDY, N_("&Stable Symlinks"), &ctx->stable_symlinks),
        /*  4 - OFFSET */
        QUICK_CHECKBOX (31, FMDX, 7, FMDY, N_("Di&ve into subdir if exists"),
                        &ctx->dive_into_subdirs),
        /*  5 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 8, FMDY, N_("Preserve &attributes"), &ctx->op_preserve),
        /*  6 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 7, FMDY, N_("Follow &links"), &ctx->follow_links),
        /*  7 - OFFSET */
        QUICK_INPUT (3, FMDX, 6, FMDY, "", 58, 0, "input2", &dest_dir),
        /*  8 - OFFSET */
        QUICK_LABEL (3, FMDX, 5, FMDY, N_("to:")),
        /*  9 - OFFSET */
        QUICK_CHECKBOX (37, FMDX, 4, FMDY, N_("&Using shell patterns"), &source_easy_patterns),
        /* 10 - OFFSET */
        QUICK_INPUT (3, FMDX, 3, FMDY, easy_patterns ? "*" : "^(.*)$", 58, 0, "input-def",
                     &source_mask),
        /* 11 - OFFSET */
        QUICK_LABEL (3, FMDX, 2, FMDY, fmd_buf),
        QUICK_END
    };

    g_return_val_if_fail (ctx != NULL, NULL);

#ifdef ENABLE_NLS
    /* buttons */
    for (i = 0; i <= 2 - OFFSET; i++)
        fmd_widgets[i].u.button.text = _(fmd_widgets[i].u.button.text);

    /* checkboxes */
    for (i = 3 - OFFSET; i <= 9 - OFFSET; i++)
        if (i != 7 - OFFSET)
            fmd_widgets[i].u.checkbox.text = _(fmd_widgets[i].u.checkbox.text);
#endif /* !ENABLE_NLS */

    fmd_xlen = max (FMDX, (size_t) COLS * 2 / 3);

    len = str_term_width1 (fmd_widgets[6 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[4 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    len = str_term_width1 (fmd_widgets[5 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[3 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    /* buttons */
    b2_len = str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) + 6 + gap; /* OK */
#ifdef ENABLE_BACKGROUND
    b1_len = str_term_width1 (fmd_widgets[1].u.button.text) + 4 + gap;  /* Background */
#endif
    b0_len = str_term_width1 (fmd_widgets[0].u.button.text) + 4;        /* Cancel */
    len = b0_len + b1_len + b2_len;
    fmd_xlen = min (max (fmd_xlen, len + 6), (size_t) COLS);

    if (only_one)
    {
        int flen;

        flen = str_term_width1 (format);
        i = fmd_xlen - flen - 4;        /* FIXME */
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, str_trunc ((const char *) text, i));
    }
    else
    {
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, *(const int *) text);
        fmd_xlen = max (fmd_xlen, (size_t) str_term_width1 (fmd_buf) + 6);
    }

    for (i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]); i > 0;)
        fmd_widgets[--i].x_divisions = fmd_xlen;

    i = (fmd_xlen - len) / 2;
    /* OK button */
    fmd_widgets[2 - OFFSET].relative_x = i;
    i += b2_len;
#ifdef ENABLE_BACKGROUND
    /* Background button */
    fmd_widgets[1].relative_x = i;
    i += b1_len;
#endif
    /* Cancel button */
    fmd_widgets[0].relative_x = i;

#define chkbox_xpos(i) \
    fmd_widgets [i].relative_x = fmd_xlen - str_term_width1 (fmd_widgets [i].u.checkbox.text) - 6
    chkbox_xpos (3 - OFFSET);
    chkbox_xpos (4 - OFFSET);
    chkbox_xpos (9 - OFFSET);
#undef chkbox_xpos

    /* inputs */
    fmd_widgets[7 - OFFSET].u.input.len = fmd_widgets[10 - OFFSET].u.input.len = fmd_xlen - 6;

    /* unselect checkbox if target filesystem don't support attributes */
    ctx->op_preserve = filegui__check_attrs_on_fs (def_text);

    /* filter out a possible password from def_text */
    {
        vfs_path_t *vpath;

        vpath = vfs_path_from_str_flags (def_text, (only_one) ? VPF_NO_CANON : VPF_NONE);
        tmp = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
        vfs_path_free (vpath);
    }
    if (source_easy_patterns)
        def_text_secure = strutils_glob_escape (tmp);
    else
        def_text_secure = strutils_regex_escape (tmp);
    g_free (tmp);

    /* destination */
    fmd_widgets[7 - OFFSET].u.input.text = def_text_secure;

    ctx->stable_symlinks = FALSE;
    *do_bg = FALSE;

    {
        struct stat buf;
        vfs_path_t *vpath;

        QuickDialog Quick_input = {
            fmd_xlen, FMDY, -1, -1, op_names[operation],
            "[Mask Copy/Rename]", fmd_widgets, NULL, NULL, TRUE
        };

      ask_file_mask:
        val = quick_dialog_skip (&Quick_input, 4);

        if (val == B_CANCEL)
        {
            g_free (def_text_secure);
            return NULL;
        }

        if (ctx->follow_links)
            ctx->stat_func = mc_stat;
        else
            ctx->stat_func = mc_lstat;

        if (ctx->op_preserve)
        {
            ctx->preserve = TRUE;
            ctx->umask_kill = 0777777;
            ctx->preserve_uidgid = (geteuid () == 0);
        }
        else
        {
            int i2;
            ctx->preserve = ctx->preserve_uidgid = FALSE;
            i2 = umask (0);
            umask (i2);
            ctx->umask_kill = i2 ^ 0777777;
        }

        if ((dest_dir == NULL) || (*dest_dir == '\0'))
        {
            g_free (def_text_secure);
            g_free (source_mask);
            return dest_dir;
        }

        ctx->search_handle = mc_search_new (source_mask, -1);

        if (ctx->search_handle == NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Invalid source pattern `%s'"), source_mask);
            g_free (dest_dir);
            g_free (source_mask);
            goto ask_file_mask;
        }

        g_free (def_text_secure);
        g_free (source_mask);

        ctx->search_handle->is_case_sensitive = TRUE;
        if (source_easy_patterns)
            ctx->search_handle->search_type = MC_SEARCH_T_GLOB;
        else
            ctx->search_handle->search_type = MC_SEARCH_T_REGEX;

        tmp = dest_dir;
        dest_dir = tilde_expand (tmp);
        g_free (tmp);
        vpath = vfs_path_from_str (dest_dir);

        ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
        if (ctx->dest_mask == NULL)
            ctx->dest_mask = dest_dir;
        else
            ctx->dest_mask++;
        orig_mask = ctx->dest_mask;
        if (*ctx->dest_mask == '\0'
            || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask)
                && (!only_one
                    || (mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode))))
            || (ctx->dive_into_subdirs
                && ((!only_one && !is_wildcarded (ctx->dest_mask))
                    || (only_one && mc_stat (vpath, &buf) == 0 && S_ISDIR (buf.st_mode)))))
            ctx->dest_mask = g_strdup ("\\0");
        else
        {
            ctx->dest_mask = g_strdup (ctx->dest_mask);
            *orig_mask = '\0';
        }
        if (!*dest_dir)
        {
            g_free (dest_dir);
            dest_dir = g_strdup ("./");
        }
        vfs_path_free (vpath);
        if (val == B_USER)
            *do_bg = TRUE;
    }

    return dest_dir;
}