124 lines
2.1 KiB
C
124 lines
2.1 KiB
C
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <stdint.h>
|
|
#include "get_stat.h"
|
|
#include "make_path.h"
|
|
#include "human.h"
|
|
|
|
unsigned int h_flag;
|
|
unsigned int s_flag;
|
|
unsigned int c_flag;
|
|
unsigned int b_flag;
|
|
char n_flag = '\n';
|
|
off_t total;
|
|
|
|
void print(off_t size, const char *filename) {
|
|
if (h_flag)
|
|
printf("%s\t%s%c", mu_humansize(size, 1024), filename, n_flag);
|
|
|
|
else
|
|
printf("%jd\t%s%c", (intmax_t)size / 1024, filename, n_flag);
|
|
}
|
|
|
|
off_t du(const char *path, int recurs_flag) {
|
|
off_t sum = 0;
|
|
|
|
struct stat sb;
|
|
if (mu_get_lstat("du", path, &sb))
|
|
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;
|
|
|
|
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);
|
|
}
|
|
|
|
/* Get file size */
|
|
else {
|
|
sum = 512 * sb.st_blocks + 512;
|
|
|
|
if (c_flag)
|
|
total += sum;
|
|
|
|
if (!recurs_flag)
|
|
print(sum, path);
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
int opt;
|
|
while ((opt = getopt(argc, argv, "hsbc0")) != -1) {
|
|
switch (opt) {
|
|
case 'h':
|
|
h_flag = 1;
|
|
break;
|
|
|
|
case 's':
|
|
s_flag = 1;
|
|
break;
|
|
|
|
case 'c':
|
|
c_flag = 1;
|
|
break;
|
|
|
|
case '0':
|
|
n_flag = '\0';
|
|
break;
|
|
|
|
default:
|
|
printf("du [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]\n\t[-0 end each output line with NUL, not newline]\n");
|
|
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;
|
|
}
|