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