xref: /freebsd/contrib/ntp/tests/libntp/realpath.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 #include "config.h"
2 
3 #include "ntp_stdlib.h"
4 #include "unity.h"
5 
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <dirent.h>
10 #include <stdarg.h>
11 
12 static char * resolved;
13 
14 void setUp(void);
15 void setUp(void) {
16 	resolved = NULL;
17 }
18 
19 void tearDown(void);
20 void tearDown(void) {
21 	free(resolved);
22 	resolved = NULL;
23 }
24 
25 static int/*BOOL*/ isValidAbsPath(const char * path)
26 {
27 	int retv = FALSE;
28 	/* this needs some elaboration: */
29 	if (path && path[0] == '/') {
30 		struct stat sb;
31 		if (0 == lstat(path, &sb)) {
32 			retv = (sb.st_mode & S_IFMT) != S_IFLNK;
33 		}
34 	}
35 	return retv;
36 }
37 
38 static const char * errMsg(const char *fmt, ...)
39 {
40 	static char buf[256];
41 	va_list va;
42 	va_start(va, fmt);
43 	vsnprintf(buf, sizeof(buf), fmt, va);
44 	va_end(va);
45 	return buf;
46 }
47 
48 void test_CurrentWorkingDir(void);
49 void test_CurrentWorkingDir(void) {
50 #   ifdef SYS_WINNT
51 	TEST_IGNORE_MESSAGE("not applicable to windows so far");
52 #   else
53 	resolved = ntp_realpath(".");
54 	TEST_ASSERT_NOT_NULL_MESSAGE(resolved, "failed to resolve '.'");
55 	TEST_ASSERT_TRUE_MESSAGE(isValidAbsPath(resolved), "'.' not resolved to absolute path");
56 #   endif
57 }
58 
59 void test_DevLinks(void);
60 void test_DevLinks(void) {
61 #   ifdef SYS_WINNT
62 	TEST_IGNORE_MESSAGE("not applicable to windows so far");
63 #   else
64 	char            nam[512];
65 	char            abs[512];
66 	struct dirent * ent;
67 	DIR           * dfs = opendir("/dev");
68 
69 	TEST_ASSERT_NOT_NULL_MESSAGE(dfs, "failed to open '/dev' !?!");
70 	while (NULL != (ent = readdir(dfs))) {
71 		/* the /dev/std{in,out,err} symlinks are prone to some
72 		 * kind of race condition under Linux, so we better skip
73 		 * them here; running tests in parallel can fail mysteriously
74 		 * otherwise. (Dunno *how* this could happen, but it
75 		 * did at some point in time, quite reliably...)
76 		 */
77 		if (!strncmp(ent->d_name, "std", 3))
78 			continue;
79 		/* otherwise build the full name & try to resolve: */
80 		snprintf(nam, sizeof(nam), "/dev/%s", ent->d_name);
81 		resolved = ntp_realpath(nam);
82 		TEST_ASSERT_NOT_NULL_MESSAGE(resolved, errMsg("could not resolve '%s'", nam));
83 		strlcpy(abs, resolved, sizeof(abs));
84 		free(resolved);
85 		resolved = NULL;
86 		/* test/development code:
87 		if (strcmp(nam, abs))
88 			printf(" '%s' --> '%s'\n", nam, abs);
89 		*/
90 		TEST_ASSERT_TRUE_MESSAGE(isValidAbsPath(abs), errMsg("could not validate '%s'", abs));
91 	}
92 	closedir(dfs);
93 #   endif
94 }
95