xref: /onnv-gate/usr/src/lib/libshell/common/bltins/whence.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1982-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                  David Korn <dgk@research.att.com>                   *
184887Schin *                                                                      *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin  * command [-pvVx] name [arg...]
234887Schin  * whence [-afvp] name...
244887Schin  *
254887Schin  *   David Korn
264887Schin  *   AT&T Labs
274887Schin  *
284887Schin  */
294887Schin 
304887Schin #include	"defs.h"
314887Schin #include	<error.h>
324887Schin #include	"shtable.h"
334887Schin #include	"name.h"
344887Schin #include	"path.h"
354887Schin #include	"shlex.h"
364887Schin #include	"builtins.h"
374887Schin 
384887Schin #define P_FLAG	1
394887Schin #define V_FLAG	2
404887Schin #define A_FLAG	4
414887Schin #define F_FLAG	010
424887Schin #define X_FLAG	020
438462SApril.Chin@Sun.COM #define Q_FLAG	040
444887Schin 
454887Schin static int whence(Shell_t *,char**, int);
464887Schin 
474887Schin /*
484887Schin  * command is called with argc==0 when checking for -V or -v option
494887Schin  * In this case return 0 when -v or -V or unknown option, otherwise
504887Schin  *   the shift count to the command is returned
514887Schin  */
b_command(register int argc,char * argv[],void * extra)524887Schin int	b_command(register int argc,char *argv[],void *extra)
534887Schin {
544887Schin 	register int n, flags=0;
558462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
564887Schin 	opt_info.index = opt_info.offset = 0;
574887Schin 	while((n = optget(argv,sh_optcommand))) switch(n)
584887Schin 	{
594887Schin 	    case 'p':
604887Schin 		if(sh_isoption(SH_RESTRICTED))
614887Schin 			 errormsg(SH_DICT,ERROR_exit(1),e_restricted,"-p");
624887Schin 		sh_onstate(SH_DEFPATH);
634887Schin 		break;
644887Schin 	    case 'v':
654887Schin 		flags |= X_FLAG;
664887Schin 		break;
674887Schin 	    case 'V':
684887Schin 		flags |= V_FLAG;
694887Schin 		break;
704887Schin 	    case 'x':
714887Schin 		shp->xargexit = 1;
724887Schin 		break;
734887Schin 	    case ':':
744887Schin 		if(argc==0)
754887Schin 			return(0);
764887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
774887Schin 		break;
784887Schin 	    case '?':
794887Schin 		if(argc==0)
804887Schin 			return(0);
814887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
824887Schin 		break;
834887Schin 	}
844887Schin 	if(argc==0)
854887Schin 		return(flags?0:opt_info.index);
864887Schin 	argv += opt_info.index;
874887Schin 	if(error_info.errors || !*argv)
884887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
894887Schin 	return(whence(shp,argv, flags));
904887Schin }
914887Schin 
924887Schin /*
934887Schin  *  for the whence command
944887Schin  */
b_whence(int argc,char * argv[],void * extra)954887Schin int	b_whence(int argc,char *argv[],void *extra)
964887Schin {
974887Schin 	register int flags=0, n;
988462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
994887Schin 	NOT_USED(argc);
1004887Schin 	if(*argv[0]=='t')
1014887Schin 		flags = V_FLAG;
1024887Schin 	while((n = optget(argv,sh_optwhence))) switch(n)
1034887Schin 	{
1044887Schin 	    case 'a':
1054887Schin 		flags |= A_FLAG;
1064887Schin 		/* FALL THRU */
1074887Schin 	    case 'v':
1084887Schin 		flags |= V_FLAG;
1094887Schin 		break;
1104887Schin 	    case 'f':
1114887Schin 		flags |= F_FLAG;
1124887Schin 		break;
1134887Schin 	    case 'p':
1144887Schin 		flags |= P_FLAG;
1158462SApril.Chin@Sun.COM 		flags &= ~V_FLAG;
1168462SApril.Chin@Sun.COM 		break;
1178462SApril.Chin@Sun.COM 	    case 'q':
1188462SApril.Chin@Sun.COM 		flags |= Q_FLAG;
1194887Schin 		break;
1204887Schin 	    case ':':
1214887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
1224887Schin 		break;
1234887Schin 	    case '?':
1244887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
1254887Schin 		break;
1264887Schin 	}
1274887Schin 	argv += opt_info.index;
1284887Schin 	if(error_info.errors || !*argv)
1294887Schin 		errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
1304887Schin 	return(whence(shp, argv, flags));
1314887Schin }
1324887Schin 
whence(Shell_t * shp,char ** argv,register int flags)1334887Schin static int whence(Shell_t *shp,char **argv, register int flags)
1344887Schin {
1354887Schin 	register const char *name;
1364887Schin 	register Namval_t *np;
1374887Schin 	register const char *cp;
1384887Schin 	register int aflag,r=0;
1394887Schin 	register const char *msg;
1404887Schin 	int	tofree;
1414887Schin 	Dt_t *root;
1424887Schin 	Namval_t *nq;
1434887Schin 	char *notused;
1448462SApril.Chin@Sun.COM 	Pathcomp_t *pp=0;
1454887Schin 	int notrack = 1;
1468462SApril.Chin@Sun.COM 	if(flags&Q_FLAG)
1478462SApril.Chin@Sun.COM 		flags &= ~A_FLAG;
1484887Schin 	while(name= *argv++)
1494887Schin 	{
1504887Schin 		tofree=0;
1514887Schin 		aflag = ((flags&A_FLAG)!=0);
1524887Schin 		cp = 0;
1534887Schin 		np = 0;
1544887Schin 		if(flags&P_FLAG)
1554887Schin 			goto search;
1568462SApril.Chin@Sun.COM 		if(flags&Q_FLAG)
1578462SApril.Chin@Sun.COM 			goto bltins;
1584887Schin 		/* reserved words first */
1594887Schin 		if(sh_lookup(name,shtab_reserved))
1604887Schin 		{
1614887Schin 			sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):"");
1624887Schin 			if(!aflag)
1634887Schin 				continue;
1644887Schin 			aflag++;
1654887Schin 		}
1664887Schin 		/* non-tracked aliases */
1674887Schin 		if((np=nv_search(name,shp->alias_tree,0))
1684887Schin 			&& !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED))
1694887Schin 			&& (cp=nv_getval(np)))
1704887Schin 		{
1714887Schin 			if(flags&V_FLAG)
1724887Schin 			{
1734887Schin 				if(nv_isattr(np,NV_EXPORT))
1744887Schin 					msg = sh_translate(is_xalias);
1754887Schin 				else
1764887Schin 					msg = sh_translate(is_alias);
1774887Schin 				sfprintf(sfstdout,msg,name);
1784887Schin 			}
1794887Schin 			sfputr(sfstdout,sh_fmtq(cp),'\n');
1804887Schin 			if(!aflag)
1814887Schin 				continue;
1824887Schin 			cp = 0;
1834887Schin 			aflag++;
1844887Schin 		}
1854887Schin 		/* built-ins and functions next */
1868462SApril.Chin@Sun.COM 	bltins:
1874887Schin 		root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
1884887Schin 		if(np= nv_bfsearch(name, root, &nq, &notused))
1894887Schin 		{
1904887Schin 			if(is_abuiltin(np) && nv_isnull(np))
1914887Schin 				goto search;
1924887Schin 			cp = "";
1934887Schin 			if(flags&V_FLAG)
1944887Schin 			{
1954887Schin 				if(nv_isnull(np))
1964887Schin 					cp = sh_translate(is_ufunction);
1974887Schin 				else if(is_abuiltin(np))
1988462SApril.Chin@Sun.COM 				{
1998462SApril.Chin@Sun.COM 					if(nv_isattr(np,BLT_SPC))
2008462SApril.Chin@Sun.COM 						cp = sh_translate(is_spcbuiltin);
2018462SApril.Chin@Sun.COM 					else
2028462SApril.Chin@Sun.COM 						cp = sh_translate(is_builtin);
2038462SApril.Chin@Sun.COM 				}
2044887Schin 				else
2054887Schin 					cp = sh_translate(is_function);
2064887Schin 			}
2078462SApril.Chin@Sun.COM 			if(flags&Q_FLAG)
2088462SApril.Chin@Sun.COM 				continue;
2094887Schin 			sfprintf(sfstdout,"%s%s\n",name,cp);
2104887Schin 			if(!aflag)
2114887Schin 				continue;
2124887Schin 			cp = 0;
2134887Schin 			aflag++;
2144887Schin 		}
2154887Schin 	search:
2164887Schin 		if(sh_isstate(SH_DEFPATH))
2174887Schin 		{
2184887Schin 			cp=0;
2194887Schin 			notrack=1;
2204887Schin 		}
2218462SApril.Chin@Sun.COM 		do
2224887Schin 		{
2238462SApril.Chin@Sun.COM 			if(path_search(name,&pp,2+(aflag>1)))
2248462SApril.Chin@Sun.COM 				cp = name;
2258462SApril.Chin@Sun.COM 			else
2264887Schin 			{
2278462SApril.Chin@Sun.COM 				cp = stakptr(PATH_OFFSET);
2288462SApril.Chin@Sun.COM 				if(*cp==0)
2298462SApril.Chin@Sun.COM 					cp = 0;
2308462SApril.Chin@Sun.COM 				else if(*cp!='/')
2318462SApril.Chin@Sun.COM 				{
2328462SApril.Chin@Sun.COM 					cp = path_fullname(cp);
2338462SApril.Chin@Sun.COM 					tofree=1;
2348462SApril.Chin@Sun.COM 				}
2354887Schin 			}
2368462SApril.Chin@Sun.COM 			if(flags&Q_FLAG)
2378462SApril.Chin@Sun.COM 				r |= !cp;
2388462SApril.Chin@Sun.COM 			else if(cp)
2394887Schin 			{
2408462SApril.Chin@Sun.COM 				if(flags&V_FLAG)
2414887Schin 				{
2428462SApril.Chin@Sun.COM 					if(*cp!= '/')
2438462SApril.Chin@Sun.COM 					{
2448462SApril.Chin@Sun.COM 						if(!np && (np=nv_search(name,shp->track_tree,0)))
2458462SApril.Chin@Sun.COM 							sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(0),cp);
2468462SApril.Chin@Sun.COM 						else if(!np || nv_isnull(np))
2478462SApril.Chin@Sun.COM 							sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction));
2488462SApril.Chin@Sun.COM 						continue;
2498462SApril.Chin@Sun.COM 					}
2508462SApril.Chin@Sun.COM 					sfputr(sfstdout,sh_fmtq(name),' ');
2518462SApril.Chin@Sun.COM 					/* built-in version of program */
2528462SApril.Chin@Sun.COM 					if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0)))
2538462SApril.Chin@Sun.COM 						msg = sh_translate(is_builtver);
2548462SApril.Chin@Sun.COM 					/* tracked aliases next */
2558462SApril.Chin@Sun.COM 					else if(aflag>1 || !notrack || strchr(name,'/'))
2568462SApril.Chin@Sun.COM 						msg = sh_translate("is");
2578462SApril.Chin@Sun.COM 					else
2588462SApril.Chin@Sun.COM 						msg = sh_translate(is_talias);
2598462SApril.Chin@Sun.COM 					sfputr(sfstdout,msg,' ');
2604887Schin 				}
2618462SApril.Chin@Sun.COM 				sfputr(sfstdout,sh_fmtq(cp),'\n');
2628462SApril.Chin@Sun.COM 				if(aflag)
2638462SApril.Chin@Sun.COM 				{
2648462SApril.Chin@Sun.COM 					if(aflag<=1)
2658462SApril.Chin@Sun.COM 						aflag++;
2668462SApril.Chin@Sun.COM 					if (pp)
2678462SApril.Chin@Sun.COM 						pp = pp->next;
2688462SApril.Chin@Sun.COM 				}
2694887Schin 				else
2708462SApril.Chin@Sun.COM 					pp = 0;
2718462SApril.Chin@Sun.COM 				if(tofree)
2728462SApril.Chin@Sun.COM 					free((char*)cp);
2734887Schin 			}
2748462SApril.Chin@Sun.COM 			else if(aflag<=1)
2754887Schin 			{
2768462SApril.Chin@Sun.COM 				r |= 1;
2778462SApril.Chin@Sun.COM 				if(flags&V_FLAG)
2788462SApril.Chin@Sun.COM 					 errormsg(SH_DICT,ERROR_exit(0),e_found,sh_fmtq(name));
2794887Schin 			}
2808462SApril.Chin@Sun.COM 		} while(pp);
2814887Schin 	}
2824887Schin 	return(r);
2834887Schin }
2844887Schin 
285