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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.16 static const char RCSid[] = "$Id: getpath.c,v 2.15 2003/10/27 10:19:31 schorsch 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     * External symbols declared in standard.h
8     */
9    
10 greg 2.10 #include "copyright.h"
11 greg 1.1
12 schorsch 2.11 #include <string.h>
13     #include <ctype.h>
14 greg 2.7
15 schorsch 2.14 #include "rtio.h"
16 greg 1.1
17    
18 schorsch 2.11 #ifdef _WIN32
19     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     register char *fname,
27     register char *searchpath,
28     int mode
29     )
30 greg 1.1 {
31 schorsch 2.11 static char pname[PATH_MAX];
32 schorsch 2.15 char uname[512];
33 greg 1.1 register 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 schorsch 2.11 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 schorsch 2.15 cp = uname;
50     for (i=0;i<sizeof(uname)&&*fname!='\0'&&!ISDIRSEP(*fname);i++)
51 schorsch 2.11 *cp++ = *fname++;
52     *cp = '\0';
53 schorsch 2.15 cp = gethomedir(uname, pname, sizeof(pname));
54     if(cp == NULL) return NULL;
55 schorsch 2.11 strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
56     break;
57 greg 1.1 }
58     }
59 greg 2.8 if (pname[0]) /* got it, check access if search requested */
60     return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
61 greg 1.1
62     if (searchpath == NULL) { /* don't search */
63 schorsch 2.11 strncpy(pname, fname, sizeof(pname)-1);
64 greg 1.1 return(pname);
65     }
66 schorsch 2.11 /* check search path */
67 greg 1.1 do {
68     cp = pname;
69 schorsch 2.11 while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
70 greg 2.3 cp++;
71 schorsch 2.11 }
72     if (cp > pname && !ISDIRSEP(cp[-1])) {
73 greg 2.3 *cp++ = DIRSEP;
74 schorsch 2.11 }
75     strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
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     #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 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