ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/getpath.c
(Generate patch)

Comparing ray/src/common/getpath.c (file contents):
Revision 2.3 by greg, Tue Jun 16 13:29:35 1992 UTC vs.
Revision 2.11 by schorsch, Thu Jun 26 00:58:09 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
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 < #define  NULL           0
10 > #include "copyright.h"
11  
12 < #include  <pwd.h>
13 <
14 < #ifndef DIRSEP
15 < #define DIRSEP          '/'
12 > #include  <string.h>
13 > #include  <ctype.h>
14 > #ifndef  _WIN32 /* XXX was NIX, do we still compile on Amiga? */
15 >  #include  <pwd.h>
16 >  #include  <sys/types.h>
17   #endif
18 #ifndef PATHSEP
19 #define PATHSEP         ':'
20 #endif
18  
19 < extern char  *strcpy(), *strcat(), *getenv();
23 < extern struct passwd  *getpwnam();
19 > #include  "paths.h"
20  
21  
22 +
23 + #ifdef _WIN32
24 + static char *
25 + core_getpath    /* wrapped below: expand fname, return full path */
26 + #else
27   char *
28 < getpath(fname, searchpath, mode)        /* expand fname, return full path */
29 < register char  *fname;
30 < register char  *searchpath;
31 < int  mode;
28 > getpath /* expand fname, return full path */
29 > #endif
30 > (
31 > register char  *fname,
32 > register char  *searchpath,
33 > int  mode
34 > )
35   {
36 <        static char  pname[256];
36 > #ifndef  _WIN32 /* XXX was NIX, do we still compile on Amiga? */
37          struct passwd  *pwent;
38 + #endif
39 +        static char  pname[PATH_MAX];
40          register char  *cp;
41  
42 <        if (fname == NULL)
37 <                return(NULL);
42 >        if (fname == NULL) { return(NULL); }
43  
44 <        switch (*fname) {
45 <        case DIRSEP:                            /* relative to root */
46 <        case '.':                               /* relative to cwd */
47 <                strcpy(pname, fname);
48 <                return(pname);
49 < #ifndef NIX
50 <        case '~':                               /* relative to home directory */
51 <                fname++;
52 <                if (*fname == '\0' || *fname == DIRSEP) {       /* ours */
53 <                        if ((cp = getenv("HOME")) == NULL)
54 <                                return(NULL);
55 <                        strcpy(pname, cp);
56 <                        strcat(pname, fname);
57 <                        return(pname);
58 <                }
59 <                cp = pname;                                     /* user */
60 <                do
56 <                        *cp++ = *fname++;
57 <                while (*fname && *fname != DIRSEP);
58 <                *cp = '\0';
59 <                if ((pwent = getpwnam(pname)) == NULL)
60 <                        return(NULL);
61 <                strcpy(pname, pwent->pw_dir);
62 <                strcat(pname, fname);
63 <                return(pname);
44 >        pname[0] = '\0';                /* check for full specification */
45 >
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 + #ifndef _WIN32 /* XXX was NIX, do we still compile on Amiga? */
68 +                                /* 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 +                }
83          }
84 +        if (pname[0])           /* got it, check access if search requested */
85 +                return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
86  
87          if (searchpath == NULL) {                       /* don't search */
88 <                strcpy(pname, fname);
88 >                strncpy(pname, fname, sizeof(pname)-1);
89                  return(pname);
90          }
91 <                                                        /* check search path */
91 >        /* check search path */
92          do {
93                  cp = pname;
94 <                while (*searchpath && (*cp = *searchpath++) != PATHSEP)
94 >                while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
95                          cp++;
96 <                if (cp > pname && cp[-1] != DIRSEP)
96 >                }
97 >                if (cp > pname && !ISDIRSEP(cp[-1])) {
98                          *cp++ = DIRSEP;
99 <                strcpy(cp, fname);
99 >                }
100 >                strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
101                  if (access(pname, mode) == 0)           /* file accessable? */
102                          return(pname);
103          } while (*searchpath);
104 <                                                        /* not found */
104 >        /* not found */
105          return(NULL);
106   }
107 +
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 + #ifndef _WIN32 /* XXX was NIX, do we still compile on Amiga? */
175 +        fp = getpath("~lp", getenv("PATH"), F_OK);
176 +        printf(fmt, "~lp",         "PATH", "F_OK", fp);
177 + #endif
178 + }
179 + #endif
180 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines