ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
Revision: 2.21
Committed: Sat Dec 28 18:05:14 2019 UTC (4 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.20: +1 -2 lines
Log Message:
Removed redundant include files

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: getpath.c,v 2.20 2019/07/21 16:48:34 greg Exp $";
3 #endif
4 /*
5 * getpath.c - function to search for file in a list of directories
6 *
7 * External symbols declared in rtio.h
8 */
9
10 #include "copyright.h"
11
12 #include <ctype.h>
13
14 #include "rtio.h"
15 #include "paths.h"
16
17
18 #if defined(_WIN32) || defined(_WIN64)
19 static char *
20 core_getpath /* wrapped below: expand fname, return full path */
21 #else
22 char *
23 getpath /* expand fname, return full path */
24 #endif
25 (
26 char *fname,
27 char *searchpath,
28 int mode
29 )
30 {
31 static char pname[PATH_MAX];
32 char uname[512];
33 char *cp;
34 int i;
35
36 if (fname == NULL) { return(NULL); }
37
38 pname[0] = '\0'; /* check for full specification */
39
40 if (ISABS(fname)) { /* absolute path */
41 strlcpy(pname, fname, sizeof(pname));
42 } else {
43 switch (*fname) {
44 case '.': /* relative to cwd */
45 strlcpy(pname, fname, sizeof(pname));
46 break;
47 case '~': /* relative to home directory */
48 fname++;
49 cp = uname;
50 for (i = 0; i < sizeof(uname) && *fname
51 && !ISDIRSEP(*fname); i++)
52 *cp++ = *fname++;
53 *cp = '\0';
54 cp = gethomedir(uname, pname, sizeof(pname));
55 if(cp == NULL) return NULL;
56 strlcat(pname, fname, sizeof(pname));
57 break;
58 }
59 }
60 if (pname[0]) /* got it, check access if search requested */
61 return(!searchpath || access(pname,mode)==0 ? pname : NULL);
62
63 if (!searchpath) { /* no search */
64 strlcpy(pname, fname, sizeof(pname));
65 return(pname);
66 }
67 /* check search path */
68 do {
69 cp = pname;
70 while (*searchpath && (*cp = *searchpath++) != PATHSEP)
71 cp += (cp-pname < sizeof(pname)-2);
72 if (cp > pname && !ISDIRSEP(cp[-1]))
73 *cp++ = DIRSEP;
74 *cp = '\0';
75 strlcat(pname, fname, sizeof(pname));
76 if (access(pname, mode) == 0) /* file accessable? */
77 return(pname);
78 } while (*searchpath);
79 /* not found */
80 return(NULL);
81 }
82
83
84 #if defined(_WIN32) || defined(_WIN64)
85 /* This is a wrapper around the above, "emulating" access mode X_OK,
86 which is not supported on Windows.
87 If we see X_OK and the filename has no extension, then we'll remove
88 the X_OK from the mode, append ".exe" to the file name, and search
89 with the resulting string. If that fails, we'll try again with ".bat".
90 Theoretically, we might still not have execute rights on a file we find
91 like this, but that's rare enough not to be worth checking the ACLs.
92 */
93 char *
94 getpath( /* expand fname, return full path */
95 char *ffname,
96 char *searchpath,
97 int mode
98 )
99 {
100 char *cp;
101 char fname[PATH_MAX];
102
103 if (ffname == NULL)
104 return(NULL);
105
106 /* if we have a dot in the string, we assume there is a file name
107 extension present */
108 /* XXX We'd better test for .exe/.bat/.etc explicitly */
109 if (!(mode & X_OK) || (strrchr(ffname, '.') != NULL)) {
110 return core_getpath(ffname, searchpath, mode);
111 }
112
113 /* We're looking for an executable, Windows doesn't have X_OK. */
114 mode &= ~X_OK;
115 /* Append .exe */
116 strncpy(fname, ffname, sizeof(fname)-5);
117 strcat(fname, ".exe");
118 cp = core_getpath(fname, searchpath, mode);
119 if (cp != NULL) return cp;
120
121 /* Try with .bat this time... */
122 strncpy(fname, ffname, sizeof(fname)-5);
123 strcat(fname, ".bat");
124 cp = core_getpath(fname, searchpath, mode);
125 return cp;
126 }
127 #endif /* _WIN32 */
128
129
130 #ifdef TEST_MODULE
131 int main()
132 {
133 char * fp;
134 char fmt[] = "%15s %-10s %s: %s\n";
135
136 fp = getpath("rayinit.cal", getenv("RAYPATH"), R_OK);
137 printf(fmt, "rayinit.cal", "RAYPATH", "R_OK", fp);
138 fp = getpath("mkillum", getenv("PATH"), X_OK);
139 printf(fmt, "mkillum", "PATH", "X_OK", fp);
140 fp = getpath("/", getenv("PATH"), W_OK);
141 printf(fmt, "/", "PATH", "W_OK", fp);
142 fp = getpath("~", getenv("PATH"), F_OK);
143 printf(fmt, "~", "PATH", "F_OK", fp);
144 printf("Undefining HOME and HOMEPATH\n");
145 unsetenv("HOME");
146 unsetenv("HOMEPATH");
147 fp = getpath("~", getenv("PATH"), F_OK);
148 printf(fmt, "~", "PATH", "F_OK", fp);
149 fp = getpath("~lp/blah", getenv("PATH"), F_OK);
150 printf(fmt, "~lp/blah", "PATH", "F_OK", fp);
151 }
152 #endif
153