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.2 by greg, Wed Mar 25 10:57:29 1992 UTC vs.
Revision 2.13 by schorsch, Thu Jul 3 20:59:00 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>
12 > #include  <string.h>
13 > #include  <ctype.h>
14 > #ifdef   RHAS_GETPWNAM
15 >  #include  <pwd.h>
16 >  #include  <sys/types.h>
17 > #endif
18  
19 < extern char  *strcpy(), *strcat(), *getenv();
16 < 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 > #ifdef   RHAS_GETPWNAM
37          struct passwd  *pwent;
38 + #endif
39 +        static char  pname[PATH_MAX];
40          register char  *cp;
41  
42 <        if (fname == NULL)
30 <                return(NULL);
42 >        if (fname == NULL) { return(NULL); }
43  
44 <        switch (*fname) {
45 <        case '/':                               /* relative to root */
46 <        case '.':                               /* relative to cwd */
47 <                strcpy(pname, fname);
48 <                return(pname);
49 <        case '~':                               /* relative to home directory */
50 <                fname++;
51 <                if (*fname == '\0' || *fname == '/') {          /* ours */
52 <                        if ((cp = getenv("HOME")) == NULL)
53 <                                return(NULL);
54 <                        strcpy(pname, cp);
55 <                        strcat(pname, fname);
56 <                        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 > #ifdef RHAS_GETPWNAM
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                  }
46                cp = pname;                                     /* user */
47                do
48                        *cp++ = *fname++;
49                while (*fname && *fname != '/');
50                *cp = '\0';
51                if ((pwent = getpwnam(pname)) == NULL)
52                        return(NULL);
53                strcpy(pname, pwent->pw_dir);
54                strcat(pname, fname);
55                return(pname);
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++) != ':')
95 <                        if (*cp == '\\') {              /* escape */
96 <                                if (*searchpath)
97 <                                        *cp++ = *searchpath++;
98 <                        } else
99 <                                cp++;
100 <                if (cp > pname && cp[-1] != '/')
72 <                        *cp++ = '/';
73 <                strcpy(cp, fname);
94 >                while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
95 >                        cp++;
96 >                }
97 >                if (cp > pname && !ISDIRSEP(cp[-1])) {
98 >                        *cp++ = DIRSEP;
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 RHAS_GETPWNAM
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