]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testfind.c
First cut 1.27 see kes23Oct02
[bacula/bacula] / bacula / src / tools / testfind.c
1 /*  
2  * Test program for find files
3  */
4
5 #include "bacula.h"
6 #include "findlib/find.h"
7 #include "jcr.h"
8
9
10 /* Global variables */
11 static int num_files = 0;
12 static int max_file_len = 0;
13 static int max_path_len = 0;
14 static int trunc_fname = 0;
15 static int trunc_path = 0;
16 static int attrs = 0;
17
18
19 static int print_file(FF_PKT *ff, void *pkt);
20 static void count_files(FF_PKT *ff);
21
22 static void usage()
23 {
24    fprintf(stderr, _(
25 "\n"
26 "Usage: testfind [-d debug_level] [-] [pattern1 ...]\n"
27 "       -dnn        set debug level to nn\n"
28 "       -           read pattern(s) from stdin\n"
29 "       -?          print this message.\n"
30 "\n"
31 "Patterns are file inclusion -- normally directories.\n"
32 "Debug level >= 1 prints each file found.\n"
33 "Debug level >= 10 prints path/file for catalog.\n"
34 "Errors always printed.\n"
35 "Files/paths truncated is number with len > 255.\n"
36 "Truncation is only in catalog.\n"
37 "\n"));
38
39    exit(1);
40 }
41
42
43 int
44 main (int argc, char *const *argv)
45 {
46    FF_PKT *ff;
47    char name[1000];
48    int i, ch;
49
50    while ((ch = getopt(argc, argv, "ad:?")) != -1) {
51       switch (ch) {
52          case 'a':                    /* print extended attributes *debug* */
53             attrs = 1;
54             break;
55
56          case 'd':                    /* set debug level */
57             debug_level = atoi(optarg);
58             if (debug_level <= 0) {
59                debug_level = 1; 
60             }
61             break;
62
63          case '?':
64          default:
65             usage();
66
67       }  
68    }
69    argc -= optind;
70    argv += optind;
71
72   ff = init_find_files();
73    if (argc == 0) {
74      add_fname_to_include_list(ff, 0, "/"); /* default to / */
75   } else {   
76       for (i=0; i < argc; i++) {
77         if (strcmp(argv[i], "-") == 0) {
78            while (fgets(name, sizeof(name)-1, stdin)) {
79               strip_trailing_junk(name);
80               add_fname_to_include_list(ff, 0, name); 
81            }
82            continue;
83         }
84         add_fname_to_include_list(ff, 0, argv[i]); 
85      }
86   }
87
88   find_files(ff, print_file, NULL);
89   term_find_files(ff);
90   
91    printf(_("\
92 Total files    : %d\n\
93 Max file length: %d\n\
94 Max path length: %d\n\
95 Files truncated: %d\n\
96 Paths truncated: %d\n"),
97      num_files, max_file_len, max_path_len,
98      trunc_fname, trunc_path);
99   
100   sm_dump(False);
101   exit(0);
102 }
103
104 static int print_file(FF_PKT *ff, void *pkt)
105 {
106
107    switch (ff->type) {
108    case FT_LNKSAVED:
109       if (debug_level == 1) {
110          printf("%s\n", ff->fname);
111       } else if (debug_level > 1) {
112          printf("Lnka: %s -> %s\n", ff->fname, ff->link);
113       }
114       break;
115    case FT_REGE:
116       if (debug_level == 1) {
117          printf("%s\n", ff->fname);
118       } else if (debug_level > 1) {
119          printf("Empty: %s\n", ff->fname);
120       }
121       count_files(ff);
122       break; 
123    case FT_REG:
124       if (debug_level == 1) {
125          printf("%s\n", ff->fname);
126       } else if (debug_level > 1) {
127          printf("Reg: %s\n", ff->fname);
128       }
129       count_files(ff);
130       break;
131    case FT_LNK:
132       if (debug_level == 1) {
133          printf("%s\n", ff->fname);
134       } else if (debug_level > 1) {
135          printf("Lnk: %s -> %s\n", ff->fname, ff->link);
136       }
137       count_files(ff);
138       break;
139    case FT_DIR:
140       if (debug_level == 1) {
141          printf("%s\n", ff->fname);
142       } else if (debug_level > 1) {
143          printf("Dir: %s\n", ff->fname);
144       }
145       count_files(ff);
146       break;
147    case FT_SPEC:
148       if (debug_level == 1) {
149          printf("%s\n", ff->fname);
150       } else if (debug_level > 1) {
151          printf("Spec: %s\n", ff->fname);
152       }
153       count_files(ff);
154       break;
155    case FT_NOACCESS:
156       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
157       break;
158    case FT_NOFOLLOW:
159       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
160       break;
161    case FT_NOSTAT:
162       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
163       break;
164    case FT_NOCHG:
165       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
166       break;
167    case FT_ISARCH:
168       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
169       break;
170    case FT_NORECURSE:
171       printf(_("Recursion turned off. Directory not entered. %s\n"), ff->fname);
172       break;
173    case FT_NOFSCHG:
174       printf(_("Skip: File system change prohibited. Directory not entered. %s\n"), ff->fname);
175       break;
176    case FT_NOOPEN:
177       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
178       break;
179    default:
180       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
181       break;
182    }
183    if (attrs) {
184       char attr[200];
185       encode_attribsEx(NULL, attr, ff);
186       if (*attr != 0) {
187          printf("AttrEx=%s\n", attr);
188       }
189       set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
190    }
191    return 1;
192 }
193
194 static void count_files(FF_PKT *ar) 
195 {
196    int fnl, pnl;
197    char *l, *p;
198    char file[MAXSTRING];
199    char spath[MAXSTRING];
200
201    num_files++;
202
203    /* Find path without the filename.  
204     * I.e. everything after the last / is a "filename".
205     * OK, maybe it is a directory name, but we treat it like
206     * a filename. If we don't find a / then the whole name
207     * must be a path name (e.g. c:).
208     */
209    for (p=l=ar->fname; *p; p++) {
210       if (*p == '/') {
211          l = p;                       /* set pos of last slash */
212       }
213    }
214    if (*l == '/') {                   /* did we find a slash? */
215       l++;                            /* yes, point to filename */
216    } else {                           /* no, whole thing must be path name */
217       l = p;
218    }
219
220    /* If filename doesn't exist (i.e. root directory), we
221     * simply create a blank name consisting of a single 
222     * space. This makes handling zero length filenames
223     * easier.
224     */
225    fnl = p - l;
226    if (fnl > max_file_len) {
227       max_file_len = fnl;
228    }
229    if (fnl > 255) {
230       printf(_("===== Filename truncated to 255 chars: %s\n"), l);
231       fnl = 255;
232       trunc_fname++;
233    }
234    if (fnl > 0) {
235       strncpy(file, l, fnl);          /* copy filename */
236       file[fnl] = 0;
237    } else {
238       file[0] = ' ';                  /* blank filename */
239       file[1] = 0;
240    }
241
242    pnl = l - ar->fname;    
243    if (pnl > max_path_len) {
244       max_path_len = pnl;
245    }
246    if (pnl > 255) {
247       printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
248       pnl = 255;
249       trunc_path++;
250    }
251    strncpy(spath, ar->fname, pnl);
252    spath[pnl] = 0;
253    if (pnl == 0) {
254       spath[0] = ' ';
255       spath[1] = 0;
256       printf(_("========== Path length is zero. File=%s\n"), ar->fname);
257    }
258    if (debug_level >= 10) {
259       printf("Path: %s\n", spath);
260       printf("File: %s\n", file);
261    }
262
263 }