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; }
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); }
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; }
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); }
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; }
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; }