diff options
Diffstat (limited to 'winsup/testsuite/libltp/lib/search_path.c')
-rw-r--r-- | winsup/testsuite/libltp/lib/search_path.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/winsup/testsuite/libltp/lib/search_path.c b/winsup/testsuite/libltp/lib/search_path.c new file mode 100644 index 000000000..d6570cb59 --- /dev/null +++ b/winsup/testsuite/libltp/lib/search_path.c @@ -0,0 +1,251 @@ +/* $Header$ */ + +/* + * (C) COPYRIGHT CRAY RESEARCH, INC. + * UNPUBLISHED PROPRIETARY INFORMATION. + * ALL RIGHTS RESERVED. + */ +/********************************************************** + * + * UNICOS Feature Test and Evaluation - Cray Research, Inc. + * + * FUNCTION NAME : search_path + * + * FUNCTION TITLE : search PATH locations for desired filename + * + * SYNOPSIS: + * int search_path(cmd, res_path, access_mode, fullpath) + * char *cmd; + * char *res_path; + * int access_mode; + * int fullpath; + * + * AUTHOR : Richard Logan + * + * INITIAL RELEASE : UNICOS 7.0 + * + * DESCRIPTION + * Search_path will walk through PATH and attempt to find "cmd". If cmd is + * a full or relative path, it is checked but PATH locations are not scanned. + * search_path will put the resulting path in res_path. It is assumed + * that res_path points to a string that is at least PATH_MAX + * (or MAXPATHLEN on the suns) in size. Access_mode is just as is + * says, the mode to be used on access to determine if cmd can be found. + * If fullpath is set, res_path will contain the full path to cmd. + * If it is not set, res_path may or may not contain the full path to cmd. + * If fullpath is not set, the path in PATH prepended to cmd is used, + * which could be a relative path. If fullpath is set, the current + * directory is prepended to path/cmd before access is called. + * If cmd is found, search_path will return 0. If cmd cannot be + * found, 1 is returned. If an error has occurred, -1 is returned + * and an error mesg is placed in res_path. + * If the length of path/cmd is larger then PATH_MAX, then that path + * location is skipped. + * + *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <sys/errno.h> +#include <sys/param.h> +#include <sys/stat.h> + +extern int errno; + +struct stat stbuf; + +#ifndef AS_CMD +#define AS_CMD 0 +#endif + +/* + * Make sure PATH_MAX is defined. Define it to MAXPATHLEN, if set. Otherwise + * set it to 1024. + */ +#ifndef PATH_MAX +#ifndef MAXPATHLEN +#define PATH_MAX 1024 +#else /* MAXPATHLEN */ +#define PATH_MAX MAXPATHLEN +#endif /* MAXPATHLEN */ +#endif /* PATH_MAX */ + + +#if AS_CMD +main(argc, argv) +int argc; +char **argv; +{ + char path[PATH_MAX]; + int ind; + + if (argc <= 1 ) { + printf("missing argument\n"); + exit(1); + } + + for(ind=1;ind < argc; ind++) { + if ( search_path(argv[ind], path, F_OK, 0) < 0 ) { + printf("ERROR: %s\n", path); + } + else { + printf("path of %s is %s\n", argv[ind], path); + } + } + +} + +#endif + +/* + */ +int +search_path(cmd, res_path, access_mode, fullpath) +char *cmd; /* The requested filename */ +char *res_path; /* The resulting path or error mesg */ +int access_mode; /* the mode used by access(2) */ +int fullpath; /* if set, cwd will be prepended to all non-full paths */ +{ + char *cp; /* used to scan PATH for directories */ + int ret; /* return value from access */ + char *pathenv; + char tmppath[PATH_MAX]; + char curpath[PATH_MAX]; + char *path; + int lastpath; + int toolong=0; + +#if DEBUG +printf("search_path: cmd = %s, access_mode = %d, fullpath = %d\n", cmd, access_mode, fullpath); +#endif + + /* + * full or relative path was given + */ + if ( (cmd[0] == '/') || ( (cp=strchr(cmd, '/')) != NULL )) { + if ( access(cmd, access_mode) == 0 ) { + + if ( cmd[0] != '/' ) { /* relative path */ + if ( getcwd(curpath, PATH_MAX) == NULL ) { + strcpy(res_path, curpath); + return -1; + } + if ( (strlen(curpath) + strlen(cmd) + 1) > (size_t)PATH_MAX ) { + sprintf(res_path, "cmd (as relative path) and cwd is longer than %d", + PATH_MAX); + return -1; + } + sprintf(res_path, "%s/%s", curpath, cmd); + } + else + strcpy(res_path, cmd); + return 0; + } + else { + sprintf(res_path, "file %s not found", cmd); + return -1; + } + } + + /* get the PATH variable */ + if ( (pathenv=getenv("PATH")) == NULL) { + /* no path to scan, return */ + sprintf(res_path, "Unable to get PATH env. variable"); + return -1; + } + + /* + * walk through each path in PATH. + * Each path in PATH is placed in tmppath. + * pathenv cannot be modified since it will affect PATH. + * If a signal came in while we have modified the PATH + * memory, we could create a problem for the caller. + */ + + curpath[0]='\0'; + + cp = pathenv; + path = pathenv; + lastpath = 0; + for (;;) { + + if ( lastpath ) + break; + + if ( cp != pathenv ) + path = ++cp; /* already set on first iteration */ + + /* find end of current path */ + + for (; ((*cp != ':') && (*cp != '\0')); cp++); + + /* + * copy path to tmppath so it can be NULL terminated + * and so we do not modify path memory. + */ + strncpy(tmppath, path, (cp-path) ); + tmppath[cp-path]='\0'; +#if DEBUG +printf("search_path: tmppath = %s\n", tmppath); +#endif + + if ( *cp == '\0' ) + lastpath=1; /* this is the last path entry */ + + /* Check lengths so not to overflow res_path */ + if ( strlen(tmppath) + strlen(cmd) + 2 > (size_t)PATH_MAX ) { + toolong++; + continue; + } + + sprintf(res_path, "%s/%s", tmppath, cmd); +#if DEBUG +printf("search_path: res_path = '%s'\n", res_path); +#endif + + + /* if the path is not full at this point, prepend the current + * path to get the full path. + * Note: this could not be wise to do when under a protected + * directory. + */ + + if ( fullpath && res_path[0] != '/' ) { /* not a full path */ + if ( curpath[0] == '\0' ) { + if ( getcwd(curpath, PATH_MAX) == NULL ) { + strcpy(res_path, curpath); + return -1; + } + } + if ( (strlen(curpath) + strlen(res_path) + 2) > (size_t)PATH_MAX ) { + toolong++; + continue; + } + sprintf(tmppath, "%s/%s", curpath, res_path); + strcpy(res_path, tmppath); +#if DEBUG +printf("search_path: full res_path= '%s'\n", res_path); +#endif + + } + + + if ( (ret=access(res_path, access_mode)) == 0 ) { +#if DEBUG +printf("search_path: found res_path = %s\n", res_path); +#endif + return 0; + } + } + + /* return failure */ + if ( toolong ) + sprintf(res_path, + "Unable to find file, %d path/file strings were too long", toolong); + else + strcpy(res_path, "Unable to find file"); + return 1; /* not found */ +} + |