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