1ba19398 |
1 | #include <stdlib.h> |
2 | #include <stdio.h> |
3 | #include <unistd.h> |
4 | #include <errno.h> |
5 | #include <dirent.h> |
6 | #include <string.h> |
7 | #include <sys/stat.h> |
8 | #include <attr/xattr.h> |
9 | #include <attr/attributes.h> |
10 | |
0b768200 |
11 | int printsize = 0; |
12 | int printnames = 1; |
13 | long long tsize = 0; |
14 | |
1ba19398 |
15 | int bkselect(char *path, int s) |
16 | { |
17 | DIR *d; |
18 | int r; |
19 | struct dirent *de; |
20 | struct stat sb; |
21 | char *pb; |
22 | char ab[16]; |
23 | int pbl, pl, al; |
24 | |
25 | al = sizeof(ab) - 1; |
26 | if(attr_get(path, "bkselect", ab, &al, 0)) { |
27 | if(errno == ENOATTR) { |
28 | } else if(errno == EPERM) { |
29 | /* Ignore for now because of weird effects... */ |
30 | } else if(errno == E2BIG) { |
31 | fprintf(stderr, "warning: bad bkselect value on %s", path); |
32 | } else { |
33 | perror(path); |
34 | return(1); |
35 | } |
36 | } else { |
37 | ab[al] = 0; |
38 | if(!strcmp(ab, "y")) { |
39 | s = 1; |
40 | } else if(!strcmp(ab, "n")) { |
41 | s = 0; |
42 | } else { |
43 | fprintf(stderr, "warning: bad bkselect value on %s", path); |
44 | } |
45 | } |
46 | |
47 | if((d = opendir(path)) == NULL) { |
48 | perror(path); |
49 | return(1); |
50 | } |
51 | |
52 | r = 0; |
53 | pl = strlen(path); |
54 | pb = malloc(pbl = pl + 2); |
55 | strcpy(pb, path); |
56 | pb[pl] = '/'; |
57 | while((de = readdir(d)) != NULL) { |
58 | if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) |
59 | continue; |
60 | if(strlen(de->d_name) + pl + 2 > pbl) { |
61 | pbl = strlen(de->d_name) + pl + 2; |
62 | pb = realloc(pb, pbl); |
63 | } |
64 | strcpy(pb + pl + 1, de->d_name); |
65 | if(lstat(pb, &sb)) { |
66 | perror(pb); |
67 | continue; |
68 | } |
69 | if(S_ISDIR(sb.st_mode)) { |
70 | if(bkselect(pb, s)) |
71 | r = 1; |
72 | } else if(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) { |
15f697c9 |
73 | if(s) { |
74 | if(printnames) |
75 | printf("%s\n", pb); |
76 | tsize += sb.st_size; |
77 | } |
1ba19398 |
78 | } |
79 | } |
80 | |
81 | closedir(d); |
82 | return(r); |
83 | } |
84 | |
0b768200 |
85 | void usage(void) |
86 | { |
15f697c9 |
87 | fprintf(stderr, "usage: bkselect [-hsqo] path...\n"); |
0b768200 |
88 | } |
89 | |
1ba19398 |
90 | int main(int argc, char **argv) |
91 | { |
15f697c9 |
92 | int c, i, r, s; |
1ba19398 |
93 | |
15f697c9 |
94 | s = 1; |
95 | while((c = getopt(argc, argv, "hsqo")) >= 0) { |
0b768200 |
96 | switch(c) { |
97 | case 's': |
98 | printsize = 1; |
99 | break; |
100 | case 'q': |
101 | printnames = 0; |
102 | break; |
15f697c9 |
103 | case 'o': |
104 | s = 0; |
105 | break; |
0b768200 |
106 | case 'h': |
107 | default: |
108 | usage(); |
109 | exit((c == 'h')?0:1); |
110 | } |
111 | } |
112 | if(argc - optind < 1) { |
113 | usage(); |
1ba19398 |
114 | exit(1); |
115 | } |
116 | r = 0; |
0b768200 |
117 | for(i = optind; i < argc; i++) { |
15f697c9 |
118 | if(bkselect(argv[i], s)) |
1ba19398 |
119 | r = 1; |
120 | } |
0b768200 |
121 | if(printsize) |
122 | printf("%lli\n", tsize); |
1ba19398 |
123 | return(r); |
124 | } |