]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/testls.c
Backport from BEE
[bacula/bacula] / bacula / src / tools / testls.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  * Test program for listing files during regression testing
18  *   Links have their permissions and time bashed since they cannot
19  *   be set by Bacula.
20  *
21  *  Kern Sibbald, MM
22  *
23  */
24
25 #include "bacula.h"
26 #include "findlib/find.h"
27
28 /* Dummy functions */
29 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
30 int generate_job_event(JCR *jcr, const char *event) { return 1; }
31 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) { }
32
33
34 /* Global variables */
35 int attrs = 0;
36
37 static JCR *jcr;
38 static int num_files = 0;
39
40 static int print_file(JCR *jcr, FF_PKT *ff, bool);
41 static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
42 static int count_files(JCR *jcr, FF_PKT *ff, bool top_level);
43
44 static void usage()
45 {
46    fprintf(stderr, _(
47 "\n"
48 "Usage: testls [-d debug_level] [-] [pattern1 ...]\n"
49 "       -a          print extended attributes (Win32 debug)\n"
50 "       -d <nn>     set debug level to <nn>\n"
51 "       -dt         print timestamp in debug output\n"
52 "       -e          specify file of exclude patterns\n"
53 "       -i          specify file of include patterns\n"
54 "       -q          quiet, don't print filenames (debug)\n"
55 "       -           read pattern(s) from stdin\n"
56 "       -?          print this message.\n"
57 "\n"
58 "Patterns are 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 always printed.\n"
62 "Files/paths truncated is number with len > 255.\n"
63 "Truncation is only in catalog.\n"
64 "\n"));
65
66    exit(1);
67 }
68
69
70 int main(int argc, char *const *argv)
71 {
72    FF_PKT *ff;
73    char name[1000];
74    bool quiet = false;
75    int i, ch;
76    char *inc = NULL;
77    char *exc = NULL;
78    FILE *fd;
79
80    setlocale(LC_ALL, "");
81    bindtextdomain("bacula", LOCALEDIR);
82    textdomain("bacula");
83    lmgr_init_thread();
84
85    while ((ch = getopt(argc, argv, "ad:e:i:q?")) != -1) {
86       switch (ch) {
87       case 'a':                       /* print extended attributes *debug* */
88          attrs = 1;
89          break;
90
91       case 'd':                       /* set debug level */
92          if (*optarg == 't') {
93             dbg_timestamp = true;
94          } else {
95             debug_level = atoi(optarg);
96             if (debug_level <= 0) {
97                debug_level = 1;
98             }
99          }
100          break;
101
102       case 'e':                       /* exclude patterns */
103          exc = optarg;
104          break;
105
106       case 'i':                       /* include patterns */
107          inc = optarg;
108          break;
109
110       case 'q':
111          quiet = true;
112          break;
113
114       case '?':
115       default:
116          usage();
117
118       }
119    }
120    argc -= optind;
121    argv += optind;
122
123    jcr = new_jcr(sizeof(JCR), NULL);
124
125    ff = init_find_files();
126    if (argc == 0 && !inc) {
127       add_fname_to_include_list(ff, 0, "/"); /* default to / */
128    } else {
129       for (i=0; i < argc; i++) {
130          if (strcmp(argv[i], "-") == 0) {
131              while (fgets(name, sizeof(name)-1, stdin)) {
132                 strip_trailing_junk(name);
133                 add_fname_to_include_list(ff, 0, name);
134               }
135               continue;
136          }
137          add_fname_to_include_list(ff, 0, argv[i]);
138       }
139    }
140    if (inc) {
141       fd = fopen(inc, "rb");
142       if (!fd) {
143          printf(_("Could not open include file: %s\n"), inc);
144          exit(1);
145       }
146       while (fgets(name, sizeof(name)-1, fd)) {
147          strip_trailing_junk(name);
148          add_fname_to_include_list(ff, 0, name);
149       }
150       fclose(fd);
151    }
152
153    if (exc) {
154       fd = fopen(exc, "rb");
155       if (!fd) {
156          printf(_("Could not open exclude file: %s\n"), exc);
157          exit(1);
158       }
159       while (fgets(name, sizeof(name)-1, fd)) {
160          strip_trailing_junk(name);
161          add_fname_to_exclude_list(ff, name);
162       }
163       fclose(fd);
164    }
165    if (quiet) {
166       match_files(jcr, ff, count_files);
167    } else {
168       match_files(jcr, ff, print_file);
169    }
170    printf(_("Files seen = %d\n"), num_files);
171    term_include_exclude_files(ff);
172    term_find_files(ff);
173
174    free_jcr(jcr);
175    term_last_jobs_list();             /* free jcr chain */
176    close_memory_pool();
177    lmgr_cleanup_main();
178    sm_dump(false);
179    exit(0);
180 }
181
182 static int count_files(JCR *jcr, FF_PKT *ff, bool top_level)
183 {
184    num_files++;
185    return 1;
186 }
187
188 static int print_file(JCR *jcr, FF_PKT *ff, bool top_level)
189 {
190
191    switch (ff->type) {
192    case FT_LNKSAVED:
193    case FT_REGE:
194    case FT_REG:
195    case FT_LNK:
196    case FT_DIREND:
197    case FT_SPEC:
198       print_ls_output(ff->fname, ff->link, ff->type, &ff->statp);
199       break;
200    case FT_DIRBEGIN:
201       break;
202    case FT_NOACCESS:
203       printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno));
204       break;
205    case FT_NOFOLLOW:
206       printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno));
207       break;
208    case FT_NOSTAT:
209       printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno));
210       break;
211    case FT_NOCHG:
212       printf(_("Skip: File not saved. No change. %s\n"), ff->fname);
213       break;
214    case FT_ISARCH:
215       printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname);
216       break;
217    case FT_NORECURSE:
218       printf(_("Recursion turned off. Directory not entered. %s\n"), ff->fname);
219       break;
220    case FT_NOFSCHG:
221       printf(_("Skip: File system change prohibited. Directory not entered. %s\n"), ff->fname);
222       break;
223    case FT_NOOPEN:
224       printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno));
225       break;
226    default:
227       printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname);
228       break;
229    }
230    num_files++;
231    return 1;
232 }
233
234 static void print_ls_output(char *fname, char *link, int type, struct stat *statp)
235 {
236    char buf[2000];
237    char ec1[30];
238    char *p, *f;
239    int n;
240
241    if (type == FT_LNK) {
242       statp->st_mtime = 0;
243       statp->st_mode |= 0777;
244    }
245    p = encode_mode(statp->st_mode, buf);
246    n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
247    p += n;
248    n = sprintf(p, "%-4d %-4d", (int)statp->st_uid, (int)statp->st_gid);
249    p += n;
250    n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1));
251    p += n;
252    if (S_ISCHR(statp->st_mode) || S_ISBLK(statp->st_mode)) {
253       n = sprintf(p, "%4x ", (int)statp->st_rdev);
254    } else {
255       n = sprintf(p, "     ");
256    }
257    p += n;
258    p = encode_time(statp->st_mtime, p);
259    *p++ = ' ';
260    /* Copy file name */
261    for (f=fname; *f && (p-buf) < (int)sizeof(buf); )
262       *p++ = *f++;
263    if (type == FT_LNK) {
264       *p++ = '-';
265       *p++ = '>';
266       *p++ = ' ';
267       /* Copy link name */
268       for (f=link; *f && (p-buf) < (int)sizeof(buf); )
269          *p++ = *f++;
270    }
271    *p++ = '\n';
272    *p = 0;
273    fputs(buf, stdout);
274 }
275
276 bool python_set_prog(JCR*, char const*) { return false; }