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.7 by greg, Mon Sep 21 11:59:42 1992 UTC vs.
Revision 2.21 by greg, Sat Dec 28 18:05:14 2019 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 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 < #include  "standard.h"
10 > #include "copyright.h"
11  
12 + #include  <ctype.h>
13 +
14 + #include  "rtio.h"
15   #include  "paths.h"
16  
15 #ifndef  NIX
16 #include  <pwd.h>
17 extern struct passwd  *getpwnam();
18 #endif
17  
18 <
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 */
23 < register char  *fname;
24 < register char  *searchpath;
25 < int  mode;
26 < {
27 < #ifndef  NIX
28 <        struct passwd  *pwent;
23 > getpath /* expand fname, return full path */
24   #endif
25 <        static char  pname[MAXPATH];
26 <        register char  *cp;
25 > (
26 >        char  *fname,
27 >        char  *searchpath,
28 >        int  mode
29 > )
30 > {
31 >        static char  pname[PATH_MAX];
32 >        char uname[512];
33 >        char  *cp;
34 >        int i;
35  
36 <        if (fname == NULL)
34 <                return(NULL);
36 >        if (fname == NULL) { return(NULL); }
37  
38 <        switch (*fname) {
39 <        CASEDIRSEP:                             /* relative to root */
40 <        case '.':                               /* relative to cwd */
41 <                strcpy(pname, fname);
42 <                return(pname);
43 < #ifndef NIX
44 <        case '~':                               /* relative to home directory */
45 <                fname++;
46 <                if (*fname == '\0' || ISDIRSEP(*fname)) {       /* ours */
47 <                        if ((cp = getenv("HOME")) == NULL)
48 <                                return(NULL);
49 <                        strcpy(pname, cp);
50 <                        strcat(pname, fname);
51 <                        return(pname);
38 >        pname[0] = '\0';                /* check for full specification */
39 >
40 >        if (ISABS(fname)) { /* absolute path */
41 >                strlcpy(pname, fname, sizeof(pname));
42 >        } else {
43 >                switch (*fname) {
44 >                        case '.':               /* relative to cwd */
45 >                                strlcpy(pname, fname, sizeof(pname));
46 >                                break;
47 >                        case '~':               /* relative to home directory */
48 >                                fname++;
49 >                                cp = uname;
50 >                                for (i = 0; i < sizeof(uname) && *fname
51 >                                                && !ISDIRSEP(*fname); i++)
52 >                                        *cp++ = *fname++;
53 >                                *cp = '\0';
54 >                                cp = gethomedir(uname, pname, sizeof(pname));
55 >                                if(cp == NULL) return NULL;
56 >                                strlcat(pname, fname, sizeof(pname));
57 >                                break;
58                  }
51                cp = pname;                                     /* user */
52                do
53                        *cp++ = *fname++;
54                while (*fname && !ISDIRSEP(*fname));
55                *cp = '\0';
56                if ((pwent = getpwnam(pname)) == NULL)
57                        return(NULL);
58                strcpy(pname, pwent->pw_dir);
59                strcat(pname, fname);
60                return(pname);
61 #endif
59          }
60 +        if (pname[0])           /* got it, check access if search requested */
61 +                return(!searchpath || access(pname,mode)==0 ? pname : NULL);
62  
63 <        if (searchpath == NULL) {                       /* don't search */
64 <                strcpy(pname, fname);
63 >        if (!searchpath) {                      /* no search */
64 >                strlcpy(pname, fname, sizeof(pname));
65                  return(pname);
66          }
67 <                                                        /* check search path */
67 >        /* check search path */
68          do {
69                  cp = pname;
70                  while (*searchpath && (*cp = *searchpath++) != PATHSEP)
71 <                        cp++;
71 >                        cp += (cp-pname < sizeof(pname)-2);
72                  if (cp > pname && !ISDIRSEP(cp[-1]))
73                          *cp++ = DIRSEP;
74 <                strcpy(cp, fname);
74 >                *cp = '\0';
75 >                strlcat(pname, fname, sizeof(pname));
76                  if (access(pname, mode) == 0)           /* file accessable? */
77                          return(pname);
78          } while (*searchpath);
79 <                                                        /* not found */
79 >        /* not found */
80          return(NULL);
81   }
82 +
83 +
84 + #if defined(_WIN32) || defined(_WIN64)
85 + /* This is a wrapper around the above, "emulating" access mode X_OK,
86 +   which is not supported on Windows.
87 +   If we see X_OK and the filename has no extension, then we'll remove
88 +   the X_OK from the mode, append ".exe" to the file name, and search
89 +   with the resulting string. If that fails, we'll try again with ".bat".
90 +   Theoretically, we might still not have execute rights on a file we find
91 +   like this, but that's rare enough not to be worth checking the ACLs.
92 + */
93 + char *
94 + getpath(        /* expand fname, return full path */
95 +        char  *ffname,
96 +        char  *searchpath,
97 +        int  mode
98 + )
99 + {
100 +        char  *cp;
101 +        char fname[PATH_MAX];
102 +
103 +        if (ffname == NULL)
104 +                return(NULL);
105 +
106 +        /* if we have a dot in the string, we assume there is a file name
107 +           extension present */
108 +        /* XXX We'd better test for .exe/.bat/.etc explicitly */
109 +        if (!(mode & X_OK) || (strrchr(ffname, '.') != NULL)) {
110 +                return core_getpath(ffname, searchpath, mode);
111 +        }
112 +
113 +        /* We're looking for an executable, Windows doesn't have X_OK. */
114 +        mode &= ~X_OK;
115 +        /* Append .exe */
116 +        strncpy(fname, ffname, sizeof(fname)-5);
117 +        strcat(fname, ".exe");
118 +        cp = core_getpath(fname, searchpath, mode);
119 +        if (cp != NULL) return cp;
120 +
121 +        /* Try with .bat this time... */
122 +        strncpy(fname, ffname, sizeof(fname)-5);
123 +        strcat(fname, ".bat");
124 +        cp = core_getpath(fname, searchpath, mode);
125 +        return cp;
126 + }
127 + #endif /* _WIN32 */
128 +
129 +
130 + #ifdef TEST_MODULE
131 + int main()
132 + {
133 +        char * fp;
134 +        char fmt[] = "%15s %-10s %s: %s\n";
135 +
136 +        fp = getpath("rayinit.cal", getenv("RAYPATH"), R_OK);
137 +        printf(fmt,  "rayinit.cal",        "RAYPATH", "R_OK", fp);
138 +        fp = getpath("mkillum", getenv("PATH"), X_OK);
139 +        printf(fmt,  "mkillum",        "PATH", "X_OK", fp);
140 +        fp = getpath("/", getenv("PATH"), W_OK);
141 +        printf(fmt,  "/",        "PATH", "W_OK", fp);
142 +        fp = getpath("~", getenv("PATH"), F_OK);
143 +        printf(fmt,  "~",        "PATH", "F_OK", fp);
144 +        printf("Undefining HOME and HOMEPATH\n");
145 +        unsetenv("HOME");
146 +        unsetenv("HOMEPATH");
147 +        fp = getpath("~", getenv("PATH"), F_OK);
148 +        printf(fmt,  "~",        "PATH", "F_OK", fp);
149 +        fp = getpath("~lp/blah", getenv("PATH"), F_OK);
150 +        printf(fmt, "~lp/blah",         "PATH", "F_OK", fp);
151 + }
152 + #endif
153 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines