annotate toys/posix/du.c @ 658:2b957eaa00c7

Add du command.
author Ashwini Kumar <ak.ashwini@gmail.com>
date Sun, 26 Aug 2012 21:17:00 -0500
parents
children 7e846e281e38
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
658
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
1 /* vi: set sw=4 ts=4:
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
2 *
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
3 * du.c - disk usage program.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
4 *
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
5 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
6 *
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
7 * See http://opengroup.org/onlinepubs/9699919799/utilities/du.html
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
8
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
9 USE_DU(NEWTOY(du, "d#<0hmlcaHkLsx", TOYFLAG_USR|TOYFLAG_BIN))
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
10
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
11 config DU
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
12 bool "du"
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
13 default y
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
14 help
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
15 usage: du [-d N] [-askxHLlmc] [file...]
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
16
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
17 Estimate file space usage (default in unit of 512 blocks).
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
18 -a Show all file sizes
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
19 -H Follow symlinks on cmdline
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
20 -L Follow all symlinks
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
21 -k Show size in units of 1024.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
22 -s Show only the total Size for each file specified
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
23 -x Estimate size only on the same device
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
24 -c Print total size of all arguments
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
25 -d N Limit output to directories (and files with -a) of depth < N
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
26 -l Count sizes many times if hard linked
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
27 -h Sizes in human readable format (e.g., 1K 243M 2G )
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
28 -m Sizes in megabytes
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
29 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
30
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
31 #include "toys.h"
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
32
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
33 DEFINE_GLOBALS(
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
34 long maxdepth;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
35 long depth;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
36 long *dirsum;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
37 long total;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
38 dev_t st_dev;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
39 struct arg_list *inodes;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
40 )
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
41
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
42 #define TT this.du
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
43
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
44 #define FLAG_x 1
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
45 #define FLAG_s 2
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
46 #define FLAG_L 4
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
47 #define FLAG_k 8
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
48 #define FLAG_H 16
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
49 #define FLAG_a 32
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
50 #define FLAG_c 64
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
51 #define FLAG_l 128
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
52 #define FLAG_m 256
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
53 #define FLAG_h 512
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
54 #define FLAG_d 1024
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
55
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
56 typedef struct node_size {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
57 struct dirtree *node;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
58 long size;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
59 }node_size;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
60
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
61 typedef struct inode_ent {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
62 ino_t ino;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
63 dev_t dev;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
64 }inode_ent_t;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
65
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
66 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
67 * Adding '/' to the name if name is '.' or '..'
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
68 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
69
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
70 char *make_pathproper(char *str)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
71 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
72 char *path = str;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
73 switch(strlen(str)) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
74 case 1:
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
75 if(str[0] == '.') path = xstrdup("./");
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
76 break;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
77 case 2:
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
78 if(str[0] == '.' && str[1] == '.') path = xstrdup("../");
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
79 break;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
80 default:
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
81 break;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
82 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
83 return path;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
84 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
85
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
86 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
87 * Print the size of the given entry in specified format, default in blocks of 512 bytes
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
88 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
89 void print(long size, char* name)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
90 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
91 unsigned long long tempsize = (unsigned long long)size * 512;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
92 unsigned long unit = 512;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
93 char *sizestr = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
94 if(TT.depth > TT.maxdepth) return;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
95 if(toys.optflags & FLAG_h) unit = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
96 if(toys.optflags & FLAG_k) unit = 1024;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
97 if(toys.optflags & FLAG_m) unit = 1024*1024;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
98 sizestr = make_human_readable(tempsize, unit); //make human readable string, depending upon unit size.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
99 xprintf("%s\t%s\n",sizestr, name);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
100 free(sizestr);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
101 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
102
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
103 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
104 * free the inodes which are stored for hard link reference
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
105 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
106 void free_inodes(void *data)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
107 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
108 void *arg = ((struct arg_list*)data)->arg;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
109 if(arg) free(arg);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
110 free(data);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
111 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
112
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
113 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
114 * allocate and add a node to the list
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
115 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
116 static void llist_add_inode(struct arg_list **old, void *data)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
117 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
118 struct arg_list *new = xmalloc(sizeof(struct arg_list));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
119
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
120 new->arg = (char*)data;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
121 new->next = *old;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
122 *old = new;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
123 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
124
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
125 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
126 * check if the given stat entry is already there in list or not
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
127 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
128 int is_inode_present(struct stat *st)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
129 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
130 struct arg_list *temparg = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
131 inode_ent_t *ent = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
132 if(!TT.inodes) return 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
133 for(temparg = TT.inodes; temparg; temparg = (struct arg_list *)temparg->next) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
134 ent = (inode_ent_t*)temparg->arg;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
135 if(ent && ent->ino == st->st_ino && ent->dev == st->st_dev) return 1;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
136 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
137 return 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
138 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
139
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
140 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
141 * Compute the size of the node
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
142 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
143 int do_du(struct dirtree *node)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
144 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
145 inode_ent_t *ino_details = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
146 node_size *nd = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
147 if(!dirtree_notdotdot(node)) return 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
148 if((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev)) //if file not on same device, don't count size
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
149 return DIRTREE_RECURSE;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
150
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
151 if(!(toys.optflags & FLAG_l) && node->st.st_nlink > 1 && !node->extra) { //keeping reference for hard links
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
152 if(is_inode_present(&node->st)) return DIRTREE_RECURSE;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
153 ino_details = xzalloc(sizeof(inode_ent_t));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
154 ino_details->ino = node->st.st_ino;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
155 ino_details->dev = node->st.st_dev;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
156 llist_add_inode(&TT.inodes, (void*)ino_details);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
157 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
158
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
159 if(S_ISDIR(node->st.st_mode)) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
160 if(!(node->extra && (long)((node_size*)(node->extra))->node == (long)node)) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
161 nd = xzalloc(sizeof(node_size));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
162 nd->node = node;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
163 nd->size = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
164 TT.dirsum = (long*)&(nd->size);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
165 node->extra = (long)nd;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
166 *TT.dirsum = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
167 TT.depth++;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
168 return (DIRTREE_RECURSE|DIRTREE_COMEAGAIN | ((toys.optflags & FLAG_L) ? DIRTREE_SYMFOLLOW : 0)); //DIRTREE_COMEAGAIN to comeback and print the entry.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
169 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
170 else if(node->extra) { //extra is set for a returning DIR entry.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
171 long offset = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
172 nd = (node_size*)node->extra;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
173 offset = nd->size;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
174 nd->size += node->st.st_blocks;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
175 TT.depth--;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
176 if(!(toys.optflags & FLAG_s))
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
177 print(*TT.dirsum, dirtree_path(node, NULL));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
178 if((node->parent) && (node->parent->extra)) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
179 /* when returning from internal directory, get the saved size of the parent and continue from there */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
180 nd = (node_size*)node->parent->extra;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
181 TT.dirsum = (long*)&(nd->size);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
182 *TT.dirsum += offset;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
183 *TT.dirsum += node->st.st_blocks;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
184 return DIRTREE_RECURSE;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
185 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
186 else if(!node->parent) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
187 /*if node has no parent, it means it is the top in the tree, stop recursing here */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
188 TT.total += *TT.dirsum;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
189 if((toys.optflags & FLAG_s))
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
190 print(*TT.dirsum, dirtree_path(node, NULL));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
191 return 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
192 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
193 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
194 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
195 else if(!(node->parent)) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
196 /* this is the file specified on cmdline */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
197 TT.total += node->st.st_blocks;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
198 print(node->st.st_blocks, dirtree_path(node, NULL));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
199 return 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
200 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
201 if(TT.dirsum) *TT.dirsum += node->st.st_blocks;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
202 if(toys.optflags & FLAG_a && !(toys.optflags & FLAG_s))
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
203 print(node->st.st_blocks, dirtree_path(node, NULL));
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
204 return DIRTREE_RECURSE;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
205 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
206
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
207 /*
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
208 * DU utility main function
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
209 */
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
210 void du_main(void)
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
211 {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
212 int symfollow = toys.optflags & (FLAG_H | FLAG_L);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
213 TT.total = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
214 TT.inodes = NULL;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
215
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
216 if(!(toys.optflags & FLAG_d)) TT.maxdepth = INT_MAX;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
217 if(toys.optc == 0) toys.optargs[0] = "./";
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
218 while(*toys.optargs) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
219 TT.depth = 0;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
220 char *path = make_pathproper(*toys.optargs);
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
221 struct dirtree *root = dirtree_add_node(AT_FDCWD, path, symfollow); //create a node
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
222 if(root) {
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
223 TT.st_dev = root->st.st_dev;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
224 handle_callback(root, do_du); //this will recurse thru the DIR children.
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
225 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
226 toys.optargs++;
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
227 }
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
228 if(TT.inodes) llist_traverse(TT.inodes, free_inodes); //free the stored nodes
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
229 if(toys.optflags & FLAG_c) print(TT.total, "total");
2b957eaa00c7 Add du command.
Ashwini Kumar <ak.ashwini@gmail.com>
parents:
diff changeset
230 }