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.15 by schorsch, Mon Oct 27 10:19:31 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  
15   #include  "paths.h"
16 + #include  "rtio.h"
17  
16 #ifndef  NIX
17 #include  <pwd.h>
18 extern struct passwd  *getpwnam();
19 #endif
18  
19 <
19 > #ifdef _WIN32
20 > static char *
21 > core_getpath    /* wrapped below: expand fname, return full path */
22 > #else
23   char *
24 < getpath(fname, searchpath, mode)        /* expand fname, return full path */
24 < register char  *fname;
25 < register char  *searchpath;
26 < int  mode;
27 < {
28 < #ifndef  NIX
29 <        struct passwd  *pwent;
24 > getpath /* expand fname, return full path */
25   #endif
26 <        static char  pname[MAXPATH];
26 > (
27 > register char  *fname,
28 > register char  *searchpath,
29 > int  mode
30 > )
31 > {
32 >        static char  pname[PATH_MAX];
33 >        char uname[512];
34          register char  *cp;
35 +        int i;
36  
37 <        if (fname == NULL)
35 <                return(NULL);
37 >        if (fname == NULL) { return(NULL); }
38  
39          pname[0] = '\0';                /* check for full specification */
40 <        switch (*fname) {
41 <        CASEDIRSEP:                             /* relative to root */
42 <        case '.':                               /* relative to cwd */
43 <                strcpy(pname, fname);
44 <                break;
45 < #ifndef NIX
46 <        case '~':                               /* relative to home directory */
47 <                fname++;
48 <                if (*fname == '\0' || ISDIRSEP(*fname)) {       /* ours */
49 <                        if ((cp = getenv("HOME")) == NULL)
50 <                                return(NULL);
51 <                        strcpy(pname, cp);
52 <                        strcat(pname, fname);
53 <                        break;
40 >
41 >        if (ISABS(fname)) { /* absolute path */
42 >                strncpy(pname, fname, sizeof(pname)-1);
43 >        } else {
44 >                switch (*fname) {
45 >                        case '.':                               /* relative to cwd */
46 >                                strncpy(pname, fname, sizeof(pname)-1);
47 >                                break;
48 >                        case '~':                               /* relative to home directory */
49 >                                fname++;
50 >                                cp = uname;
51 >                                for (i=0;i<sizeof(uname)&&*fname!='\0'&&!ISDIRSEP(*fname);i++)
52 >                                        *cp++ = *fname++;
53 >                                *cp = '\0';
54 >                                cp = gethomedir(uname, pname, sizeof(pname));
55 >                                if(cp == NULL) return NULL;
56 >                                strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
57 >                                break;
58                  }
53                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;
63 #endif
59          }
60          if (pname[0])           /* got it, check access if search requested */
61                  return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
62  
63          if (searchpath == NULL) {                       /* don't search */
64 <                strcpy(pname, fname);
64 >                strncpy(pname, fname, sizeof(pname)-1);
65                  return(pname);
66          }
67 <                                                        /* check search path */
67 >        /* check search path */
68          do {
69                  cp = pname;
70 <                while (*searchpath && (*cp = *searchpath++) != PATHSEP)
70 >                while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
71                          cp++;
72 <                if (cp > pname && !ISDIRSEP(cp[-1]))
72 >                }
73 >                if (cp > pname && !ISDIRSEP(cp[-1])) {
74                          *cp++ = DIRSEP;
75 <                strcpy(cp, fname);
75 >                }
76 >                strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
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 + #ifdef _WIN32
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 + register char  *ffname,
97 + register char  *searchpath,
98 + int  mode
99 + )
100 + {
101 +        register char  *cp;
102 +        char fname[PATH_MAX];
103 +
104 +        if (ffname == NULL)
105 +                return(NULL);
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) || (strrchr(ffname, '.') != NULL)) {
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