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.4 by greg, Mon Jul 13 16:33:19 1992 UTC vs.
Revision 2.15 by schorsch, Mon Oct 27 10:19:31 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 < #ifndef  NIX
13 < #include  <pwd.h>
15 < #endif
12 > #include  <string.h>
13 > #include  <ctype.h>
14  
15 < #ifndef DIRSEP
16 < #define DIRSEP          '/'
19 < #endif
20 < #ifndef PATHSEP
21 < #define PATHSEP         ':'
22 < #endif
15 > #include  "paths.h"
16 > #include  "rtio.h"
17  
24 extern char  *strcpy(), *strcat(), *getenv();
25 extern struct passwd  *getpwnam();
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 */
30 < register char  *fname;
31 < register char  *searchpath;
32 < int  mode;
33 < {
34 < #ifndef  NIX
35 <        struct passwd  *pwent;
24 > getpath /* expand fname, return full path */
25   #endif
26 <        static char  pname[256];
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)
41 <                return(NULL);
37 >        if (fname == NULL) { return(NULL); }
38  
39 <        switch (*fname) {
40 <        case DIRSEP:                            /* relative to root */
41 <        case '.':                               /* relative to cwd */
42 <                strcpy(pname, fname);
43 <                return(pname);
44 < #ifndef NIX
45 <        case '~':                               /* relative to home directory */
46 <                fname++;
47 <                if (*fname == '\0' || *fname == DIRSEP) {       /* ours */
48 <                        if ((cp = getenv("HOME")) == NULL)
49 <                                return(NULL);
50 <                        strcpy(pname, cp);
51 <                        strcat(pname, fname);
52 <                        return(pname);
39 >        pname[0] = '\0';                /* check for full specification */
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                  }
58                cp = pname;                                     /* user */
59                do
60                        *cp++ = *fname++;
61                while (*fname && *fname != DIRSEP);
62                *cp = '\0';
63                if ((pwent = getpwnam(pname)) == NULL)
64                        return(NULL);
65                strcpy(pname, pwent->pw_dir);
66                strcat(pname, fname);
67                return(pname);
68 #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 && cp[-1] != DIRSEP)
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