예제 #1
0
파일: cmd.c 프로젝트: BpArCuCTeMbI/mc
static int
compare_files (const vfs_path_t * vpath1, const vfs_path_t * vpath2, off_t size)
{
    int file1;
    int result = -1;            /* Different by default */

    if (size == 0)
        return 0;

    file1 = open (vfs_path_as_str (vpath1), O_RDONLY);
    if (file1 >= 0)
    {
        int file2;

        file2 = open (vfs_path_as_str (vpath2), O_RDONLY);
        if (file2 >= 0)
        {
#ifdef HAVE_MMAP
            char *data1;

            /* Ugly if jungle */
            data1 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file1, 0);
            if (data1 != (char *) -1)
            {
                char *data2;

                data2 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file2, 0);
                if (data2 != (char *) -1)
                {
                    rotate_dash (TRUE);
                    result = memcmp (data1, data2, size);
                    munmap (data2, size);
                }
                munmap (data1, size);
            }
#else
            /* Don't have mmap() :( Even more ugly :) */
            char buf1[BUFSIZ], buf2[BUFSIZ];
            int n1, n2;
            rotate_dash (TRUE);
            do
            {
                while ((n1 = read (file1, buf1, sizeof (buf1))) == -1 && errno == EINTR)
                    ;
                while ((n2 = read (file2, buf2, sizeof (buf2))) == -1 && errno == EINTR)
                    ;
            }
            while (n1 == n2 && n1 == sizeof (buf1) && memcmp (buf1, buf2, sizeof (buf1)) == 0);
            result = (n1 != n2) || memcmp (buf1, buf2, n1);
#endif /* !HAVE_MMAP */
            close (file2);
        }
        close (file1);
    }
    rotate_dash (FALSE);

    return result;
}
예제 #2
0
void
dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
               const dir_sort_options_t * sort_op, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int link_to_dir, stale_link;
    struct stat st;
    file_entry_t *fentry;

    /* ".." (if any) must be the first entry in the list */
    if (!dir_list_init (list))
        return;

    fentry = &list->list[0];
    if (dir_get_dotdot_stat (vpath, &st))
        fentry->st = st;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        return;
    }

    tree_store_start_check (vpath);

    {
        const char *vpath_str;

        vpath_str = vfs_path_as_str (vpath);
        /* Do not add a ".." entry to the root directory */
        if ((vpath_str[0] == PATH_SEP) && (vpath_str[1] == '\0'))
            list->len--;
    }

    while ((dp = mc_readdir (dirp)) != NULL)
    {
        if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link))
            continue;

        if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0))
            goto ret;

        if ((list->len & 31) == 0)
            rotate_dash (TRUE);
    }

    dir_list_sort (list, sort, sort_op);

  ret:
    mc_closedir (dirp);
    tree_store_end_check ();
    rotate_dash (FALSE);
}
예제 #3
0
static int
compare_files (char *name1, char *name2, off_t size)
{
    int file1, file2;
    int result = -1;            /* Different by default */

    if (size == 0)
        return 0;

    file1 = open (name1, O_RDONLY);
    if (file1 >= 0)
    {
        file2 = open (name2, O_RDONLY);
        if (file2 >= 0)
        {
#ifdef HAVE_MMAP
            char *data1, *data2;
            /* Ugly if jungle */
            data1 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file1, 0);
            if (data1 != (char *) -1)
            {
                data2 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file2, 0);
                if (data2 != (char *) -1)
                {
                    rotate_dash ();
                    result = memcmp (data1, data2, size);
                    munmap (data2, size);
                }
                munmap (data1, size);
            }
#else
            /* Don't have mmap() :( Even more ugly :) */
            char buf1[BUFSIZ], buf2[BUFSIZ];
            int n1, n2;
            rotate_dash ();
            do
            {
                while ((n1 = read (file1, buf1, BUFSIZ)) == -1 && errno == EINTR);
                while ((n2 = read (file2, buf2, BUFSIZ)) == -1 && errno == EINTR);
            }
            while (n1 == n2 && n1 == BUFSIZ && !memcmp (buf1, buf2, BUFSIZ));
            result = (n1 != n2) || memcmp (buf1, buf2, n1);
#endif /* !HAVE_MMAP */
            close (file2);
        }
        close (file1);
    }
    return result;
}
예제 #4
0
void
dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort,
                 const dir_sort_options_t * sort_op, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int i, link_to_dir, stale_link;
    struct stat st;
    int marked_cnt;
    GHashTable *marked_files;
    const char *tmp_path;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        dir_list_clean (list);
        dir_list_init (list);
        return;
    }

    tree_store_start_check (vpath);

    marked_files = g_hash_table_new (g_str_hash, g_str_equal);
    alloc_dir_copy (list->len);
    for (marked_cnt = i = 0; i < list->len; i++)
    {
        file_entry_t *fentry, *dfentry;

        fentry = &list->list[i];
        dfentry = &dir_copy.list[i];

        dfentry->fnamelen = fentry->fnamelen;
        dfentry->fname = g_strndup (fentry->fname, fentry->fnamelen);
        dfentry->f.marked = fentry->f.marked;
        dfentry->f.dir_size_computed = fentry->f.dir_size_computed;
        dfentry->f.link_to_dir = fentry->f.link_to_dir;
        dfentry->f.stale_link = fentry->f.stale_link;
        dfentry->sort_key = NULL;
        dfentry->second_sort_key = NULL;
        if (fentry->f.marked)
        {
            g_hash_table_insert (marked_files, dfentry->fname, dfentry);
            marked_cnt++;
        }
    }

    /* save len for later dir_list_clean() */
    dir_copy.len = list->len;

    /* Add ".." except to the root directory. The ".." entry
       (if any) must be the first in the list. */
    tmp_path = vfs_path_get_by_index (vpath, 0)->path;
    if (vfs_path_elements_count (vpath) == 1 && IS_PATH_SEP (tmp_path[0]) && tmp_path[1] == '\0')
    {
        /* root directory */
        dir_list_clean (list);
    }
    else
    {
        dir_list_clean (list);
        if (!dir_list_init (list))
        {
            dir_list_clean (&dir_copy);
            return;
        }

        if (dir_get_dotdot_stat (vpath, &st))
        {
            file_entry_t *fentry;

            fentry = &list->list[0];
            fentry->st = st;
        }
    }

    while ((dp = mc_readdir (dirp)) != NULL)
    {
        file_entry_t *fentry;

        if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link))
            continue;

        if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0))
        {
            mc_closedir (dirp);
            /* Norbert (Feb 12, 1997):
               Just in case someone finds this memory leak:
               -1 means big trouble (at the moment no memory left),
               I don't bother with further cleanup because if one gets to
               this point he will have more problems than a few memory
               leaks and because one 'dir_list_clean' would not be enough (and
               because I don't want to spent the time to make it working,
               IMHO it's not worthwhile).
               dir_list_clean (&dir_copy);
             */
            tree_store_end_check ();
            g_hash_table_destroy (marked_files);
            return;
        }
        fentry = &list->list[list->len - 1];

        fentry->f.marked = 0;

        /*
         * If we have marked files in the copy, scan through the copy
         * to find matching file.  Decrease number of remaining marks if
         * we copied one.
         */
        if (marked_cnt > 0 && g_hash_table_lookup (marked_files, dp->d_name) != NULL)
        {
            fentry->f.marked = 1;
            marked_cnt--;
        }

        if ((list->len & 15) == 0)
            rotate_dash (TRUE);
    }
    mc_closedir (dirp);
    tree_store_end_check ();
    g_hash_table_destroy (marked_files);

    dir_list_sort (list, sort, sort_op);

    dir_list_clean (&dir_copy);
    rotate_dash (FALSE);
}
예제 #5
0
파일: dir.c 프로젝트: Chainie/mc
int
do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int count,
               gboolean lc_reverse, gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int next_free = 0;
    int i, status, link_to_dir, stale_link;
    struct stat st;
    int marked_cnt;
    GHashTable *marked_files;
    const char *tmp_path;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        clean_dir (list, count);
        return set_zero_dir (list) ? 1 : 0;
    }

    tree_store_start_check (vpath);

    marked_files = g_hash_table_new (g_str_hash, g_str_equal);
    alloc_dir_copy (list->size);
    for (marked_cnt = i = 0; i < count; i++)
    {
        dir_copy.list[i].fnamelen = list->list[i].fnamelen;
        dir_copy.list[i].fname = list->list[i].fname;
        dir_copy.list[i].f.marked = list->list[i].f.marked;
        dir_copy.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed;
        dir_copy.list[i].f.link_to_dir = list->list[i].f.link_to_dir;
        dir_copy.list[i].f.stale_link = list->list[i].f.stale_link;
        dir_copy.list[i].sort_key = NULL;
        dir_copy.list[i].second_sort_key = NULL;
        if (list->list[i].f.marked)
        {
            g_hash_table_insert (marked_files, dir_copy.list[i].fname, &dir_copy.list[i]);
            marked_cnt++;
        }
    }

    /* Add ".." except to the root directory. The ".." entry
       (if any) must be the first in the list. */
    tmp_path = vfs_path_get_by_index (vpath, 0)->path;
    if (!
        (vfs_path_elements_count (vpath) == 1 && (tmp_path[0] == PATH_SEP)
         && (tmp_path[1] == '\0')))
    {
        if (!set_zero_dir (list))
        {
            clean_dir (list, count);
            clean_dir (&dir_copy, count);
            return next_free;
        }

        if (get_dotdot_dir_stat (vpath, &st))
            list->list[next_free].st = st;

        next_free++;
    }

    while ((dp = mc_readdir (dirp)))
    {
        status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link);
        if (status == 0)
            continue;
        if (status == -1)
        {
            mc_closedir (dirp);
            /* Norbert (Feb 12, 1997):
               Just in case someone finds this memory leak:
               -1 means big trouble (at the moment no memory left),
               I don't bother with further cleanup because if one gets to
               this point he will have more problems than a few memory
               leaks and because one 'clean_dir' would not be enough (and
               because I don't want to spent the time to make it working,
               IMHO it's not worthwhile).
               clean_dir (&dir_copy, count);
             */
            tree_store_end_check ();
            g_hash_table_destroy (marked_files);
            return next_free;
        }

        list->list[next_free].f.marked = 0;

        /*
         * If we have marked files in the copy, scan through the copy
         * to find matching file.  Decrease number of remaining marks if
         * we copied one.
         */
        if (marked_cnt > 0)
        {
            if ((g_hash_table_lookup (marked_files, dp->d_name)))
            {
                list->list[next_free].f.marked = 1;
                marked_cnt--;
            }
        }

        list->list[next_free].fnamelen = NLENGTH (dp);
        list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen);
        list->list[next_free].f.link_to_dir = link_to_dir;
        list->list[next_free].f.stale_link = stale_link;
        list->list[next_free].f.dir_size_computed = 0;
        list->list[next_free].st = st;
        list->list[next_free].sort_key = NULL;
        list->list[next_free].second_sort_key = NULL;
        next_free++;
        if (!(next_free % 16))
            rotate_dash ();
    }
    mc_closedir (dirp);
    tree_store_end_check ();
    g_hash_table_destroy (marked_files);
    if (next_free)
    {
        do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);
    }
    clean_dir (&dir_copy, count);
    return next_free;
}
예제 #6
0
파일: dir.c 프로젝트: Chainie/mc
int
do_load_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, gboolean lc_reverse,
             gboolean lc_case_sensitive, gboolean exec_ff, const char *fltr)
{
    DIR *dirp;
    struct dirent *dp;
    int status, link_to_dir, stale_link;
    int next_free = 0;
    struct stat st;
    char *path;

    /* ".." (if any) must be the first entry in the list */
    if (!set_zero_dir (list))
        return next_free;

    if (get_dotdot_dir_stat (vpath, &st))
        list->list[next_free].st = st;
    next_free++;

    dirp = mc_opendir (vpath);
    if (dirp == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot read directory contents"));
        return next_free;
    }

    tree_store_start_check (vpath);

    /* Do not add a ".." entry to the root directory */
    path = vfs_path_to_str (vpath);
    if ((path[0] == PATH_SEP) && (path[1] == '\0'))
        next_free--;
    g_free (path);

    while ((dp = mc_readdir (dirp)) != NULL)
    {
        status = handle_dirent (list, fltr, dp, &st, next_free, &link_to_dir, &stale_link);
        if (status == 0)
            continue;
        if (status == -1)
            goto ret;

        list->list[next_free].fnamelen = NLENGTH (dp);
        list->list[next_free].fname = g_strndup (dp->d_name, list->list[next_free].fnamelen);
        list->list[next_free].f.marked = 0;
        list->list[next_free].f.link_to_dir = link_to_dir;
        list->list[next_free].f.stale_link = stale_link;
        list->list[next_free].f.dir_size_computed = 0;
        list->list[next_free].st = st;
        list->list[next_free].sort_key = NULL;
        list->list[next_free].second_sort_key = NULL;
        next_free++;

        if ((next_free & 31) == 0)
            rotate_dash ();
    }

    if (next_free != 0)
        do_sort (list, sort, next_free - 1, lc_reverse, lc_case_sensitive, exec_ff);

  ret:
    mc_closedir (dirp);
    tree_store_end_check ();
    return next_free;
}