micro-utils/coreutils/du.c

138 lines
2.1 KiB
C
Raw Normal View History

2023-10-21 15:05:49 +03:00
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
2023-10-31 12:53:32 +03:00
#include "get_stat.h"
#include "make_path.h"
2023-10-21 15:05:49 +03:00
unsigned int h_flag;
unsigned int s_flag;
unsigned int b_flag;
unsigned int m_flag;
2023-10-29 12:27:44 +03:00
void print(double size, const char *filename) {
char c = 0;
if (h_flag) {
2023-11-05 18:45:11 +03:00
if (size < 1048576 && !m_flag) {
2023-11-05 18:31:17 +03:00
size = size / 1024;
2023-10-29 12:27:44 +03:00
c = 'K';
2023-11-05 18:31:17 +03:00
}
2023-10-29 12:27:44 +03:00
else if (size < 1073741824) {
size = size / 1048576;
c = 'M';
}
else if (size < 1099511627776) {
size = size / 1073741824;
c = 'G';
}
}
2023-10-21 15:05:49 +03:00
/* Kb */
2023-10-29 12:27:44 +03:00
else if (!b_flag)
2023-10-21 15:05:49 +03:00
size = size / 1024;
/* Mb */
else if (m_flag)
size = size / 1048576;
2023-11-05 18:31:17 +03:00
printf("%.1f%c %s\n", size, c, filename);
2023-10-21 15:05:49 +03:00
}
2023-10-29 12:27:44 +03:00
double du(const char *path, int recurs_flag) {
double sum = 0;
2023-10-21 15:05:49 +03:00
struct stat sb;
2023-10-31 12:53:32 +03:00
if (mu_get_lstat("du", path, &sb))
2023-11-06 23:52:48 +03:00
return 0;
2023-10-21 15:05:49 +03:00
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;
2023-10-31 12:53:32 +03:00
char *new_path = mu_make_path("du", path, ep->d_name);
2023-10-21 15:05:49 +03:00
if (new_path == NULL)
2023-11-06 23:52:48 +03:00
return 0;
2023-10-21 15:05:49 +03:00
2023-10-21 15:27:42 +03:00
sum += du(new_path, 1);
2023-10-21 15:05:49 +03:00
free(new_path);
}
closedir(dp);
2023-10-21 15:27:42 +03:00
2023-10-21 16:02:07 +03:00
if (!s_flag && recurs_flag) {
print(sum, path);
return sum;
2023-10-21 15:27:42 +03:00
}
2023-10-21 16:02:07 +03:00
/* Silent mode */
else if (!recurs_flag)
2023-10-21 15:27:42 +03:00
print(sum, path);
2023-10-21 15:05:49 +03:00
}
2023-10-21 15:27:42 +03:00
else {
sum = sb.st_size;
if (!recurs_flag)
print(sum, path);
}
2023-10-21 15:05:49 +03:00
return sum;
}
2023-11-06 23:52:48 +03:00
int main(int argc, char **argv) {
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
int opt;
while ((opt = getopt(argc, argv, "hsbm")) != -1) {
switch (opt) {
case 'h':
h_flag = 1;
break;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case 's':
s_flag = 1;
break;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case 'b':
b_flag = 1;
break;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case 'm':
b_flag = 1;
m_flag = 1;
break;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
default:
2023-11-07 16:21:46 +03:00
printf("du [file1 file2...]\n\t[-h Sizes in human readable format]\n\t[-s Display only a total for each argument]\n\t[-b Apparent size] [-m Size in megabyte]\n");
2023-11-06 23:52:48 +03:00
return 0;
2023-10-21 15:05:49 +03:00
}
}
2023-11-06 23:52:48 +03:00
if (argv[optind] == NULL)
2023-10-21 15:27:42 +03:00
du(".", 0);
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
else {
argv += optind;
argc -= optind;
for (int i = 0; i < argc; i++)
2023-10-21 15:27:42 +03:00
du(argv[i], 0);
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
}
2023-10-21 15:05:49 +03:00
return 0;
}
2023-11-06 23:52:48 +03:00