home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / forum4.lzh / SPRACHEN / C / DU / du.c
C/C++ Source or Header  |  1987-12-14  |  8KB  |  249 lines

  1. /* DU.C (Disk usage) 
  2.  * 
  3.  * Displays directory sizes similar to the UNIX DU function.
  4.  *
  5.  * This program is based on Size.C by Avy Moise, 1987, Toronto, Canada
  6.  *
  7.  * Modified by Tom Leitner, Sep. 1987, Graz, Austria
  8.  *
  9.  * Usage is : DU [<opts>] <directory> [<opts>]
  10.  *
  11.  *  It will collect all the sizes (not including file descriptor and
  12.  *  directory space taken) for the specified directory and prints
  13.  *  them in a table along with all subdirectories. The directory
  14.  *  size is printed in Bytes, kBytes and 256 Byte Sector Units.
  15.  *  If the directory specification is omitted, the current directory
  16.  *  will be used.
  17.  *
  18.  * Note: The # of files displayed include also the directory files.
  19.  *
  20.  */
  21.  
  22. /* system includes */
  23.  
  24. #include <stdio.h>
  25. #include <dir.h>
  26. #include <modes.h>
  27. #include <sgstat.h>
  28. #include <time.h>
  29.  
  30. /* constants & macros */
  31.  
  32. #define RBF (1)                 /* random block file found opened       */
  33. #define PIPE (2)                /* pipe file opened                     */
  34. #define NET (4)                 /* network file opened                  */
  35. #define TRUE 1                  /* logical true                         */
  36. #define FALSE 0                 /* logical false                        */
  37. #define KB(x) (x+1023L)/1024    /* formula to calculate kB from bytes   */
  38. #define SECT(x) (x+255L)/256    /* formula to calc. sectors from bytes  */
  39. #define MAXPATH 256             /* max. # of characters for path name   */
  40.  
  41. /* global variables */
  42.  
  43. char path[MAXPATH] = "";        /* string to store the path             */
  44. int files = 0;                  /* # of files found                     */
  45. int dirs = 0;/* # of directories found       
  46.         */
  47. char flag_total = FALSE;        /* just print a summary                 */
  48. char dir_flag;/* indicates a directory read   
  49.         */
  50. struct sgtbuf cur_time;         /* current time                         */
  51. char *root;                     /* root directory to start from         */
  52.  
  53. /*--------------------------------- M A I N ----------------------------------*/
  54.  
  55. main(argc, argv)
  56.         int argc;
  57.         char *argv[];
  58. {
  59.         unsigned long filesize(), tot_size;
  60.         get_parms(argc, argv);
  61.         if (!flag_total) {
  62.                 getime(&cur_time);
  63.                 printf("Disk usage starting from \"%s\" on ", root);
  64.                 print_date(&cur_time);
  65.                 printf("\n\nDirectory name                      Bytes    kBytes   Sectors    File #\n");
  66.                 printf("--------------                   --------   -------   -------   -------\n");
  67.         }
  68.         tot_size = filesize(root);
  69.         printf("\nTotal of %lu kBytes (%lu sectors) in %d directories and %d files.\n\n", 
  70.                KB(tot_size), SECT(tot_size), dirs, files);
  71. }
  72.  
  73. /*------------------- print the date supplied in the buffer ------------------*/
  74.  
  75. print_date(bp)
  76. struct sgtbuf *bp;
  77. {
  78.         register int i;
  79.         char sbuf[11];
  80.         sprintf(sbuf, "19%2d-%2d-%2d", bp->t_year, bp->t_month, bp->t_day);
  81.         for (i = 0; i < 10; i++)
  82.               if (sbuf[i] == ' ') sbuf[i] = '0';
  83.         printf("%s  ", sbuf);
  84.         sprintf(sbuf, "%2d:%2d:%2d", bp->t_hour, bp->t_minute, bp->t_second);
  85.         for (i = 0; i < 8; i++) 
  86.               if (sbuf[i] == ' ') sbuf[i] = '0';
  87.         printf("%s", sbuf);
  88. }
  89.  
  90. /*-------------------- parses command line for parameters --------------------*/
  91.  
  92. get_parms(argc,argv)
  93. int argc;
  94. char *argv[];
  95. {
  96.         char *s;
  97.         int pc = 0;
  98.         while (--argc>0) {
  99.                 if ((*++argv)[0] == '-') {
  100.                         for (s = argv[0]+1;*s != '\0';s++)
  101.                                 switch(toupper(*s)) {
  102.                                 case 'A':
  103.                                         flag_total = TRUE;
  104.                                         break;
  105.                                 case '?':
  106.                                         usage();
  107.                                         exit(0);
  108.                                 default:
  109.                                         fprintf(stderr,
  110.                                                 "%s: unknown option '%c'\n",
  111.                                                 _prgname(),*s);
  112.                                         exit(1);
  113.                                 }
  114.                 }
  115.                 else if (pc == 0) {
  116.                         root = argv[0];
  117.                         pc++;
  118.                 } else {
  119.                         fprintf(stderr,"%s: only one parameter allowed\n",
  120.                                 _prgname());
  121.                         exit(1);
  122.                 }
  123.         }
  124.         if (pc == 0) root = ".";
  125. }
  126.  
  127. /*------------------------- print usage explanations -------------------------*/
  128.  
  129. #define E(txt) fprintf(stderr, txt)
  130. usage()
  131. {
  132.         fprintf(stderr,"Syntax: %s <directory>\n",_prgname());
  133.         E("Function: displays information about disk usage\n");
  134.         E("Options : -a displays just the final summary\n");
  135. }
  136. #undef E(txt)
  137.  
  138. /*------------------------------ main algorithm ------------------------------*/
  139.  
  140. unsigned long filesize( filename )
  141. char *filename;
  142. {
  143.   unsigned long size=0L;
  144.   int fd, pl, dfiles;
  145.   DIR *dirp;
  146.   struct direct *dirrec;
  147.   static struct sgbuf stat;
  148.  
  149. /* set the dir_flag to FALSE by default  */
  150.  
  151.   dir_flag =  FALSE;
  152.   
  153. /* setup the cumulative path name */
  154.         
  155.   pl = strlen(path);
  156.   if (pl) strncat(path, "/", MAXPATH);
  157.   strncat(path, filename, MAXPATH);
  158.         
  159. /* try to open the file */
  160.  
  161.   if( ((fd=open(filename,S_IREAD)) < 0) &&              /* regular file ? */
  162.       ((fd=open(filename,S_IFDIR|S_IREAD)) < 0) )       /* directory ?    */
  163.     fprintf(stderr,"Cannot open '%s'\n", filename);
  164.     
  165. /* successfully opened. check if it's on the right device */
  166.  
  167.   else {
  168.     _gs_opt(fd, &stat);
  169.     if( (stat.sg_class == RBF) || (stat.sg_class == NET) ||
  170.           (stat.sg_class == PIPE) ) {
  171.                   
  172. /* ok. we're on a valid device : now check if we hit a directory file */
  173.  
  174.        if( stat.sg_att & S_IFDIR ) {
  175.                
  176. /* yes. we hit a directory file. close the FD and CHD into it. */
  177.  
  178.           close(fd);
  179.           if( (dirp = opendir( filename )) && !chdir( filename) ) {
  180.                   
  181. /* skip the "." and the ".." entries */
  182.  
  183.             readdir(dirp); readdir( dirp );
  184.             
  185. /* get file sizes of all files in this directory */
  186.  
  187.             dfiles = 0;
  188.             while (dirrec = readdir (dirp))
  189.               if (dirrec->d_addr) {
  190.                  size += filesize(dirrec->d_name);
  191.                  if (!dir_flag) {
  192.                          dfiles++;      /* update local file counter  */
  193.                          files++;       /* update global file counter */
  194.                  }
  195.               }
  196.                  
  197. /* end of directory : close it and print the results */
  198.  
  199.             closedir( dirp );
  200.             chdir("..");
  201.             if (!flag_total) printline(path, size, dfiles);
  202.             dirs++;             /* update the directory counter */
  203.             dir_flag = TRUE;
  204.           }
  205.           
  206. /* ERROR occurred : can't CHD into this directory. */
  207.  
  208.           else
  209.             fprintf(stderr, "Cannot chdir '%s'\n", filename);
  210.  
  211. /* the given filename was no directory. it's a normal file so just get its
  212.    size and increment the file count */
  213.    
  214.        } else {
  215.          size = _gs_size( fd );
  216.          close( fd );
  217.        }
  218.      }
  219.      
  220. /* the given file name is not on a valid device */
  221.  
  222.      else
  223.      fprintf(stderr,"Cannot read size - not a block special device\n");
  224.   }
  225.   
  226. /* reset the cumulative PATH string */
  227.  
  228.   path[pl] = (char) NULL;
  229.   return( size );
  230. }
  231.  
  232. /*-------------------------- print one table entry ---------------------------*/
  233.  
  234. printline(path, size, dfiles)
  235. char *path;
  236. unsigned long size;
  237. int dfiles;
  238. {
  239.         if (strlen(path) > 32) {
  240.                 printf("%s\n", path);
  241.                 path = "";
  242.         }
  243.         printf("%-32s %8lu   %7lu   %7lu   %7d\n", 
  244.                 path, size, KB(size), SECT(size), dfiles);
  245. }
  246.  
  247. /* E O F */
  248.  
  249.