1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2002
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /* 10/31/2002   Port to LTP     robbiew@us.ibm.com */
21 /* 06/30/2001   Port to Linux   nsharoff@us.ibm.com */
22 
23 /*
24  * NAME
25  *	test_func.c - nftw() calls these functions.
26  */
27 
28 #include "nftw.h"
29 
30 extern pathdata pathdat[];
31 extern struct list mnem[], badlist[];
32 extern char *dirlist[NDIRLISTENTS];
33 extern const char *rw_fs_name;
34 extern int npathdats, ngoods, nbads, nmnem, visit, next_fd[4];
35 extern FILE *temp;
36 
37 /*
38  * Calling function should free the dirlist array.
39  */
40 int
41 test_func1(const char *path_name, const struct stat *stat_pointer,
42 	   int ftw_integer, struct FTW *ftwp)
43 {
44 	char *s;
45 	const char *p;
46 
47 	temp = stderr;
48 
49 	if ((s = malloc((size_t)(strlen((char *)path_name) + 1)))
50 	    == NULL) {
51 		perror("malloc in test_func1");
52 		return 999;
53 	}
54 
55 	if ((p = strstr(path_name, NFTW)) != NULL) {
56 		p += strlen(NFTW);
57 	} else {
58 		p = path_name;
59 	}
60 
61 	(void)strcpy(s, p);
62 	dirlist[visit++] = s;
63 
64 #ifdef DEBUG
65 	fprintf(temp, "INFO: Call to fn() at %s\n", path_name);
66 #endif
67 
68 	if (visit >= NDIRLISTENTS) {
69 		fprintf(temp, "ERROR: Too many paths traversed\n");
70 		return 999;
71 	}
72 	return 0;
73 }
74 
75 int
76 test_func3(const char *path_name, const struct stat *stat_pointer,
77 	   int ftw_integer, struct FTW *ftwp)
78 {
79 	visit++;
80 	temp = stderr;
81 #ifdef DEBUG
82 	fprintf(temp, "INFO: Call to fn() at %s\n", path_name);
83 #endif
84 
85 	if (visit >= NDIRLISTENTS) {
86 		fprintf(temp, "ERROR: Too many paths traversed\n");
87 		return 999;
88 	}
89 
90 	if (strcmp(path_name, "./tmp/data/dirl/dir_right.1/dir_right.2/right.3")
91 	    == 0) {
92 		fprintf(temp,
93 			"ERROR: Target of right.3 was already reported so this file should not be\n");
94 		return 999;
95 	}
96 
97 	return 0;
98 }
99 
100 int
101 test_func4(const char *path_name, const struct stat *stat_pointer,
102 	   int ftw_integer, struct FTW *ftwp)
103 {
104 	visit++;
105 	do_info(path_name);
106 
107 	/* Stop traversal once directory is visited. */
108 	if (strcmp(path_name, "./tmp/data/d777") == 0)
109 		return 999;
110 	return 0;
111 }
112 
113 int
114 test_func5(const char *path_name, const struct stat *stat_pointer,
115 	   int ftw_integer, struct FTW *ftwp)
116 {
117 	char pathcwd[PATH_MAX];
118 
119 	if (ftw_integer == FTW_D)
120 		return (0);
121 
122 	if (getcwd(pathcwd, sizeof(pathcwd)) == NULL) {
123 		perror("getcwd");
124 		return 998;
125 	}
126 
127 	if (strstr(path_name, pathcwd) == 0) {
128 		fprintf(temp, "ERROR: For file %s cwd is %s\n", path_name,
129 			pathcwd);
130 		return 999;
131 	}
132 
133 	return (0);
134 }
135 
136 int
137 test_func7(const char *path_name, const struct stat *stat_pointer,
138 	   int ftw_integer, struct FTW *ftwp)
139 {
140 	int i, found;
141 	const char *p;
142 
143 	do_info(path_name);
144 
145 	if ((p = strstr(path_name, NFTW)) != NULL) {
146 		p += strlen(NFTW);
147 	} else {
148 		p = path_name;
149 	}
150 
151 	for (found = i = 0; i < nbads; i++) {
152 		if (strcmp(p, badlist[i].s) == 0) {
153 			found++;
154 			break;
155 		}
156 	}
157 
158 	if (!found) {
159 		fprintf(temp, "ERROR: Should not have traversed %s\n",
160 			path_name);
161 		return 999;
162 	}
163 	return 0;
164 }
165 
166 int
167 test_func8(const char *path_name, const struct stat *stat_pointer,
168 	   int ftw_integer, struct FTW *ftwp)
169 {
170 	int i;
171 	const char *p;
172 	struct stat st_buf;
173 
174 	do_info(path_name);
175 
176 	if ((p = strstr(path_name, NFTW)) != NULL) {
177 		p += strlen(NFTW);
178 	} else {
179 		p = path_name;
180 	}
181 
182 	for (i = 0; i < nbads; i++) {
183 		if (ftw_integer == FTW_D || ftw_integer == FTW_F ||
184 		    ftw_integer == FTW_SL) {
185 			if ((((ftw_integer == FTW_D) || (ftw_integer ==
186 							 FTW_F)) ?
187 			     stat(path_name, &st_buf) : lstat(path_name,
188 							      &st_buf)) == -1) {
189 				perror("stat");
190 				return 999;
191 			}
192 
193 			if (st_buf.st_dev != stat_pointer->st_dev) {
194 				fprintf(temp,
195 					"ERROR: st_dev members do not match for %s\n",
196 					path_name);
197 				return 999;
198 			}
199 
200 			if (st_buf.st_ino != stat_pointer->st_ino) {
201 				fprintf(temp,
202 					"ERROR: st_ino members do not match for %s\n",
203 					path_name);
204 				return 999;
205 			}
206 
207 			if (st_buf.st_mode != stat_pointer->st_mode) {
208 				fprintf(temp,
209 					"ERROR: st_mode members do not match for %s\n",
210 					path_name);
211 				return 999;
212 			}
213 
214 			if (st_buf.st_nlink != stat_pointer->st_nlink) {
215 				fprintf(temp,
216 					"ERROR: st_nlink members d o not match for %s\n",
217 					path_name);
218 				return 999;
219 			}
220 
221 			if (st_buf.st_uid != stat_pointer->st_uid) {
222 				fprintf(temp,
223 					"ERROR: st_uid members do not match for %s\n",
224 					path_name);
225 				return 999;
226 			}
227 
228 			if (st_buf.st_gid != stat_pointer->st_gid) {
229 				fprintf(temp,
230 					"ERROR: st_gid members do not match for %s\n",
231 					path_name);
232 				return 999;
233 			}
234 
235 			if (st_buf.st_size != stat_pointer->st_size) {
236 				fprintf(temp,
237 					"ERROR: st_size members do not match for %s\n",
238 					path_name);
239 				return 999;
240 			}
241 		}
242 
243 	}
244 	return 0;
245 }
246 
247 int
248 test_func9(const char *path_name, const struct stat *stat_pointer,
249 	   int ftw_integer, struct FTW *ftwp)
250 {
251 	int i;
252 	const char *p;
253 
254 	do_info(path_name);
255 
256 	if ((p = strstr(path_name, NFTW)) != NULL) {
257 		p += strlen(NFTW);
258 	} else {
259 		p = path_name;
260 	}
261 
262 	for (i = 0; i < nbads; i++) {
263 		if (strcmp(p, badlist[i].s) == 0) {
264 
265 			if (ftw_integer == FTW_F) {
266 				if (ftw_integer != badlist[i].i) {
267 					fprintf(temp,
268 						"ERROR: Bad thrid arg to fn () for %s\n",
269 						path_name);
270 					fprintf(temp, "       Expected %s\n",
271 						ftw_mnemonic(badlist[i].i));
272 					fprintf(temp, "       Received %s\n",
273 						ftw_mnemonic(ftw_integer));
274 					return 999;
275 				}
276 			}
277 		}
278 	}
279 	return 0;
280 }
281 
282 int
283 test_func10(const char *path_name, const struct stat *stat_pointer,
284 	    int ftw_integer, struct FTW *ftwp)
285 {
286 	int i;
287 	const char *p;
288 
289 	do_info(path_name);
290 
291 	if ((p = strstr(path_name, NFTW)) != NULL) {
292 		p += strlen(NFTW);
293 	} else {
294 		p = path_name;
295 	}
296 
297 	for (i = 0; i < nbads; i++) {
298 		if (strcmp(p, badlist[i].s) == 0) {
299 			if (ftw_integer == FTW_D) {
300 				if (ftw_integer != badlist[i].i) {
301 					fprintf(temp,
302 						"ERROR: Bad third arg to fn () for %s\n",
303 						path_name);
304 					fprintf(temp, "       Expected %s\n",
305 						ftw_mnemonic(badlist[i].i));
306 					fprintf(temp, "       Received %s\n",
307 						ftw_mnemonic(ftw_integer));
308 					return 999;
309 				}
310 			}
311 		}
312 	}
313 	return 0;
314 }
315 
316 int
317 test_func11(const char *path_name, const struct stat *stat_pointer,
318 	    int ftw_integer, struct FTW *ftwp)
319 {
320 	int i;
321 	const char *p;
322 
323 	do_info(path_name);
324 
325 	if ((p = strstr(path_name, NFTW)) != NULL) {
326 		p += strlen(NFTW);
327 	} else {
328 		p = path_name;
329 	}
330 
331 	for (i = 0; i < nbads; i++) {
332 		if (strcmp(p, badlist[i].s) == 0) {
333 			if (ftw_integer == FTW_DP) {
334 				if (ftw_integer != badlist[i].i) {
335 					fprintf(temp,
336 						"ERROR: Bad third arg to fn () for %s\n",
337 						path_name);
338 					fprintf(temp, "       Expected %s\n",
339 						ftw_mnemonic(badlist[i].i));
340 					fprintf(temp, "       Received %s\n",
341 						ftw_mnemonic(ftw_integer));
342 					return 999;
343 				}
344 			}
345 		}
346 	}
347 	return 0;
348 }
349 
350 int
351 test_func12(const char *path_name, const struct stat *stat_pointer,
352 	    int ftw_integer, struct FTW *ftwp)
353 {
354 	int i;
355 	const char *p;
356 
357 	do_info(path_name);
358 
359 	if ((p = strstr(path_name, NFTW)) != NULL) {
360 		p += strlen(NFTW);
361 	} else {
362 		p = path_name;
363 	}
364 
365 	for (i = 0; i < nbads; i++) {
366 		if (strcmp(p, badlist[i].s) == 0) {
367 			if (ftw_integer == FTW_SL) {
368 				if (ftw_integer != badlist[i].i) {
369 					fprintf(temp,
370 						"ERROR: Bad third arg to fn() for %s.  Expected %s, Received %s\n",
371 						path_name,
372 						ftw_mnemonic(badlist[i].i),
373 						ftw_mnemonic(ftw_integer));
374 					return 999;
375 				}
376 			}
377 		}
378 	}
379 	return 0;
380 }
381 
382 int
383 test_func13(const char *path_name, const struct stat *stat_pointer,
384 	    int ftw_integer, struct FTW *ftwp)
385 {
386 	int i;
387 	const char *p;
388 
389 	do_info(path_name);
390 
391 	if ((p = strstr(path_name, NFTW)) != NULL) {
392 		p += strlen(NFTW);
393 	} else {
394 		p = path_name;
395 	}
396 
397 	for (i = 0; i < nbads; i++) {
398 		if (strcmp(p, badlist[i].s) == 0) {
399 
400 			if (ftw_integer == FTW_SLN) {
401 				if (ftw_integer != badlist[i].i) {
402 					fprintf(temp,
403 						"ERROR: Bad third arg to fn() for %s\n",
404 						path_name);
405 					fprintf(temp, "       Expected %s\n",
406 						ftw_mnemonic(badlist[i].i));
407 					fprintf(temp, "       Received %s\n",
408 						ftw_mnemonic(ftw_integer));
409 					return 999;
410 				}
411 			}
412 		}
413 	}
414 	return 0;
415 }
416 
417 int
418 test_func14(const char *path_name, const struct stat *stat_pointer,
419 	    int ftw_integer, struct FTW *ftwp)
420 {
421 	int i;
422 	const char *p;
423 
424 	do_info(path_name);
425 
426 	if ((p = strstr(path_name, NFTW)) != NULL) {
427 		p += strlen(NFTW);
428 	} else {
429 		p = path_name;
430 	}
431 
432 	for (i = 0; i < nbads; i++) {
433 		if (strcmp(p, badlist[i].s) == 0) {
434 
435 			if (ftw_integer == FTW_DNR) {
436 				if (ftw_integer != badlist[i].i) {
437 					fprintf(temp,
438 						"ERROR: Bad third arg to fn() for %s\n",
439 						path_name);
440 					fprintf(temp, "       Expected %s\n",
441 						ftw_mnemonic(badlist[i].i));
442 					fprintf(temp, "       Received %s\n",
443 						ftw_mnemonic(ftw_integer));
444 					return 999;
445 				}
446 			}
447 		}
448 	}
449 	return 0;
450 }
451 
452 int
453 test_func15(const char *path_name, const struct stat *stat_pointer,
454 	    int ftw_integer, struct FTW *ftwp)
455 {
456 	do_info(path_name);
457 	if (strcmp(path_name, "./tmp/data/d666/errs") == 0) {
458 		if (ftw_integer != FTW_NS) {
459 			fprintf(temp,
460 				"ERROR: FTW_NS not passed for file in unsearchable dir\n");
461 			return 999;
462 		}
463 	}
464 	return 0;
465 }
466 
467 int
468 test_func16(const char *path_name, const struct stat *stat_pointer,
469 	    int ftw_integer, struct FTW *ftwp)
470 {
471 	const char *p;
472 
473 	if ((p = strstr(path_name, NFTW2)) != NULL) {
474 		p += strlen(NFTW2) + 1;
475 	} else {
476 		p = path_name;
477 	}
478 
479 	if (ftwp->level != getlev(p)) {
480 		fprintf(temp, "ERROR: Incorrect value of level for %s\n",
481 			path_name);
482 		fprintf(temp, "       Expected %d, received %d\n",
483 			getlev(p), ftwp->level);
484 		return 999;
485 	}
486 	if (ftwp->base != getbase(path_name)) {
487 		fprintf(temp, "ERROR: Incorrect value of base for %s\n",
488 			path_name);
489 		fprintf(temp, "       Expected %d, received %d\n",
490 			getbase(path_name), ftwp->base);
491 		return 999;
492 	}
493 	return 0;
494 }
495 
496 int
497 test_func17(const char *path_name, const struct stat *stat_pointer,
498 	    int ftw_integer, struct FTW *ftwp)
499 {
500 	do_info(path_name);
501 
502 	if (ftw_integer == FTW_SL) {
503 		visit++;
504 		return 999;
505 	}
506 	return 0;
507 }
508 
509 int
510 test_func18(const char *path_name, const struct stat *stat_pointer,
511 	    int ftw_integer, struct FTW *ftwp)
512 {
513 	do_info(path_name);
514 	if (ftw_integer == FTW_SLN) {
515 		visit++;
516 		return 999;
517 	}
518 	return 0;
519 }
520 
521 int
522 test_func19(const char *path_name, const struct stat *stat_pointer,
523 	    int ftw_integer, struct FTW *ftwp)
524 {
525 	do_info(path_name);
526 	visit++;
527 	if (ftw_integer == FTW_DNR) {
528 		if (strcmp(path_name, "./tmp/data/d333") == 0) {
529 			return 0;
530 		} else {
531 			fprintf(temp,
532 				"ERROR: When FTW_DNR is passed to the function fn the\n");
533 			fprintf(temp,
534 				"       descendants of the directory should not have\n");
535 			fprintf(temp, "       Been processed\n");
536 			return 999;
537 		}
538 	} else {
539 		fprintf(temp,
540 			"ERROR: Directory has read permission or FTW_DNR was not passed to fn\n");
541 		return 999;
542 	}
543 }
544 
545 int
546 test_func20(const char *path_name, const struct stat *stat_pointer,
547 	    int ftw_integer, struct FTW *ftwp)
548 {
549 	return 0;
550 }
551 
552 int
553 test_func21(const char *path_name, const struct stat *stat_pointer,
554 	    int ftw_integer, struct FTW *ftwp)
555 {
556 	int fd;
557 
558 	do_info(path_name);
559 	/* get next file descriptor available */
560 	if ((fd = open(path_name, O_RDONLY)) == -1) {
561 		perror("open");
562 		return 999;
563 	}
564 
565 	if (close(fd) == -1) {
566 		perror("close");
567 		return 999;
568 	}
569 
570 	if ((fd != next_fd[0]) && (fd != next_fd[1])) {
571 		fprintf(temp,
572 			"ERROR: Expected next fd available to be %d (none used) or %d (1 used)\n",
573 			next_fd[0], next_fd[1]);
574 		fprintf(temp, "       Next fd available is %d\n", fd);
575 		return 999;
576 	}
577 	return 0;
578 }
579 
580 int
581 test_func22(const char *path_name, const struct stat *stat_pointer,
582 	    int ftw_integer, struct FTW *ftwp)
583 {
584 	int fd;
585 	int i;
586 
587 	do_info(path_name);
588 	/* get next file descriptor available */
589 	if ((fd = open(path_name, O_RDONLY)) == -1) {
590 		perror("open");
591 		return 999;
592 	}
593 
594 	if (close(fd) == -1) {
595 		perror("close");
596 		return 999;
597 	}
598 
599 	for (i = 0; i <= ftwp->level + 1; i++) {
600 		if (fd == next_fd[i])
601 			return 0;
602 	}
603 
604 	fprintf(temp,
605 		"ERROR: At the start of the traversal the next four fds were: %d, %d, %d, and %d\n",
606 		next_fd[0], next_fd[1], next_fd[2], next_fd[3]);
607 	fprintf(temp, "       Traversing level %d the next fd is %d\n",
608 		ftwp->level, fd);
609 	return 999;
610 }
611 
612 int
613 test_func23(const char *path_name, const struct stat *stat_pointer,
614 	    int ftw_integer, struct FTW *ftwp)
615 {
616 	visit++;
617 	do_info(path_name);
618 
619 	if (ftw_integer == FTW_F) {
620 
621 #ifdef DEBUG
622 		fprintf(temp,
623 			"INFO: fn() returning non-zero after traversal of %d objects\n",
624 			visit);
625 #endif
626 
627 		return 999;
628 	}
629 
630 	return 0;
631 }
632