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.22 by greg, Mon Nov 22 18:23:56 2021 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 rtio.h
8   */
9  
10 < #define  NULL           0
10 > #include "copyright.h"
11  
12 < #include  <pwd.h>
12 > #include  <ctype.h>
13  
14 < extern char  *strcpy(), *strcat(), *getenv();
15 < extern struct passwd  *getpwnam();
14 > #include  "rtio.h"
15 > #include  "paths.h"
16  
17  
18 + #if defined(_WIN32) || defined(_WIN64)
19 + static char *
20 + core_getpath    /* wrapped below: expand fname, return full path */
21 + #else
22   char *
23 < getpath(fname, searchpath, mode)        /* expand fname, return full path */
24 < register char  *fname;
25 < register char  *searchpath;
26 < int  mode;
23 > getpath /* expand fname, return full path */
24 > #endif
25 > (
26 >        char  *fname,
27 >        char  *searchpath,
28 >        int  mode
29 > )
30   {
31 <        static char  pname[256];
32 <        struct passwd  *pwent;
33 <        register char  *cp;
31 >        static char  pname[PATH_MAX];
32 >        char uname[512];
33 >        char  *cp;
34 >        int i;
35  
36 <        if (fname == NULL)
37 <                return(NULL);
36 >        if (!fname | (fname == pname))
37 >                return(fname);
38  
39 <        switch (*fname) {
40 <        case '/':                               /* relative to root */
41 <        case '.':                               /* relative to cwd */
42 <                strcpy(pname, fname);
43 <                return(pname);
44 <        case '~':                               /* relative to home directory */
45 <                fname++;
46 <                if (*fname == '\0' || *fname == '/') {          /* ours */
47 <                        if ((cp = getenv("HOME")) == NULL)
48 <                                return(NULL);
49 <                        strcpy(pname, cp);
50 <                        strcat(pname, fname);
51 <                        return(pname);
39 >        pname[0] = '\0';                /* check for full specification */
40 >
41 >        if (ISABS(fname)) {             /* absolute path */
42 >                strlcpy(pname, fname, sizeof(pname));
43 >        } else {
44 >                switch (*fname) {
45 >                        case '.':       /* relative to cwd */
46 >                                strlcpy(pname, fname, sizeof(pname));
47 >                                break;
48 >                        case '~':       /* relative to home directory */
49 >                                fname++;
50 >                                cp = uname;
51 >                                for (i = 0; i < sizeof(uname) && *fname
52 >                                                && !ISDIRSEP(*fname); i++)
53 >                                        *cp++ = *fname++;
54 >                                *cp = '\0';
55 >                                cp = gethomedir(uname, pname, sizeof(pname));
56 >                                if(cp == NULL) return NULL;
57 >                                strlcat(pname, fname, sizeof(pname));
58 >                                break;
59                  }
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);
60          }
61 +        if (pname[0])           /* got it, check access if search requested */
62 +                return(!searchpath || access(pname,mode)==0 ? pname : NULL);
63  
64 <        if (searchpath == NULL) {                       /* don't search */
65 <                strcpy(pname, fname);
64 >        if (!searchpath) {              /* no search? */
65 >                strlcpy(pname, fname, sizeof(pname));
66                  return(pname);
67          }
68 <                                                        /* check search path */
68 >        /* check search path */
69          do {
70                  cp = pname;
71 <                while (*searchpath && (*cp = *searchpath++) != ':')
72 <                        if (*cp == '\\') {              /* escape */
73 <                                if (*searchpath)
74 <                                        *cp++ = *searchpath++;
75 <                        } else
76 <                                cp++;
71 <                if (cp > pname && cp[-1] != '/')
72 <                        *cp++ = '/';
73 <                strcpy(cp, fname);
71 >                while (*searchpath && (*cp = *searchpath++) != PATHSEP)
72 >                        cp += (cp-pname < sizeof(pname)-2);
73 >                if (cp > pname && !ISDIRSEP(cp[-1]))
74 >                        *cp++ = DIRSEP;
75 >                *cp = '\0';
76 >                strlcat(pname, fname, sizeof(pname));
77                  if (access(pname, mode) == 0)           /* file accessable? */
78                          return(pname);
79          } while (*searchpath);
80 <                                                        /* not found */
80 >        /* not found */
81          return(NULL);
82   }
83 +
84 +
85 + #if defined(_WIN32) || defined(_WIN64)
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 +        char  *ffname,
97 +        char  *searchpath,
98 +        int  mode
99 + )
100 + {
101 +        char  *cp;
102 +        char fname[PATH_MAX];
103 +
104 +        if (!fname | (fname == pname))
105 +                return(fname);
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) || strchr(ffname, '.') > ffname) {
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 +        printf("Undefining HOME and HOMEPATH\n");
146 +        unsetenv("HOME");
147 +        unsetenv("HOMEPATH");
148 +        fp = getpath("~", getenv("PATH"), F_OK);
149 +        printf(fmt,  "~",        "PATH", "F_OK", fp);
150 +        fp = getpath("~lp/blah", getenv("PATH"), F_OK);
151 +        printf(fmt, "~lp/blah",         "PATH", "F_OK", fp);
152 + }
153 + #endif
154 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines