ann.py: Further improvements.
[utils.git] / bkselect.c
CommitLineData
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 10int printsize = 0;
11int printnames = 1;
12long long tsize = 0;
13
1ba19398 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;
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 84void usage(void)
85{
30449be1 86 fprintf(stderr, "usage: bkselect [-hsqo] [path...]\n");
0b768200 87}
88
1ba19398 89int 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}