Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/du.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 23  Line 23 
23   * 4) Fixed busybox bug #1284 involving long overflow with human_readable.   * 4) Fixed busybox bug #1284 involving long overflow with human_readable.
24   */   */
25    
26  #include "busybox.h"  #include "libbb.h"
27    
28    struct globals {
29  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
30  # if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K   unsigned long disp_hr;
 static unsigned long disp_hr = 1024;  
 # else  
 static unsigned long disp_hr = 512;  
 # endif  
 #elif ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K  
 static unsigned disp_k = 1;  
31  #else  #else
32  static unsigned disp_k; /* bss inits to 0 */   unsigned disp_k;
33  #endif  #endif
34    
35  static int max_print_depth = INT_MAX;   int max_print_depth;
36  static nlink_t count_hardlinks = 1;   nlink_t count_hardlinks;
37    
38  static int status;   bool status;
39  static int print_files;   bool one_file_system;
40  static int slink_depth;   int print_files;
41  static int du_depth;   int slink_depth;
42  static int one_file_system;   int du_depth;
43  static dev_t dir_dev;   dev_t dir_dev;
44    };
45    #define G (*(struct globals*)&bb_common_bufsiz1)
46    
47    
48  static void print(long size, const char * const filename)  static void print(unsigned long size, const char *filename)
49  {  {
50   /* TODO - May not want to defer error checking here. */   /* TODO - May not want to defer error checking here. */
51  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
52   printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),   printf("%s\t%s\n", make_human_readable_str(size, 512, G.disp_hr),
53   filename);   filename);
54  #else  #else
55   if (disp_k) {   if (G.disp_k) {
56   size++;   size++;
57   size >>= 1;   size >>= 1;
58   }   }
# Line 64  static void print(long size, const char Line 61  static void print(long size, const char
61  }  }
62    
63  /* tiny recursive du */  /* tiny recursive du */
64  static long du(const char * const filename)  static unsigned long du(const char *filename)
65  {  {
66   struct stat statbuf;   struct stat statbuf;
67   long sum;   unsigned long sum;
68    
69   if (lstat(filename, &statbuf) != 0) {   if (lstat(filename, &statbuf) != 0) {
70   bb_perror_msg("%s", filename);   bb_simple_perror_msg(filename);
71   status = EXIT_FAILURE;   G.status = EXIT_FAILURE;
72   return 0;   return 0;
73   }   }
74    
75   if (one_file_system) {   if (G.one_file_system) {
76   if (du_depth == 0) {   if (G.du_depth == 0) {
77   dir_dev = statbuf.st_dev;   G.dir_dev = statbuf.st_dev;
78   } else if (dir_dev != statbuf.st_dev) {   } else if (G.dir_dev != statbuf.st_dev) {
79   return 0;   return 0;
80   }   }
81   }   }
# Line 86  static long du(const char * const filena Line 83  static long du(const char * const filena
83   sum = statbuf.st_blocks;   sum = statbuf.st_blocks;
84    
85   if (S_ISLNK(statbuf.st_mode)) {   if (S_ISLNK(statbuf.st_mode)) {
86   if (slink_depth > du_depth) { /* -H or -L */   if (G.slink_depth > G.du_depth) { /* -H or -L */
87   if (stat(filename, &statbuf) != 0) {   if (stat(filename, &statbuf) != 0) {
88   bb_perror_msg("%s", filename);   bb_simple_perror_msg(filename);
89   status = EXIT_FAILURE;   G.status = EXIT_FAILURE;
90   return 0;   return 0;
91   }   }
92   sum = statbuf.st_blocks;   sum = statbuf.st_blocks;
93   if (slink_depth == 1) {   if (G.slink_depth == 1) {
94   slink_depth = INT_MAX; /* Convert -H to -L. */   G.slink_depth = INT_MAX; /* Convert -H to -L. */
95   }   }
96   }   }
97   }   }
98    
99   if (statbuf.st_nlink > count_hardlinks) {   if (statbuf.st_nlink > G.count_hardlinks) {
100   /* Add files/directories with links only once */   /* Add files/directories with links only once */
101   if (is_in_ino_dev_hashtable(&statbuf, NULL)) {   if (is_in_ino_dev_hashtable(&statbuf)) {
102   return 0;   return 0;
103   }   }
104   add_to_ino_dev_hashtable(&statbuf, NULL);   add_to_ino_dev_hashtable(&statbuf, NULL);
# Line 114  static long du(const char * const filena Line 111  static long du(const char * const filena
111    
112   dir = warn_opendir(filename);   dir = warn_opendir(filename);
113   if (!dir) {   if (!dir) {
114   status = EXIT_FAILURE;   G.status = EXIT_FAILURE;
115   return sum;   return sum;
116   }   }
117    
# Line 128  static long du(const char * const filena Line 125  static long du(const char * const filena
125   newfile = concat_subpath_file(filename, name);   newfile = concat_subpath_file(filename, name);
126   if (newfile == NULL)   if (newfile == NULL)
127   continue;   continue;
128   ++du_depth;   ++G.du_depth;
129   sum += du(newfile);   sum += du(newfile);
130   --du_depth;   --G.du_depth;
131   free(newfile);   free(newfile);
132   }   }
133   closedir(dir);   closedir(dir);
134   } else if (du_depth > print_files) {   } else if (G.du_depth > G.print_files) {
135   return sum;   return sum;
136   }   }
137   if (du_depth <= max_print_depth) {   if (G.du_depth <= G.max_print_depth) {
138   print(sum, filename);   print(sum, filename);
139   }   }
140   return sum;   return sum;
141  }  }
142    
143  int du_main(int argc, char **argv)  int du_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
144    int du_main(int argc UNUSED_PARAM, char **argv)
145  {  {
146   long total;   unsigned long total;
147   int slink_depth_save;   int slink_depth_save;
148   int print_final_total;   bool print_final_total;
  char *smax_print_depth;  
149   unsigned opt;   unsigned opt;
150    
 #if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K  
  if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */  
151  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
152   disp_hr = 512;   USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;)
153     SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;)
154     if (getenv("POSIXLY_CORRECT"))  /* TODO - a new libbb function? */
155     G.disp_hr = 512;
156  #else  #else
157   disp_k = 0;   USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)
158  #endif   /* SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */
  }  
