--- ray/src/common/getpath.c 2003/02/22 02:07:22 2.9 +++ ray/src/common/getpath.c 2003/10/27 10:19:31 2.15 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: getpath.c,v 2.9 2003/02/22 02:07:22 greg Exp $"; +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 @@ -7,134 +7,148 @@ static const char RCSid[] = "$Id: getpath.c,v 2.9 2003 * External symbols declared in standard.h */ -/* ==================================================================== - * The Radiance Software License, Version 1.0 - * - * Copyright (c) 1990 - 2002 The Regents of the University of California, - * through Lawrence Berkeley National Laboratory. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes Radiance software - * (http://radsite.lbl.gov/) - * developed by the Lawrence Berkeley National Laboratory - * (http://www.lbl.gov/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Radiance," "Lawrence Berkeley National Laboratory" - * and "The Regents of the University of California" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact radiance@radsite.lbl.gov. - * - * 5. Products derived from this software may not be called "Radiance", - * nor may "Radiance" appear in their name, without prior written - * permission of Lawrence Berkeley National Laboratory. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of Lawrence Berkeley National Laboratory. For more - * information on Lawrence Berkeley National Laboratory, please see - * . - */ +#include "copyright.h" -#include "standard.h" +#include +#include #include "paths.h" +#include "rtio.h" -#ifndef NIX -#include -extern struct passwd *getpwnam(); -#endif - +#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); } pname[0] = '\0'; /* check for full specification */ - switch (*fname) { - CASEDIRSEP: /* relative to root */ - case '.': /* relative to cwd */ - strcpy(pname, fname); - break; -#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); - break; + + 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); - break; -#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 +