--- ray/src/common/getpath.c 2003/02/22 02:07:22 2.9
+++ ray/src/common/getpath.c 2016/03/06 01:13:17 2.19
@@ -1,140 +1,154 @@
#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.19 2016/03/06 01:13:17 schorsch Exp $";
#endif
/*
* getpath.c - function to search for file in a list of directories
*
- * External symbols declared in standard.h
+ * External symbols declared in rtio.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 "rtio.h"
#include "paths.h"
-#ifndef NIX
-#include
-extern struct passwd *getpwnam();
-#endif
-
+#if defined(_WIN32) || defined(_WIN64)
+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 *cp;
+(
+ char *fname,
+ char *searchpath,
+ int mode
+)
+{
+ static char pname[PATH_MAX];
+ char uname[512];
+ 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);
}
+
+
+#if defined(_WIN32) || defined(_WIN64)
+/* 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 */
+ char *ffname,
+ char *searchpath,
+ int mode
+)
+{
+ 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
+