161 lines
3.5 KiB
C
161 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/dir.h>
|
|
|
|
char path[BUFSIZ], name[BUFSIZ];
|
|
int aflg;
|
|
int sflg;
|
|
char *dot = ".";
|
|
|
|
#define ML 1000
|
|
struct {
|
|
int dev;
|
|
ino_t ino;
|
|
} ml[ML];
|
|
int mlx;
|
|
|
|
long descend();
|
|
|
|
#define kb(n) (howmany(n * DEV_BSIZE, 1024))
|
|
|
|
main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
long blocks = 0;
|
|
register char *np;
|
|
int pid;
|
|
|
|
argc--, argv++;
|
|
again:
|
|
if (argc && !strcmp(*argv, "-s")) {
|
|
sflg++;
|
|
argc--, argv++;
|
|
goto again;
|
|
}
|
|
if (argc && !strcmp(*argv, "-a")) {
|
|
aflg++;
|
|
argc--, argv++;
|
|
goto again;
|
|
}
|
|
if (argc == 0) {
|
|
argv = ˙
|
|
argc = 1;
|
|
}
|
|
do {
|
|
if (argc > 1) {
|
|
pid = fork();
|
|
if (pid == -1) {
|
|
fprintf(stderr, "No more processes.\n");
|
|
exit(1);
|
|
}
|
|
if (pid != 0)
|
|
wait((int *)0);
|
|
}
|
|
if (argc == 1 || pid == 0) {
|
|
(void) strcpy(path, *argv);
|
|
(void) strcpy(name, *argv);
|
|
if (np = rindex(name, '/')) {
|
|
*np++ = '\0';
|
|
if (chdir(*name ? name : "/") < 0) {
|
|
perror(*name ? name : "/");
|
|
exit(1);
|
|
}
|
|
} else
|
|
np = path;
|
|
blocks = descend(path, *np ? np : ".");
|
|
if (sflg)
|
|
printf("%ld\t%s\n", kb(blocks), path);
|
|
if (argc > 1)
|
|
exit(1);
|
|
}
|
|
argc--, argv++;
|
|
} while (argc > 0);
|
|
exit(0);
|
|
}
|
|
|
|
DIR *dirp = NULL;
|
|
|
|
long
|
|
descend(base, name)
|
|
char *base, *name;
|
|
{
|
|
char *ebase0, *ebase;
|
|
struct stat stb;
|
|
int i;
|
|
long blocks = 0;
|
|
long curoff = NULL;
|
|
register struct direct *dp;
|
|
|
|
ebase0 = ebase = index(base, 0);
|
|
if (ebase > base && ebase[-1] == '/')
|
|
ebase--;
|
|
if (lstat(name, &stb) < 0) {
|
|
perror(base);
|
|
*ebase0 = 0;
|
|
return (0);
|
|
}
|
|
if (stb.st_nlink > 1 && (stb.st_mode&S_IFMT) != S_IFDIR) {
|
|
for (i = 0; i <= mlx; i++)
|
|
if (ml[i].ino == stb.st_ino && ml[i].dev == stb.st_dev)
|
|
return (0);
|
|
if (mlx < ML) {
|
|
ml[mlx].dev = stb.st_dev;
|
|
ml[mlx].ino = stb.st_ino;
|
|
mlx++;
|
|
}
|
|
}
|
|
blocks = stb.st_blocks;
|
|
if ((stb.st_mode&S_IFMT) != S_IFDIR) {
|
|
if (aflg)
|
|
printf("%ld\t%s\n", kb(blocks), base);
|
|
return (blocks);
|
|
}
|
|
if (dirp != NULL)
|
|
closedir(dirp);
|
|
dirp = opendir(name);
|
|
if (dirp == NULL) {
|
|
perror(base);
|
|
*ebase0 = 0;
|
|
return (0);
|
|
}
|
|
if (chdir(name) < 0) {
|
|
perror(base);
|
|
*ebase0 = 0;
|
|
closedir(dirp);
|
|
dirp = NULL;
|
|
return (0);
|
|
}
|
|
while (dp = readdir(dirp)) {
|
|
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
|
continue;
|
|
(void) sprintf(ebase, "/%s", dp->d_name);
|
|
curoff = telldir(dirp);
|
|
blocks += descend(base, ebase+1);
|
|
*ebase = 0;
|
|
if (dirp == NULL) {
|
|
dirp = opendir(".");
|
|
if (dirp == NULL) {
|
|
perror(".");
|
|
return (0);
|
|
}
|
|
seekdir(dirp, curoff);
|
|
}
|
|
}
|
|
closedir(dirp);
|
|
dirp = NULL;
|
|
if (sflg == 0)
|
|
printf("%ld\t%s\n", kb(blocks), base);
|
|
if (chdir("..") < 0) {
|
|
(void) sprintf(index(base, 0), "/..");
|
|
perror(base);
|
|
exit(1);
|
|
}
|
|
*ebase0 = 0;
|
|
return (blocks);
|
|
}
|