summaryrefslogtreecommitdiff
path: root/ltp_framework/lib/search_path.c
blob: a9dff82928b601be1dc8372d5f881be5bce8f6f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/* $Header: /cvsroot/ltp/ltp/lib/search_path.c,v 1.4 2009/07/20 10:59:32 vapier Exp $ */

/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 */


/**********************************************************
 *
 *    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 <errno.h>
#include <sys/param.h>
#include <sys/stat.h>


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