2004-01-09 11:03:27 +03:00
|
|
|
/*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* All rights reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-01-09 11:03:27 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-10-20 05:03:09 +04:00
|
|
|
#include "ompi_config.h"
|
2004-01-09 11:03:27 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-01-09 11:03:27 +03:00
|
|
|
#include <unistd.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
2004-01-09 11:03:27 +03:00
|
|
|
|
2005-07-04 05:59:52 +04:00
|
|
|
#include "opal/util/path.h"
|
2005-07-04 04:13:44 +04:00
|
|
|
#include "opal/util/argv.h"
|
2004-01-09 11:03:27 +03:00
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
/*
|
2004-01-09 11:03:27 +03:00
|
|
|
* PATH environment variable separator
|
|
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
|
|
#define PATHENVSEP ';'
|
|
|
|
#else
|
|
|
|
#define PATHENVSEP ':'
|
|
|
|
#endif
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
static void path_env_load(char *path, int *pargc, char ***pargv);
|
|
|
|
static char *path_access(char *fname, char *path, int mode);
|
|
|
|
static char *list_env_get(char *var, char **list);
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Locates a file with certain permissions
|
|
|
|
*/
|
2005-07-04 05:59:52 +04:00
|
|
|
char *opal_path_find(char *fname, char **pathv, int mode, char **envv)
|
2004-01-09 11:03:27 +03:00
|
|
|
{
|
2005-02-09 20:13:54 +03:00
|
|
|
char *fullpath;
|
|
|
|
char *delimit;
|
|
|
|
char *env;
|
|
|
|
char *pfix;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* If absolute path is given, return it without searching. */
|
|
|
|
|
2004-01-14 01:21:30 +03:00
|
|
|
if ('/' == *fname) {
|
2005-02-09 20:13:54 +03:00
|
|
|
return path_access(fname, "", mode);
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Initialize. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
fullpath = NULL;
|
|
|
|
i = 0;
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Consider each directory until the file is found. Thus, the
|
|
|
|
order of directories is important. */
|
|
|
|
|
|
|
|
while (pathv[i] && NULL == fullpath) {
|
|
|
|
|
|
|
|
/* Replace environment variable at the head of the string. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
if ('$' == *pathv[i]) {
|
2004-01-14 01:21:30 +03:00
|
|
|
delimit = strchr(pathv[i], '/');
|
2004-01-09 11:03:27 +03:00
|
|
|
if (delimit) {
|
|
|
|
*delimit = '\0';
|
|
|
|
}
|
|
|
|
env = list_env_get(pathv[i]+1, envv);
|
|
|
|
if (delimit) {
|
2004-01-14 01:21:30 +03:00
|
|
|
*delimit = '/';
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
if (NULL != env) {
|
2004-01-09 11:03:27 +03:00
|
|
|
if (!delimit) {
|
|
|
|
fullpath = path_access(fname, env, mode);
|
|
|
|
} else {
|
2004-10-18 19:38:19 +04:00
|
|
|
pfix = (char*) malloc(strlen(env) + strlen(delimit) + 1);
|
2005-02-09 20:13:54 +03:00
|
|
|
if (NULL == pfix) {
|
|
|
|
return NULL;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
strcpy(pfix, env);
|
|
|
|
strcat(pfix, delimit);
|
|
|
|
fullpath = path_access(fname, pfix, mode);
|
2004-02-10 03:09:36 +03:00
|
|
|
free(pfix);
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fullpath = path_access(fname, pathv[i], mode);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
return fullpath;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
/*
|
|
|
|
* Locates a file with certain permissions from a list of search paths
|
2004-01-09 11:03:27 +03:00
|
|
|
*/
|
2005-07-04 05:59:52 +04:00
|
|
|
char *opal_path_findv(char *fname, int mode, char **envv, char *wrkdir)
|
2004-01-09 11:03:27 +03:00
|
|
|
{
|
2005-02-09 20:13:54 +03:00
|
|
|
char **dirv;
|
|
|
|
char *fullpath;
|
|
|
|
char *path;
|
|
|
|
int dirc;
|
|
|
|
int i;
|
|
|
|
bool found_dot = false;
|
|
|
|
|
|
|
|
/* Set the local search paths. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
dirc = 0;
|
|
|
|
dirv = NULL;
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
if (NULL != (path = list_env_get("PATH", envv))) {
|
2004-01-09 11:03:27 +03:00
|
|
|
path_env_load(path, &dirc, &dirv);
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Replace the "." path by the working directory. */
|
|
|
|
|
|
|
|
if (NULL != wrkdir) {
|
|
|
|
for (i = 0; i < dirc; ++i) {
|
|
|
|
if (0 == strcmp(dirv[i], ".")) {
|
|
|
|
found_dot = true;
|
|
|
|
free(dirv[i]);
|
|
|
|
dirv[i] = strdup(wrkdir);
|
|
|
|
if (NULL == dirv[i]){
|
|
|
|
return NULL;
|
|
|
|
}
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* If we didn't find "." in the path and we have a wrkdir, append
|
|
|
|
the wrkdir to the end of the path */
|
|
|
|
|
|
|
|
if (!found_dot && NULL != wrkdir) {
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_append(&dirc, &dirv, wrkdir);
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
2005-03-18 06:43:59 +03:00
|
|
|
if(NULL == dirv)
|
|
|
|
return NULL;
|
2005-07-04 05:59:52 +04:00
|
|
|
fullpath = opal_path_find(fname, dirv, mode, envv);
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_free(dirv);
|
2005-02-09 20:13:54 +03:00
|
|
|
return fullpath;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2005-02-09 20:13:54 +03:00
|
|
|
* Forms a complete pathname and checks it for existance and
|
|
|
|
* permissions
|
2004-01-09 11:03:27 +03:00
|
|
|
*
|
2004-01-09 21:47:52 +03:00
|
|
|
* Accepts:
|
|
|
|
* -fname File name
|
|
|
|
* -path Path prefix
|
|
|
|
* -mode Target permissions which must be satisfied
|
2004-01-09 11:03:27 +03:00
|
|
|
*
|
2004-01-09 21:47:52 +03:00
|
|
|
* Returns:
|
|
|
|
* -Full pathname of located file Success
|
|
|
|
* -NULL Failure
|
2004-01-09 11:03:27 +03:00
|
|
|
*/
|
2005-02-09 20:13:54 +03:00
|
|
|
static char *path_access(char *fname, char *path, int mode)
|
2004-01-09 11:03:27 +03:00
|
|
|
{
|
2005-02-09 20:13:54 +03:00
|
|
|
char *fullpath;
|
|
|
|
|
|
|
|
/* Allocate space for the full pathname. */
|
|
|
|
|
2004-10-18 19:38:19 +04:00
|
|
|
fullpath = (char*) malloc(strlen(path) + strlen(fname) + 2);
|
2005-02-09 20:13:54 +03:00
|
|
|
if (NULL == fullpath) {
|
|
|
|
return NULL;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen(path) > 0) {
|
|
|
|
strcpy(fullpath, path);
|
2004-01-14 01:21:30 +03:00
|
|
|
strcat(fullpath, "/");
|
2004-01-09 11:03:27 +03:00
|
|
|
strcat(fullpath, fname);
|
|
|
|
} else {
|
|
|
|
strcpy(fullpath, fname);
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Get status on the full path name to check for existance. Then
|
|
|
|
check the permissions. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
if (access(fullpath, mode)) {
|
2004-02-10 03:09:36 +03:00
|
|
|
free(fullpath);
|
2005-02-09 20:13:54 +03:00
|
|
|
fullpath = NULL;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
return fullpath;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Loads argument array with $PATH env var.
|
|
|
|
*
|
2004-01-09 21:47:52 +03:00
|
|
|
* Accepts
|
|
|
|
* -path String contiaing the $PATH
|
|
|
|
* -argc Pointer to argc
|
|
|
|
* -argv Pointer to list of argv
|
2004-01-09 11:03:27 +03:00
|
|
|
*/
|
2005-02-09 20:13:54 +03:00
|
|
|
static void path_env_load(char *path, int *pargc, char ***pargv)
|
2004-01-09 11:03:27 +03:00
|
|
|
{
|
2005-02-09 20:13:54 +03:00
|
|
|
char *p;
|
|
|
|
char saved;
|
2004-01-09 11:03:27 +03:00
|
|
|
|
|
|
|
if (NULL == path) {
|
2005-02-09 20:13:54 +03:00
|
|
|
*pargc = 0;
|
|
|
|
return;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Loop through the paths (delimited by PATHENVSEP), adding each
|
|
|
|
one to argv. */
|
|
|
|
|
|
|
|
while ('\0' != *path) {
|
|
|
|
|
|
|
|
/* Locate the delimiter. */
|
|
|
|
|
|
|
|
for (p = path; *p && (*p != PATHENVSEP); ++p) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add the path. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
if (p != path) {
|
|
|
|
saved = *p;
|
|
|
|
*p = '\0';
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_append(pargc, pargv, path);
|
2004-01-09 11:03:27 +03:00
|
|
|
*p = saved;
|
|
|
|
path = p;
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
|
|
|
|
/* Skip past the delimiter, if present. */
|
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
if (*path) {
|
|
|
|
++path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
|
2004-01-09 11:03:27 +03:00
|
|
|
/**
|
|
|
|
* Gets value of variable in list or environment. Looks in the list first
|
|
|
|
*
|
2004-01-09 21:47:52 +03:00
|
|
|
* Accepts:
|
|
|
|
* -var String variable
|
|
|
|
* -list Pointer to environment list
|
2004-01-09 11:03:27 +03:00
|
|
|
*
|
2004-01-09 21:47:52 +03:00
|
|
|
* Returns:
|
|
|
|
* -List Pointer to environment list Success
|
|
|
|
* -NULL Failure
|
2004-01-09 11:03:27 +03:00
|
|
|
*/
|
2005-02-09 20:13:54 +03:00
|
|
|
static char *list_env_get(char *var, char **list)
|
2004-01-09 11:03:27 +03:00
|
|
|
{
|
2004-01-09 21:47:52 +03:00
|
|
|
int n;
|
2004-01-09 11:03:27 +03:00
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
if (NULL != list) {
|
2004-01-09 11:03:27 +03:00
|
|
|
n = strlen(var);
|
|
|
|
|
2005-02-09 20:13:54 +03:00
|
|
|
while (NULL != *list) {
|
2004-01-09 11:03:27 +03:00
|
|
|
if ((0 == strncmp(var, *list, n)) && ('=' == (*list)[n])) {
|
2005-02-09 20:13:54 +03:00
|
|
|
return (*list + n + 1);
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
++list;
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
}
|
2005-02-09 20:13:54 +03:00
|
|
|
return getenv(var);
|
2004-01-09 11:03:27 +03:00
|
|
|
}
|
|
|
|
|