Initial import.
[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>
8#include <attr/xattr.h>
9#include <attr/attributes.h>
10
11int bkselect(char *path, int s)
12{
13 DIR *d;
14 int r;
15 struct dirent *de;
16 struct stat sb;
17 char *pb;
18 char ab[16];
19 int pbl, pl, al;
20
21 al = sizeof(ab) - 1;
22 if(attr_get(path, "bkselect", ab, &al, 0)) {
23 if(errno == ENOATTR) {
24 } else if(errno == EPERM) {
25 /* Ignore for now because of weird effects... */
26 } else if(errno == E2BIG) {
27 fprintf(stderr, "warning: bad bkselect value on %s", path);
28 } else {
29 perror(path);
30 return(1);
31 }
32 } else {
33 ab[al] = 0;
34 if(!strcmp(ab, "y")) {
35 s = 1;
36 } else if(!strcmp(ab, "n")) {
37 s = 0;
38 } else {
39 fprintf(stderr, "warning: bad bkselect value on %s", path);
40 }
41 }
42
43 if((d = opendir(path)) == NULL) {
44 perror(path);
45 return(1);
46 }
47
48 r = 0;
49 pl = strlen(path);
50 pb = malloc(pbl = pl + 2);
51 strcpy(pb, path);
52 pb[pl] = '/';
53 while((de = readdir(d)) != NULL) {
54 if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
55 continue;
56 if(strlen(de->d_name) + pl + 2 > pbl) {
57 pbl = strlen(de->d_name) + pl + 2;
58 pb = realloc(pb, pbl);
59 }
60 strcpy(pb + pl + 1, de->d_name);
61 if(lstat(pb, &sb)) {
62 perror(pb);
63 continue;
64 }
65 if(S_ISDIR(sb.st_mode)) {
66 if(bkselect(pb, s))
67 r = 1;
68 } else if(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) {
69 if(s)
70 printf("%s\n", pb);
71 }
72 }
73
74 closedir(d);
75 return(r);
76}
77
78int main(int argc, char **argv)
79{
80 int i, r;
81
82 if(argc < 1) {
83 fprintf(stderr, "usage: bkselect path...\n");
84 exit(1);
85 }
86 r = 0;
87 for(i = 1; i < argc; i++) {
88 if(bkselect(argv[i], 0))
89 r = 1;
90 }
91 return(r);
92}