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)) { |
0b768200 |
73 | if(s && printnames) |
1ba19398 |
74 | printf("%s\n", pb); |
0b768200 |
75 | tsize += sb.st_size; |
1ba19398 |
76 | } |
77 | } |
78 | |
79 | closedir(d); |
80 | return(r); |
81 | } |
82 | |
0b768200 |
83 | void usage(void) |
84 | { |
85 | fprintf(stderr, "usage: bkselect [-hsq] path...\n"); |
86 | } |
87 | |
1ba19398 |
88 | int main(int argc, char **argv) |
89 | { |
0b768200 |
90 | int c, i, r; |
1ba19398 |
91 | |
0b768200 |
92 | while((c = getopt(argc, argv, "hsq")) >= 0) { |
93 | switch(c) { |
94 | case 's': |
95 | printsize = 1; |
96 | break; |
97 | case 'q': |
98 | printnames = 0; |
99 | break; |
100 | case 'h': |
101 | default: |
102 | usage(); |
103 | exit((c == 'h')?0:1); |
104 | } |
105 | } |
106 | if(argc - optind < 1) { |
107 | usage(); |
1ba19398 |
108 | exit(1); |
109 | } |
110 | r = 0; |
0b768200 |
111 | for(i = optind; i < argc; i++) { |
1ba19398 |
112 | if(bkselect(argv[i], 0)) |
113 | r = 1; |
114 | } |
0b768200 |
115 | if(printsize) |
116 | printf("%lli\n", tsize); |
1ba19398 |
117 | return(r); |
118 | } |