xref: /onnv-gate/usr/src/lib/libshell/common/bltins/misc.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  * exec [arg...]
234887Schin  * eval [arg...]
244887Schin  * jobs [-lnp] [job...]
254887Schin  * login [arg...]
264887Schin  * let expr...
274887Schin  * . file [arg...]
284887Schin  * :, true, false
294887Schin  * vpath [top] [base]
304887Schin  * vmap [top] [base]
314887Schin  * wait [job...]
324887Schin  * shift [n]
334887Schin  *
344887Schin  *   David Korn
354887Schin  *   AT&T Labs
364887Schin  *
374887Schin  */
384887Schin 
394887Schin #include	"defs.h"
404887Schin #include	"variables.h"
414887Schin #include	"shnodes.h"
424887Schin #include	"path.h"
434887Schin #include	"io.h"
444887Schin #include	"name.h"
454887Schin #include	"history.h"
464887Schin #include	"builtins.h"
474887Schin #include	"jobs.h"
484887Schin 
494887Schin #define DOTMAX	MAXDEPTH	/* maximum level of . nesting */
504887Schin 
514887Schin static void     noexport(Namval_t*,void*);
524887Schin 
534887Schin struct login
544887Schin {
554887Schin 	Shell_t *sh;
564887Schin 	int     clear;
574887Schin 	char    *arg0;
584887Schin };
594887Schin 
b_exec(int argc,char * argv[],void * extra)604887Schin int    b_exec(int argc,char *argv[], void *extra)
614887Schin {
624887Schin 	struct login logdata;
634887Schin 	register int n;
644887Schin 	logdata.clear = 0;
654887Schin 	logdata.arg0 = 0;
668462SApril.Chin@Sun.COM 	logdata.sh = ((Shbltin_t*)extra)->shp;
674887Schin         logdata.sh->st.ioset = 0;
684887Schin 	while (n = optget(argv, sh_optexec)) switch (n)
694887Schin 	{
704887Schin 	    case 'a':
714887Schin 		logdata.arg0 = opt_info.arg;
724887Schin 		argc = 0;
734887Schin 		break;
744887Schin 	    case 'c':
754887Schin 		logdata.clear=1;
764887Schin 		break;
774887Schin 	    case ':':
784887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
794887Schin 		break;
804887Schin 	    case '?':
814887Schin 		errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
824887Schin 		return(2);
834887Schin 	}
844887Schin 	argv += opt_info.index;
854887Schin 	if(error_info.errors)
864887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
874887Schin 	if(*argv)
884887Schin                 B_login(0,argv,(void*)&logdata);
894887Schin 	return(0);
904887Schin }
914887Schin 
noexport(register Namval_t * np,void * data)924887Schin static void     noexport(register Namval_t* np, void *data)
934887Schin {
944887Schin 	NOT_USED(data);
954887Schin 	nv_offattr(np,NV_EXPORT);
964887Schin }
974887Schin 
B_login(int argc,char * argv[],void * extra)984887Schin int    B_login(int argc,char *argv[],void *extra)
994887Schin {
1004887Schin 	struct checkpt *pp;
1014887Schin 	register struct login *logp=0;
1024887Schin 	register Shell_t *shp;
1034887Schin 	const char *pname;
1044887Schin 	if(argc)
1058462SApril.Chin@Sun.COM 		shp = ((Shbltin_t*)extra)->shp;
1064887Schin 	else
1074887Schin 	{
1084887Schin 		logp = (struct login*)extra;
1094887Schin 		shp = logp->sh;
1104887Schin 	}
1114887Schin 	pp = (struct checkpt*)shp->jmplist;
1124887Schin 	if(sh_isoption(SH_RESTRICTED))
1134887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[0]);
1144887Schin 	else
1154887Schin         {
1164887Schin 		register struct argnod *arg=shp->envlist;
1174887Schin 		register Namval_t* np;
1184887Schin 		register char *cp;
11910898Sroland.mainz@nrubsig.org 		if(shp->subshell && !shp->subshare)
1204887Schin 			sh_subfork();
1214887Schin 		if(logp && logp->clear)
1224887Schin 		{
1234887Schin #ifdef _ENV_H
1244887Schin 			env_close(shp->env);
1254887Schin 			shp->env = env_open((char**)0,3);
1264887Schin #else
1274887Schin 			nv_scan(shp->var_tree,noexport,0,NV_EXPORT,NV_EXPORT);
1284887Schin #endif
1294887Schin 		}
1304887Schin 		while(arg)
1314887Schin 		{
1324887Schin 			if((cp=strchr(arg->argval,'=')) &&
1334887Schin 				(*cp=0,np=nv_search(arg->argval,shp->var_tree,0)))
1344887Schin 			{
1354887Schin 				nv_onattr(np,NV_EXPORT);
1364887Schin 				sh_envput(shp->env,np);
1374887Schin 			}
1384887Schin 			if(cp)
1394887Schin 				*cp = '=';
1404887Schin 			arg=arg->argnxt.ap;
1414887Schin 		}
1424887Schin 		pname = argv[0];
1434887Schin 		if(logp && logp->arg0)
1444887Schin 			argv[0] = logp->arg0;
1454887Schin #ifdef JOBS
1468462SApril.Chin@Sun.COM 		if(job_close(shp) < 0)
1474887Schin 			return(1);
1484887Schin #endif /* JOBS */
1494887Schin 		/* force bad exec to terminate shell */
1504887Schin 		pp->mode = SH_JMPEXIT;
1514887Schin 		sh_sigreset(2);
1528462SApril.Chin@Sun.COM 		sh_freeup(shp);
1534887Schin 		path_exec(pname,argv,NIL(struct argnod*));
1548462SApril.Chin@Sun.COM 		sh_done(shp,0);
1554887Schin         }
1564887Schin 	return(1);
1574887Schin }
1584887Schin 
b_let(int argc,char * argv[],void * extra)1594887Schin int    b_let(int argc,char *argv[],void *extra)
1604887Schin {
1614887Schin 	register int r;
1624887Schin 	register char *arg;
1634887Schin 	NOT_USED(argc);
1644887Schin 	NOT_USED(extra);
1654887Schin 	while (r = optget(argv,sh_optlet)) switch (r)
1664887Schin 	{
1674887Schin 	    case ':':
1684887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
1694887Schin 		break;
1704887Schin 	    case '?':
1714887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
1724887Schin 		break;
1734887Schin 	}
1744887Schin 	argv += opt_info.index;
1754887Schin 	if(error_info.errors || !*argv)
1764887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
1774887Schin 	while(arg= *argv++)
1784887Schin 		r = !sh_arith(arg);
1794887Schin 	return(r);
1804887Schin }
1814887Schin 
b_eval(int argc,char * argv[],void * extra)1824887Schin int    b_eval(int argc,char *argv[], void *extra)
1834887Schin {
1844887Schin 	register int r;
1858462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
1864887Schin 	NOT_USED(argc);
1874887Schin 	while (r = optget(argv,sh_opteval)) switch (r)
1884887Schin 	{
1894887Schin 	    case ':':
1904887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
1914887Schin 		break;
1924887Schin 	    case '?':
1934887Schin 		errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
1944887Schin 		return(2);
1954887Schin 	}
1964887Schin 	if(error_info.errors)
1974887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
1984887Schin 	argv += opt_info.index;
1994887Schin 	if(*argv && **argv)
2004887Schin 	{
2014887Schin 		sh_offstate(SH_MONITOR);
2024887Schin 		sh_eval(sh_sfeval(argv),0);
2034887Schin 	}
2044887Schin 	return(shp->exitval);
2054887Schin }
2064887Schin 
b_dot_cmd(register int n,char * argv[],void * extra)2074887Schin int    b_dot_cmd(register int n,char *argv[],void* extra)
2084887Schin {
2094887Schin 	register char *script;
2104887Schin 	register Namval_t *np;
2114887Schin 	register int jmpval;
2128462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
2134887Schin 	struct sh_scoped savst, *prevscope = shp->st.self;
2144887Schin 	char *filename=0;
2154887Schin 	int	fd;
2164887Schin 	struct dolnod   *argsave=0, *saveargfor;
2174887Schin 	struct checkpt buff;
2184887Schin 	Sfio_t *iop=0;
2198462SApril.Chin@Sun.COM 	short level;
2204887Schin 	while (n = optget(argv,sh_optdot)) switch (n)
2214887Schin 	{
2224887Schin 	    case ':':
2234887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
2244887Schin 		break;
2254887Schin 	    case '?':
2264887Schin 		errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
2274887Schin 		return(2);
2284887Schin 	}
2294887Schin 	argv += opt_info.index;
2304887Schin 	script = *argv;
2314887Schin 	if(error_info.errors || !script)
2324887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
2338462SApril.Chin@Sun.COM 	if(shp->dot_depth+1 > DOTMAX)
2344887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
2354887Schin 	if(!(np=shp->posix_fun))
2364887Schin 	{
2374887Schin 		/* check for KornShell style function first */
2384887Schin 		np = nv_search(script,shp->fun_tree,0);
2394887Schin 		if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX))
2404887Schin 		{
2414887Schin 			if(!np->nvalue.ip)
2424887Schin 			{
2438462SApril.Chin@Sun.COM 				path_search(script,NIL(Pathcomp_t**),0);
2444887Schin 				if(np->nvalue.ip)
2454887Schin 				{
2464887Schin 					if(nv_isattr(np,NV_FPOSIX))
2474887Schin 						np = 0;
2484887Schin 				}
2494887Schin 				else
2504887Schin 					errormsg(SH_DICT,ERROR_exit(1),e_found,script);
2514887Schin 			}
2524887Schin 		}
2534887Schin 		else
2544887Schin 			np = 0;
2554887Schin 		if(!np)
2564887Schin 		{
2574887Schin 			if((fd=path_open(script,path_get(script))) < 0)
2584887Schin 				errormsg(SH_DICT,ERROR_system(1),e_open,script);
2598462SApril.Chin@Sun.COM 			filename = path_fullname(stkptr(shp->stk,PATH_OFFSET));
2604887Schin 		}
2614887Schin 	}
2624887Schin 	*prevscope = shp->st;
2638462SApril.Chin@Sun.COM 	shp->st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
2648462SApril.Chin@Sun.COM 	shp->st.var_local = shp->st.save_tree = shp->var_tree;
2654887Schin 	if(filename)
2668462SApril.Chin@Sun.COM 	{
2674887Schin 		shp->st.filename = filename;
2688462SApril.Chin@Sun.COM 		shp->st.lineno = 1;
2698462SApril.Chin@Sun.COM 	}
2708462SApril.Chin@Sun.COM 	level  = shp->fn_depth+shp->dot_depth+1;
2718462SApril.Chin@Sun.COM 	nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16);
2724887Schin 	shp->st.prevst = prevscope;
2734887Schin 	shp->st.self = &savst;
2744887Schin 	shp->topscope = (Shscope_t*)shp->st.self;
2754887Schin 	prevscope->save_tree = shp->var_tree;
2764887Schin 	shp->st.cmdname = argv[0];
2774887Schin 	if(np)
2784887Schin 		shp->st.filename = np->nvalue.rp->fname;
2794887Schin 	nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
2804887Schin 	shp->posix_fun = 0;
2814887Schin 	if(np || argv[1])
2828462SApril.Chin@Sun.COM 		argsave = sh_argnew(shp,argv,&saveargfor);
2834887Schin 	sh_pushcontext(&buff,SH_JMPDOT);
2844887Schin 	jmpval = sigsetjmp(buff.buff,0);
2854887Schin 	if(jmpval == 0)
2864887Schin 	{
2878462SApril.Chin@Sun.COM 		shp->dot_depth++;
2884887Schin 		if(np)
2894887Schin 			sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
2904887Schin 		else
2914887Schin 		{
2924887Schin 			char buff[IOBSIZE+1];
2934887Schin 			iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fd,SF_READ);
2944887Schin 			sh_eval(iop,0);
2954887Schin 		}
2964887Schin 	}
2974887Schin 	sh_popcontext(&buff);
2984887Schin 	if(!np)
2994887Schin 		free((void*)shp->st.filename);
3004887Schin 	shp->dot_depth--;
3014887Schin 	if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
3028462SApril.Chin@Sun.COM 		sh_argreset(shp,argsave,saveargfor);
3034887Schin 	else
3044887Schin 	{
3054887Schin 		prevscope->dolc = shp->st.dolc;
3064887Schin 		prevscope->dolv = shp->st.dolv;
3074887Schin 	}
3084887Schin 	if (shp->st.self != &savst)
3094887Schin 		*shp->st.self = shp->st;
3104887Schin 	/* only restore the top Shscope_t portion for posix functions */
3114887Schin 	memcpy((void*)&shp->st, (void*)prevscope, sizeof(Shscope_t));
3124887Schin 	shp->topscope = (Shscope_t*)prevscope;
3134887Schin 	nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
3144887Schin 	if(shp->exitval > SH_EXITSIG)
3154887Schin 		sh_fault(shp->exitval&SH_EXITMASK);
3164887Schin 	if(jmpval && jmpval!=SH_JMPFUN)
3174887Schin 		siglongjmp(*shp->jmplist,jmpval);
3184887Schin 	return(shp->exitval);
3194887Schin }
3204887Schin 
3214887Schin /*
3224887Schin  * null, true  command
3234887Schin  */
b_true(int argc,register char * argv[],void * extra)3244887Schin int    b_true(int argc,register char *argv[],void *extra)
3254887Schin {
3264887Schin 	NOT_USED(argc);
3274887Schin 	NOT_USED(argv[0]);
3284887Schin 	NOT_USED(extra);
3294887Schin 	return(0);
3304887Schin }
3314887Schin 
3324887Schin /*
3334887Schin  * false  command
3344887Schin  */
b_false(int argc,register char * argv[],void * extra)3354887Schin int    b_false(int argc,register char *argv[], void *extra)
3364887Schin {
3374887Schin 	NOT_USED(argc);
3384887Schin 	NOT_USED(argv[0]);
3394887Schin 	NOT_USED(extra);
3404887Schin 	return(1);
3414887Schin }
3424887Schin 
b_shift(register int n,register char * argv[],void * extra)3434887Schin int    b_shift(register int n, register char *argv[], void *extra)
3444887Schin {
3454887Schin 	register char *arg;
3468462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3474887Schin 	while((n = optget(argv,sh_optshift))) switch(n)
3484887Schin 	{
3494887Schin 		case ':':
3504887Schin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
3514887Schin 			break;
3524887Schin 		case '?':
3534887Schin 			errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
3544887Schin 			return(2);
3554887Schin 	}
3564887Schin 	if(error_info.errors)
3574887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
3584887Schin 	argv += opt_info.index;
3594887Schin 	n = ((arg= *argv)?(int)sh_arith(arg):1);
3604887Schin 	if(n<0 || shp->st.dolc<n)
3614887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
3624887Schin 	else
3634887Schin 	{
3644887Schin 		shp->st.dolv += n;
3654887Schin 		shp->st.dolc -= n;
3664887Schin 	}
3674887Schin 	return(0);
3684887Schin }
3694887Schin 
b_wait(int n,register char * argv[],void * extra)3704887Schin int    b_wait(int n,register char *argv[],void *extra)
3714887Schin {
3728462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3734887Schin 	while((n = optget(argv,sh_optwait))) switch(n)
3744887Schin 	{
3754887Schin 		case ':':
3764887Schin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
3774887Schin 			break;
3784887Schin 		case '?':
3794887Schin 			errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
3804887Schin 			break;
3814887Schin 	}
3824887Schin 	if(error_info.errors)
3834887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
3844887Schin 	argv += opt_info.index;
3854887Schin 	job_bwait(argv);
3864887Schin 	return(shp->exitval);
3874887Schin }
3884887Schin 
3894887Schin #ifdef JOBS
3904887Schin #   if 0
3914887Schin     /* for the dictionary generator */
3924887Schin 	int    b_fg(int n,char *argv[],void *extra){}
3934887Schin 	int    b_disown(int n,char *argv[],void *extra){}
3944887Schin #   endif
b_bg(register int n,register char * argv[],void * extra)3954887Schin int    b_bg(register int n,register char *argv[],void *extra)
3964887Schin {
3974887Schin 	register int flag = **argv;
3988462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
3994887Schin 	register const char *optstr = sh_optbg;
4004887Schin 	if(*argv[0]=='f')
4014887Schin 		optstr = sh_optfg;
4024887Schin 	else if(*argv[0]=='d')
4034887Schin 		optstr = sh_optdisown;
4044887Schin 	while((n = optget(argv,optstr))) switch(n)
4054887Schin 	{
4064887Schin 	    case ':':
4074887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
4084887Schin 		break;
4094887Schin 	    case '?':
4104887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
4114887Schin 		break;
4124887Schin 	}
4134887Schin 	if(error_info.errors)
4144887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
4154887Schin 	argv += opt_info.index;
4164887Schin 	if(!sh_isoption(SH_MONITOR) || !job.jobcontrol)
4174887Schin 	{
4184887Schin 		if(sh_isstate(SH_INTERACTIVE))
4194887Schin 			errormsg(SH_DICT,ERROR_exit(1),e_no_jctl);
4204887Schin 		return(1);
4214887Schin 	}
4224887Schin 	if(flag=='d' && *argv==0)
4234887Schin 		argv = (char**)0;
4244887Schin 	if(job_walk(sfstdout,job_switch,flag,argv))
4254887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_no_job);
4264887Schin 	return(shp->exitval);
4274887Schin }
4284887Schin 
b_jobs(register int n,char * argv[],void * extra)4294887Schin int    b_jobs(register int n,char *argv[],void *extra)
4304887Schin {
4314887Schin 	register int flag = 0;
4328462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
4334887Schin 	while((n = optget(argv,sh_optjobs))) switch(n)
4344887Schin 	{
4354887Schin 	    case 'l':
4364887Schin 		flag = JOB_LFLAG;
4374887Schin 		break;
4384887Schin 	    case 'n':
4394887Schin 		flag = JOB_NFLAG;
4404887Schin 		break;
4414887Schin 	    case 'p':
4424887Schin 		flag = JOB_PFLAG;
4434887Schin 		break;
4444887Schin 	    case ':':
4454887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
4464887Schin 		break;
4474887Schin 	    case '?':
4484887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
4494887Schin 		break;
4504887Schin 	}
4514887Schin 	argv += opt_info.index;
4524887Schin 	if(error_info.errors)
4534887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
4544887Schin 	if(*argv==0)
4554887Schin 		argv = (char**)0;
4564887Schin 	if(job_walk(sfstdout,job_list,flag,argv))
4574887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_no_job);
4584887Schin 	job_wait((pid_t)0);
4594887Schin 	return(shp->exitval);
4604887Schin }
4614887Schin #endif
4624887Schin 
4634887Schin #ifdef _cmd_universe
4644887Schin /*
4654887Schin  * There are several universe styles that are masked by the getuniv(),
4664887Schin  * setuniv() calls.
4674887Schin  */
b_universe(int argc,char * argv[],void * extra)4684887Schin int	b_universe(int argc, char *argv[],void *extra)
4694887Schin {
4704887Schin 	register char *arg;
4714887Schin 	register int n;
4724887Schin 	NOT_USED(extra);
4734887Schin 	while((n = optget(argv,sh_optuniverse))) switch(n)
4744887Schin 	{
4754887Schin 	    case ':':
4764887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
4774887Schin 		break;
4784887Schin 	    case '?':
4794887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
4804887Schin 		break;
4814887Schin 	}
4824887Schin 	argv += opt_info.index;
4834887Schin 	argc -= opt_info.index;
4844887Schin 	if(error_info.errors || argc>1)
4854887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
4864887Schin 	if(arg = argv[0])
4874887Schin 	{
4884887Schin 		if(!astconf("UNIVERSE",0,arg))
4894887Schin 			errormsg(SH_DICT,ERROR_exit(1), e_badname,arg);
4904887Schin 	}
4914887Schin 	else
4924887Schin 	{
4934887Schin 		if(!(arg=astconf("UNIVERSE",0,0)))
4944887Schin 			errormsg(SH_DICT,ERROR_exit(1),e_nouniverse);
4954887Schin 		else
4964887Schin 			sfputr(sfstdout,arg,'\n');
4974887Schin 	}
4984887Schin 	return(0);
4994887Schin }
5004887Schin #endif /* cmd_universe */
5014887Schin 
5024887Schin #if SHOPT_FS_3D
5034887Schin #   if 0
5044887Schin     /* for the dictionary generator */
5054887Schin     int	b_vmap(int argc,char *argv[], void *extra){}
5064887Schin #   endif
b_vpath(register int argc,char * argv[],void * extra)5074887Schin     int	b_vpath(register int argc,char *argv[], void *extra)
5084887Schin     {
5094887Schin 	register int flag, n;
5104887Schin 	register const char *optstr;
5114887Schin 	register char *vend;
5128462SApril.Chin@Sun.COM 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
5134887Schin 	if(argv[0][1]=='p')
5144887Schin 	{
5154887Schin 		optstr = sh_optvpath;
5164887Schin 		flag = FS3D_VIEW;
5174887Schin 	}
5184887Schin 	else
5194887Schin 	{
5204887Schin 		optstr = sh_optvmap;
5214887Schin 		flag = FS3D_VERSION;
5224887Schin 	}
5234887Schin 	while(n = optget(argv, optstr)) switch(n)
5244887Schin 	{
5254887Schin 	    case ':':
5264887Schin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
5274887Schin 		break;
5284887Schin 	    case '?':
5294887Schin 		errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
5304887Schin 		break;
5314887Schin 	}
5324887Schin 	if(error_info.errors)
5334887Schin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
5344887Schin 	if(!shp->lim.fs3d)
5354887Schin 		goto failed;
5364887Schin 	argv += opt_info.index;
5374887Schin 	argc -= opt_info.index;
5384887Schin 	switch(argc)
5394887Schin 	{
5404887Schin 	    case 0:
5414887Schin 	    case 1:
5424887Schin 		flag |= FS3D_GET;
5434887Schin 		if((n = mount(*argv,(char*)0,flag,0)) >= 0)
5444887Schin 		{
5458462SApril.Chin@Sun.COM 			vend = stkalloc(shp->stk,++n);
5464887Schin 			n = mount(*argv,vend,flag|FS3D_SIZE(n),0);
5474887Schin 		}
5484887Schin 		if(n < 0)
5494887Schin 			goto failed;
5504887Schin 		if(argc==1)
5514887Schin 		{
5524887Schin 			sfprintf(sfstdout,"%s\n",vend);
5534887Schin 			break;
5544887Schin 		}
5554887Schin 		n = 0;
5564887Schin 		while(flag = *vend++)
5574887Schin 		{
5584887Schin 			if(flag==' ')
5594887Schin 			{
5604887Schin 				flag  = e_sptbnl[n+1];
5614887Schin 				n = !n;
5624887Schin 			}
5634887Schin 			sfputc(sfstdout,flag);
5644887Schin 		}
5654887Schin 		if(n)
5664887Schin 			sfputc(sfstdout,'\n');
5674887Schin 		break;
5684887Schin 	     default:
5694887Schin 		if((argc&1))
5704887Schin 			errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
5714887Schin 		/*FALLTHROUGH*/
5724887Schin 	     case 2:
5734887Schin 		if(!shp->lim.fs3d)
5744887Schin 			goto failed;
57510898Sroland.mainz@nrubsig.org 		if(shp->subshell && !shp->subshare)
5764887Schin 			sh_subfork();
5774887Schin  		for(n=0;n<argc;n+=2)
5784887Schin 		{
5794887Schin 			if(mount(argv[n+1],argv[n],flag,0)<0)
5804887Schin 				goto failed;
5814887Schin 		}
5824887Schin 	}
5834887Schin 	return(0);
5844887Schin failed:
5854887Schin 	if(argc>1)
5864887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_cantset,flag==2?e_mapping:e_versions);
5874887Schin 	else
5884887Schin 		errormsg(SH_DICT,ERROR_exit(1),e_cantget,flag==2?e_mapping:e_versions);
5894887Schin 	return(1);
5904887Schin     }
5914887Schin #endif /* SHOPT_FS_3D */
5924887Schin 
593