/* $Header: /cvsroot/ltp/ltp/lib/search_path.c,v 1.1 2000/08/04 20:48:22 nstraz Exp $ */

/*
 *	(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 */
}

