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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.21 static const char RCSid[] = "$Id: getpath.c,v 2.20 2019/07/21 16:48:34 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * getpath.c - function to search for file in a list of directories
6 greg 2.9 *
7 greg 2.18 * External symbols declared in rtio.h
8 greg 2.9 */
9    
10 greg 2.10 #include "copyright.h"
11 greg 1.1
12 schorsch 2.11 #include <ctype.h>
13 greg 2.7
14 schorsch 2.14 #include "rtio.h"
15 greg 2.17 #include "paths.h"
16 greg 1.1
17    
18 schorsch 2.19 #if defined(_WIN32) || defined(_WIN64)
19 schorsch 2.11 static char *
20     core_getpath /* wrapped below: expand fname, return full path */
21     #else
22 greg 1.1 char *
23 schorsch 2.11 getpath /* expand fname, return full path */
24     #endif
25     (
26 greg 2.18 char *fname,
27     char *searchpath,
28     int mode
29 schorsch 2.11 )
30 greg 1.1 {
31 schorsch 2.11 static char pname[PATH_MAX];
32 schorsch 2.15 char uname[512];
33 greg 2.18 char *cp;
34 schorsch 2.15 int i;
35 greg 1.1
36 schorsch 2.11 if (fname == NULL) { return(NULL); }
37 greg 1.1
38 greg 2.8 pname[0] = '\0'; /* check for full specification */
39 schorsch 2.11
40 schorsch 2.15 if (ISABS(fname)) { /* absolute path */
41 greg 2.20 strlcpy(pname, fname, sizeof(pname));
42 schorsch 2.11 } else {
43     switch (*fname) {
44 greg 2.20 case '.': /* relative to cwd */
45     strlcpy(pname, fname, sizeof(pname));
46 schorsch 2.11 break;
47 greg 2.20 case '~': /* relative to home directory */
48 schorsch 2.11 fname++;
49 schorsch 2.15 cp = uname;
50 greg 2.20 for (i = 0; i < sizeof(uname) && *fname
51     && !ISDIRSEP(*fname); i++)
52 schorsch 2.11 *cp++ = *fname++;
53     *cp = '\0';
54 schorsch 2.15 cp = gethomedir(uname, pname, sizeof(pname));
55     if(cp == NULL) return NULL;
56 greg 2.20 strlcat(pname, fname, sizeof(pname));
57 schorsch 2.11 break;
58 greg 1.1 }
59     }
60 greg 2.8 if (pname[0]) /* got it, check access if search requested */
61 greg 2.20 return(!searchpath || access(pname,mode)==0 ? pname : NULL);
62 greg 1.1
63 greg 2.20 if (!searchpath) { /* no search */
64     strlcpy(pname, fname, sizeof(pname));
65 greg 1.1 return(pname);
66     }
67 schorsch 2.11 /* check search path */
68 greg 1.1 do {
69     cp = pname;
70 greg 2.20 while (*searchpath && (*cp = *searchpath++) != PATHSEP)
71     cp += (cp-pname < sizeof(pname)-2);
72     if (cp > pname && !ISDIRSEP(cp[-1]))
73 greg 2.3 *cp++ = DIRSEP;
74 greg 2.20 *cp = '\0';
75     strlcat(pname, fname, sizeof(pname));
76 greg 1.1 if (access(pname, mode) == 0) /* file accessable? */
77     return(pname);
78     } while (*searchpath);
79 schorsch 2.11 /* not found */
80 greg 1.1 return(NULL);
81     }
82 schorsch 2.11
83    
84 schorsch 2.19 #if defined(_WIN32) || defined(_WIN64)
85 schorsch 2.11 /* 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 greg 2.18 char *ffname,
96     char *searchpath,
97     int mode
98 schorsch 2.11 )
99     {
100 greg 2.18 char *cp;
101 schorsch 2.11 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 schorsch 2.15 printf("Undefining HOME and HOMEPATH\n");
145 schorsch 2.11 unsetenv("HOME");
146 schorsch 2.15 unsetenv("HOMEPATH");
147 schorsch 2.11 fp = getpath("~", getenv("PATH"), F_OK);
148     printf(fmt, "~", "PATH", "F_OK", fp);
149 schorsch 2.15 fp = getpath("~lp/blah", getenv("PATH"), F_OK);
150     printf(fmt, "~lp/blah", "PATH", "F_OK", fp);
151 schorsch 2.11 }
152     #endif
153