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.10 by greg, Tue Feb 25 02:47:21 2003 UTC vs.
Revision 2.11 by schorsch, Thu Jun 26 00:58:09 2003 UTC

# Line 9 | Line 9 | static const char      RCSid[] = "$Id$";
9  
10   #include "copyright.h"
11  
12 < #include  "standard.h"
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  
19   #include  "paths.h"
20  
16 #ifndef  NIX
17 #include  <pwd.h>
18 extern struct passwd  *getpwnam();
19 #endif
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 < #ifndef  NIX
36 > #ifndef  _WIN32 /* XXX was NIX, do we still compile on Amiga? */
37          struct passwd  *pwent;
38   #endif
39 <        static char  pname[MAXPATH];
39 >        static char  pname[PATH_MAX];
40          register char  *cp;
41  
42 <        if (fname == NULL)
35 <                return(NULL);
42 >        if (fname == NULL) { return(NULL); }
43  
44          pname[0] = '\0';                /* check for full specification */
45 <        switch (*fname) {
46 <        CASEDIRSEP:                             /* relative to root */
47 <        case '.':                               /* relative to cwd */
48 <                strcpy(pname, fname);
49 <                break;
50 < #ifndef NIX
51 <        case '~':                               /* relative to home directory */
52 <                fname++;
53 <                if (*fname == '\0' || ISDIRSEP(*fname)) {       /* ours */
54 <                        if ((cp = getenv("HOME")) == NULL)
55 <                                return(NULL);
56 <                        strcpy(pname, cp);
57 <                        strcat(pname, fname);
58 <                        break;
59 <                }
60 <                cp = pname;                                     /* user */
54 <                do
55 <                        *cp++ = *fname++;
56 <                while (*fname && !ISDIRSEP(*fname));
57 <                *cp = '\0';
58 <                if ((pwent = getpwnam(pname)) == NULL)
59 <                        return(NULL);
60 <                strcpy(pname, pwent->pw_dir);
61 <                strcat(pname, fname);
62 <                break;
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 && !ISDIRSEP(cp[-1]))
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