ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
Revision: 2.17
Committed: Thu Feb 12 18:55:50 2004 UTC (20 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 2.16: +2 -1 lines
Log Message:
Moved paths.h out of rtio.h and included it manually where R_OK was needed

File Contents

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