home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / du.zip / du.c < prev    next >
C/C++ Source or Header  |  1993-04-29  |  4KB  |  149 lines

  1. /* Unix-style du for OS/2 */
  2.  
  3. /*
  4. * syntax: du [-s] [directory-list]
  5. * -s gives only summary of sizes for directories named on commandline.
  6. * If no directories are specified, the current directory is assumed.
  7. * Size of subtree given, then contribution by current node in parenthesis:
  8. *
  9. *       1234 (       567) foo
  10. *
  11. * This entry shows that the subtree below and including directory foo uses
  12. * 1234 bytes, and foo itself contains files accounting for 567 bytes. The
  13. * remainder is in files in subdirectories below foo.
  14. *
  15. * Pipe the result through the sort filter to see the space hogs grouped at
  16. * the end of the list.
  17. */
  18.  
  19. /*
  20. * Copyright 1993 by Kenneth Porter (shiva@well.sf.ca.us).
  21. * Freely redistributable.
  22. * Code may be used if attribution given.
  23. */
  24.  
  25. #define INCL_NOPM
  26. #define INCL_NOCOMMON
  27. #define INCL_DOSERRORS
  28. #define INCL_DOSFILEMGR
  29. #include <os2.h>
  30.  
  31. #include <process.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35.  
  36. static void du(char *dirname, int summary);
  37. static long du2(char *dirname, int silent, long *pfiles);
  38. static void ShowDirSize(char *dirname, long size, long files);
  39. static void FileFindError(char *dirname, ULONG error, char *what);
  40.  
  41. int main(int argc, char *argv[])
  42. {
  43.     int i,summary;
  44.     --argc;
  45.     ++argv;
  46.     // check for summary switch
  47.     if (argc && 0 == strcmp(argv[0],"-s")) {
  48.     summary = 1;
  49.     --argc;
  50.     ++argv;
  51.     }
  52.     else summary = 0;
  53.     // check if any directories were specified on the command line
  54.     if (!argc) du(".",summary);
  55.     else for (i=0; i<argc; i++) du(argv[i],summary);
  56.     return 0;
  57. }
  58.  
  59. void du(char *dirname, int summary)
  60. {
  61.     long size,files;
  62.     size = du2(dirname,summary,&files);
  63.     if (summary && 0 != size) ShowDirSize(dirname,size,files);
  64. }
  65.  
  66. long du2(char *dirname, int silent, long *pfiles)
  67. {
  68.     // first search for directories, doing them recursively, then do files
  69.     ULONG rc;
  70.     long size=0, subfiles;
  71.     HDIR hdir;
  72.     ULONG SearchCount;
  73.     FILEFINDBUF3 *pbuf;
  74.     char namebuffer[CCHMAXPATH], subbuffer[CCHMAXPATH];
  75.  
  76.     pbuf = calloc(1,sizeof *pbuf);
  77.     *pfiles = 0;
  78.     strcpy(namebuffer,dirname);
  79.     if ('\\' != namebuffer[strlen(namebuffer)-1]) strcat(namebuffer,"\\");
  80.     strcat(namebuffer,"*");
  81.     SearchCount = 1;
  82.     hdir = HDIR_CREATE;
  83.     rc = DosFindFirst((PSZ)namebuffer,&hdir,
  84.               MUST_HAVE_DIRECTORY|
  85.               FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM|FILE_ARCHIVED,
  86.               pbuf,sizeof *pbuf,&SearchCount,FIL_STANDARD);
  87.     while (ERROR_NO_MORE_FILES != rc) {
  88.     if (0 != rc) {
  89.         DosFindClose(hdir);
  90.         FileFindError(dirname,rc,"directory");
  91.         return 0;
  92.     }
  93.     /* !!!!!!!!!!!!!!!! This is the spot that gives me grief! */
  94.     /* Occasionally a normal file is returned, so the following test is
  95.     necessary */
  96.     if (pbuf->attrFile & FILE_DIRECTORY) {
  97.         if (0 != strcmp(pbuf->achName,".") &&
  98.         0 != strcmp(pbuf->achName,"..")) {
  99.         strcpy(subbuffer,dirname);
  100.         if ('\\' != subbuffer[strlen(subbuffer)-1])
  101.             strcat(subbuffer,"\\");
  102.         strcat(subbuffer,pbuf->achName);
  103.         size += du2(subbuffer,silent,&subfiles);
  104.         }
  105.     }
  106. #if 0
  107.     else printf("File %s\\%s returned as directory\n",
  108.             dirname,pbuf->achName);
  109. #endif
  110.     SearchCount = 1;
  111.     rc = DosFindNext(hdir,pbuf,sizeof *pbuf,&SearchCount);
  112.     }
  113.     DosFindClose(hdir);
  114.     hdir = HDIR_CREATE;
  115.     SearchCount = 1;
  116.     // search for anything that's not a directory
  117.     rc = DosFindFirst((PSZ)namebuffer,&hdir,
  118.               FILE_READONLY|FILE_HIDDEN|FILE_SYSTEM|FILE_ARCHIVED,
  119.               pbuf,sizeof *pbuf,&SearchCount,FIL_STANDARD);
  120.     while (ERROR_NO_MORE_FILES != rc) {
  121.     if (0 != rc) {
  122.         DosFindClose(hdir);
  123.         FileFindError(dirname,rc,"file");
  124.         return 0;
  125.     }
  126.     *pfiles += pbuf->cbFileAlloc;
  127.     SearchCount = 1;
  128.     rc = DosFindNext(hdir,pbuf,sizeof *pbuf,&SearchCount);
  129.     }
  130.     DosFindClose(hdir);
  131.     size += *pfiles;
  132.     if (!silent) ShowDirSize(dirname,size,*pfiles);
  133.     free(pbuf);
  134.     return size;
  135. }
  136.  
  137. void ShowDirSize(char *dirname, long size, long files)
  138. {
  139.     printf("%10ld (%10ld) %s\n",size,files,dirname);
  140. }
  141.  
  142. static void FileFindError(char *dirname, ULONG error, char *what)
  143. {
  144.     fprintf(stderr,
  145.         "Search failed for %s '%s'; reason %d\n",
  146.         what,dirname,error);
  147. }
  148.  
  149.