X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=coreutils%2Fdu.c;h=3f7621b3de2ac1972cb8502bd183a0e7b64fa526;hb=6aabfd5e30087bb0ffdb6404aa6d650014de2dc0;hp=9e4e11473437f081f43f622356d378e69e46113c;hpb=0f5e1ab949193ee7b6228bc66730da9d573464eb;p=oweals%2Fbusybox.git diff --git a/coreutils/du.c b/coreutils/du.c index 9e4e11473..3f7621b3d 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -1,9 +1,10 @@ +/* vi: set sw=4 ts=4: */ /* * Mini du implementation for busybox * * - * Copyright (C) 1999 by Lineo, inc. - * Written by John Beppu + * Copyright (C) 1999,2000,2001 by Lineo, inc. + * Written by John Beppu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,63 +22,178 @@ * */ -#include "internal.h" #include #include #include #include -/* -#include -#include -*/ +#include +#include +#include +#include +#include "busybox.h" + + +#ifdef BB_FEATURE_HUMAN_READABLE +static unsigned long disp_hr = KILOBYTE; +#endif + +typedef void (Display) (long, char *); + +static int du_depth = 0; +static int count_hardlinks = 0; +static Display *print; -typedef void (Display)(size_t, char *); +static void print_normal(long size, char *filename) +{ + unsigned long base; +#ifdef BB_FEATURE_HUMAN_READABLE + switch (disp_hr) { + case MEGABYTE: + base = KILOBYTE; + break; + case KILOBYTE: + base = 1; + break; + default: + base = 0; + } + printf("%s\t%s\n", make_human_readable_str(size, base), filename); +#else + printf("%ld\t%s\n", size, filename); +#endif +} -static void -print(size_t size, char *filename) +static void print_summary(long size, char *filename) { - fprintf(stdout, "%-7d %s\n", (size >> 1), filename); + if (du_depth == 1) { + printf("summary\n"); + print_normal(size, filename); + } } /* tiny recursive du */ -static size_t -size(char *filename) +static long du(char *filename) { - struct stat statbuf; - size_t sum; + struct stat statbuf; + long sum; + int len; + + if ((lstat(filename, &statbuf)) != 0) { + perror_msg("%s", filename); + return 0; + } - if ((lstat(filename, &statbuf)) != 0) { return 0; } - sum = statbuf.st_blocks; + du_depth++; + sum = (statbuf.st_blocks >> 1); - if (S_ISDIR(statbuf.st_mode)) { - DIR *dir; - struct dirent *entry; + /* Don't add in stuff pointed to by symbolic links */ + if (S_ISLNK(statbuf.st_mode)) { + sum = 0L; + if (du_depth == 1) + print(sum, filename); + } + if (S_ISDIR(statbuf.st_mode)) { + DIR *dir; + struct dirent *entry; + + dir = opendir(filename); + if (!dir) { + du_depth--; + return 0; + } - dir = opendir(filename); - if (!dir) { return 0; } - while ((entry = readdir(dir))) { - char newfile[512]; - char *name = entry->d_name; + len = strlen(filename); + if (filename[len - 1] == '/') + filename[--len] = '\0'; - if ( (strcmp(name, "..") == 0) - || (strcmp(name, ".") == 0)) - { continue; } + while ((entry = readdir(dir))) { + char *newfile; + char *name = entry->d_name; - sprintf(newfile, "%s/%s", filename, name); - sum += size(newfile); + if ((strcmp(name, "..") == 0) + || (strcmp(name, ".") == 0)) { + continue; + } + newfile = concat_path_file(filename, name); + sum += du(newfile); + free(newfile); + } + closedir(dir); + print(sum, filename); + } + else if (statbuf.st_nlink > 1 && !count_hardlinks) { + /* Add files with hard links only once */ + if (is_in_ino_dev_hashtable(&statbuf, NULL)) { + sum = 0L; + if (du_depth == 1) + print(sum, filename); + } + else { + add_to_ino_dev_hashtable(&statbuf, NULL); + } } - closedir(dir); - print(sum, filename); - } - return sum; + du_depth--; + return sum; } -int -du_main(int argc, char **argv) +int du_main(int argc, char **argv) { - /* I'll fill main() in shortly */ - size("."); - exit(0); + int status = EXIT_SUCCESS; + int i; + int c; + + /* default behaviour */ + print = print_normal; + + /* parse argv[] */ + while ((c = getopt(argc, argv, "sl" +#ifdef BB_FEATURE_HUMAN_READABLE +"hm" +#endif +"k")) != EOF) { + switch (c) { + case 's': + print = print_summary; + break; + case 'l': + count_hardlinks = 1; + break; +#ifdef BB_FEATURE_HUMAN_READABLE + case 'h': disp_hr = 0; break; + case 'm': disp_hr = MEGABYTE; break; +#endif + case 'k': break; + default: + show_usage(); + } + } + + /* go through remaining args (if any) */ + if (optind >= argc) { + if (du(".") == 0) + status = EXIT_FAILURE; + } else { + long sum; + + for (i=optind; i < argc; i++) { + if ((sum = du(argv[i])) == 0) + status = EXIT_FAILURE; + if(is_directory(argv[i], FALSE, NULL)==FALSE) { + print_normal(sum, argv[i]); + } + reset_ino_dev_hashtable(); + } + } + + return status; } +/* $Id: du.c,v 1.45 2001/04/25 05:39:18 andersen Exp $ */ +/* +Local Variables: +c-file-style: "linux" +c-basic-offset: 4 +tab-width: 4 +End: +*/