2 * Test program for find files
5 Copyright (C) 2000-2005 Kern Sibbald
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 version 2 as amended with additional clauses defined in the
10 file LICENSE in the main source directory.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 the file LICENSE for additional details.
20 #include "findlib/find.h"
23 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
30 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
31 int generate_job_event(JCR *jcr, const char *event) { return 1; }
33 /* Global variables */
34 static int num_files = 0;
35 static int max_file_len = 0;
36 static int max_path_len = 0;
37 static int trunc_fname = 0;
38 static int trunc_path = 0;
43 static int print_file(FF_PKT *ff, void *pkt, bool);
44 static void count_files(FF_PKT *ff);
50 "Usage: testfind [-d debug_level] [-] [pattern1 ...]\n"
51 " -a print extended attributes (Win32 debug)\n"
52 " -dnn set debug level to nn\n"
53 " -e specify file of exclude patterns\n"
54 " -i specify file of include patterns\n"
55 " - read pattern(s) from stdin\n"
56 " -? print this message.\n"
58 "Patterns are used for file inclusion -- normally directories.\n"
59 "Debug level >= 1 prints each file found.\n"
60 "Debug level >= 10 prints path/file for catalog.\n"
61 "Errors are always printed.\n"
62 "Files/paths truncated is the number of files/paths with len > 255.\n"
63 "Truncation is only in the catalog.\n"
71 main (int argc, char *const *argv)
75 int i, ch, hard_links;
80 while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
82 case 'a': /* print extended attributes *debug* */
86 case 'd': /* set debug level */
87 debug_level = atoi(optarg);
88 if (debug_level <= 0) {
93 case 'e': /* exclude patterns */
97 case 'i': /* include patterns */
110 jcr = new_jcr(sizeof(JCR), NULL);
112 ff = init_find_files();
113 if (argc == 0 && !inc) {
114 add_fname_to_include_list(ff, 0, "/"); /* default to / */
116 for (i=0; i < argc; i++) {
117 if (strcmp(argv[i], "-") == 0) {
118 while (fgets(name, sizeof(name)-1, stdin)) {
119 strip_trailing_junk(name);
120 add_fname_to_include_list(ff, 0, name);
124 add_fname_to_include_list(ff, 0, argv[i]);
128 fd = fopen(inc, "r");
130 printf("Could not open include file: %s\n", inc);
133 while (fgets(name, sizeof(name)-1, fd)) {
134 strip_trailing_junk(name);
135 add_fname_to_include_list(ff, 0, name);
141 fd = fopen(exc, "r");
143 printf("Could not open exclude file: %s\n", exc);
146 while (fgets(name, sizeof(name)-1, fd)) {
147 strip_trailing_junk(name);
148 add_fname_to_exclude_list(ff, name);
152 match_files(jcr, ff, print_file, NULL);
153 term_include_exclude_files(ff);
154 hard_links = term_find_files(ff);
158 "Max file length: %d\n"
159 "Max path length: %d\n"
160 "Files truncated: %d\n"
161 "Paths truncated: %d\n"
162 "Hard links : %d\n"),
163 num_files, max_file_len, max_path_len,
164 trunc_fname, trunc_path, hard_links);
172 static int print_file(FF_PKT *ff, void *pkt, bool top_level)
177 if (debug_level == 1) {
178 printf("%s\n", ff->fname);
179 } else if (debug_level > 1) {
180 printf("Lnka: %s -> %s\n", ff->fname, ff->link);
184 if (debug_level == 1) {
185 printf("%s\n", ff->fname);
186 } else if (debug_level > 1) {
187 printf("Empty: %s\n", ff->fname);
192 if (debug_level == 1) {
193 printf("%s\n", ff->fname);
194 } else if (debug_level > 1) {
195 printf("Reg: %s\n", ff->fname);
200 if (debug_level == 1) {
201 printf("%s\n", ff->fname);
202 } else if (debug_level > 1) {
203 printf("Lnk: %s -> %s\n", ff->fname, ff->link);
214 char errmsg[100] = "";
215 if (ff->type == FT_NORECURSE) {
216 bstrncpy(errmsg, "\t[will not descend: recursion turned off]", sizeof(errmsg));
217 } else if (ff->type == FT_NOFSCHG) {
218 bstrncpy(errmsg, "\t[will not descend: file system change not allowed]", sizeof(errmsg));
219 } else if (ff->type == FT_INVALIDFS) {
220 bstrncpy(errmsg, "\t[will not descend: disallowed file system]", sizeof(errmsg));
222 printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
224 ff->type = FT_DIREND;
228 if (debug_level == 1) {
229 printf("%s\n", ff->fname);
230 } else if (debug_level > 1) {
231 printf("Spec: %s\n", ff->fname);
236 printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
239 printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
242 printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
245 printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
248 printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
251 printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
254 printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
259 encode_attribsEx(NULL, attr, ff);
261 printf("AttrEx=%s\n", attr);
263 // set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr);
268 static void count_files(FF_PKT *ar)
272 char file[MAXSTRING];
273 char spath[MAXSTRING];
277 /* Find path without the filename.
278 * I.e. everything after the last / is a "filename".
279 * OK, maybe it is a directory name, but we treat it like
280 * a filename. If we don't find a / then the whole name
281 * must be a path name (e.g. c:).
283 for (p=l=ar->fname; *p; p++) {
285 l = p; /* set pos of last slash */
288 if (*l == '/') { /* did we find a slash? */
289 l++; /* yes, point to filename */
290 } else { /* no, whole thing must be path name */
294 /* If filename doesn't exist (i.e. root directory), we
295 * simply create a blank name consisting of a single
296 * space. This makes handling zero length filenames
300 if (fnl > max_file_len) {
304 printf(_("===== Filename truncated to 255 chars: %s\n"), l);
309 strncpy(file, l, fnl); /* copy filename */
312 file[0] = ' '; /* blank filename */
317 if (pnl > max_path_len) {
321 printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname);
325 strncpy(spath, ar->fname, pnl);
330 printf(_("========== Path length is zero. File=%s\n"), ar->fname);
332 if (debug_level >= 10) {
333 printf("Path: %s\n", spath);
334 printf("File: %s\n", file);
339 bool python_set_prog(JCR*, char const*) { return false; }