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.3 by greg, Tue Jun 16 13:29:35 1992 UTC vs.
Revision 2.16 by schorsch, Fri Nov 14 17:22:06 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  
15 < #ifndef DIRSEP
16 < #define DIRSEP          '/'
17 < #endif
18 < #ifndef PATHSEP
19 < #define PATHSEP         ':'
20 < #endif
15 > #include  "rtio.h"
16  
22 extern char  *strcpy(), *strcat(), *getenv();
23 extern struct passwd  *getpwnam();
17  
18 <
18 > #ifdef _WIN32
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 > register char  *fname,
27 > register char  *searchpath,
28 > int  mode
29 > )
30   {
31 <        static char  pname[256];
32 <        struct passwd  *pwent;
31 >        static char  pname[PATH_MAX];
32 >        char uname[512];
33          register char  *cp;
34 +        int i;
35  
36 <        if (fname == NULL)
37 <                return(NULL);
36 >        if (fname == NULL) { return(NULL); }
37  
38 <        switch (*fname) {
39 <        case DIRSEP:                            /* 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' || *fname == DIRSEP) {       /* 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 >                strncpy(pname, fname, sizeof(pname)-1);
42 >        } else {
43 >                switch (*fname) {
44 >                        case '.':                               /* relative to cwd */
45 >                                strncpy(pname, fname, sizeof(pname)-1);
46 >                                break;
47 >                        case '~':                               /* relative to home directory */
48 >                                fname++;
49 >                                cp = uname;
50 >                                for (i=0;i<sizeof(uname)&&*fname!='\0'&&!ISDIRSEP(*fname);i++)
51 >                                        *cp++ = *fname++;
52 >                                *cp = '\0';
53 >                                cp = gethomedir(uname, pname, sizeof(pname));
54 >                                if(cp == NULL) return NULL;
55 >                                strncat(pname, fname, sizeof(pname)-strlen(pname)-1);
56 >                                break;
57                  }
54                cp = pname;                                     /* user */
55                do
56                        *cp++ = *fname++;
57                while (*fname && *fname != DIRSEP);
58                *cp = '\0';
59                if ((pwent = getpwnam(pname)) == NULL)
60                        return(NULL);
61                strcpy(pname, pwent->pw_dir);
62                strcat(pname, fname);
63                return(pname);
64 #endif
58          }
59 +        if (pname[0])           /* got it, check access if search requested */
60 +                return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL);
61  
62          if (searchpath == NULL) {                       /* don't search */
63 <                strcpy(pname, fname);
63 >                strncpy(pname, fname, sizeof(pname)-1);
64                  return(pname);
65          }
66 <                                                        /* check search path */
66 >        /* check search path */
67          do {
68                  cp = pname;
69 <                while (*searchpath && (*cp = *searchpath++) != PATHSEP)
69 >                while (*searchpath && (*cp = *searchpath++) != PATHSEP) {
70                          cp++;
71 <                if (cp > pname && cp[-1] != DIRSEP)
71 >                }
72 >                if (cp > pname && !ISDIRSEP(cp[-1])) {
73                          *cp++ = DIRSEP;
74 <                strcpy(cp, fname);
74 >                }
75 >                strncpy(cp, fname, sizeof(pname)-strlen(pname)-1);
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 + #ifdef _WIN32
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 + register char  *ffname,
96 + register char  *searchpath,
97 + int  mode
98 + )
99 + {
100 +        register 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