示例#1
0
文件: main.c 项目: BrEacK/mc
gboolean
do_cd (const vfs_path_t * new_dir_vpath, enum cd_enum exact)
{
    gboolean res;
    const vfs_path_t *_new_dir_vpath = new_dir_vpath;

    if (current_panel->is_panelized)
    {
        size_t new_vpath_len;

        new_vpath_len = vfs_path_len (new_dir_vpath);
        if (vfs_path_ncmp (new_dir_vpath, panelized_panel.root_vpath, new_vpath_len) == 0)
            _new_dir_vpath = panelized_panel.root_vpath;
    }

    res = do_panel_cd (current_panel, _new_dir_vpath, exact);

#ifdef HAVE_CHARSET
    if (res)
    {
        const vfs_path_element_t *path_element;

        path_element = vfs_path_get_by_index (current_panel->cwd_vpath, -1);
        if (path_element->encoding != NULL)
            current_panel->codepage = get_codepage_index (path_element->encoding);
        else
            current_panel->codepage = SELECT_CHARSET_NO_TRANSLATE;
    }
#endif /* HAVE_CHARSET */

    return res;
}
示例#2
0
/* *INDENT-OFF* */
START_PARAMETRIZED_TEST (test_path_length, test_path_length_ds)
/* *INDENT-ON* */
{
    /* given */
    vfs_path_t *vpath;
    size_t actual_length;

    vpath = vfs_path_from_str (data->input_path);

    /* when */
    actual_length = vfs_path_len (vpath);

    /* then */
    mctest_assert_int_eq (actual_length, data->expected_length);

    vfs_path_free (vpath);
}
示例#3
0
文件: util.c 项目: JBurant/mc
void
save_file_position (const vfs_path_t * filename_vpath, long line, long column, off_t offset,
                    GArray * bookmarks)
{
    static size_t filepos_max_saved_entries = 0;
    char *fn, *tmp_fn;
    FILE *f, *tmp_f;
    char buf[MC_MAXPATHLEN + 100];
    size_t i;
    const size_t len = vfs_path_len (filename_vpath);
    gboolean src_error = FALSE;

    if (filepos_max_saved_entries == 0)
        filepos_max_saved_entries = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
                                                       "filepos_max_saved_entries", 1024);

    fn = mc_config_get_full_path (MC_FILEPOS_FILE);
    if (fn == NULL)
        goto early_error;

    mc_util_make_backup_if_possible (fn, TMP_SUFFIX);

    /* open file */
    f = fopen (fn, "w");
    if (f == NULL)
        goto open_target_error;

    tmp_fn = g_strdup_printf ("%s" TMP_SUFFIX, fn);
    tmp_f = fopen (tmp_fn, "r");
    if (tmp_f == NULL)
    {
        src_error = TRUE;
        goto open_source_error;
    }

    /* put the new record */
    if (line != 1 || column != 0 || bookmarks != NULL)
    {
        if (fprintf
            (f, "%s %ld;%ld;%" PRIuMAX, vfs_path_as_str (filename_vpath), line, column,
             (uintmax_t) offset) < 0)
            goto write_position_error;
        if (bookmarks != NULL)
            for (i = 0; i < bookmarks->len && i < MAX_SAVED_BOOKMARKS; i++)
                if (fprintf (f, ";%zu", g_array_index (bookmarks, size_t, i)) < 0)
                    goto write_position_error;

        if (fprintf (f, "\n") < 0)
            goto write_position_error;
    }

    i = 1;
    while (fgets (buf, sizeof (buf), tmp_f) != NULL)
    {
        if (buf[len] == ' ' && strncmp (buf, vfs_path_as_str (filename_vpath), len) == 0
            && strchr (&buf[len + 1], ' ') == NULL)
            continue;

        fprintf (f, "%s", buf);
        if (++i > filepos_max_saved_entries)
            break;
    }

  write_position_error:
    fclose (tmp_f);
  open_source_error:
    g_free (tmp_fn);
    fclose (f);
    if (src_error)
        mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX);
    else
        mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX);
  open_target_error:
    g_free (fn);
  early_error:
    if (bookmarks != NULL)
        g_array_free (bookmarks, TRUE);
}
示例#4
0
文件: util.c 项目: JBurant/mc
void
load_file_position (const vfs_path_t * filename_vpath, long *line, long *column, off_t * offset,
                    GArray ** bookmarks)
{
    char *fn;
    FILE *f;
    char buf[MC_MAXPATHLEN + 100];
    const size_t len = vfs_path_len (filename_vpath);

    /* defaults */
    *line = 1;
    *column = 0;
    *offset = 0;

    /* open file with positions */
    fn = mc_config_get_full_path (MC_FILEPOS_FILE);
    f = fopen (fn, "r");
    g_free (fn);
    if (f == NULL)
        return;

    /* prepare array for serialized bookmarks */
    if (bookmarks != NULL)
        *bookmarks = g_array_sized_new (FALSE, FALSE, sizeof (size_t), MAX_SAVED_BOOKMARKS);

    while (fgets (buf, sizeof (buf), f) != NULL)
    {
        const char *p;
        gchar **pos_tokens;

        /* check if the filename matches the beginning of string */
        if (strncmp (buf, vfs_path_as_str (filename_vpath), len) != 0)
            continue;

        /* followed by single space */
        if (buf[len] != ' ')
            continue;

        /* and string without spaces */
        p = &buf[len + 1];
        if (strchr (p, ' ') != NULL)
            continue;

        pos_tokens = g_strsplit (p, ";", 3 + MAX_SAVED_BOOKMARKS);
        if (pos_tokens[0] == NULL)
        {
            *line = 1;
            *column = 0;
            *offset = 0;
        }
        else
        {
            *line = strtol (pos_tokens[0], NULL, 10);
            if (pos_tokens[1] == NULL)
            {
                *column = 0;
                *offset = 0;
            }
            else
            {
                *column = strtol (pos_tokens[1], NULL, 10);
                if (pos_tokens[2] == NULL)
                    *offset = 0;
                else if (bookmarks != NULL)
                {
                    size_t i;

                    *offset = (off_t) g_ascii_strtoll (pos_tokens[2], NULL, 10);

                    for (i = 0; i < MAX_SAVED_BOOKMARKS && pos_tokens[3 + i] != NULL; i++)
                    {
                        size_t val;

                        val = strtoul (pos_tokens[3 + i], NULL, 10);
                        g_array_append_val (*bookmarks, val);
                    }
                }
            }
        }

        g_strfreev (pos_tokens);
    }

    fclose (f);
}
示例#5
0
static void
show_tree (WTree * tree)
{
    Widget *w = WIDGET (tree);
    WDialog *h = w->owner;
    tree_entry *current;
    int i, j, topsublevel;
    int x = 0, y = 0;
    int tree_lines, tree_cols;

    /* Initialize */
    tree_lines = tlines (tree);
    tree_cols = w->cols;

    widget_move (w, y, x);
    if (tree->is_panel)
    {
        tree_cols -= 2;
        x = y = 1;
    }

    g_free (tree->tree_shown);
    tree->tree_shown = g_new0 (tree_entry *, tree_lines);

    if (tree->store->tree_first)
        topsublevel = tree->store->tree_first->sublevel;
    else
        topsublevel = 0;
    if (!tree->selected_ptr)
    {
        tree->selected_ptr = tree->store->tree_first;
        tree->topdiff = 0;
    }
    current = tree->selected_ptr;

    /* Calculate the directory which is to be shown on the topmost line */
    if (!tree_navigation_flag)
        current = back_ptr (current, &tree->topdiff);
    else
    {
        i = 0;
        while (current->prev && i < tree->topdiff)
        {
            current = current->prev;

            if (current->sublevel < tree->selected_ptr->sublevel)
            {
                if (vfs_path_equal (current->name, tree->selected_ptr->name))
                    i++;
            }
            else if (current->sublevel == tree->selected_ptr->sublevel)
            {
                const char *cname;

                cname = vfs_path_as_str (current->name);
                for (j = strlen (cname) - 1; !IS_PATH_SEP (cname[j]); j--)
                    ;
                if (vfs_path_equal_len (current->name, tree->selected_ptr->name, j))
                    i++;
            }
            else if (current->sublevel == tree->selected_ptr->sublevel + 1)
            {
                j = vfs_path_len (tree->selected_ptr->name);
                if (j > 1 && vfs_path_equal_len (current->name, tree->selected_ptr->name, j))
                    i++;
            }
        }
        tree->topdiff = i;
    }

    /* Loop for every line */
    for (i = 0; i < tree_lines; i++)
    {
        tty_setcolor (tree->is_panel ? NORMAL_COLOR : TREE_NORMALC (h));

        /* Move to the beginning of the line */
        tty_draw_hline (w->y + y + i, w->x + x, ' ', tree_cols);

        if (current == NULL)
            continue;

        if (tree->is_panel)
            tty_setcolor (widget_get_state (w, WST_FOCUSED) && current == tree->selected_ptr
                          ? SELECTED_COLOR : NORMAL_COLOR);
        else
            tty_setcolor (current == tree->selected_ptr ? TREE_CURRENTC (h) : TREE_NORMALC (h));

        tree->tree_shown[i] = current;
        if (current->sublevel == topsublevel)
            /* Show full name */
            tty_print_string (str_fit_to_term
                              (vfs_path_as_str (current->name),
                               tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT));
        else
        {
            /* Sub level directory */
            tty_set_alt_charset (TRUE);

            /* Output branch parts */
            for (j = 0; j < current->sublevel - topsublevel - 1; j++)
            {
                if (tree_cols - 8 - 3 * j < 9)
                    break;
                tty_print_char (' ');
                if (current->submask & (1 << (j + topsublevel + 1)))
                    tty_print_char (ACS_VLINE);
                else
                    tty_print_char (' ');
                tty_print_char (' ');
            }
            tty_print_char (' ');
            j++;
            if (!current->next || !(current->next->submask & (1 << current->sublevel)))
                tty_print_char (ACS_LLCORNER);
            else
                tty_print_char (ACS_LTEE);
            tty_print_char (ACS_HLINE);
            tty_set_alt_charset (FALSE);

            /* Show sub-name */
            tty_print_char (' ');
            tty_print_string (str_fit_to_term
                              (current->subname, tree_cols - x - 3 * j, J_LEFT_FIT));
        }

        /* Calculate the next value for current */
        current = current->next;
        if (tree_navigation_flag)
        {
            while (current != NULL)
            {
                if (current->sublevel < tree->selected_ptr->sublevel)
                {
                    if (vfs_path_equal_len (current->name, tree->selected_ptr->name,
                                            vfs_path_len (current->name)))
                        break;
                }
                else if (current->sublevel == tree->selected_ptr->sublevel)
                {
                    const char *cname;

                    cname = vfs_path_as_str (current->name);
                    for (j = strlen (cname) - 1; !IS_PATH_SEP (cname[j]); j--)
                        ;
                    if (vfs_path_equal_len (current->name, tree->selected_ptr->name, j))
                        break;
                }
                else if (current->sublevel == tree->selected_ptr->sublevel + 1
                         && vfs_path_len (tree->selected_ptr->name) > 1)
                {
                    if (vfs_path_equal_len (current->name, tree->selected_ptr->name,
                                            vfs_path_len (tree->selected_ptr->name)))
                        break;
                }
                current = current->next;
            }
        }
    }

    tree_show_mini_info (tree, tree_lines, tree_cols);
}
示例#6
0
文件: ext.c 项目: inso/mc
int
regex_command_for (void *target, const vfs_path_t * filename_vpath, const char *action,
                   vfs_path_t ** script_vpath)
{
    char *p, *q, *r, c;
    size_t file_len;
    gboolean found = FALSE;
    gboolean error_flag = FALSE;
    int ret = 0;
    struct stat mystat;
    int view_at_line_number;
    char *include_target;
    int include_target_len;
    int have_type = 0;          /* Flag used by regex_check_type() */

    if (filename_vpath == NULL)
        return 0;

    if (script_vpath != NULL)
        *script_vpath = NULL;

    /* Check for the special View:%d parameter */
    if (strncmp (action, "View:", 5) == 0)
    {
        view_at_line_number = atoi (action + 5);
        action = "View";
    }
    else
    {
        view_at_line_number = 0;
    }

    if (data == NULL)
    {
        char *extension_file;
        gboolean mc_user_ext = TRUE;
        gboolean home_error = FALSE;

        extension_file = mc_config_get_full_path (MC_FILEBIND_FILE);
        if (!exist_file (extension_file))
        {
            g_free (extension_file);
          check_stock_mc_ext:
            extension_file = mc_build_filename (mc_global.sysconfig_dir, MC_LIB_EXT, NULL);
            if (!exist_file (extension_file))
            {
                g_free (extension_file);
                extension_file = mc_build_filename (mc_global.share_data_dir, MC_LIB_EXT, NULL);
            }
            mc_user_ext = FALSE;
        }

        g_file_get_contents (extension_file, &data, NULL, NULL);
        g_free (extension_file);
        if (data == NULL)
            return 0;

        if (strstr (data, "default/") == NULL)
        {
            if (strstr (data, "regex/") == NULL && strstr (data, "shell/") == NULL &&
                strstr (data, "type/") == NULL)
            {
                g_free (data);
                data = NULL;

                if (!mc_user_ext)
                {
                    char *title;

                    title = g_strdup_printf (_(" %s%s file error"),
                                             mc_global.sysconfig_dir, MC_LIB_EXT);
                    message (D_ERROR, title, _("The format of the %smc.ext "
                                               "file has changed with version 3.0. It seems that "
                                               "the installation failed. Please fetch a fresh "
                                               "copy from the Midnight Commander package."),
                             mc_global.sysconfig_dir);
                    g_free (title);
                    return 0;
                }

                home_error = TRUE;
                goto check_stock_mc_ext;
            }
        }

        if (home_error)
        {
            char *filebind_filename;
            char *title;

            filebind_filename = mc_config_get_full_path (MC_FILEBIND_FILE);
            title = g_strdup_printf (_("%s file error"), filebind_filename);
            message (D_ERROR, title,
                     _("The format of the %s file has "
                       "changed with version 3.0. You may either want to copy "
                       "it from %smc.ext or use that file as an example of how to write it."),
                     filebind_filename, mc_global.sysconfig_dir);
            g_free (filebind_filename);
            g_free (title);
        }
    }

    mc_stat (filename_vpath, &mystat);

    include_target = NULL;
    include_target_len = 0;
    file_len = vfs_path_len (filename_vpath);

    for (p = data; *p != '\0'; p++)
    {
        for (q = p; *q == ' ' || *q == '\t'; q++)
            ;
        if (*q == '\n' || *q == '\0')
            p = q;              /* empty line */
        if (*p == '#')          /* comment */
            while (*p != '\0' && *p != '\n')
                p++;
        if (*p == '\n')
            continue;
        if (*p == '\0')
            break;
        if (p == q)
        {                       /* i.e. starts in the first column, should be
                                 * keyword/descNL
                                 */
            gboolean case_insense;

            found = FALSE;
            q = strchr (p, '\n');
            if (q == NULL)
                q = strchr (p, '\0');
            c = *q;
            *q = '\0';
            if (include_target)
            {
                if ((strncmp (p, "include/", 8) == 0)
                    && (strncmp (p + 8, include_target, include_target_len) == 0))
                    found = TRUE;
            }
            else if (strncmp (p, "regex/", 6) == 0)
            {
                mc_search_t *search;

                p += 6;
                case_insense = (strncmp (p, "i/", 2) == 0);
                if (case_insense)
                    p += 2;

                search = mc_search_new (p, -1);
                if (search != NULL)
                {
                    search->search_type = MC_SEARCH_T_REGEX;
                    search->is_case_sensitive = !case_insense;
                    found =
                        mc_search_run (search, vfs_path_as_str (filename_vpath), 0, file_len, NULL);
                    mc_search_free (search);
                }
            }
            else if (strncmp (p, "directory/", 10) == 0)
            {
                if (S_ISDIR (mystat.st_mode)
                    && mc_search (p + 10, vfs_path_as_str (filename_vpath), MC_SEARCH_T_REGEX))
                    found = TRUE;
            }
            else if (strncmp (p, "shell/", 6) == 0)
            {
                int (*cmp_func) (const char *s1, const char *s2, size_t n) = strncmp;

                p += 6;
                case_insense = (strncmp (p, "i/", 2) == 0);
                if (case_insense)
                {
                    p += 2;
                    cmp_func = strncasecmp;
                }

                if (*p == '.' && file_len >= (size_t) (q - p))
                {
                    if (cmp_func
                        (p, vfs_path_as_str (filename_vpath) + file_len - (q - p), q - p) == 0)
                        found = TRUE;
                }
                else
                {
                    if ((size_t) (q - p) == file_len
                        && cmp_func (p, vfs_path_as_str (filename_vpath), q - p) == 0)
                        found = TRUE;
                }
            }
            else if (strncmp (p, "type/", 5) == 0)
            {
                GError *error = NULL;

                p += 5;

                case_insense = (strncmp (p, "i/", 2) == 0);
                if (case_insense)
                    p += 2;

                found = regex_check_type (filename_vpath, p, &have_type, case_insense, &error);
                if (error != NULL)
                {
                    g_error_free (error);
                    error_flag = TRUE;  /* leave it if file cannot be opened */
                }
            }
            else if (strncmp (p, "default/", 8) == 0)
                found = TRUE;

            *q = c;
            p = q;
            if (*p == '\0')
                break;
        }
        else
        {                       /* List of actions */
            p = q;
            q = strchr (p, '\n');
            if (q == NULL)
                q = strchr (p, '\0');
            if (found && !error_flag)
            {
                r = strchr (p, '=');
                if (r != NULL)
                {
                    c = *r;
                    *r = '\0';
                    if (strcmp (p, "Include") == 0)
                    {
                        char *t;

                        include_target = p + 8;
                        t = strchr (include_target, '\n');
                        if (t != NULL)
                            *t = '\0';
                        include_target_len = strlen (include_target);
                        if (t != NULL)
                            *t = '\n';

                        *r = c;
                        p = q;
                        found = FALSE;

                        if (*p == '\0')
                            break;
                        continue;
                    }

                    if (strcmp (action, p) != 0)
                        *r = c;
                    else
                    {
                        *r = c;

                        for (p = r + 1; *p == ' ' || *p == '\t'; p++)
                            ;

                        /* Empty commands just stop searching
                         * through, they don't do anything
                         */
                        if (p < q)
                        {
                            vfs_path_t *sv;

                            sv = exec_extension (target, filename_vpath, r + 1,
                                                 view_at_line_number);
                            if (script_vpath != NULL)
                                *script_vpath = sv;
                            else
                                exec_cleanup_script (sv);

                            ret = 1;
                        }
                        break;
                    }
                }
            }
            p = q;
            if (*p == '\0')
                break;
        }
    }
    if (error_flag)
        ret = -1;
    return ret;
}