116 lines
2.0 KiB
C
116 lines
2.0 KiB
C
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <sys/stat.h>
|
|
|
|
unsigned int h_flag;
|
|
unsigned int s_flag;
|
|
unsigned int b_flag;
|
|
unsigned int m_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 = 0;
|
|
|
|
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 && recurs_flag) {
|
|
print(sum, path);
|
|
return sum;
|
|
}
|
|
|
|
/* Silent mode */
|
|
else if (!recurs_flag)
|
|
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], "--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)] [-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;
|
|
}
|