summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/bltins/whence.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshell/common/bltins/whence.c')
-rw-r--r--usr/src/lib/libshell/common/bltins/whence.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/usr/src/lib/libshell/common/bltins/whence.c b/usr/src/lib/libshell/common/bltins/whence.c
new file mode 100644
index 0000000000..7d05a741d6
--- /dev/null
+++ b/usr/src/lib/libshell/common/bltins/whence.c
@@ -0,0 +1,273 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Knowledge Ventures *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* David Korn <dgk@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * command [-pvVx] name [arg...]
+ * whence [-afvp] name...
+ *
+ * David Korn
+ * AT&T Labs
+ *
+ */
+
+#include "defs.h"
+#include <error.h>
+#include "shtable.h"
+#include "name.h"
+#include "path.h"
+#include "shlex.h"
+#include "builtins.h"
+
+#define P_FLAG 1
+#define V_FLAG 2
+#define A_FLAG 4
+#define F_FLAG 010
+#define X_FLAG 020
+
+static int whence(Shell_t *,char**, int);
+
+/*
+ * command is called with argc==0 when checking for -V or -v option
+ * In this case return 0 when -v or -V or unknown option, otherwise
+ * the shift count to the command is returned
+ */
+int b_command(register int argc,char *argv[],void *extra)
+{
+ register int n, flags=0;
+ register Shell_t *shp = (Shell_t*)extra;
+ opt_info.index = opt_info.offset = 0;
+ while((n = optget(argv,sh_optcommand))) switch(n)
+ {
+ case 'p':
+ if(sh_isoption(SH_RESTRICTED))
+ errormsg(SH_DICT,ERROR_exit(1),e_restricted,"-p");
+ sh_onstate(SH_DEFPATH);
+ break;
+ case 'v':
+ flags |= X_FLAG;
+ break;
+ case 'V':
+ flags |= V_FLAG;
+ break;
+ case 'x':
+ shp->xargexit = 1;
+ break;
+ case ':':
+ if(argc==0)
+ return(0);
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
+ break;
+ case '?':
+ if(argc==0)
+ return(0);
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
+ break;
+ }
+ if(argc==0)
+ return(flags?0:opt_info.index);
+ argv += opt_info.index;
+ if(error_info.errors || !*argv)
+ errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
+ return(whence(shp,argv, flags));
+}
+
+/*
+ * for the whence command
+ */
+int b_whence(int argc,char *argv[],void *extra)
+{
+ register int flags=0, n;
+ register Shell_t *shp = (Shell_t*)extra;
+ NOT_USED(argc);
+ if(*argv[0]=='t')
+ flags = V_FLAG;
+ while((n = optget(argv,sh_optwhence))) switch(n)
+ {
+ case 'a':
+ flags |= A_FLAG;
+ /* FALL THRU */
+ case 'v':
+ flags |= V_FLAG;
+ break;
+ case 'f':
+ flags |= F_FLAG;
+ break;
+ case 'p':
+ flags |= P_FLAG;
+ break;
+ case ':':
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
+ break;
+ case '?':
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
+ break;
+ }
+ argv += opt_info.index;
+ if(error_info.errors || !*argv)
+ errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
+ return(whence(shp, argv, flags));
+}
+
+static int whence(Shell_t *shp,char **argv, register int flags)
+{
+ register const char *name;
+ register Namval_t *np;
+ register const char *cp;
+ register int aflag,r=0;
+ register const char *msg;
+ int tofree;
+ Dt_t *root;
+ Namval_t *nq;
+ char *notused;
+#ifdef PATH_BFPATH
+ Pathcomp_t *pp;
+#endif
+ int notrack = 1;
+ while(name= *argv++)
+ {
+ tofree=0;
+ aflag = ((flags&A_FLAG)!=0);
+ cp = 0;
+ np = 0;
+#ifdef PATH_BFPATH
+ pp = 0;
+#endif
+ if(flags&P_FLAG)
+ goto search;
+ /* reserved words first */
+ if(sh_lookup(name,shtab_reserved))
+ {
+ sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):"");
+ if(!aflag)
+ continue;
+ aflag++;
+ }
+ /* non-tracked aliases */
+ if((np=nv_search(name,shp->alias_tree,0))
+ && !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED))
+ && (cp=nv_getval(np)))
+ {
+ if(flags&V_FLAG)
+ {
+ if(nv_isattr(np,NV_EXPORT))
+ msg = sh_translate(is_xalias);
+ else
+ msg = sh_translate(is_alias);
+ sfprintf(sfstdout,msg,name);
+ }
+ sfputr(sfstdout,sh_fmtq(cp),'\n');
+ if(!aflag)
+ continue;
+ cp = 0;
+ aflag++;
+ }
+ /* built-ins and functions next */
+ root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
+ if(np= nv_bfsearch(name, root, &nq, &notused))
+ {
+ if(is_abuiltin(np) && nv_isnull(np))
+ goto search;
+ cp = "";
+ if(flags&V_FLAG)
+ {
+ if(nv_isnull(np))
+ cp = sh_translate(is_ufunction);
+ else if(is_abuiltin(np))
+ cp = sh_translate(is_builtin);
+ else
+ cp = sh_translate(is_function);
+ }
+ sfprintf(sfstdout,"%s%s\n",name,cp);
+ if(!aflag)
+ continue;
+ cp = 0;
+ aflag++;
+ }
+ search:
+ if(sh_isstate(SH_DEFPATH))
+ {
+ cp=0;
+ notrack=1;
+ }
+#ifdef PATH_BFPATH
+ if(path_search(name,pp,2))
+ cp = name;
+ else
+ {
+ cp = stakptr(PATH_OFFSET);
+ if(*cp==0)
+ cp = 0;
+ else if(*cp!='/')
+ {
+ cp = path_fullname(cp);
+ tofree=1;
+ }
+ }
+#else
+ if(path_search(name,cp,2))
+ cp = name;
+ else
+ cp = shp->lastpath;
+ shp->lastpath = 0;
+#endif
+ if(cp)
+ {
+ if(flags&V_FLAG)
+ {
+ if(*cp!= '/')
+ {
+#ifdef PATH_BFPATH
+ if(!np && (np=nv_search(name,shp->track_tree,0)))
+ sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(0),cp);
+ else if(!np || nv_isnull(np))
+#else
+ if(!np || nv_isnull(np))
+#endif
+ sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction));
+ continue;
+ }
+ sfputr(sfstdout,sh_fmtq(name),' ');
+ /* built-in version of program */
+ if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0)))
+ msg = sh_translate(is_builtver);
+ /* tracked aliases next */
+ else if(!notrack || strchr(name,'/'))
+ msg = sh_translate("is");
+ else
+ msg = sh_translate(is_talias);
+ sfputr(sfstdout,msg,' ');
+ }
+ sfputr(sfstdout,sh_fmtq(cp),'\n');
+ if(tofree)
+ free((char*)cp);
+ }
+ else if(aflag<=1)
+ {
+ r |= 1;
+ if(flags&V_FLAG)
+ {
+ sfprintf(sfstdout,sh_translate(e_found),sh_fmtq(name));
+ sfputc(sfstdout,'\n');
+ }
+ }
+ }
+ return(r);
+}
+