home *** CD-ROM | disk | FTP | other *** search
- /*
- * fdfcomm.c
- *
- * common functions for find duplicates program
- *
- * Roy Bixler
- * March 23, 1991
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-
- #include <ctype.h>
- #include <dir.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <sys\types.h> /* must be included before stat.h */
- #include <sys\stat.h>
-
- #include "cmp.h"
- #include "fdfcomm.h"
- #include "elib.h"
-
-
-
- FILE_LIST *F_list = NULL, *I_del_menu[N_INTERACTIVE];
- char Match_criteria = 0, Sort_criteria = 0, Sort_order = ASCENDING;
- char i_flag = 0; /* interactive delete mode */
- char l_flag = 0; /* long listing? */
- char v_flag = 0; /* verbose? */
- static char Sorted;
-
-
-
- /*
- * print_fdate
- *
- * given a dta structure, print out the date in it
- */
- void print_fdate(struct ffblk *dta)
-
- {
- printf("%02d/%02d/%02d",
- (dta->ff_fdate >> 9) + 80,
- (dta->ff_fdate >> 5) & 0xf,
- (dta->ff_fdate) & 0x1f);
- }
-
-
-
- /*
- * print_ftime
- *
- * given a dta structure, print out the time in it
- */
- void print_ftime(struct ffblk *dta)
-
- {
- printf("%02d:%02d:%02d",
- (dta->ff_ftime >> 11),
- (dta->ff_ftime >> 5) & 0x3f,
- (dta->ff_ftime & 0x1f));
- }
-
-
-
- /*
- * print_fdatetime
- *
- * print the given dta's date, a space and the dta's time
- */
- void print_fdatetime(struct ffblk *dta)
-
- {
- print_fdate(dta);
- printf(" ");
- print_ftime(dta);
- }
-
-
-
- /*
- * print_fpath
- *
- * given a path and a dta, print the path with the dta's name tacked on the
- * end
- */
- void print_fpath(char *path, char *f_name)
-
- {
- static char *dir_sep = PATH_SEPARATOR;
- int path_len;
-
- if (path != NULL) {
- path_len = strlen(path);
- printf("%s%s%s", path,
- ((path_len > 0) && (path[path_len-1] == dir_sep[0]))
- ? ""
- : PATH_SEPARATOR,
- f_name);
- }
- }
-
- /*
- * long_listing
- *
- * print out the complete information on the given file
- */
- void long_listing(char *path, struct ffblk *dta)
-
- {
- if (path != NULL) {
- printf("%c ", (dta->ff_attrib == 0x10) ? 'd' : '-');
- print_fdatetime(dta);
- printf(" %8ld ", dta->ff_fsize);
- print_fpath(path, dta->ff_name);
- printf("\n");
- }
- }
-
- /*
- * print_match_header
- *
- * prints the first match of files
- */
- void print_match_header(FILE_LIST *start)
-
- {
- if (l_flag)
- return; /* no header */
- else if (Match_criteria & NAMES_MATCH)
- printf("file %s found in directories:\n", start->dta.ff_name);
- else if (Match_criteria & CONTENTS_MATCH)
- printf("files with matching contents (size = %ld) found:\n",
- start->dta.ff_fsize);
- else if (Match_criteria & SIZES_MATCH)
- printf("files of length %ld found:\n", start->dta.ff_fsize);
- else if (Match_criteria & TIMES_MATCH) {
- printf("files with timestamp ");
- print_fdatetime(&start->dta);
- printf(" found:\n");
- }
- }
-
-
-
- /*
- * print_next_match
- *
- * prints out any matches after the first one
- */
- void print_next_match(FILE_LIST *next, int menu_num)
-
- {
- if (menu_num >= 0)
- printf("%d)%s", menu_num, (l_flag) ? " " : "");
- if (l_flag)
- long_listing(next->path, &next->dta);
- else if (Match_criteria & NAMES_MATCH)
- printf("\t%s\n", next->path);
- else {
- printf("\t"); print_fpath(next->path, next->dta.ff_name);
- printf("\n");
- }
-
- next->printed = 1;
- }
-
-
-
- /*
- * print_id_menu
- *
- * given a starting point in the file list, print out an interactive delete
- * menu.
- */
- void print_id_menu(FILE_LIST **menu, int num_items)
-
- {
- int i;
-
- print_match_header(menu[0]);
- for (i = 0; i < num_items; i++)
- print_next_match(menu[i], i+1);
- }
-
-
-
- /*
- * cmpflist
- *
- * returns non-zero if the FILE_LIST parameter is less/greater than the given
- * dta/path combination according to the sort criteria. If sort
- * order is ASCENDING, non-zero returned if FILE_LIST less than dta/path
- * combo, vice-versa for DESCENDING order.
- */
- int cmpflist(FILE_LIST *fd, char *path, struct ffblk *dta)
-
- {
- long cmptime_tmp;
- int tmp;
-
- switch (Sort_criteria) {
- case NAME_SORT:
- return (Sort_order == ASCENDING)
- ? (((tmp = strcmp(fd->dta.ff_name, dta->ff_name)) < 0) ||
- ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
- : (((tmp = strcmp(fd->dta.ff_name, dta->ff_name)) > 0) ||
- ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
- case SIZE_SORT:
- return (Sort_order == ASCENDING)
- ? ((fd->dta.ff_fsize < dta->ff_fsize) ||
- ((fd->dta.ff_fsize == dta->ff_fsize) &&
- (strcmp(fd->dta.ff_name, dta->ff_name) < 0)) ||
- ((fd->dta.ff_fsize == dta->ff_fsize) &&
- (strcmp(fd->path, path) <= 0)))
- : ((fd->dta.ff_fsize > dta->ff_fsize) ||
- ((fd->dta.ff_fsize == dta->ff_fsize) &&
- (strcmp(fd->dta.ff_name, dta->ff_name) > 0)) ||
- ((fd->dta.ff_fsize == dta->ff_fsize) &&
- (strcmp(fd->path, path) >= 0)));
- case TIME_SORT:
- return (Sort_order == ASCENDING)
- ? (((cmptime_tmp = cmptime(&fd->dta, dta)) < 0) ||
- ((cmptime_tmp == 0) &&
- ((tmp = strcmp(fd->dta.ff_name,
- dta->ff_name)) < 0)) ||
- ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
- : (((cmptime_tmp = cmptime(&fd->dta, dta)) > 0) ||
- ((cmptime_tmp == 0) &&
- ((tmp = strcmp(fd->dta.ff_name,
- dta->ff_name)) > 0)) ||
- ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
- default:
- return 0; /* unknown sort criteria */
- }
- }
-
-
-
- /*
- * cmpflist_eq
- *
- * returns non-zero if the two FILE_LIST parameters are equal according to the
- * sort criteria.
- */
- int cmpflist_eq(FILE_LIST *fd1, FILE_LIST *fd2)
-
- {
- if (fd1 == NULL)
- return (fd2 == NULL);
- else if (fd2 == NULL)
- return 0;
- switch (Sort_criteria) {
- case NAME_SORT:
- return !strcmp(fd1->dta.ff_name, fd2->dta.ff_name);
- case SIZE_SORT:
- return (fd1->dta.ff_fsize == fd2->dta.ff_fsize);
- case TIME_SORT:
- return !cmptime(&fd1->dta, &fd2->dta);
- default:
- return 0; /* unknown sort criteria */
- }
- }
-
-
-
- /*
- * files_match
- *
- * return non-zero if the given two files 'match' according to names and the
- * criteria set by the flags (contents, date/time, size or almost any
- * combination of these).
- */
- int files_match(FILE_LIST *file1, FILE_LIST *file2)
-
- {
- return (((!(Match_criteria & NAMES_MATCH)) ||
- (!strcmp(file1->dta.ff_name, file2->dta.ff_name))) &&
- ((!(Match_criteria & SIZES_MATCH)) ||
- (file1->dta.ff_fsize == file2->dta.ff_fsize)) &&
- ((!(Match_criteria & TIMES_MATCH)) ||
- (!cmptime(&file1->dta, &file2->dta))) &&
- ((!(Match_criteria & CONTENTS_MATCH)) ||
- (compare_path_name_files(file1->path, file1->dta.ff_name,
- file2->path, file2->dta.ff_name))));
- }
-
-
-
- /*
- * gen_list
- *
- * given a path, generate a list of all files in the path and its
- * subdirectories.
- */
- void gen_list(char *path)
-
- {
- struct ffblk dta;
- char *path_list, *save_path;
-
- if (path == NULL)
- return;
- path_list = append_dir_to_path(path, ADD_TO_PATH);
- if ((findfirst(path_list, &dta, FA_DIREC) >= 0) &&
- ((save_path = malloc((size_t) (strlen(path)+1))) != NULL)) {
- strcpy(save_path, path);
- do {
- if (dta.ff_attrib & FA_DIREC)
- gen_list_of_dir(path, dta.ff_name);
- else
- add_file_to_list(save_path, &dta);
- } while (!findnext(&dta));
- }
-
- free(path_list);
- }
-
-
-
- /*
- * add_file_to_list
- *
- * given a path and a file on the path, add it to the list according to the
- * sort criteria.
- */
- void add_file_to_list(char *path, struct ffblk *dta)
-
- {
- FILE_LIST *prev = NULL, *new, *cur = F_list;
-
- if (Sorted)
- while ((cur != NULL) && (cmpflist(cur, path, dta))) {
- prev = cur;
- cur = cur->next;
- }
-
- if ((new = malloc((size_t) sizeof(FILE_LIST))) == NULL) {
- printf("add_file_to_list: memory allocation failure\n");
- exit(-1);
- }
- else {
- memcpy(&new->dta, dta, sizeof(struct ffblk));
- new->path = path;
- new->added = 0;
- new->printed = 0;
- new->next = cur;
- if (prev == NULL)
- F_list = new;
- else
- prev->next = new;
- }
- }
-
-
-
- /*
- * gen_list_of_dir
- *
- * given a path and a sub-directory, call 'gen_list()' to generate a list
- * of the sub-directory on the path.
- */
- void gen_list_of_dir(char *path, char *subdir)
-
- {
- char *new_path;
-
- if (!is_special(subdir)) {
- gen_list(new_path = append_dir_to_path(path, subdir));
- if (v_flag > 1) {
- printf("Searching ");
- print_fpath(path, subdir);
- printf("\n");
- }
- free(new_path);
- }
- }
-
-
-
- /*
- * list_files
- *
- * given a path, generate a linked list of files on the path or (recursively)
- * its subdirectories. If 'sorted' is non-zero, make sure the list is
- * sorted.
- */
- void list_files(char *prog_name, char *path, char sorted)
-
- {
- struct stat statbuf;
- static char target_dir[MAX_STR];
-
- if (just_disk(path)){
- get_cur_path(path, target_dir);
- path = target_dir;
- }
-
- if ((access(path, 0)) || ((!stat(path, &statbuf)) &&
- (!(statbuf.st_mode & S_IFDIR)))) {
- printf("%s: directory %s does not exist\n", prog_name, path);
- print_help();
- exit(-1);
- }
- else {
- Sorted = sorted;
- gen_list(path);
- if (v_flag > 1)
- printf("\n");
- }
- }
-
- void get_cur_path(char *new, char *target_dir)
- {
- char cur_dir[MAX_STR];
-
- getcwd(cur_dir, MAX_STR);
- change_disk(new, cur_dir);
- getcwd(target_dir, MAX_STR);
- setdisk(*cur_dir - 'A');
- chdir(cur_dir);
- }
-
-
- void change_disk(char *dir, char *cur_dir)
- {
- int maxdrives;
-
- if (isupper(*dir))
- tolower(*dir);
- maxdrives = setdisk(*dir - 'a');
- if (maxdrives < (*dir - 'a') + 1){
- setdisk(*cur_dir - 'A');
- printf("drive '%c' is not accessable\n", *dir);
- print_help();
- exit(-1);
- }
-
- }
-
- /*
- * just_disk()
- *
- * Input:
- * dir - the directory to be checked
- * Output:
- * returns :
- * 1 - if 'dir' is a current directory (ie 'X:')
- * 0 - otherwise
- */
-
- int just_disk(char *dir)
- {
- if ((strlen(dir) == 2) && (*(dir + 1) == ':'))
- return(1);
- else
- return(0);
- }
-
-
- /*
- * print_flist
- *
- * given a pointer to the first entry of a file list, dump the list to standard
- * output
- */
- void print_flist(FILE_LIST *flist)
-
- {
- for (;flist != NULL; flist = flist->next)
- printf("path = %s\tname = %s\n", flist->path, flist->dta.ff_name);
- }
-
-
-
- /*
- * compare_path_name_files
- *
- * given a pair of files specified by path and name, return non-zero if their
- * contents match, zero if contents don't match.
- */
- int compare_path_name_files(char *path1, char *name1, char *path2, char *name2)
-
- {
- int ret_val;
- char *file1;
- char *file2;
-
- file1 = append_dir_to_path(path1, name1);
- file2 = append_dir_to_path(path2, name2);
- if ((file1 == NULL) || (file2 == NULL)) {
- printf("compare_path_name_files: memory allocation failed!\n");
- exit(-1);
- }
-
- ret_val = compare_files(file1, file2);
-
- free(file1);
- free(file2);
-
- return ret_val;
- }
-
-
-
- /*
- * delete_path_name_file
- *
- * given a file specified by path and name, return zero if the file was
- * successfully deleted, non-zero if not. 'force' parameter, if non-zero, will
- * try to change the mode of a file from read-only to delete it.
- */
- int delete_path_name_file(char *path, char *f_name, char force)
-
- {
- char *file = append_dir_to_path(path, f_name);
- int ret_val;
-
- if (file == NULL) {
- printf("delete_path_name_file: memory allocation failed\n");
- exit(-1);
- }
-
- ret_val = delete_file(file, force);
-
- free(file);
-
- return ret_val;
- }
-