diff options
Diffstat (limited to 'du.c')
-rw-r--r-- | du.c | 62 |
1 files changed, 58 insertions, 4 deletions
@@ -36,18 +36,32 @@ | |||
36 | 36 | ||
37 | typedef void (Display) (long, char *); | 37 | typedef void (Display) (long, char *); |
38 | 38 | ||
39 | static const char du_usage[] = | 39 | typedef 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 | ||
47 | static INODETYPE *inode_hash_list[HASH_SIZE]; | ||
48 | |||
49 | static 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 | ||
44 | static int du_depth = 0; | 57 | static int du_depth = 0; |
58 | static int count_hardlinks = 0; | ||
45 | 59 | ||
46 | static Display *print; | 60 | static Display *print; |
47 | 61 | ||
48 | static void print_normal(long size, char *filename) | 62 | static 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 | ||
53 | static void print_summary(long size, char *filename) | 67 | static 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 */ | ||
75 | static 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 */ | ||
90 | static 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 */ |
62 | static long du(char *filename) | 106 | static 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 $ */ |