blob: a5ebfadd9e5803243b8c789613c2ae878bba07bb [file] [log] [blame]
vapier45a8ba02009-07-20 10:59:32 +00001/* $Header: /cvsroot/ltp/ltp/lib/search_path.c,v 1.4 2009/07/20 10:59:32 vapier Exp $ */
nstraz090ed002000-08-04 20:48:22 +00002
3/*
robbiew85944b72006-07-19 14:00:55 +00004 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * Further, this software is distributed without any warranty that it is
15 * free of the rightful claim of any third person regarding infringement
16 * or the like. Any license provided herein, whether implied or
17 * otherwise, applies only to this software file. Patent licenses, if
18 * any, provided herein do not apply to combinations of this program with
19 * other software, or any other product whatsoever.
20 *
21 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080022 * with this program; if not, write the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
robbiew85944b72006-07-19 14:00:55 +000024 *
25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 * Mountain View, CA 94043, or:
27 *
28 * http://www.sgi.com
29 *
30 * For further information regarding this notice, see:
31 *
32 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
nstraz090ed002000-08-04 20:48:22 +000033 */
robbiew85944b72006-07-19 14:00:55 +000034
nstraz090ed002000-08-04 20:48:22 +000035/**********************************************************
vapier45a8ba02009-07-20 10:59:32 +000036 *
nstraz090ed002000-08-04 20:48:22 +000037 * UNICOS Feature Test and Evaluation - Cray Research, Inc.
vapier45a8ba02009-07-20 10:59:32 +000038 *
39 * FUNCTION NAME : search_path
40 *
nstraz090ed002000-08-04 20:48:22 +000041 * FUNCTION TITLE : search PATH locations for desired filename
vapier45a8ba02009-07-20 10:59:32 +000042 *
nstraz090ed002000-08-04 20:48:22 +000043 * SYNOPSIS:
44 * int search_path(cmd, res_path, access_mode, fullpath)
45 * char *cmd;
46 * char *res_path;
47 * int access_mode;
48 * int fullpath;
vapier45a8ba02009-07-20 10:59:32 +000049 *
nstraz090ed002000-08-04 20:48:22 +000050 * AUTHOR : Richard Logan
vapier45a8ba02009-07-20 10:59:32 +000051 *
nstraz090ed002000-08-04 20:48:22 +000052 * INITIAL RELEASE : UNICOS 7.0
vapier45a8ba02009-07-20 10:59:32 +000053 *
nstraz090ed002000-08-04 20:48:22 +000054 * DESCRIPTION
55 * Search_path will walk through PATH and attempt to find "cmd". If cmd is
56 * a full or relative path, it is checked but PATH locations are not scanned.
57 * search_path will put the resulting path in res_path. It is assumed
58 * that res_path points to a string that is at least PATH_MAX
59 * (or MAXPATHLEN on the suns) in size. Access_mode is just as is
60 * says, the mode to be used on access to determine if cmd can be found.
61 * If fullpath is set, res_path will contain the full path to cmd.
62 * If it is not set, res_path may or may not contain the full path to cmd.
63 * If fullpath is not set, the path in PATH prepended to cmd is used,
64 * which could be a relative path. If fullpath is set, the current
65 * directory is prepended to path/cmd before access is called.
66 * If cmd is found, search_path will return 0. If cmd cannot be
67 * found, 1 is returned. If an error has occurred, -1 is returned
vapier45a8ba02009-07-20 10:59:32 +000068 * and an error mesg is placed in res_path.
nstraz090ed002000-08-04 20:48:22 +000069 * If the length of path/cmd is larger then PATH_MAX, then that path
70 * location is skipped.
vapier45a8ba02009-07-20 10:59:32 +000071 *
nstraz090ed002000-08-04 20:48:22 +000072 *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
73
74#include <stdio.h>
75#include <unistd.h>
76#include <string.h>
77#include <stdlib.h>
robbiewa70576c2003-03-04 18:33:41 +000078#include <errno.h>
nstraz090ed002000-08-04 20:48:22 +000079#include <sys/param.h>
80#include <sys/stat.h>
81
nstraz090ed002000-08-04 20:48:22 +000082struct stat stbuf;
83
84#ifndef AS_CMD
85#define AS_CMD 0
86#endif
87
88/*
89 * Make sure PATH_MAX is defined. Define it to MAXPATHLEN, if set. Otherwise
90 * set it to 1024.
91 */
92#ifndef PATH_MAX
93#ifndef MAXPATHLEN
94#define PATH_MAX 1024
Wanlong Gao354ebb42012-12-07 10:10:04 +080095#else /* MAXPATHLEN */
nstraz090ed002000-08-04 20:48:22 +000096#define PATH_MAX MAXPATHLEN
Wanlong Gao354ebb42012-12-07 10:10:04 +080097#endif /* MAXPATHLEN */
98#endif /* PATH_MAX */
nstraz090ed002000-08-04 20:48:22 +000099
100#if AS_CMD
101main(argc, argv)
102int argc;
103char **argv;
104{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800105 char path[PATH_MAX];
106 int ind;
nstraz090ed002000-08-04 20:48:22 +0000107
Wanlong Gao354ebb42012-12-07 10:10:04 +0800108 if (argc <= 1) {
109 printf("missing argument\n");
110 exit(1);
111 }
nstraz090ed002000-08-04 20:48:22 +0000112
Wanlong Gao354ebb42012-12-07 10:10:04 +0800113 for (ind = 1; ind < argc; ind++) {
114 if (search_path(argv[ind], path, F_OK, 0) < 0) {
115 printf("ERROR: %s\n", path);
116 } else {
117 printf("path of %s is %s\n", argv[ind], path);
118 }
nstraz090ed002000-08-04 20:48:22 +0000119 }
vapier45a8ba02009-07-20 10:59:32 +0000120
nstraz090ed002000-08-04 20:48:22 +0000121}
122
123#endif
124
125/*
126 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800127int search_path(cmd, res_path, access_mode, fullpath)
128char *cmd; /* The requested filename */
129char *res_path; /* The resulting path or error mesg */
130int access_mode; /* the mode used by access(2) */
131int fullpath; /* if set, cwd will be prepended to all non-full paths */
nstraz090ed002000-08-04 20:48:22 +0000132{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133 char *cp; /* used to scan PATH for directories */
134 int ret; /* return value from access */
135 char *pathenv;
136 char tmppath[PATH_MAX];
137 char curpath[PATH_MAX];
138 char *path;
139 int lastpath;
140 int toolong = 0;
nstraz090ed002000-08-04 20:48:22 +0000141
142#if DEBUG
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 printf("search_path: cmd = %s, access_mode = %d, fullpath = %d\n", cmd,
144 access_mode, fullpath);
nstraz090ed002000-08-04 20:48:22 +0000145#endif
146
nstraz090ed002000-08-04 20:48:22 +0000147 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800148 * full or relative path was given
nstraz090ed002000-08-04 20:48:22 +0000149 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800150 if ((cmd[0] == '/') || ((cp = strchr(cmd, '/')) != NULL)) {
151 if (access(cmd, access_mode) == 0) {
nstraz090ed002000-08-04 20:48:22 +0000152
Wanlong Gao354ebb42012-12-07 10:10:04 +0800153 if (cmd[0] != '/') { /* relative path */
154 if (getcwd(curpath, PATH_MAX) == NULL) {
155 strcpy(res_path, curpath);
156 return -1;
157 }
158 if ((strlen(curpath) + strlen(cmd) + 1) >
159 (size_t) PATH_MAX) {
160 sprintf(res_path,
161 "cmd (as relative path) and cwd is longer than %d",
162 PATH_MAX);
163 return -1;
164 }
165 sprintf(res_path, "%s/%s", curpath, cmd);
166 } else
167 strcpy(res_path, cmd);
168 return 0;
169 } else {
170 sprintf(res_path, "file %s not found", cmd);
171 return -1;
172 }
nstraz090ed002000-08-04 20:48:22 +0000173 }
174
Wanlong Gao354ebb42012-12-07 10:10:04 +0800175 /* get the PATH variable */
176 if ((pathenv = getenv("PATH")) == NULL) {
177 /* no path to scan, return */
178 sprintf(res_path, "Unable to get PATH env. variable");
179 return -1;
nstraz090ed002000-08-04 20:48:22 +0000180 }
181
Wanlong Gao354ebb42012-12-07 10:10:04 +0800182 /*
183 * walk through each path in PATH.
184 * Each path in PATH is placed in tmppath.
185 * pathenv cannot be modified since it will affect PATH.
186 * If a signal came in while we have modified the PATH
187 * memory, we could create a problem for the caller.
188 */
nstraz090ed002000-08-04 20:48:22 +0000189
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 curpath[0] = '\0';
191
192 cp = pathenv;
193 path = pathenv;
194 lastpath = 0;
195 for (;;) {
196
197 if (lastpath)
198 break;
199
200 if (cp != pathenv)
201 path = ++cp; /* already set on first iteration */
202
203 /* find end of current path */
204
205 for (; ((*cp != ':') && (*cp != '\0')); cp++) ;
206
207 /*
208 * copy path to tmppath so it can be NULL terminated
209 * and so we do not modify path memory.
210 */
211 strncpy(tmppath, path, (cp - path));
212 tmppath[cp - path] = '\0';
nstraz090ed002000-08-04 20:48:22 +0000213#if DEBUG
Wanlong Gao354ebb42012-12-07 10:10:04 +0800214 printf("search_path: tmppath = %s\n", tmppath);
nstraz090ed002000-08-04 20:48:22 +0000215#endif
nstraz090ed002000-08-04 20:48:22 +0000216
Wanlong Gao354ebb42012-12-07 10:10:04 +0800217 if (*cp == '\0')
218 lastpath = 1; /* this is the last path entry */
219
220 /* Check lengths so not to overflow res_path */
221 if (strlen(tmppath) + strlen(cmd) + 2 > (size_t) PATH_MAX) {
222 toolong++;
223 continue;
224 }
225
226 sprintf(res_path, "%s/%s", tmppath, cmd);
227#if DEBUG
228 printf("search_path: res_path = '%s'\n", res_path);
229#endif
230
231 /* if the path is not full at this point, prepend the current
232 * path to get the full path.
233 * Note: this could not be wise to do when under a protected
234 * directory.
235 */
236
237 if (fullpath && res_path[0] != '/') { /* not a full path */
238 if (curpath[0] == '\0') {
239 if (getcwd(curpath, PATH_MAX) == NULL) {
240 strcpy(res_path, curpath);
241 return -1;
242 }
243 }
244 if ((strlen(curpath) + strlen(res_path) + 2) >
245 (size_t) PATH_MAX) {
246 toolong++;
247 continue;
248 }
249 sprintf(tmppath, "%s/%s", curpath, res_path);
250 strcpy(res_path, tmppath);
251#if DEBUG
252 printf("search_path: full res_path= '%s'\n", res_path);
253#endif
254
255 }
256
257 if ((ret = access(res_path, access_mode)) == 0) {
258#if DEBUG
259 printf("search_path: found res_path = %s\n", res_path);
260#endif
261 return 0;
262 }
263 }
264
265 /* return failure */
266 if (toolong)
267 sprintf(res_path,
268 "Unable to find file, %d path/file strings were too long",
269 toolong);
270 else
271 strcpy(res_path, "Unable to find file");
272 return 1; /* not found */
nstraz090ed002000-08-04 20:48:22 +0000273}