#include #include #include #include #include #include #include unsigned int h_flag; unsigned int s_flag; unsigned int b_flag; unsigned int m_flag; unsigned int L_flag; void print(long size, const char *filename) { /* Kb */ if (!b_flag) size = size / 1024; /* Mb */ else if (m_flag) size = size / 1048576; printf("%ld\t%s\n", size, filename); } long du(const char *path, int recurs_flag) { long sum; struct stat sb; if (lstat(path, &sb) != 0) { fprintf(stderr, "du: lstat() %s\n", strerror(errno)); return 0; } 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; size_t len = strlen(path) + strlen(ep->d_name) + 2; char *new_path = malloc(len + 1); if (new_path == NULL) continue; snprintf(new_path, len, "%s/%s", path, ep->d_name); sum += du(new_path, 1); free(new_path); } closedir(dp); if (s_flag) if (!recurs_flag) { print(sum, path); } else print(sum, path); } else { sum = sb.st_size; if (!recurs_flag) print(sum, path); } return sum; } int main(const int argc, const char **argv) { int i; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; else if (!strcmp(argv[i], "-h")) h_flag = 1; else if (!strcmp(argv[i], "-s")) s_flag = 1; else if (!strcmp(argv[i], "-b")) b_flag = 1; else if (!strcmp(argv[i], "-m")) { b_flag = 1; m_flag = 1; } else if (!strcmp(argv[i], "-L")) L_flag = 1; else if (!strcmp(argv[i], "--help")) { printf("du [-h (Sizes in human readable format (e.g., 1K 243M 2G))] [-s (Display only a total for each argument)] [-b (Apparent size)] [-L (Follow all symlinks)] [-m (Size in megabyte)] [file file2...]\n"); return 0; } } if (argc - i == 0) du(".", 0); else for (; i < argc; i++) du(argv[i], 0); return 0; }