home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / dosdu.lzh / dosdu / du.c
Encoding:
C/C++ Source or Header  |  1991-01-06  |  7.4 KB  |  259 lines

  1.  Fax  :          : (61 2) 805-7433   |   This one goes up to 11.....
  2.  
  3. /*
  4.  *    du.c: Calculate disk usage similar to UNIX version
  5.  *
  6.  * Compiles under TC.  May need mods for MSC.
  7.  *
  8.  * PLEASE : If you make any improvements, send a copy to me so I can make
  9.  *               changes available to everyone.....
  10.  *
  11.  *  Author: Mark Allsop (Internet address: mallsop@suna.mqcc.mq.oz.au)
  12.  *
  13.  *  See #define VERSION and __DATE__ in compile for current version and date
  14.  *
  15.  *  This software is placed into the public domain.  The author grants the right
  16.  * to anyone to alter this program, provided that any upgrades or modifications
  17.  * are mailed back to him.
  18.  *  This program may not be sold for any profit.  The source code may, however ,
  19.  * be used as part of any other package PROVIDED appropriate credit is given in
  20.  * the program source code AND documentation and that no fee is ever charged
  21.  * for just the code in this program.  This entire comment block MUST appear
  22.  * in the code at the place of usage of the code in this module.
  23.  *  For further information, contact the author!
  24.  *  This disclaimer is intended to stop people ripping off my software, and
  25.  * using what was free and making money from it.  I call such people *scum*.
  26.  * I encourage you to release other utilities into the public domain so that
  27.  * life can be made easier for all of us.
  28.  */
  29.  
  30. /*
  31.  * This currently changes the directories to find files.  This is slow, but I
  32.  * havn't had the time to do it properly yet.  You should just use strings
  33.  * and the path and cat/uncat them.
  34.  */
  35.  
  36. /*
  37.  * Options:-
  38.  *    -a: generate an entry for every file
  39.  *    -s: only display grand total for each of the file names
  40.  *    -r: display error info about unreadable directories, etc.
  41.  *      -k: display sizes in Kb
  42.  *      -m: display sizes in Mb
  43.  */
  44.  
  45. #include <conio.h>
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <dos.h>
  49. #include <dir.h>
  50.  
  51. #define VERSION    "1.0"
  52. #define MAXPATHLEN 100
  53. #define conv_size(size)    ((size_type == KB) ? (size) / 1024 : (size_type==MB) \
  54.                           ? (size) / 1048576 : (size))
  55.  
  56. int c_break(void);
  57. void sw_flags (int *ac, char **av, char *letters, int *flags);
  58. unsigned long find_usage(char *path, int quiet);
  59. void du_help(char *fname);
  60.  
  61. enum Size_type {BYTES, KB, MB} size_type;
  62.  
  63. int all, disp_errs;
  64. int curr_disk, diff_drv;
  65. char cwd_org[MAXPATHLEN], cwd_org2[MAXPATHLEN];
  66.  
  67. main(int ac, char **av)
  68. {
  69.     /* all & disp_errs are global to save stack space during recusrion */
  70.   int i, j, flags[5], quiet;
  71.   char dir[MAXPATHLEN];
  72.  
  73.   if (av[1][0] == '?') {
  74.     du_help(av[0]);
  75.     return(0);
  76.   }
  77.  
  78.   ctrlbrk(c_break);    /* Catch ctrl-c's so you don't get left elsewhere */
  79.  
  80.   sw_flags(&ac, av, "arskm", flags);
  81.   all = flags[0];
  82.   disp_errs = flags[1];
  83.   quiet = flags[2];
  84.   size_type = (flags[4]) ? MB : ((flags[3]) ? KB : BYTES);
  85.  
  86.   printf("Sizes given are in %s\n", (size_type == KB) ? "Kb"
  87.                  : (size_type == MB) ? "Mb" : "bytes");
  88.   getcwd(cwd_org, MAXPATHLEN);    /* Save cwd so we can return to it */
  89.   curr_disk = getdisk();
  90.   if (ac == 1) {
  91.     strcpy(dir, ".");
  92.     printf("%12ld %s\n", conv_size(find_usage(dir, quiet)), dir);
  93.   } else {
  94.     for (i=1; i<ac; i++) {
  95.     strcpy(dir, av[i]);
  96.     if (dir[1] == ':' && strlen(dir) >= 2) {
  97.       setdisk(toupper(dir[0])-'A');
  98.       getcwd(cwd_org2, MAXPATHLEN);    /* Save cwd so we can return to it */
  99.       diff_drv=1;    /* Diff drive - need to restore 2wice *
  100.  
  101.       j=2;
  102.       while(dir[j] != '\0'){
  103.     dir[j-2] = dir[j];
  104.     j++;
  105.       }
  106.       dir[j-2] = dir[j];
  107.       if (dir[0] == '\0')    /* No name! Can't have that now, can we! */
  108.         strcpy(dir, ".");
  109.     }
  110.     else
  111.       diff_drv=0;        /* Same drive as before */
  112.     if (chdir(dir) == 0)    /* Directory exists */
  113.       printf("%12ld %s\n", conv_size(find_usage(dir, quiet)), dir);
  114.     else
  115.       printf("%s: No such file or directory\n", dir);
  116.     setdisk(curr_disk);
  117.     chdir(cwd_org);        /* Return to original directory */
  118.     }
  119.     if (diff_drv) {
  120.       chdir(cwd_org2);        /* Reset for each command */
  121.       diff_drv=0;
  122.     }
  123.   }
  124.   if (diff_drv)
  125.     chdir(cwd_org2);        /* Reset for each command */
  126.   setdisk(curr_disk);
  127.   chdir(cwd_org);        /* Return to original directory */
  128.   return(0);
  129. }
  130.  
  131. unsigned long find_usage(char *path, int quiet)
  132. {
  133.   char dpath[MAXPATHLEN];
  134.   struct ffblk fblk;
  135.   unsigned long size = 0, tsiz;
  136.  
  137.   if (findfirst("*.*", &fblk, 0xff) == 0) {
  138.     do {
  139.       if (!strcmp(fblk.ff_name, ".") || !strcmp(fblk.ff_name, ".."))
  140.     continue;
  141.       switch (fblk.ff_attrib) {
  142.     case FA_DIREC:
  143.       size += (unsigned long)fblk.ff_fsize;
  144.       if (chdir(fblk.ff_name) == 0) {
  145.         sprintf(dpath, "%s\\%s", path, fblk.ff_name);
  146.         tsiz = find_usage(dpath, quiet);
  147.         if (!quiet)
  148.           printf("%12ld %s\n", conv_size(tsiz), dpath);
  149.         size += tsiz;
  150.         chdir("..");
  151.           }
  152.           else if (disp_errs)
  153.             printf("%s\\%s: Permission Denied\n", path, fblk.ff_name);
  154.       break;
  155.     case FA_LABEL:
  156.     case FA_RDONLY:
  157.     case FA_HIDDEN:
  158.     case FA_SYSTEM:
  159.     case FA_ARCH:
  160.     default:
  161.       size += (unsigned long)fblk.ff_fsize;
  162.           if (all)
  163.         printf("%12ld %s\\%s\n", conv_size(fblk.ff_fsize), path,
  164.                                 fblk.ff_name);
  165.       break;
  166.       }
  167.     } while (findnext(&fblk) == 0);
  168.   }
  169.   return(size);            /* Default: can't have had any size! */
  170. }
  171.  
  172. void du_help(char *fname)
  173. {
  174.   printf("%s [-s][-a][-r][-k][-m] [list of names]: disk usage\n", fname);
  175.   printf("     -s: Only display grand total for each specified name\n");
  176.   printf("     -a: Generate an entry for each file\n");
  177.   printf("     -r: Display errors for directories that can't be opened\n");
  178.   printf("     -k: Display sizes in Kb\n");
  179.   printf("     -m: Display sizes in Mb\n");
  180.   printf("list of names: list of file/directory names for usage of.\n");
  181.   printf(
  182. "    Author: Mark Allsop, Internet address: mallsop@suna.mqcc.mq.oz.au.\n");
  183.   printf("    Date: %s.  Version: %s.  Public domain program.\n",
  184.                               __DATE__, VERSION);
  185. }
  186.  
  187. int c_break(void)
  188. {
  189.   printf("User interrupt!\n");
  190.   if (diff_drv)
  191.     chdir(cwd_org2);        /* Reset for each command */
  192.   chdir(cwd_org);        /* Return to original directory */
  193.   setdisk(curr_disk);
  194.   exit(1);            /* They want out! */
  195. }
  196.  
  197.  
  198. /*
  199.  * swflag.c: Parse flag type switches.
  200.  *
  201.  * sw_flag (&ac, av, "letters", flags)
  202.  *
  203.  * For each letter, if it is found in a switch which contains
  204.  * only valid letters from the sequence "letters" then the corresponding
  205.  * flag is set true, else set false. The flags count the number of occurrences
  206.  
  207.  * of the switch letter. Thus, the program can use repetition for
  208.  * emphasis.
  209.  * e.g. letter "v" for verbosity; -vv would mean extra verbose.
  210.  *
  211.  * HISTORY
  212.  * 19-Sep-86  Leonard Hamey (lgh) at Carnegie-Mellon University
  213.  *    Fixed bug which allowed a lone hyphen to be matched as a flags
  214.  *    argument with no flags.
  215.  *
  216.  *  9-Aug-86  Leonard Hamey (lgh) at Carnegie-Mellon University
  217.  *    Created.
  218.  */
  219.  
  220. void sw_flags(ac, av, letters, flags)
  221. int *ac;
  222. register char **av;
  223. register char *letters;
  224. register int *flags;
  225. {
  226.   register char *p;
  227.   register int i, j;
  228.   if (letters[0] == '-')
  229.     letters++;
  230.   for (i = 0; letters[i] != '\0'; i++)
  231.     flags[i] = 0;
  232.   for (i = *ac; --i >= 1; )
  233.   {
  234.     p = av[i];
  235.     if (*p == '-' && p[1] != '\0')
  236.     {
  237.       for (p++; *p != '\0'; p++)
  238.     if (strchr (letters, *p) == 0)
  239.       break;
  240.       if (*p != '\0')
  241.     continue;
  242.       for (p = av[i]+1; *p != '\0'; p++)
  243.       { /*
  244.      * Count occurrences of the flag
  245.      */
  246.     flags[strchr(letters,*p) - letters]++;
  247.       }
  248.       /*
  249.        * Discard argument.
  250.        */
  251.       (*ac)--;
  252.       for (j = i; j < *ac; j++)
  253.     av[j] = av[j+1];
  254.       av[j] = NULL;
  255.     }
  256.   }
  257. }
  258.  
  259.