ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
Revision: 2.14
Committed: Thu Jul 17 09:21:29 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.13: +2 -2 lines
Log Message:
Added prototypes and includes from patch by Randolph Fritz.
Added more required includes and reduced other compile warnings.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.14 static const char RCSid[] = "$Id: getpath.c,v 2.13 2003/07/03 20:59:00 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 schorsch 2.13 #ifdef RHAS_GETPWNAM
15 schorsch 2.11 #include <pwd.h>
16     #include <sys/types.h>
17     #endif
18 greg 2.7
19 greg 2.6 #include "paths.h"
20 schorsch 2.14 #include "rtio.h"
21 greg 1.1
22    
23 schorsch 2.11 #ifdef _WIN32
24     static char *
25     core_getpath /* wrapped below: expand fname, return full path */
26     #else
27 greg 1.1 char *
28 schorsch 2.11 getpath /* expand fname, return full path */
29     #endif
30     (
31     register char *fname,
32     register char *searchpath,
33     int mode
34     )
35 greg 1.1 {
36 schorsch 2.13 #ifdef RHAS_GETPWNAM
37 greg 2.4 struct passwd *pwent;
38     #endif
39 schorsch 2.11 static char pname[PATH_MAX];
40 greg 1.1 register char *cp;
41    
42 schorsch 2.11 if (fname == NULL) { return(NULL); }
43 greg 1.1
44 greg 2.8 pname[0] = '\0'; /* check for full specification */
45 schorsch 2.11
46     if (ISABS(fname)) { /* Can't use CASEDIRSEP below on Windows */
47     strncpy(pname, fname, sizeof(pname)-1);
48     } else {
49     switch (*fname) {
50     /* XXX This doesn't work on Windows */
51     /* CASEDIRSEP: */ /* relative to root */
52     case '.': /* relative to cwd */
53     strncpy(pname, fname, sizeof(pname)-1);
54     break;
55     case '~': /* relative to home directory */
56     fname++;
57     if (*fname == '\0' || ISDIRSEP(*fname)) { /* ours */
58     if ((cp = getenv("HOME")) == NULL)
59     #ifdef _WIN32 /* Windows sometimes uses a different var name */
60     if ((cp = getenv("HOMEDIR")) == NULL)
61     #endif
62     return(NULL);
63     strncpy(pname, cp, sizeof(pname)-1);
64     strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
65     break;
66     }
67 schorsch 2.13 #ifdef RHAS_GETPWNAM
68 schorsch 2.11 /* XXX Should we request our own home directory from the
69     XXX system as well if the above fails? */
70     /* XXX In any case, we need do the same thing on Windows... */
71     cp = pname; /* user */
72     do
73     *cp++ = *fname++;
74     while (*fname && !ISDIRSEP(*fname));
75     *cp = '\0';
76     if ((pwent = getpwnam(pname)) == NULL)
77     return(NULL);
78     strncpy(pname, pwent->pw_dir, sizeof(pname)-1);
79     strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
80     break;
81     #endif
82 greg 1.1 }
83     }
84 greg 2.8 if (pname[0]) /* got it, check access if search requested */
85     return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
86 greg 1.1
87     if (searchpath == NULL) { /* don't search */
88 schorsch 2.11 strncpy(pname, fname, sizeof(pname)-1);
89 greg 1.1 return(pname);
90     }
91 schorsch 2.11 /* check search path */
92 greg 1.1 do {
93     cp = pname;
94 schorsch 2.11 while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
95 greg 2.3 cp++;
96 schorsch 2.11 }
97     if (cp > pname && !ISDIRSEP(cp[-1])) {
98 greg 2.3 *cp++ = DIRSEP;
99 schorsch 2.11 }
100     strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
101 greg 1.1 if (access(pname, mode) == 0) /* file accessable? */
102     return(pname);
103     } while (*searchpath);
104 schorsch 2.11 /* not found */
105 greg 1.1 return(NULL);
106     }
107 schorsch 2.11
108    
109     #ifdef _WIN32
110     /* This is a wrapper around the above, "emulating" access mode X_OK,
111     which is not supported on Windows.
112     If we see X_OK and the filename has no extension, then we'll remove
113     the X_OK from the mode, append ".exe" to the file name, and search
114     with the resulting string. If that fails, we'll try again with ".bat".
115     Theoretically, we might still not have execute rights on a file we find
116     like this, but that's rare enough not to be worth checking the ACLs.
117     */
118     char *
119     getpath( /* expand fname, return full path */
120     register char *ffname,
121     register char *searchpath,
122     int mode
123     )
124     {
125     register char *cp;
126     char fname[PATH_MAX];
127    
128     if (ffname == NULL)
129     return(NULL);
130    
131     /* if we have a dot in the string, we assume there is a file name
132     extension present */
133     /* XXX We'd better test for .exe/.bat/.etc explicitly */
134     if (!(mode & X_OK) || (strrchr(ffname, '.') != NULL)) {
135     return core_getpath(ffname, searchpath, mode);
136     }
137    
138     /* We're looking for an executable, Windows doesn't have X_OK. */
139     mode &= ~X_OK;
140     /* Append .exe */
141     strncpy(fname, ffname, sizeof(fname)-5);
142     strcat(fname, ".exe");
143     cp = core_getpath(fname, searchpath, mode);
144     if (cp != NULL) return cp;
145    
146     /* Try with .bat this time... */
147     strncpy(fname, ffname, sizeof(fname)-5);
148     strcat(fname, ".bat");
149     cp = core_getpath(fname, searchpath, mode);
150     return cp;
151     }
152     #endif /* _WIN32 */
153    
154    
155     #ifdef TEST_MODULE
156     int main()
157     {
158     char * fp;
159     char fmt[] = "%15s %-10s %s: %s\n";
160    
161     fp = getpath("rayinit.cal", getenv("RAYPATH"), R_OK);
162     printf(fmt, "rayinit.cal", "RAYPATH", "R_OK", fp);
163     fp = getpath("mkillum", getenv("PATH"), X_OK);
164     printf(fmt, "mkillum", "PATH", "X_OK", fp);
165     fp = getpath("/", getenv("PATH"), W_OK);
166     printf(fmt, "/", "PATH", "W_OK", fp);
167     fp = getpath("~", getenv("PATH"), F_OK);
168     printf(fmt, "~", "PATH", "F_OK", fp);
169     printf("Undefining HOME and HOMEDIR\n");
170     unsetenv("HOME");
171     unsetenv("HOMEDIR");
172     fp = getpath("~", getenv("PATH"), F_OK);
173     printf(fmt, "~", "PATH", "F_OK", fp);
174 schorsch 2.12 #ifndef RHAS_GETPWNAM
175 schorsch 2.11 fp = getpath("~lp", getenv("PATH"), F_OK);
176     printf(fmt, "~lp", "PATH", "F_OK", fp);
177     #endif
178     }
179     #endif
180