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