1 #ifndef lint 2 static char *sccsid = "@(#)du.c 4.5 (Berkeley) 05/07/82"; 3 #endif 4 5 #include <stdio.h> 6 #include <sys/param.h> 7 #include <sys/stat.h> 8 #include <dir.h> 9 10 #define howmany(x, y) (((x) + (y) - 1) / (y)) 11 12 char path[BUFSIZ], name[BUFSIZ]; 13 int aflg; 14 int sflg; 15 char *dot = "."; 16 17 #define ML 1000 18 struct { 19 int dev; 20 ino_t ino; 21 } ml[ML]; 22 int mlx; 23 24 long descend(); 25 char *index(), *rindex(), *strcpy(), *sprintf(); 26 27 main(argc, argv) 28 int argc; 29 char **argv; 30 { 31 long kbytes = 0; 32 register char *np; 33 34 argc--, argv++; 35 again: 36 if (argc && !strcmp(*argv, "-s")) { 37 sflg++; 38 argc--, argv++; 39 goto again; 40 } 41 if (argc && !strcmp(*argv, "-a")) { 42 aflg++; 43 argc--, argv++; 44 goto again; 45 } 46 if (argc == 0) { 47 argv = ˙ 48 argc = 1; 49 } 50 do { 51 (void) strcpy(path, *argv); 52 (void) strcpy(name, *argv); 53 if (np = rindex(name, '/')) { 54 *np++ = '\0'; 55 if (chdir(*name ? name : "/") < 0) { 56 perror(*name ? name : "/"); 57 exit(1); 58 } 59 } else 60 np = path; 61 kbytes = descend(path, *np ? np : "."); 62 if (sflg) 63 printf("%ld\t%s\n", kbytes, path); 64 argc--, argv++; 65 } while (argc > 0); 66 exit(0); 67 } 68 69 DIR *dirp = NULL; 70 71 long 72 descend(base, name) 73 char *base, *name; 74 { 75 char *ebase0, *ebase; 76 struct stat stb; 77 int i; 78 long kbytes = 0; 79 long curoff = NULL; 80 register struct direct *dp; 81 82 ebase0 = ebase = index(base, 0); 83 if (ebase > base && ebase[-1] == '/') 84 ebase--; 85 if (lstat(name, &stb) < 0) { 86 perror(base); 87 *ebase0 = 0; 88 return (0); 89 } 90 if (stb.st_nlink > 1 && (stb.st_mode&S_IFMT) != S_IFDIR) { 91 for (i = 0; i <= mlx; i++) 92 if (ml[i].ino == stb.st_ino && ml[i].dev == stb.st_dev) 93 return (0); 94 if (mlx < ML) { 95 ml[mlx].dev = stb.st_dev; 96 ml[mlx].ino = stb.st_ino; 97 mlx++; 98 } 99 } 100 kbytes = howmany(stb.st_size, 1024); 101 if ((stb.st_mode&S_IFMT) != S_IFDIR) { 102 if (aflg) 103 printf("%ld\t%s\n", kbytes, base); 104 return (kbytes); 105 } 106 if (chdir(name) < 0) 107 return (0); 108 if (dirp != NULL) 109 closedir(dirp); 110 dirp = opendir("."); 111 if (dirp == NULL) { 112 perror(base); 113 *ebase0 = 0; 114 return (0); 115 } 116 while (dp = readdir(dirp)) { 117 if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) 118 continue; 119 (void) sprintf(ebase, "/%s", dp->d_name); 120 curoff = telldir(dirp); 121 kbytes += descend(base, ebase+1); 122 *ebase = 0; 123 if (dirp == NULL) { 124 dirp = opendir("."); 125 seekdir(dirp, curoff); 126 } 127 } 128 closedir(dirp); 129 dirp = NULL; 130 if (sflg == 0) 131 printf("%ld\t%s\n", kbytes, base); 132 if (chdir("..") < 0) { 133 (void) sprintf(index(base, 0), "/.."); 134 perror(base); 135 exit(1); 136 } 137 *ebase0 = 0; 138 return (kbytes); 139 } 140