1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1982-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * David Korn <dgk@research.att.com> *
18da2e3ebdSchin * *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin * command [-pvVx] name [arg...]
23da2e3ebdSchin * whence [-afvp] name...
24da2e3ebdSchin *
25da2e3ebdSchin * David Korn
26da2e3ebdSchin * AT&T Labs
27da2e3ebdSchin *
28da2e3ebdSchin */
29da2e3ebdSchin
30da2e3ebdSchin #include "defs.h"
31da2e3ebdSchin #include <error.h>
32da2e3ebdSchin #include "shtable.h"
33da2e3ebdSchin #include "name.h"
34da2e3ebdSchin #include "path.h"
35da2e3ebdSchin #include "shlex.h"
36da2e3ebdSchin #include "builtins.h"
37da2e3ebdSchin
38da2e3ebdSchin #define P_FLAG 1
39da2e3ebdSchin #define V_FLAG 2
40da2e3ebdSchin #define A_FLAG 4
41da2e3ebdSchin #define F_FLAG 010
42da2e3ebdSchin #define X_FLAG 020
437c2fbfb3SApril Chin #define Q_FLAG 040
44da2e3ebdSchin
45da2e3ebdSchin static int whence(Shell_t *,char**, int);
46da2e3ebdSchin
47da2e3ebdSchin /*
48da2e3ebdSchin * command is called with argc==0 when checking for -V or -v option
49da2e3ebdSchin * In this case return 0 when -v or -V or unknown option, otherwise
50da2e3ebdSchin * the shift count to the command is returned
51da2e3ebdSchin */
b_command(register int argc,char * argv[],void * extra)52da2e3ebdSchin int b_command(register int argc,char *argv[],void *extra)
53da2e3ebdSchin {
54da2e3ebdSchin register int n, flags=0;
557c2fbfb3SApril Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
56da2e3ebdSchin opt_info.index = opt_info.offset = 0;
57da2e3ebdSchin while((n = optget(argv,sh_optcommand))) switch(n)
58da2e3ebdSchin {
59da2e3ebdSchin case 'p':
60da2e3ebdSchin if(sh_isoption(SH_RESTRICTED))
61da2e3ebdSchin errormsg(SH_DICT,ERROR_exit(1),e_restricted,"-p");
62da2e3ebdSchin sh_onstate(SH_DEFPATH);
63da2e3ebdSchin break;
64da2e3ebdSchin case 'v':
65da2e3ebdSchin flags |= X_FLAG;
66da2e3ebdSchin break;
67da2e3ebdSchin case 'V':
68da2e3ebdSchin flags |= V_FLAG;
69da2e3ebdSchin break;
70da2e3ebdSchin case 'x':
71da2e3ebdSchin shp->xargexit = 1;
72da2e3ebdSchin break;
73da2e3ebdSchin case ':':
74da2e3ebdSchin if(argc==0)
75da2e3ebdSchin return(0);
76da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
77da2e3ebdSchin break;
78da2e3ebdSchin case '?':
79da2e3ebdSchin if(argc==0)
80da2e3ebdSchin return(0);
81da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
82da2e3ebdSchin break;
83da2e3ebdSchin }
84da2e3ebdSchin if(argc==0)
85da2e3ebdSchin return(flags?0:opt_info.index);
86da2e3ebdSchin argv += opt_info.index;
87da2e3ebdSchin if(error_info.errors || !*argv)
88da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
89da2e3ebdSchin return(whence(shp,argv, flags));
90da2e3ebdSchin }
91da2e3ebdSchin
92da2e3ebdSchin /*
93da2e3ebdSchin * for the whence command
94da2e3ebdSchin */
b_whence(int argc,char * argv[],void * extra)95da2e3ebdSchin int b_whence(int argc,char *argv[],void *extra)
96da2e3ebdSchin {
97da2e3ebdSchin register int flags=0, n;
987c2fbfb3SApril Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
99da2e3ebdSchin NOT_USED(argc);
100da2e3ebdSchin if(*argv[0]=='t')
101da2e3ebdSchin flags = V_FLAG;
102da2e3ebdSchin while((n = optget(argv,sh_optwhence))) switch(n)
103da2e3ebdSchin {
104da2e3ebdSchin case 'a':
105da2e3ebdSchin flags |= A_FLAG;
106da2e3ebdSchin /* FALL THRU */
107da2e3ebdSchin case 'v':
108da2e3ebdSchin flags |= V_FLAG;
109da2e3ebdSchin break;
110da2e3ebdSchin case 'f':
111da2e3ebdSchin flags |= F_FLAG;
112da2e3ebdSchin break;
113da2e3ebdSchin case 'p':
114da2e3ebdSchin flags |= P_FLAG;
1157c2fbfb3SApril Chin flags &= ~V_FLAG;
1167c2fbfb3SApril Chin break;
1177c2fbfb3SApril Chin case 'q':
1187c2fbfb3SApril Chin flags |= Q_FLAG;
119da2e3ebdSchin break;
120da2e3ebdSchin case ':':
121da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
122da2e3ebdSchin break;
123da2e3ebdSchin case '?':
124da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
125da2e3ebdSchin break;
126da2e3ebdSchin }
127da2e3ebdSchin argv += opt_info.index;
128da2e3ebdSchin if(error_info.errors || !*argv)
129da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
130da2e3ebdSchin return(whence(shp, argv, flags));
131da2e3ebdSchin }
132da2e3ebdSchin
whence(Shell_t * shp,char ** argv,register int flags)133da2e3ebdSchin static int whence(Shell_t *shp,char **argv, register int flags)
134da2e3ebdSchin {
135da2e3ebdSchin register const char *name;
136da2e3ebdSchin register Namval_t *np;
137da2e3ebdSchin register const char *cp;
138da2e3ebdSchin register int aflag,r=0;
139da2e3ebdSchin register const char *msg;
140da2e3ebdSchin int tofree;
141da2e3ebdSchin Dt_t *root;
142da2e3ebdSchin Namval_t *nq;
143da2e3ebdSchin char *notused;
1447c2fbfb3SApril Chin Pathcomp_t *pp=0;
145da2e3ebdSchin int notrack = 1;
1467c2fbfb3SApril Chin if(flags&Q_FLAG)
1477c2fbfb3SApril Chin flags &= ~A_FLAG;
148da2e3ebdSchin while(name= *argv++)
149da2e3ebdSchin {
150da2e3ebdSchin tofree=0;
151da2e3ebdSchin aflag = ((flags&A_FLAG)!=0);
152da2e3ebdSchin cp = 0;
153da2e3ebdSchin np = 0;
154da2e3ebdSchin if(flags&P_FLAG)
155da2e3ebdSchin goto search;
1567c2fbfb3SApril Chin if(flags&Q_FLAG)
1577c2fbfb3SApril Chin goto bltins;
158da2e3ebdSchin /* reserved words first */
159da2e3ebdSchin if(sh_lookup(name,shtab_reserved))
160da2e3ebdSchin {
161da2e3ebdSchin sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):"");
162da2e3ebdSchin if(!aflag)
163da2e3ebdSchin continue;
164da2e3ebdSchin aflag++;
165da2e3ebdSchin }
166da2e3ebdSchin /* non-tracked aliases */
167da2e3ebdSchin if((np=nv_search(name,shp->alias_tree,0))
168da2e3ebdSchin && !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED))
169da2e3ebdSchin && (cp=nv_getval(np)))
170da2e3ebdSchin {
171da2e3ebdSchin if(flags&V_FLAG)
172da2e3ebdSchin {
173da2e3ebdSchin if(nv_isattr(np,NV_EXPORT))
174da2e3ebdSchin msg = sh_translate(is_xalias);
175da2e3ebdSchin else
176da2e3ebdSchin msg = sh_translate(is_alias);
177da2e3ebdSchin sfprintf(sfstdout,msg,name);
178da2e3ebdSchin }
179da2e3ebdSchin sfputr(sfstdout,sh_fmtq(cp),'\n');
180da2e3ebdSchin if(!aflag)
181da2e3ebdSchin continue;
182da2e3ebdSchin cp = 0;
183da2e3ebdSchin aflag++;
184da2e3ebdSchin }
185da2e3ebdSchin /* built-ins and functions next */
1867c2fbfb3SApril Chin bltins:
187da2e3ebdSchin root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
188da2e3ebdSchin if(np= nv_bfsearch(name, root, &nq, ¬used))
189da2e3ebdSchin {
190da2e3ebdSchin if(is_abuiltin(np) && nv_isnull(np))
191da2e3ebdSchin goto search;
192da2e3ebdSchin cp = "";
193da2e3ebdSchin if(flags&V_FLAG)
194da2e3ebdSchin {
195da2e3ebdSchin if(nv_isnull(np))
196da2e3ebdSchin cp = sh_translate(is_ufunction);
197da2e3ebdSchin else if(is_abuiltin(np))
1987c2fbfb3SApril Chin {
1997c2fbfb3SApril Chin if(nv_isattr(np,BLT_SPC))
2007c2fbfb3SApril Chin cp = sh_translate(is_spcbuiltin);
2017c2fbfb3SApril Chin else
202da2e3ebdSchin cp = sh_translate(is_builtin);
2037c2fbfb3SApril Chin }
204da2e3ebdSchin else
205da2e3ebdSchin cp = sh_translate(is_function);
206da2e3ebdSchin }
2077c2fbfb3SApril Chin if(flags&Q_FLAG)
2087c2fbfb3SApril Chin continue;
209da2e3ebdSchin sfprintf(sfstdout,"%s%s\n",name,cp);
210da2e3ebdSchin if(!aflag)
211da2e3ebdSchin continue;
212da2e3ebdSchin cp = 0;
213da2e3ebdSchin aflag++;
214da2e3ebdSchin }
215da2e3ebdSchin search:
216da2e3ebdSchin if(sh_isstate(SH_DEFPATH))
217da2e3ebdSchin {
218da2e3ebdSchin cp=0;
219da2e3ebdSchin notrack=1;
220da2e3ebdSchin }
2217c2fbfb3SApril Chin do
2227c2fbfb3SApril Chin {
2237c2fbfb3SApril Chin if(path_search(name,&pp,2+(aflag>1)))
224da2e3ebdSchin cp = name;
225da2e3ebdSchin else
226da2e3ebdSchin {
227da2e3ebdSchin cp = stakptr(PATH_OFFSET);
228da2e3ebdSchin if(*cp==0)
229da2e3ebdSchin cp = 0;
230da2e3ebdSchin else if(*cp!='/')
231da2e3ebdSchin {
232da2e3ebdSchin cp = path_fullname(cp);
233da2e3ebdSchin tofree=1;
234da2e3ebdSchin }
235da2e3ebdSchin }
2367c2fbfb3SApril Chin if(flags&Q_FLAG)
2377c2fbfb3SApril Chin r |= !cp;
2387c2fbfb3SApril Chin else if(cp)
239da2e3ebdSchin {
240da2e3ebdSchin if(flags&V_FLAG)
241da2e3ebdSchin {
242da2e3ebdSchin if(*cp!= '/')
243da2e3ebdSchin {
244da2e3ebdSchin if(!np && (np=nv_search(name,shp->track_tree,0)))
245da2e3ebdSchin sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(0),cp);
246da2e3ebdSchin else if(!np || nv_isnull(np))
247da2e3ebdSchin sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction));
248da2e3ebdSchin continue;
249da2e3ebdSchin }
250da2e3ebdSchin sfputr(sfstdout,sh_fmtq(name),' ');
251da2e3ebdSchin /* built-in version of program */
252da2e3ebdSchin if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0)))
253da2e3ebdSchin msg = sh_translate(is_builtver);
254da2e3ebdSchin /* tracked aliases next */
2557c2fbfb3SApril Chin else if(aflag>1 || !notrack || strchr(name,'/'))
256da2e3ebdSchin msg = sh_translate("is");
257da2e3ebdSchin else
258da2e3ebdSchin msg = sh_translate(is_talias);
259da2e3ebdSchin sfputr(sfstdout,msg,' ');
260da2e3ebdSchin }
261da2e3ebdSchin sfputr(sfstdout,sh_fmtq(cp),'\n');
2627c2fbfb3SApril Chin if(aflag)
2637c2fbfb3SApril Chin {
2647c2fbfb3SApril Chin if(aflag<=1)
2657c2fbfb3SApril Chin aflag++;
2667c2fbfb3SApril Chin if (pp)
2677c2fbfb3SApril Chin pp = pp->next;
2687c2fbfb3SApril Chin }
2697c2fbfb3SApril Chin else
2707c2fbfb3SApril Chin pp = 0;
271da2e3ebdSchin if(tofree)
272da2e3ebdSchin free((char*)cp);
273da2e3ebdSchin }
274da2e3ebdSchin else if(aflag<=1)
275da2e3ebdSchin {
276da2e3ebdSchin r |= 1;
277da2e3ebdSchin if(flags&V_FLAG)
2787c2fbfb3SApril Chin errormsg(SH_DICT,ERROR_exit(0),e_found,sh_fmtq(name));
279da2e3ebdSchin }
2807c2fbfb3SApril Chin } while(pp);
281da2e3ebdSchin }
282da2e3ebdSchin return(r);
283da2e3ebdSchin }
284da2e3ebdSchin
285