home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / DIR / MFD_1_00.ZIP / fdcomm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-17  |  11.7 KB  |  545 lines

  1. /*
  2.  * fdcomm.c
  3.  *
  4.  * common functions for find duplicates program
  5.  *
  6.  * Roy Bixler
  7.  * David Oertel (DOS support)
  8.  * Monk Software
  9.  * March 23, 1991
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26.  
  27.  
  28. #include <ctype.h>
  29. #include <dir.h>
  30. #include <dos.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <stdio.h>
  34. #include <sys\types.h>    /* must be included before stat.h */
  35. #include <sys\stat.h>
  36.  
  37. #include "cmp.h"
  38. #include "fdcomm.h"
  39. #include "monklib.h"
  40.  
  41.  
  42.  
  43. FILE_LIST *F_list = NULL, *I_del_menu[N_INTERACTIVE];
  44. char Match_criteria = 0, Sort_criteria = 0, Sort_order = ASCENDING;
  45. char i_flag = 0;    /* interactive delete mode */
  46. char l_flag = 0;    /* long listing? */
  47. char v_flag = 0;    /* verbose? */
  48. static char Sorted;
  49.  
  50.  
  51.  
  52. /*
  53.  * print_fdate
  54.  *
  55.  * given a dta structure, print out the date in it
  56.  */
  57. void print_fdate(struct ffblk *dta)
  58.  
  59. {
  60.     printf("%02d/%02d/%02d",
  61.            (dta->ff_fdate >> 9) + 80,
  62.            (dta->ff_fdate >> 5) & 0xf,
  63.            (dta->ff_fdate) & 0x1f);
  64. }
  65.  
  66.  
  67.  
  68. /*
  69.  * print_ftime
  70.  *
  71.  * given a dta structure, print out the time in it
  72.  */
  73. void print_ftime(struct ffblk *dta)
  74.  
  75. {
  76.     printf("%02d:%02d:%02d",
  77.            (dta->ff_ftime >> 11),
  78.            (dta->ff_ftime >> 5) & 0x3f,
  79.            (dta->ff_ftime & 0x1f));
  80. }
  81.  
  82.  
  83.  
  84. /*
  85.  * print_fdatetime
  86.  *
  87.  * print the given dta's date, a space and the dta's time
  88.  */
  89. void print_fdatetime(struct ffblk *dta)
  90.  
  91. {
  92.     print_fdate(dta);
  93.     printf(" ");
  94.     print_ftime(dta);
  95. }
  96.  
  97.  
  98.  
  99. /*
  100.  * print_fpath
  101.  *
  102.  * given a path and a dta, print the path with the dta's name tacked on the
  103.  * end
  104.  */
  105. void print_fpath(char *path, char *f_name)
  106.  
  107. {
  108.     static char *dir_sep = PATH_SEPARATOR;
  109.     int path_len;
  110.  
  111.     if (path != NULL) {
  112.         path_len = strlen(path);
  113.         printf("%s%s%s", path,
  114.                ((path_len > 0) && (path[path_len-1] == dir_sep[0]))
  115.                 ? ""
  116.                 : PATH_SEPARATOR,
  117.                 f_name);
  118.     }
  119. }
  120.  
  121. /*
  122.  * long_listing
  123.  *
  124.  * print out the complete information on the given file
  125.  */
  126. void long_listing(char *path, struct ffblk *dta)
  127.  
  128. {
  129.     if (path != NULL) {
  130.         printf("%c ", (dta->ff_attrib == 0x10) ? 'd' : '-');
  131.         print_fdatetime(dta);
  132.         printf(" %8ld ", dta->ff_fsize);
  133.          print_fpath(path, dta->ff_name);
  134.         printf("\n");
  135.     }
  136. }
  137.  
  138. /*
  139.  * print_match_header
  140.  *
  141.  * prints the first match of files
  142.  */
  143. void print_match_header(FILE_LIST *start)
  144.  
  145. {
  146.     if (l_flag)
  147.         return;    /* no header */
  148.     else if (Sort_criteria & NAME_SORT)
  149.         printf("file %s found in:\n", start->dta.ff_name);
  150.     else if (Sort_criteria & SIZE_SORT)
  151.             printf("files of length %ld found in:\n", start->dta.ff_fsize);
  152.     else if (Sort_criteria & TIME_SORT) {
  153.         printf("files with timestamp ");
  154.         print_fdatetime(&start->dta);
  155.         printf(" found in:\n");
  156.     }
  157. }
  158.  
  159.  
  160.  
  161. /*
  162.  * print_next_match
  163.  *
  164.  * prints out any matches after the first one
  165.  */
  166. void print_next_match(FILE_LIST *next, int menu_num)
  167.  
  168. {
  169.     if (menu_num >= 0)
  170.         printf("%d)%s", menu_num, (l_flag) ? " " : "");
  171.     if (l_flag)
  172.         long_listing(next->path, &next->dta);
  173.     else if (Sort_criteria & NAME_SORT)
  174.         printf("\t%s\n", next->path);
  175.     else {
  176.         printf("\t"); print_fpath(next->path, next->dta.ff_name);
  177.         printf("\n");
  178.     }
  179.  
  180.     next->printed = 1;
  181. }
  182.  
  183.  
  184.  
  185. /*
  186.  * print_id_menu
  187.  *
  188.  * given a starting point in the file list, print out an interactive delete
  189.  * menu.
  190.  */
  191. void print_id_menu(FILE_LIST **menu, int num_items)
  192.  
  193. {
  194.     int i;
  195.  
  196.     print_match_header(menu[0]);
  197.     for (i = 0; i < num_items; i++)
  198.         print_next_match(menu[i], i+1);
  199. }
  200.  
  201.  
  202.  
  203. /*
  204.  * cmpflist
  205.  *
  206.  * returns non-zero if the FILE_LIST parameter is less/greater than the given
  207.  * dta/path combination according to the sort criteria.  If sort
  208.  * order is ASCENDING,  non-zero returned if FILE_LIST less than dta/path
  209.  * combo, vice-versa for DESCENDING order.
  210.  */
  211. int cmpflist(FILE_LIST *fd, char *path, struct ffblk *dta)
  212.  
  213. {
  214.     long cmptime_tmp;
  215.     int tmp;
  216.  
  217.     switch (Sort_criteria) {
  218.     case NAME_SORT:
  219.         return (Sort_order == ASCENDING)
  220.                     ? (((tmp = strcmp(fd->dta.ff_name, dta->ff_name)) < 0) ||
  221.                        ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
  222.                     : (((tmp = strcmp(fd->dta.ff_name, dta->ff_name)) > 0) ||
  223.                        ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
  224.     case SIZE_SORT:
  225.         return (Sort_order == ASCENDING)
  226.                     ? ((fd->dta.ff_fsize < dta->ff_fsize) ||
  227.                        ((fd->dta.ff_fsize == dta->ff_fsize) &&
  228.                         (strcmp(fd->dta.ff_name, dta->ff_name) < 0)) ||
  229.                        ((fd->dta.ff_fsize == dta->ff_fsize) &&
  230.                         (strcmp(fd->path, path) <= 0)))
  231.                     : ((fd->dta.ff_fsize > dta->ff_fsize) ||
  232.                        ((fd->dta.ff_fsize == dta->ff_fsize) &&
  233.                         (strcmp(fd->dta.ff_name, dta->ff_name) > 0)) ||
  234.                        ((fd->dta.ff_fsize == dta->ff_fsize) &&
  235.                         (strcmp(fd->path, path) >= 0)));
  236.     case TIME_SORT:
  237.         return (Sort_order == ASCENDING)
  238.                     ? (((cmptime_tmp = cmptime(&fd->dta, dta)) < 0) ||
  239.                        ((cmptime_tmp == 0) &&
  240.                         ((tmp = strcmp(fd->dta.ff_name,
  241.                                        dta->ff_name)) < 0)) ||
  242.                         ((tmp == 0) && (strcmp(fd->path, path) <= 0)))
  243.                     : (((cmptime_tmp = cmptime(&fd->dta, dta)) > 0) ||
  244.                        ((cmptime_tmp == 0) &&
  245.                         ((tmp = strcmp(fd->dta.ff_name,
  246.                                        dta->ff_name)) > 0)) ||
  247.                         ((tmp == 0) && (strcmp(fd->path, path) >= 0)));
  248.     default:
  249.         return 0;    /* unknown sort criteria */
  250.     }
  251. }
  252.  
  253.  
  254.  
  255. /*
  256.  * cmpflist_eq
  257.  *
  258.  * returns non-zero if the two FILE_LIST parameters are equal according to the
  259.  * sort criteria.
  260.  */
  261. int cmpflist_eq(FILE_LIST *fd1, FILE_LIST *fd2)
  262.  
  263. {
  264.     if (fd1 == NULL)
  265.         return (fd2 == NULL);
  266.     else if (fd2 == NULL)
  267.         return 0;
  268.     switch (Sort_criteria) {
  269.     case NAME_SORT:
  270.         return !strcmp(fd1->dta.ff_name, fd2->dta.ff_name);
  271.     case SIZE_SORT:
  272.         return (fd1->dta.ff_fsize == fd2->dta.ff_fsize);
  273.     case TIME_SORT:
  274.         return !cmptime(&fd1->dta, &fd2->dta);
  275.     default:
  276.         return 0;    /* unknown sort criteria */
  277.     }
  278. }
  279.  
  280.  
  281.  
  282. /*
  283.  * files_match
  284.  *
  285.  * return non-zero if the given two files 'match' according to names and the
  286.  * criteria set by the flags (contents, date/time, size or almost any
  287.  * combination of these).
  288.  */
  289. int files_match(FILE_LIST *file1, FILE_LIST *file2)
  290.  
  291. {
  292.     return (((!(Match_criteria & NAMES_MATCH)) ||
  293.              (!strcmp(file1->dta.ff_name, file2->dta.ff_name))) &&
  294.             ((!(Match_criteria & SIZES_MATCH)) ||
  295.              (file1->dta.ff_fsize == file2->dta.ff_fsize)) &&
  296.             ((!(Match_criteria & TIMES_MATCH)) ||
  297.              (!cmptime(&file1->dta, &file2->dta))) &&
  298.             ((!(Match_criteria & CONTENTS_MATCH)) ||
  299.              (compare_path_name_files(file1->path, file1->dta.ff_name,
  300.                                        file2->path, file2->dta.ff_name))));
  301. }
  302.  
  303.  
  304.  
  305. /*
  306.  * gen_list
  307.  *
  308.  * given a path, generate a list of all files in the path and its
  309.  * subdirectories.
  310.  */
  311. void gen_list(char *path)
  312.  
  313. {
  314.     struct ffblk dta;
  315.     char *path_list, *save_path;
  316.  
  317.     if (path == NULL)
  318.         return;
  319.     path_list = append_dir_to_path(path, ADD_TO_PATH);
  320.     if ((findfirst(path_list, &dta, FA_DIREC) >= 0) &&
  321.         ((save_path = malloc((size_t) (strlen(path)+1))) != NULL)) {
  322.         strcpy(save_path, path);
  323.         do {
  324.             if (dta.ff_attrib & FA_DIREC)
  325.                 gen_list_of_dir(path, dta.ff_name);
  326.             else
  327.                 add_file_to_list(save_path, &dta);
  328.         } while (!findnext(&dta));
  329.     }
  330.  
  331.     free(path_list);
  332. }
  333.  
  334.  
  335.  
  336. /*
  337.  * add_file_to_list
  338.  *
  339.  * given a path and a file on the path, add it to the list according to the
  340.  * sort criteria.
  341.  */
  342. void add_file_to_list(char *path, struct ffblk *dta)
  343.  
  344. {
  345.     FILE_LIST *prev = NULL, *new, *cur = F_list;
  346.  
  347.     if (Sorted)
  348.         while ((cur != NULL) && (cmpflist(cur, path, dta))) {
  349.             prev = cur;
  350.             cur = cur->next;
  351.         }
  352.  
  353.     if ((new = malloc((size_t) sizeof(FILE_LIST))) == NULL) {
  354.         printf("add_file_to_list: memory allocation failure\n");
  355.         exit(-1);
  356.     }
  357.     else {
  358.         memcpy(&new->dta, dta, sizeof(struct ffblk));
  359.         new->path = path;
  360.         new->added = 0;
  361.         new->printed = 0;
  362.         new->next = cur;
  363.         if (prev == NULL)
  364.             F_list = new;
  365.         else
  366.             prev->next = new;
  367.     }
  368. }
  369.  
  370.  
  371.  
  372. /*
  373.  * gen_list_of_dir
  374.  *
  375.  * given a path and a sub-directory, call 'gen_list()' to generate a list
  376.  * of the sub-directory on the path.
  377.  */
  378. void gen_list_of_dir(char *path, char *subdir)
  379.  
  380. {
  381.     char *new_path;
  382.  
  383.     if (!is_special(subdir)) {
  384.         gen_list(new_path = append_dir_to_path(path, subdir));
  385.         if (v_flag > 1) {
  386.             printf("Searching    ");
  387.             print_fpath(path, subdir);
  388.             printf("\n");
  389.         }
  390.         free(new_path);
  391.     }
  392. }
  393.  
  394.  
  395.  
  396. /*
  397.  * list_files
  398.  *
  399.  * given a path, generate a linked list of files on the path or (recursively)
  400.  * its subdirectories.  If 'sorted' is non-zero, make sure the list is
  401.  * sorted.
  402.  */
  403. void list_files(char *prog_name, char *path, char sorted)
  404.  
  405. {
  406.     struct stat statbuf;
  407.     static char target_dir[MAX_STR];
  408.  
  409.     if (just_disk(path)){
  410.         get_cur_path(path, target_dir);
  411.         path = target_dir;
  412.     }
  413.  
  414.     if  ((access(path, 0)) || ((!stat(path, &statbuf)) &&
  415.           (!(statbuf.st_mode & S_IFDIR)))) {
  416.         printf("%s: directory %s does not exist\n", prog_name, path);
  417.         print_help();
  418.         exit(-1);
  419.     }
  420.     else {
  421.         Sorted = sorted;
  422.         gen_list(path);
  423.         if (v_flag > 1)
  424.             printf("\n");
  425.     }
  426. }
  427.  
  428. void get_cur_path(char *new, char *target_dir)
  429. {
  430.     char cur_dir[MAX_STR];
  431.  
  432.     getcwd(cur_dir, MAX_STR);
  433.     change_disk(new, cur_dir);
  434.     getcwd(target_dir, MAX_STR);
  435.     setdisk(*cur_dir - 'A');
  436.     chdir(cur_dir);
  437. }
  438.  
  439.  
  440. void change_disk(char *dir, char *cur_dir)
  441. {
  442.     int maxdrives;
  443.  
  444.     if (isupper(*dir))
  445.         tolower(*dir);
  446.     maxdrives = setdisk(*dir - 'a');
  447.     if (maxdrives < (*dir - 'a') + 1){
  448.         setdisk(*cur_dir - 'A');
  449.         printf("drive '%c' is not accessable\n", *dir);
  450.         print_help();
  451.         exit(-1);
  452.     }
  453.  
  454. }
  455.  
  456. /*
  457.  *    just_disk()
  458.  *
  459.  *    Input:
  460.  *        dir - the directory to be checked
  461.  *    Output:
  462.  *        returns : 
  463.  *            1 - if 'dir' is a current directory (ie 'X:')
  464.  *            0 - otherwise
  465.  */
  466.  
  467. int just_disk(char *dir)
  468. {
  469.     if ((strlen(dir) == 2) && (*(dir + 1) == ':'))
  470.             return(1);
  471.     else
  472.         return(0);
  473. }
  474.  
  475.  
  476. /*
  477.  * print_flist
  478.  *
  479.  * given a pointer to the first entry of a file list, dump the list to standard
  480.  * output
  481.  */
  482. void print_flist(FILE_LIST *flist)
  483.  
  484. {
  485.     for (;flist != NULL; flist = flist->next)
  486.         printf("path = %s\tname = %s\n", flist->path, flist->dta.ff_name);
  487. }
  488.  
  489.  
  490.  
  491. /*
  492.  * compare_path_name_files
  493.  *
  494.  * given a pair of files specified by path and name, return non-zero if their
  495.  * contents match, zero if contents don't match.
  496.  */
  497. int compare_path_name_files(char *path1, char *name1, char *path2, char *name2)
  498.  
  499. {
  500.     int ret_val;
  501.     char *file1;
  502.     char *file2;
  503.  
  504.     file1 = append_dir_to_path(path1, name1);
  505.     file2 = append_dir_to_path(path2, name2);
  506.     if ((file1 == NULL) || (file2 == NULL)) {
  507.         printf("compare_path_name_files: memory allocation failed!\n");
  508.         exit(-1);
  509.     }
  510.  
  511.     ret_val = compare_files(file1, file2);
  512.  
  513.     free(file1);
  514.     free(file2);
  515.  
  516.     return ret_val;
  517. }
  518.  
  519.  
  520.  
  521. /*
  522.  * delete_path_name_file
  523.  *
  524.  * given a file specified by path and name, return zero if the file was
  525.  * successfully deleted, non-zero if not.  'force' parameter, if non-zero, will
  526.  * try to change the mode of a file from read-only to delete it.
  527.  */
  528. int delete_path_name_file(char *path, char *f_name, char force)
  529.  
  530. {
  531.     char *file = append_dir_to_path(path, f_name);
  532.     int ret_val;
  533.  
  534.     if (file == NULL) {
  535.         printf("delete_path_name_file: memory allocation failed\n");
  536.         exit(-1);
  537.     }
  538.  
  539.     ret_val = delete_file(file, force);
  540.  
  541.     free(file);
  542.  
  543.     return ret_val;
  544. }
  545.