aboutsummaryrefslogtreecommitdiff
path: root/du.c
diff options
context:
space:
mode:
Diffstat (limited to 'du.c')
-rw-r--r--du.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/du.c b/du.c
index 7b5acb490..02d1d9737 100644
--- a/du.c
+++ b/du.c
@@ -36,18 +36,32 @@
36 36
37typedef void (Display) (long, char *); 37typedef void (Display) (long, char *);
38 38
39static const char du_usage[] = 39typedef struct inode_type {
40 struct inode_type *next;
41 ino_t ino;
42} INODETYPE;
43
44#define HASH_SIZE 311 /* Should be prime */
45#define hash_inode(i) ((i) % HASH_SIZE)
40 46
47static INODETYPE *inode_hash_list[HASH_SIZE];
48
49static const char du_usage[] =
41 "du [OPTION]... [FILE]...\n\n" 50 "du [OPTION]... [FILE]...\n\n"
51 "Summarize disk space used for each FILE and/or directory.\n"
52 "Disk space is printed in units of 1024 bytes.\n\n"
53 "Options:\n"
54 "\t-l\tcount sizes many times if hard linked\n"
42 "\t-s\tdisplay only a total for each argument\n"; 55 "\t-s\tdisplay only a total for each argument\n";
43 56
44static int du_depth = 0; 57static int du_depth = 0;
58static int count_hardlinks = 0;
45 59
46static Display *print; 60static Display *print;
47 61
48static void print_normal(long size, char *filename) 62static void print_normal(long size, char *filename)
49{ 63{
50 fprintf(stdout, "%-7ld %s\n", size, filename); 64 fprintf(stdout, "%ld\t%s\n", size, filename);
51} 65}
52 66
53static void print_summary(long size, char *filename) 67static void print_summary(long size, char *filename)
@@ -57,6 +71,36 @@ static void print_summary(long size, char *filename)
57 } 71 }
58} 72}
59 73
74/* Return 1 if inode is in inode hash list, else return 0 */
75static int is_in_list(const ino_t ino)
76{
77 INODETYPE *inode;
78
79 inode = inode_hash_list[hash_inode(ino)];
80 while (inode != NULL) {
81 if (inode->ino == ino)
82 return 1;
83 inode = inode->next;
84 }
85
86 return 0;
87}
88
89/* Add inode to inode hash list */
90static void add_inode(const ino_t ino)
91{
92 int i;
93 INODETYPE *inode;
94
95 i = hash_inode(ino);
96 inode = malloc(sizeof(INODETYPE));
97 if (inode == NULL)
98 fatalError("du: Not enough memory.");
99
100 inode->ino = ino;
101 inode->next = inode_hash_list[i];
102 inode_hash_list[i] = inode;
103}
60 104
61/* tiny recursive du */ 105/* tiny recursive du */
62static long du(char *filename) 106static long du(char *filename)
@@ -72,7 +116,7 @@ static long du(char *filename)
72 du_depth++; 116 du_depth++;
73 sum = (statbuf.st_blocks >> 1); 117 sum = (statbuf.st_blocks >> 1);
74 118
75 /* Don't add in stuff pointed to by links */ 119 /* Don't add in stuff pointed to by symbolic links */
76 if (S_ISLNK(statbuf.st_mode)) { 120 if (S_ISLNK(statbuf.st_mode)) {
77 return 0; 121 return 0;
78 } 122 }
@@ -104,6 +148,12 @@ static long du(char *filename)
104 closedir(dir); 148 closedir(dir);
105 print(sum, filename); 149 print(sum, filename);
106 } 150 }
151 else if (statbuf.st_nlink > 1 && !count_hardlinks) {
152 /* Add files with hard links only once */
153 if (is_in_list(statbuf.st_ino))
154 return 0;
155 add_inode(statbuf.st_ino);
156 }
107 du_depth--; 157 du_depth--;
108 return sum; 158 return sum;
109} 159}
@@ -124,7 +174,11 @@ int du_main(int argc, char **argv)
124 case 's': 174 case 's':
125 print = print_summary; 175 print = print_summary;
126 break; 176 break;
177 case 'l':
178 count_hardlinks = 1;
179 break;
127 case 'h': 180 case 'h':
181 case '-':
128 usage(du_usage); 182 usage(du_usage);
129 break; 183 break;
130 default: 184 default:
@@ -153,4 +207,4 @@ int du_main(int argc, char **argv)
153 exit(0); 207 exit(0);
154} 208}
155 209
156/* $Id: du.c,v 1.13 2000/02/13 04:10:57 beppu Exp $ */ 210/* $Id: du.c,v 1.14 2000/02/19 18:16:49 erik Exp $ */