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
30extern pathdata pathdat[];
31extern struct list mnem[], badlist[];
32extern char *dirlist[NDIRLISTENTS];
33extern const char *rw_fs_name;
34extern int npathdats, ngoods, nbads, nmnem, visit, next_fd[4];
35extern FILE *temp;
36
37/*
38 * Calling function should free the dirlist array.
39 */
40int
41test_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
75int
76test_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
100int
101test_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
113int
114test_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
136int
137test_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
166int
167test_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
247int
248test_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
282int
283test_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
316int
317test_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
350int
351test_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
382int
383test_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
417int
418test_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
452int
453test_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
467int
468test_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
496int
497test_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
509int
510test_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
521int
522test_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
545int
546test_func20(const char *path_name, const struct stat *stat_pointer,
547	    int ftw_integer, struct FTW *ftwp)
548{
549	return 0;
550}
551
552int
553test_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
580int
581test_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
612int
613test_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