home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / du.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  3.1 KB  |  168 lines

  1. #include <stdio.h>
  2. #include <sys/param.h>
  3. #include <sys/stat.h>
  4. #include <sys/dir.h>
  5. #define EQ(x,y)    (strcmp(x,y)==0)
  6. #define ML    1000
  7.  
  8. struct stat Statb;
  9. char    path[256], name[256];
  10. int    Aflag = 0,
  11.     Sflag = 0,
  12.     Noarg = 0;
  13. struct {
  14.     int    dev,
  15.         ino;
  16. } ml[ML];
  17. long    descend();
  18. char    *rindex();
  19. char    *strcpy();
  20.  
  21. main(argc, argv)
  22. char **argv;
  23. {
  24.     register    i = 1;
  25.     long    blocks = 0;
  26.     register char    *np;
  27.  
  28.     if (argc>1) {
  29.         if(EQ(argv[i], "-s")) {
  30.             ++i;
  31.             ++Sflag;
  32.         } else if(EQ(argv[i], "-a")) {
  33.             ++i;
  34.             ++Aflag;
  35.         }
  36.     }
  37.     if(i == argc)
  38.         ++Noarg;
  39.  
  40.     do {
  41.         strcpy(path, Noarg? ".": argv[i]);
  42.         strcpy(name, path);
  43.         if(np = rindex(name, '/')) {
  44.             *np++ = '\0';
  45.             if(chdir(*name? name: "/") == -1) {
  46.                 fprintf(stderr, "cannot chdir()\n");
  47.                 exit(1);
  48.             }
  49.         } else
  50.             np = path;
  51.         blocks = descend(path, *np? np: ".");
  52.         if(Sflag)
  53.             printf("%ld    %s\n", blocks, path);
  54.     } while(++i < argc);
  55.  
  56.     exit(0);
  57. }
  58.  
  59. long
  60. descend(np, fname)
  61. char *np, *fname;
  62. {
  63.     int dir = 0, /* open directory */
  64.         offset,
  65.         dsize,
  66.         entries,
  67.         dirsize;
  68.  
  69.     struct direct dentry[32];
  70.     register  struct direct *dp;
  71.     register char *c1, *c2;
  72.     int i;
  73.     char *endofname;
  74.     long blocks = 0;
  75.  
  76.     if(stat(fname,&Statb)<0) {
  77.         fprintf(stderr, "--bad status < %s >\n", name);
  78.         return 0L;
  79.     }
  80.     if(Statb.st_nlink > 1 && (Statb.st_mode&S_IFMT)!=S_IFDIR) {
  81.         static linked = 0;
  82.  
  83.         for(i = 0; i <= linked; ++i) {
  84.             if(ml[i].ino==Statb.st_ino && ml[i].dev==Statb.st_dev)
  85.                 return 0;
  86.         }
  87.         if (linked < ML) {
  88.             ml[linked].dev = Statb.st_dev;
  89.             ml[linked].ino = Statb.st_ino;
  90.             ++linked;
  91.         }
  92.     }
  93.     blocks = (Statb.st_size + BSIZE-1) >> BSHIFT;
  94.  
  95.     if((Statb.st_mode&S_IFMT)!=S_IFDIR) {
  96.         if(Aflag)
  97.             printf("%ld    %s\n", blocks, np);
  98.         return(blocks);
  99.     }
  100.  
  101.     for(c1 = np; *c1; ++c1);
  102.     if(*(c1-1) == '/')
  103.         --c1;
  104.     endofname = c1;
  105.     dirsize = Statb.st_size;
  106.     if(chdir(fname) == -1)
  107.         return 0;
  108.     for(offset=0; offset < dirsize; offset += 512) { /* each block */
  109.         dsize = 512<(dirsize-offset)? 512: (dirsize-offset);
  110.         if(!dir) {
  111.             if((dir=open(".",0))<0) {
  112.                 fprintf(stderr, "--cannot open < %s >\n",
  113.                     np);
  114.                 goto ret;
  115.             }
  116.             if(offset) lseek(dir, (long)offset, 0);
  117.             if(read(dir, (char *)dentry, dsize)<0) {
  118.                 fprintf(stderr, "--cannot read < %s >\n",
  119.                     np);
  120.                 goto ret;
  121.             }
  122.             if(dir > 10) {
  123.                 close(dir);
  124.                 dir = 0;
  125.             }
  126.         } else 
  127.             if(read(dir, (char *)dentry, dsize)<0) {
  128.                 fprintf(stderr, "--cannot read < %s >\n",
  129.                     np);
  130.                 goto ret;
  131.             }
  132.         for(dp=dentry, entries=dsize>>4; entries; --entries, ++dp) {
  133.             /* each directory entry */
  134.             if(dp->d_ino==0
  135.             || EQ(dp->d_name, ".")
  136.             || EQ(dp->d_name, ".."))
  137.                 continue;
  138.             c1 = endofname;
  139.             *c1++ = '/';
  140.             c2 = dp->d_name;
  141.             for(i=0; i<DIRSIZ; ++i)
  142.                 if(*c2)
  143.                     *c1++ = *c2++;
  144.                 else
  145.                     break;
  146.             *c1 = '\0';
  147.             if(c1 == endofname) /* ?? */
  148.                 return 0L;
  149.             blocks += descend(np, endofname+1);
  150.         }
  151.     }
  152.     *endofname = '\0';
  153.     if(!Sflag)
  154.         printf("%ld    %s\n", blocks, np);
  155. ret:
  156.     if(dir)
  157.         close(dir);
  158.     if(chdir("..") == -1) {
  159.         *endofname = '\0';
  160.         fprintf(stderr, "Bad directory <%s>\n", np);
  161.         while(*--endofname != '/');
  162.         *endofname = '\0';
  163.         if(chdir(np) == -1)
  164.             exit(1);
  165.     }
  166.     return(blocks);
  167. }
  168.