acmecert: Treat pending as processing for a few retries...
[utils.git] / bkselect.c
... / ...
CommitLineData
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 <sys/xattr.h>
9
10int printsize = 0;
11int printnames = 1;
12long long tsize = 0;
13
14int 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;
25 if((al = getxattr(path, "user.bkselect", ab, sizeof(ab))) < 0) {
26 if(errno == ENODATA) {
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)) {
72 if(s) {
73 if(printnames)
74 printf("%s\n", pb);
75 tsize += sb.st_size;
76 }
77 }
78 }
79
80 closedir(d);
81 return(r);
82}
83
84void usage(void)
85{
86 fprintf(stderr, "usage: bkselect [-hsqo] [path...]\n");
87}
88
89int main(int argc, char **argv)
90{
91 int c, i, r, s;
92
93 s = 1;
94 while((c = getopt(argc, argv, "hsqo")) >= 0) {
95 switch(c) {
96 case 's':
97 printsize = 1;
98 break;
99 case 'q':
100 printnames = 0;
101 break;
102 case 'o':
103 s = 0;
104 break;
105 case 'h':
106 default:
107 usage();
108 exit((c == 'h')?0:1);
109 }
110 }
111 if(argc - optind < 1) {
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 }
119 }
120 if(printsize)
121 printf("%lli\n", tsize);
122 return(r);
123}