--- ray/src/common/getpath.c 1992/09/08 10:04:34 2.6 +++ ray/src/common/getpath.c 2003/10/27 10:19:31 2.15 @@ -1,83 +1,154 @@ -/* Copyright (c) 1992 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: getpath.c,v 2.15 2003/10/27 10:19:31 schorsch Exp $"; #endif - /* * getpath.c - function to search for file in a list of directories + * + * External symbols declared in standard.h */ -#include "paths.h" +#include "copyright.h" -#define NULL 0 +#include +#include -#ifndef NIX -#include -extern struct passwd *getpwnam(); -#endif +#include "paths.h" +#include "rtio.h" -extern char *strcpy(), *strcat(), *getenv(); - +#ifdef _WIN32 +static char * +core_getpath /* wrapped below: expand fname, return full path */ +#else char * -getpath(fname, searchpath, mode) /* expand fname, return full path */ -register char *fname; -register char *searchpath; -int mode; -{ -#ifndef NIX - struct passwd *pwent; +getpath /* expand fname, return full path */ #endif - static char pname[MAXPATH]; +( +register char *fname, +register char *searchpath, +int mode +) +{ + static char pname[PATH_MAX]; + char uname[512]; register char *cp; + int i; - if (fname == NULL) - return(NULL); + if (fname == NULL) { return(NULL); } - switch (*fname) { - CASEDIRSEP: /* relative to root */ - case '.': /* relative to cwd */ - strcpy(pname, fname); - return(pname); -#ifndef NIX - case '~': /* relative to home directory */ - fname++; - if (*fname == '\0' || ISDIRSEP(*fname)) { /* ours */ - if ((cp = getenv("HOME")) == NULL) - return(NULL); - strcpy(pname, cp); - strcat(pname, fname); - return(pname); + pname[0] = '\0'; /* check for full specification */ + + if (ISABS(fname)) { /* absolute path */ + strncpy(pname, fname, sizeof(pname)-1); + } else { + switch (*fname) { + case '.': /* relative to cwd */ + strncpy(pname, fname, sizeof(pname)-1); + break; + case '~': /* relative to home directory */ + fname++; + cp = uname; + for (i=0;ipw_dir); - strcat(pname, fname); - return(pname); -#endif } + if (pname[0]) /* got it, check access if search requested */ + return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL); if (searchpath == NULL) { /* don't search */ - strcpy(pname, fname); + strncpy(pname, fname, sizeof(pname)-1); return(pname); } - /* check search path */ + /* check search path */ do { cp = pname; - while (*searchpath && (*cp = *searchpath++) != PATHSEP) + while (*searchpath && (*cp = *searchpath++) != PATHSEP) { cp++; - if (cp > pname && !ISDIRSEP(cp[-1])) + } + if (cp > pname && !ISDIRSEP(cp[-1])) { *cp++ = DIRSEP; - strcpy(cp, fname); + } + strncpy(cp, fname, sizeof(pname)-strlen(pname)-1); if (access(pname, mode) == 0) /* file accessable? */ return(pname); } while (*searchpath); - /* not found */ + /* not found */ return(NULL); } + + +#ifdef _WIN32 +/* This is a wrapper around the above, "emulating" access mode X_OK, + which is not supported on Windows. + If we see X_OK and the filename has no extension, then we'll remove + the X_OK from the mode, append ".exe" to the file name, and search + with the resulting string. If that fails, we'll try again with ".bat". + Theoretically, we might still not have execute rights on a file we find + like this, but that's rare enough not to be worth checking the ACLs. +*/ +char * +getpath( /* expand fname, return full path */ +register char *ffname, +register char *searchpath, +int mode +) +{ + register char *cp; + char fname[PATH_MAX]; + + if (ffname == NULL) + return(NULL); + + /* if we have a dot in the string, we assume there is a file name + extension present */ + /* XXX We'd better test for .exe/.bat/.etc explicitly */ + if (!(mode & X_OK) || (strrchr(ffname, '.') != NULL)) { + return core_getpath(ffname, searchpath, mode); + } + + /* We're looking for an executable, Windows doesn't have X_OK. */ + mode &= ~X_OK; + /* Append .exe */ + strncpy(fname, ffname, sizeof(fname)-5); + strcat(fname, ".exe"); + cp = core_getpath(fname, searchpath, mode); + if (cp != NULL) return cp; + + /* Try with .bat this time... */ + strncpy(fname, ffname, sizeof(fname)-5); + strcat(fname, ".bat"); + cp = core_getpath(fname, searchpath, mode); + return cp; +} +#endif /* _WIN32 */ + + +#ifdef TEST_MODULE +int main() +{ + char * fp; + char fmt[] = "%15s %-10s %s: %s\n"; + + fp = getpath("rayinit.cal", getenv("RAYPATH"), R_OK); + printf(fmt, "rayinit.cal", "RAYPATH", "R_OK", fp); + fp = getpath("mkillum", getenv("PATH"), X_OK); + printf(fmt, "mkillum", "PATH", "X_OK", fp); + fp = getpath("/", getenv("PATH"), W_OK); + printf(fmt, "/", "PATH", "W_OK", fp); + fp = getpath("~", getenv("PATH"), F_OK); + printf(fmt, "~", "PATH", "F_OK", fp); + printf("Undefining HOME and HOMEPATH\n"); + unsetenv("HOME"); + unsetenv("HOMEPATH"); + fp = getpath("~", getenv("PATH"), F_OK); + printf(fmt, "~", "PATH", "F_OK", fp); + fp = getpath("~lp/blah", getenv("PATH"), F_OK); + printf(fmt, "~lp/blah", "PATH", "F_OK", fp); +} +#endif +