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