#include #include #include #include #include #include #include #include "get_stat.h" #include "make_path.h" #include "human.h" static char h_flag; static char s_flag; static char c_flag; static off_t total; static void print(off_t size, const char *filename) { if (h_flag) printf("%s\t%s\n", mu_humansize(size * 512, 1024), filename); else printf("%jd\t%s\n", (intmax_t)size / 2, filename); } static off_t du(const char *path, int recurs_flag) { struct stat sb; if (mu_get_lstat("du", path, &sb)) return 0; off_t sum = sb.st_blocks; if (c_flag) total += sum; if (S_ISDIR(sb.st_mode)) { DIR *dp = opendir(path); if (!dp) { fprintf(stderr, "du: %s\n", strerror(errno)); return 0; } struct dirent *ep; while ((ep = readdir(dp)) != NULL) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) continue; char *new_path = mu_make_path("du", path, ep->d_name); if (new_path == NULL) return 0; sum += du(new_path, 1); free(new_path); } closedir(dp); if (!s_flag && recurs_flag) { print(sum, path); return sum; } /* Silent mode */ else if (!recurs_flag) print(sum, path); } else if (!recurs_flag) print(sum, path); return sum; } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "hsc")) != -1) { switch (opt) { case 'h': h_flag = 1; break; case 's': s_flag = 1; break; case 'c': c_flag = 1; break; default: puts("du [hsc] [src1 src2...]\n\t-h Sizes in human readable format\n\t-s Display only a total for each argument\n\t-c produce a grand total"); return 0; } } if (argv[optind] == NULL) du(".", 0); else { argv += optind; argc -= optind; for (int i = 0; i < argc; i++) du(argv[i], 0); } if (c_flag) print(total, "total"); return 0; }