ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
Revision: 2.16
Committed: Fri Nov 14 17:22:06 2003 UTC (20 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.15: +1 -2 lines
Log Message:
Reduced compile warnings, and other compatibility fixes.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: getpath.c,v 2.15 2003/10/27 10:19:31 schorsch Exp $";
3 #endif
4 /*
5 * getpath.c - function to search for file in a list of directories
6 *
7 * External symbols declared in standard.h
8 */
9
10 #include "copyright.h"
11
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "rtio.h"
16
17
18 #ifdef _WIN32
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 register char *fname,
27 register char *searchpath,
28 int mode
29 )
30 {
31 static char pname[PATH_MAX];
32 char uname[512];
33 register 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 strncpy(pname, fname, sizeof(pname)-1);
42 } else {
43 switch (*fname) {
44 case '.': /* relative to cwd */
45 strncpy(pname, fname, sizeof(pname)-1);
46 break;
47 case '~': /* relative to home directory */
48 fname++;
49 cp = uname;
50 for (i=0;i<sizeof(uname)&&*fname!='\0'&&!ISDIRSEP(*fname);i++)
51 *cp++ = *fname++;
52 *cp = '\0';
53 cp = gethomedir(uname, pname, sizeof(pname));
54 if(cp == NULL) return NULL;
55 strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
56 break;
57 }
58 }
59 if (pname[0]) /* got it, check access if search requested */
60 return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
61
62 if (searchpath == NULL) { /* don't search */
63 strncpy(pname, fname, sizeof(pname)-1);
64 return(pname);
65 }
66 /* check search path */
67 do {
68 cp = pname;
69 while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
70 cp++;
71 }
72 if (cp > pname && !ISDIRSEP(cp[-1])) {
73 *cp++ = DIRSEP;
74 }
75 strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
76 if (access(pname, mode) == 0) /* file accessable? */
77 return(pname);
78 } while (*searchpath);
79 /* not found */
80 return(NULL);
81 }
82
83
84 #ifdef _WIN32
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 register char *ffname,
96 register char *searchpath,
97 int mode
98 )
99 {
100 register 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