159  #endif  #endif
160     G.max_print_depth = INT_MAX;
161     G.count_hardlinks = 1;
162    
163   /* Note: SUSv3 specifies that -a and -s options cannot be used together   /* Note: SUSv3 specifies that -a and -s options cannot be used together
164   * in strictly conforming applications.  However, it also says that some   * in strictly conforming applications.  However, it also says that some
# Line 168  int du_main(int argc, char **argv) Line 167  int du_main(int argc, char **argv)
167   * ignore -a.  This is consistent with -s being equivalent to -d 0.   * ignore -a.  This is consistent with -s being equivalent to -d 0.
168   */   */
169  #if ENABLE_FEATURE_HUMAN_READABLE  #if ENABLE_FEATURE_HUMAN_READABLE
170   opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s";   opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+";
171   opt = getopt32(argc, argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth);   opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
172     argv += optind;
173   if (opt & (1 << 9)) {   if (opt & (1 << 9)) {
174   /* -h opt */   /* -h opt */
175   disp_hr = 0;   G.disp_hr = 0;
176   }   }
177   if (opt & (1 << 10)) {   if (opt & (1 << 10)) {
178   /* -m opt */   /* -m opt */
179   disp_hr = 1024*1024;   G.disp_hr = 1024*1024;
180   }   }
181   if (opt & (1 << 2)) {   if (opt & (1 << 2)) {
182   /* -k opt */   /* -k opt */
183   disp_hr = 1024;   G.disp_hr = 1024;
184   }   }
185  #else  #else
186   opt_complementary = "H-L:L-H:s-d:d-s";   opt_complementary = "H-L:L-H:s-d:d-s:d+";
187   opt = getopt32(argc, argv, "aHkLsx" "d:" "lc", &smax_print_depth);   opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth);
188     argv += optind;
189  #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K  #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
190   if (opt & (1 << 2)) {   if (opt & (1 << 2)) {
191   /* -k opt */   /* -k opt */
192   disp_k = 1;   G.disp_k = 1;
193   }   }
194  #endif  #endif
195  #endif  #endif
196   if (opt & (1 << 0)) {   if (opt & (1 << 0)) {
197   /* -a opt */   /* -a opt */
198   print_files = INT_MAX;   G.print_files = INT_MAX;
199   }   }
200   if (opt & (1 << 1)) {   if (opt & (1 << 1)) {
201   /* -H opt */   /* -H opt */
202   slink_depth = 1;   G.slink_depth = 1;
203   }   }
204   if (opt & (1 << 3)) {   if (opt & (1 << 3)) {
205   /* -L opt */   /* -L opt */
206   slink_depth = INT_MAX;   G.slink_depth = INT_MAX;
207   }   }
208   if (opt & (1 << 4)) {   if (opt & (1 << 4)) {
209   /* -s opt */   /* -s opt */
210   max_print_depth = 0;   G.max_print_depth = 0;
  }  
  one_file_system = opt & (1 << 5); /* -x opt */  
  if (opt & (1 << 6)) {  
  /* -d opt */  
  max_print_depth = xatoi_u(smax_print_depth);  
211   }   }
212     G.one_file_system = opt & (1 << 5); /* -x opt */
213   if (opt & (1 << 7)) {   if (opt & (1 << 7)) {
214   /* -l opt */   /* -l opt */
215   count_hardlinks = MAXINT(nlink_t);   G.count_hardlinks = MAXINT(nlink_t);
216   }   }
217   print_final_total = opt & (1 << 8); /* -c opt */   print_final_total = opt & (1 << 8); /* -c opt */
218    
219   /* go through remaining args (if any) */   /* go through remaining args (if any) */
220   argv += optind;   if (!*argv) {
221   if (optind >= argc) {   *--argv = (char*)".";
222   *--argv = ".";   if (G.slink_depth == 1) {
223   if (slink_depth == 1) {   G.slink_depth = 0;
  slink_depth = 0;  
224   }   }
225   }   }
226    
227   slink_depth_save = slink_depth;   slink_depth_save = G.slink_depth;
228   total = 0;   total = 0;
229   do {   do {
230   total += du(*argv);   total += du(*argv);
231   slink_depth = slink_depth_save;   G.slink_depth = slink_depth_save;
232   } while (*++argv);   } while (*++argv);
 #if ENABLE_FEATURE_CLEAN_UP  
  reset_ino_dev_hashtable();  
 #endif  
233    
234   if (print_final_total) {   if (ENABLE_FEATURE_CLEAN_UP)
235     reset_ino_dev_hashtable();
236     if (print_final_total)
237   print(total, "total");   print(total, "total");
  }  
238    
239   fflush_stdout_and_exit(status);   fflush_stdout_and_exit(G.status);
240  }  }

Legend:
Removed from v.532  
changed lines
  Added in v.816