4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
36 #include <sys/types.h>
42 static unsigned char cost
;
45 static struct entry relcmd
;
48 static void pr_path(unsigned char *, int);
51 pathlook(com
, flg
, arg
)
56 unsigned char *name
= com
;
78 if (h
->data
& (BUILTIN
| FUNCTION
))
85 if (arg
&& (pathset
= argpath(arg
)))
88 if ((h
->data
& DOT_COMMAND
) == DOT_COMMAND
)
90 if (multrel
== 0 && hashdata(h
->data
) > dotpath
)
91 oldpath
= hashdata(h
->data
);
99 if (h
->data
& (COMMAND
| REL_COMMAND
))
110 if (i
= syslook(name
, commands
, no_commands
))
112 hentry
.data
= (BUILTIN
| i
);
117 if (arg
&& (pathset
= argpath(arg
)))
118 return(PATH_COMMAND
);
120 count
= findpath(name
, oldpath
);
128 hentry
.key
= make(name
);
135 h
->data
= COMMAND
| count
;
138 h
->data
= REL_COMMAND
| count
;
139 h
->next
= relcmd
.next
;
173 ENTRY
*ptr
= relcmd
.next
;
190 if (hashtype(h
->data
) == NOTFOUND
)
193 if (h
->data
& (BUILTIN
| FUNCTION
))
198 if (h
->data
& REL_COMMAND
)
206 pr_path(h
->key
, hashdata(h
->data
));
213 prs_buff(_gettext("hits cost command\n"));
226 while (path
&& *path
)
232 if (dotpath
== 10000)
241 path
= nextpath(path
);
248 hash_func(unsigned char *name
)
259 hentry
.data
= FUNCTION
;
260 hentry
.key
= make(name
);
268 func_unhash(unsigned char *name
)
275 if (h
&& (h
->data
& FUNCTION
)) {
276 if(i
= syslook(name
, commands
, no_commands
))
277 h
->data
= (BUILTIN
|i
);
297 if (h
->data
& (BUILTIN
| FUNCTION
))
299 else if ((h
->data
& REL_COMMAND
) == REL_COMMAND
)
300 { /* unlink h from relative command list */
301 ENTRY
*ptr
= &relcmd
;
302 while(ptr
-> next
!= h
)
309 return(pathlook(name
, 0, 0));
314 * Return 0 if found, 1 if not.
317 what_is_path(unsigned char *name
)
328 hashval
= hashdata(h
->data
);
330 switch (hashtype(h
->data
))
333 prs_buff(_gettext(" is a shell builtin\n"));
338 struct namnod
*n
= lookup(name
);
339 struct fndnod
*f
= fndptr(n
->namenv
);
341 prs_buff(_gettext(" is a function\n"));
354 if ((h
->data
& DOT_COMMAND
) == DOT_COMMAND
)
356 hash
= pathlook(name
, 0, 0);
357 if (hashtype(hash
) == NOTFOUND
)
359 prs_buff(_gettext(" not"
364 hashval
= hashdata(hash
);
369 prs_buff(_gettext(" is hashed ("));
370 pr_path(name
, hashval
);
376 if (syslook(name
, commands
, no_commands
))
378 prs_buff(_gettext(" is a shell builtin\n"));
382 if ((cnt
= findpath(name
, 0)) > 0)
384 prs_buff(_gettext(" is "));
391 prs_buff(_gettext(" not found\n"));
397 findpath(unsigned char *name
, int oldpath
)
407 path
= getpath(name
);
413 path
= nextpath(path
);
415 if (oldpath
> dotpath
)
421 if ((ok
= chk_access(p
, S_IEXEC
, 1)) == 0)
432 path
= catpath(path
, name
);
436 if ((ok
= chk_access(p
, S_IEXEC
, 1)) == 0)
439 e_code
= max(e_code
, ok
);
444 return(ok
? -e_code
: count
);
448 * Determine if file given by name is accessible with permissions
450 * Regflag argument non-zero means not to consider
451 * a non-regular file as executable.
455 chk_access(unsigned char *name
, mode_t mode
, int regflag
)
466 ftype
= statb
.st_mode
& S_IFMT
;
467 if (stat((char *)name
, &statb
) == 0) {
468 ftype
= statb
.st_mode
& S_IFMT
;
469 if(mode
== S_IEXEC
&& regflag
&& ftype
!= S_IFREG
)
471 if(access((char *)name
, 010|(mode
>>6)) == 0) {
473 if (ftype
!= S_IFREG
|| mode
!= S_IEXEC
)
475 /* root can execute file as long as it has execute
476 permission for someone */
477 if (statb
.st_mode
& (S_IEXEC
|(S_IEXEC
>>3)|(S_IEXEC
>>6)))
484 return(errno
== EACCES
? 3 : 1);
488 pr_path(unsigned char *name
, int count
)
492 path
= getpath(name
);
494 while (--count
&& path
)
495 path
= nextpath(path
, name
);
503 argpath(struct argnod
*arg
)
506 unsigned char *start
;
522 if (eq(start
, pathname
))