ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
Revision: 2.15
Committed: Mon Oct 27 10:19:31 2003 UTC (20 years, 6 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.14: +12 -38 lines
Log Message:
Added gethomedir.c and various compatibility fixes.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.15 static const char RCSid[] = "$Id: getpath.c,v 2.14 2003/07/17 09:21:29 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 greg 2.6 #include "paths.h"
16 schorsch 2.14 #include "rtio.h"
17 greg 1.1
18    
19 schorsch 2.11 #ifdef _WIN32
20     static char *
21     core_getpath /* wrapped below: expand fname, return full path */
22     #else
23 greg 1.1 char *
24 schorsch 2.11 getpath /* expand fname, return full path */
25     #endif
26     (
27     register char *fname,
28     register char *searchpath,
29     int mode
30     )
31 greg 1.1 {
32 schorsch 2.11 static char pname[PATH_MAX];
33 schorsch 2.15 char uname[512];
34 greg 1.1 register char *cp;
35 schorsch 2.15 int i;
36 greg 1.1
37 schorsch 2.11 if (fname == NULL) { return(NULL); }
38 greg 1.1
39 greg 2.8 pname[0] = '\0'; /* check for full specification */
40 schorsch 2.11
41 schorsch 2.15 if (ISABS(fname)) { /* absolute path */
42 schorsch 2.11 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 schorsch 2.15 cp = uname;
51     for (i=0;i<sizeof(uname)&&*fname!='\0'&&!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 schorsch 2.11 strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
57     break;
58 greg 1.1 }
59     }
60 greg 2.8 if (pname[0]) /* got it, check access if search requested */
61     return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
62 greg 1.1
63     if (searchpath == NULL) { /* don't search */
64 schorsch 2.11 strncpy(pname, fname, sizeof(pname)-1);
65 greg 1.1 return(pname);
66     }
67 schorsch 2.11 /* check search path */
68 greg 1.1 do {
69     cp = pname;
70 schorsch 2.11 while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
71 greg 2.3 cp++;
72 schorsch 2.11 }
73     if (cp > pname && !ISDIRSEP(cp[-1])) {
74 greg 2.3 *cp++ = DIRSEP;
75 schorsch 2.11 }
76     strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
77 greg 1.1 if (access(pname, mode) == 0) /* file accessable? */
78     return(pname);
79     } while (*searchpath);
80 schorsch 2.11 /* not found */
81 greg 1.1 return(NULL);
82     }
83 schorsch 2.11
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 schorsch 2.15 printf("Undefining HOME and HOMEPATH\n");
146 schorsch 2.11 unsetenv("HOME");
147 schorsch 2.15 unsetenv("HOMEPATH");
148 schorsch 2.11 fp = getpath("~", getenv("PATH"), F_OK);
149     printf(fmt, "~", "PATH", "F_OK", fp);
150 schorsch 2.15 fp = getpath("~lp/blah", getenv("PATH"), F_OK);
151     printf(fmt, "~lp/blah", "PATH", "F_OK", fp);
152 schorsch 2.11 }
153     #endif
154