Esempio n. 1
0
File: args.c Progetto: att/ast
void sh_applyopts(Shell_t *shp, Shopt_t newflags) {
    // Cannot set -n for interactive shells since there is no way out.
    if (sh_isoption(shp, SH_INTERACTIVE)) off_option(&newflags, SH_NOEXEC);
    if (is_option(&newflags, SH_PRIVILEGED)) on_option(&newflags, SH_NOUSRPROFILE);
    int is_privileged = is_option(&newflags, SH_PRIVILEGED) != sh_isoption(shp, SH_PRIVILEGED);
    int is_privileged_off = is_option(&(shp->arg_context)->sh->offoptions, SH_PRIVILEGED);
    if ((!sh_isstate(shp, SH_INIT) && is_privileged) ||
        (sh_isstate(shp, SH_INIT) && is_privileged_off && shp->gd->userid != shp->gd->euserid)) {
        if (!is_option(&newflags, SH_PRIVILEGED)) {
            if (setuid(shp->gd->userid) < 0) {
                error(ERROR_system(0), "setuid(%d) failed", shp->gd->userid);
                return;
            }
            if (setgid(shp->gd->groupid) < 0) {
                error(ERROR_system(0), "setgid(%d) failed", shp->gd->groupid);
                return;
            }
            if (shp->gd->euserid == 0) {
                shp->gd->euserid = shp->gd->userid;
                shp->gd->egroupid = shp->gd->groupid;
            }
        } else if ((shp->gd->userid != shp->gd->euserid && setuid(shp->gd->euserid) < 0) ||
                   (shp->gd->groupid != shp->gd->egroupid && setgid(shp->gd->egroupid) < 0) ||
                   (shp->gd->userid == shp->gd->euserid && shp->gd->groupid == shp->gd->egroupid)) {
            off_option(&newflags, SH_PRIVILEGED);
        }
    }
#if SHOPT_BASH
    on_option(&newflags, SH_CMDHIST);
    on_option(&newflags, SH_CHECKHASH);
    on_option(&newflags, SH_EXECFAIL);
    on_option(&newflags, SH_EXPAND_ALIASES);
    on_option(&newflags, SH_HISTAPPEND);
    on_option(&newflags, SH_INTERACTIVE_COMM);
    on_option(&newflags, SH_LITHIST);
    on_option(&newflags, SH_NOEMPTYCMDCOMPL);

    if (!is_option(&newflags, SH_XPG_ECHO) && sh_isoption(shp, SH_XPG_ECHO)) {
        astconf("UNIVERSE", 0, "ucb");
    }
    if (is_option(&newflags, SH_XPG_ECHO) && !sh_isoption(shp, SH_XPG_ECHO)) {
        astconf("UNIVERSE", 0, "att");
    }
    if (is_option(&newflags, SH_HISTORY2) && !sh_isoption(shp, SH_HISTORY2)) {
        sh_onstate(shp, SH_HISTORY);
        sh_onoption(shp, SH_HISTORY);
    }
    if (!is_option(&newflags, SH_HISTORY2) && sh_isoption(shp, SH_HISTORY2)) {
        sh_offstate(shp, SH_HISTORY);
        sh_offoption(shp, SH_HISTORY);
    }
#endif
    shp->options = newflags;
}
Esempio n. 2
0
static void l_dirname(register Sfio_t *outfile, register const char *pathname)
{
	register const char  *last;
	/* go to end of path */
	for(last=pathname; *last; last++);
	/* back over trailing '/' */
	while(last>pathname && *--last=='/');
	/* back over non-slash chars */
	for(;last>pathname && *last!='/';last--);
	if(last==pathname)
	{
		/* all '/' or "" */
		if(*pathname!='/')
			last = pathname = ".";
	}
	else
	{
		/* back over trailing '/' */
		for(;*last=='/' && last > pathname; last--);
	}
	/* preserve // */
	if(last!=pathname && pathname[0]=='/' && pathname[1]=='/')
	{
		while(pathname[2]=='/' && pathname<last)
			pathname++;
		if(last!=pathname && pathname[0]=='/' && pathname[1]=='/' && *astconf("PATH_LEADING_SLASHES",NiL,NiL)!='1')
			pathname++;
	}
	sfwrite(outfile,pathname,last+1-pathname);
	sfputc(outfile,'\n');
}
Esempio n. 3
0
char*
pathbin(void)
{
	register char*	bin;

	static char*	val;

	if ((!(bin = getenv("PATH")) || !*bin) && !(bin = val))
	{
		if (!*(bin = astconf("PATH", NiL, NiL)) || !(bin = strdup(bin)))
			bin = "/bin:/usr/bin:/usr/local/bin";
		val = bin;
	}
	return bin;
}
Esempio n. 4
0
static void
init(void)
{
	register int	n;
	register char*	s;

	message((-1, "init"));
	state.toss = state.start = cs.time;
	for (n = 0; n < 10; n++) TOSS;
	state.fdtotal = (int)strtol(astconf("OPEN_MAX", NiL, NiL), NiL, 0);
	if (!(state.con = newof(0, Connection_t, state.fdtotal, 0)))
		error(3, "out of space [con]");
	state.con[0].type = POLL;
	if (!(state.job = state.jobnext = newof(0, Cojob_t, state.fdtotal / 2, 0)))
		error(3, "out of space [job]");
	state.jobmax = state.jobnext += state.fdtotal / 2 - 1;

	/*
	 * initialze the shell table
	 */

	state.busy = BUSY;
	state.grace = GRACE;
	state.pool = ((s = getenv(CO_ENV_PROC)) && *s) ? (int)strtol(s, NiL, 0) : POOL;
	if (!(state.home = search(DEF|NEW, csname(0), NiL, NiL)))
		error(3, "cannot get local host address");
	state.shell = state.shellnext = state.home;
	message((-1, "local name is %s", state.home->name));

	/*
	 * load the local net configuration
	 */

	info(DEF|NEW, NiL);

	/*
	 * bias the local host so it can generate more work
	 */

	if (state.home->idle)
	{
		state.home->idle = 0;
		if (!(state.home->flags & SETBIAS)) state.home->bias *= 4;
	}
}
Esempio n. 5
0
int    B_echo(int argc, char *argv[],Shbltin_t *context)
{
	static char bsd_univ;
	struct print prdata;
	prdata.options = sh_optecho+5;
	prdata.raw = prdata.echon = 0;
	prdata.sh = context->shp;
	NOT_USED(argc);
	/* This mess is because /bin/echo on BSD is different */
	if(!prdata.sh->universe)
	{
		register char *universe;
		if(universe=astconf("UNIVERSE",0,0))
			bsd_univ = (strcmp(universe,"ucb")==0);
		prdata.sh->universe = 1;
	}
	if(!bsd_univ)
		return(b_print(0,argv,(Shbltin_t*)&prdata));
	prdata.options = sh_optecho;
	prdata.raw = 1;
	while(argv[1] && *argv[1]=='-')
	{
		if(strcmp(argv[1],"-n")==0)
			prdata.echon = 1;
#if !SHOPT_ECHOE
		else if(strcmp(argv[1],"-e")==0)
			prdata.raw = 0;
		else if(strcmp(argv[1],"-ne")==0 || strcmp(argv[1],"-en")==0)
		{
			prdata.raw = 0;
			prdata.echon = 1;
		}
#endif /* SHOPT_ECHOE */
		else
			break;
		argv++;
	}
	return(b_print(0,argv,(Shbltin_t*)&prdata));
}
Esempio n. 6
0
static int
settime(void* context, const char* cmd, Time_t now, int adjust, int network)
{
	char*		s;
	char**		argv;
	char*		args[5];
	char		buf[1024];

	if (!adjust && !network)
		return tmxsettime(now);
	argv = args;
	s = "/usr/bin/date";
	if (!streq(cmd, s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK)))
	{
		*argv++ = s;
		if (streq(astconf("UNIVERSE", NiL, NiL), "att"))
		{
			tmxfmt(buf, sizeof(buf), "%m%d%H" "%M%Y.%S", now);
			if (adjust)
				*argv++ = "-a";
		}
		else
		{
			tmxfmt(buf, sizeof(buf), "%Y%m%d%H" "%M.%S", now);
			if (network)
				*argv++ = "-n";
			if (tm_info.flags & TM_UTC)
				*argv++ = "-u";
		}
		*argv++ = buf;
		*argv = 0;
		if (!sh_run(context, argv - args, args))
			return 0;
	}
	return -1;
}
Esempio n. 7
0
int	b_ulimit(int argc,char *argv[],void *extra)
{
	register char *limit;
	register int mode=0, n;
	register unsigned long hit = 0;
	Shell_t *shp = ((Shbltin_t*)extra)->shp;
#ifdef _lib_getrlimit
	struct rlimit rlp;
#endif /* _lib_getrlimit */
	const Limit_t* tp;
	char* conf;
	int label, unit, nosupport;
	rlim_t i;
	char tmp[32];
        Optdisc_t disc;
        memset(&disc, 0, sizeof(disc));
        disc.version = OPT_VERSION;
        disc.infof = infof;
	opt_info.disc = &disc;
	while((n = optget(argv,sh_optulimit))) switch(n)
	{
		case 'H':
			mode |= HARD;
			continue;
		case 'S':
			mode |= SOFT;
			continue;
		case 'a':
			hit = ~0;
			break;
		default:
			if(n < 0)
				hit |= (1L<<(-(n+1)));
			else
				errormsg(SH_DICT,2, e_notimp, opt_info.name);
			break;
		case ':':
			errormsg(SH_DICT,2, "%s", opt_info.arg);
			break;
		case '?':
			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
			break;
	}
	opt_info.disc = 0;
	/* default to -f */
	limit = argv[opt_info.index];
	if(hit==0)
		for(n=0; shtab_limits[n].option; n++)
			if(shtab_limits[n].index == RLIMIT_FSIZE)
			{
				hit |= (1L<<n);
				break;
			}
	/* only one option at a time for setting */
	label = (hit&(hit-1));
	if(error_info.errors || (limit && label) || argc>opt_info.index+1)
		errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
	if(mode==0)
		mode = (HARD|SOFT);
	for(tp = shtab_limits; tp->option && hit; tp++,hit>>=1)
	{
		if(!(hit&1))
			continue;
		nosupport = (n = tp->index) == RLIMIT_UNKNOWN;
		unit = shtab_units[tp->type];
		if(limit)
		{
			if(shp->subshell && !shp->subshare)
				sh_subfork();
			if(strcmp(limit,e_unlimited)==0)
				i = INFINITY;
			else
			{
				char *last;
				if((i=sh_strnum(limit,&last,2))==INFINITY || *last)
					errormsg(SH_DICT,ERROR_system(1),e_number,limit);
				i *= unit;
			}
			if(nosupport)
				errormsg(SH_DICT,ERROR_system(1),e_readonly,tp->name);
			else
			{
#ifdef _lib_getrlimit
				if(getrlimit(n,&rlp) <0)
					errormsg(SH_DICT,ERROR_system(1),e_number,limit);
				if(mode&HARD)
					rlp.rlim_max = i;
				if(mode&SOFT)
					rlp.rlim_cur = i;
				if(setrlimit(n,&rlp) <0)
					errormsg(SH_DICT,ERROR_system(1),e_overlimit,limit);
#else
				if((i=vlimit(n,i)) < 0)
					errormsg(SH_DICT,ERROR_system(1),e_number,limit);
#endif /* _lib_getrlimit */
			}
		}
		else
		{
			if(!nosupport)
			{
#ifdef  _lib_getrlimit
				if(getrlimit(n,&rlp) <0)
					errormsg(SH_DICT,ERROR_system(1),e_number,limit);
				if(mode&HARD)
					i = rlp.rlim_max;
				if(mode&SOFT)
					i = rlp.rlim_cur;
#else
#   ifdef _lib_ulimit
				n--;
#   endif /* _lib_ulimit */
				i = -1;
				if((i=vlimit(n,i)) < 0)
					errormsg(SH_DICT,ERROR_system(1),e_number,limit);
#endif /* _lib_getrlimit */
			}
			if(label)
			{
				if(tp->type != LIM_COUNT)
					sfsprintf(tmp,sizeof(tmp),"%s (%ss)", tp->description, e_units[tp->type]);
				else
					sfsprintf(tmp,sizeof(tmp),"%s", tp->name);
				sfprintf(sfstdout,"%-30s (-%c)  ",tmp,tp->option);
			}
			if(nosupport)
			{
				if(!tp->conf || !*(conf = astconf(tp->conf, NiL, NiL)))
					conf = (char*)e_nosupport;
				sfputr(sfstdout,conf,'\n');
			}
			else if(i!=INFINITY)
			{
				i += (unit-1);
				sfprintf(sfstdout,"%I*d\n",sizeof(i),i/unit);
			}
			else
				sfputr(sfstdout,e_unlimited,'\n');
		}
	}
	return(0);
}
Esempio n. 8
0
static int
rm(State_t* state, register FTSENT* ent)
{
	register char*	path;
	register int	n;
	int		v;
	struct stat	st;

	if (ent->fts_info == FTS_NS || ent->fts_info == FTS_ERR || ent->fts_info == FTS_SLNONE)
	{
		if (!state->force)
			error(2, "%s: not found", ent->fts_path);
	}
	else if (state->fs3d && iview(ent->fts_statp))
		fts_set(NiL, ent, FTS_SKIP);
	else switch (ent->fts_info)
	{
	case FTS_DNR:
	case FTS_DNX:
		if (state->unconditional)
		{
			if (!beenhere(ent))
				break;
			if (!chmod(ent->fts_name, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU))
			{
				fts_set(NiL, ent, FTS_AGAIN);
				break;
			}
			error_info.errors++;
		}
		else if (!state->force)
			error(2, "%s: cannot %s directory", ent->fts_path, (ent->fts_info & FTS_NR) ? "read" : "search");
		else
			error_info.errors++;
		fts_set(NiL, ent, FTS_SKIP);
		nonempty(ent);
		break;
	case FTS_D:
	case FTS_DC:
		path = ent->fts_name;
		if (path[0] == '.' && (!path[1] || path[1] == '.' && !path[2]) && (ent->fts_level > 0 || path[1]))
		{
			fts_set(NiL, ent, FTS_SKIP);
			if (!state->force)
				error(2, "%s: cannot remove", ent->fts_path);
			else
				error_info.errors++;
			break;
		}
		if (!state->recursive)
		{
			fts_set(NiL, ent, FTS_SKIP);
			error(2, "%s: directory", ent->fts_path);
			break;
		}
		if (!beenhere(ent))
		{
			if (state->unconditional && (ent->fts_statp->st_mode & S_IRWXU) != S_IRWXU)
				chmod(path, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU);
			if (ent->fts_level > 0)
			{
				char*	s;

				if (ent->fts_accpath == ent->fts_name || !(s = strrchr(ent->fts_accpath, '/')))
					v = !stat(".", &st);
				else
				{
					path = ent->fts_accpath;
					*s = 0;
					v = !stat(path, &st);
					*s = '/';
				}
				if (v)
					v = st.st_nlink <= 2 || st.st_ino == ent->fts_parent->fts_statp->st_ino && st.st_dev == ent->fts_parent->fts_statp->st_dev || strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'l');
			}
			else
				v = 1;
			if (v)
			{
				if (state->interactive)
				{
					if ((v = astquery(-1, "remove directory %s? ", ent->fts_path)) < 0 || sh_checksig(state->context))
						return -1;
					if (v > 0)
					{
						fts_set(NiL, ent, FTS_SKIP);
						nonempty(ent);
					}
				}
				if (ent->fts_info == FTS_D)
					break;
			}
			else
			{
				ent->fts_info = FTS_DC;
				error(1, "%s: hard link to directory", ent->fts_path);
			}
		}
		else if (ent->fts_info == FTS_D)
			break;
		/*FALLTHROUGH*/
	case FTS_DP:
		if (isempty(ent) || state->directory)
		{
			path = ent->fts_name;
			if (path[0] != '.' || path[1])
			{
				path = ent->fts_accpath;
				if (state->verbose)
					sfputr(sfstdout, ent->fts_path, '\n');
				if ((ent->fts_info == FTS_DC || state->directory) ? remove(path) : rmdir(path))
					switch (errno)
					{
					case ENOENT:
						break;
					case EEXIST:
#if defined(ENOTEMPTY) && (ENOTEMPTY) != (EEXIST)
					case ENOTEMPTY:
#endif
						if (ent->fts_info == FTS_DP && !beenhere(ent))
						{
							retry(ent);
							fts_set(NiL, ent, FTS_AGAIN);
							break;
						}
						/*FALLTHROUGH*/
					default:
						nonempty(ent);
						if (!state->force)
							error(ERROR_SYSTEM|2, "%s: directory not removed", ent->fts_path);
						else
							error_info.errors++;
						break;
					}
			}
			else if (!state->force)
				error(2, "%s: cannot remove", ent->fts_path);
			else
				error_info.errors++;
		}
		else
		{
			nonempty(ent);
			if (!state->force)
				error(2, "%s: directory not removed", ent->fts_path);
			else
				error_info.errors++;
		}
		break;
	default:
		path = ent->fts_accpath;
		if (state->verbose)
			sfputr(sfstdout, ent->fts_path, '\n');
		if (state->interactive)
		{
			if ((v = astquery(-1, "remove %s? ", ent->fts_path)) < 0 || sh_checksig(state->context))
				return -1;
			if (v > 0)
			{
				nonempty(ent);
				break;
			}
		}
		else if (!state->force && state->terminal && eaccess(path, W_OK))
		{
			if ((v = astquery(-1, "override protection %s for %s? ",
#ifdef ETXTBSY
				errno == ETXTBSY ? "``running program''" : 
#endif
				ent->fts_statp->st_uid != state->uid ? "``not owner''" :
				fmtmode(ent->fts_statp->st_mode & S_IPERM, 0) + 1, ent->fts_path)) < 0 ||
			    sh_checksig(state->context))
				return -1;
			if (v > 0)
			{
				nonempty(ent);
				break;
			}
		}
#if _lib_fsync
		if (state->clobber && S_ISREG(ent->fts_statp->st_mode) && ent->fts_statp->st_size > 0)
		{
			if ((n = open(path, O_WRONLY)) < 0)
				error(ERROR_SYSTEM|2, "%s: cannot clear data", ent->fts_path);
			else
			{
				off_t		c = ent->fts_statp->st_size;

				for (;;)
				{
					if (write(n, state->buf, sizeof(state->buf)) != sizeof(state->buf))
					{
						error(ERROR_SYSTEM|2, "%s: data clear error", ent->fts_path);
						break;
					}
					if (c <= sizeof(state->buf))
						break;
					c -= sizeof(state->buf);
				}
				fsync(n);
				close(n);
			}
		}
#endif
		if (remove(path))
		{
			nonempty(ent);
			switch (errno)
			{
			case ENOENT:
				break;
			default:
				if (!state->force || state->interactive)
					error(ERROR_SYSTEM|2, "%s: not removed", ent->fts_path);
				else
					error_info.errors++;
				break;
			}
		}
		break;
	}
	return 0;
}
Esempio n. 9
0
int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
{
	struct comnod	*comptr;
	struct argnod	*ap;
	register char	*out;
	char 		*av[2], *begin , *dir=0;
	int		addstar=0, rval=0, var=0, strip=1;
	int 		nomarkdirs = !sh_isoption(SH_MARKDIRS);
	sh_onstate(SH_FCOMPLETE);
	if(ep->e_nlist)
	{
		if(mode=='=' && count>0)
		{
			if(count> ep->e_nlist)
				return(-1);
			mode = '?';
			av[0] = ep->e_clist[count-1];
			av[1] = 0;
		}
		else
		{
			stakset(ep->e_stkptr,ep->e_stkoff);
			ep->e_nlist = 0;
		}
	}
	comptr = (struct comnod*)stakalloc(sizeof(struct comnod));
	ap = (struct argnod*)stakseek(ARGVAL);
#if SHOPT_MULTIBYTE
	{
		register int c = *cur;
		register genchar *cp;
		/* adjust cur */
		cp = (genchar *)outbuff + *cur;
		c = *cp;
		*cp = 0;
		*cur = ed_external((genchar*)outbuff,(char*)stakptr(0));
		*cp = c;
		*eol = ed_external((genchar*)outbuff,outbuff);
	}
#endif /* SHOPT_MULTIBYTE */
	out = outbuff + *cur + (sh_isoption(SH_VI)!=0);
	if(out[-1]=='"' || out[-1]=='\'')
	{
		rval = -(sh_isoption(SH_VI)!=0);
		goto done;
	}
	comptr->comtyp = COMSCAN;
	comptr->comarg = ap;
	ap->argflag = (ARG_MAC|ARG_EXP);
	ap->argnxt.ap = 0;
	ap->argchn.cp = 0;
	{
		register int c;
		char *last = out;
		c =  *(unsigned char*)out;
		var = mode;
		begin = out = find_begin(outbuff,last,0,&var);
		/* addstar set to zero if * should not be added */
		if(var=='$')
		{
			stakputs("${!");
			stakwrite(out,last-out);
			stakputs("@}");
			out = last;
		}
		else
		{
			addstar = '*';
			while(out < last)
			{
				c = *(unsigned char*)out;
				if(isexp(c))
					addstar = 0;
				if (c == '/')
				{
					if(addstar == 0)
						strip = 0;
					dir = out+1;
				}
				stakputc(c);
				out++;
			}
		}
		if(mode=='?')
			mode = '*';
		if(var!='$' && mode=='\\' && out[-1]!='*')
			addstar = '*';
		if(*begin=='~' && !strchr(begin,'/'))
			addstar = 0;
		stakputc(addstar);
		ap = (struct argnod*)stakfreeze(1);
	}
	if(mode!='*')
		sh_onoption(SH_MARKDIRS);
	{
		register char	**com;
		char		*cp=begin, *left=0, *saveout=".";
		int	 	nocase=0,narg,cmd_completion=0;
		register 	int size='x';
		while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t'))
			cp--;
		if(!var && !strchr(ap->argval,'/') && (((cp==outbuff&&ep->sh->nextprompt==1) || (strchr(";&|(",size)) && (cp==outbuff+1||size=='('||cp[-2]!='>') && *begin!='~' )))
		{
			cmd_completion=1;
			sh_onstate(SH_COMPLETE);
		}
		if(ep->e_nlist)
		{
			narg = 1;
			com = av;
			if(dir)
				begin += (dir-begin);
		}
		else
		{
			com = sh_argbuild(ep->sh,&narg,comptr,0);
			/* special handling for leading quotes */
			if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
			begin--;
		}
		sh_offstate(SH_COMPLETE);
                /* allow a search to be aborted */
		if(ep->sh->trapnote&SH_SIGSET)
		{
			rval = -1;
			goto done;
		}
		/*  match? */
		if (*com==0 || (narg <= 1 && (strcmp(ap->argval,*com)==0) || (addstar && com[0][strlen(*com)-1]=='*')))
		{
			rval = -1;
			goto done;
		}
		if(mode=='\\' && out[-1]=='/'  && narg>1)
			mode = '=';
		if(mode=='=')
		{
			if (strip && !cmd_completion)
			{
				register char **ptrcom;
				for(ptrcom=com;*ptrcom;ptrcom++)
					/* trim directory prefix */
					*ptrcom = path_basename(*ptrcom);
			}
			sfputc(sfstderr,'\n');
			sh_menu(sfstderr,narg,com);
			sfsync(sfstderr);
			ep->e_nlist = narg;
			ep->e_clist = com;
			goto done;
		}
		/* see if there is enough room */
		size = *eol - (out-begin);
		if(mode=='\\')
		{
			int c;
			if(dir)
			{
				c = *dir;
				*dir = 0;
				saveout = begin;
			}
			if(saveout=astconf("PATH_ATTRIBUTES",saveout,(char*)0))
				nocase = (strchr(saveout,'c')!=0);
			if(dir)
				*dir = c;
			/* just expand until name is unique */
			size += strlen(*com);
		}
		else
		{
			size += narg;
			{
				char **savcom = com;
				while (*com)
					size += strlen(cp=fmtx(*com++));
				com = savcom;
			}
		}
		/* see if room for expansion */
		if(outbuff+size >= &outbuff[MAXLINE])
		{
			com[0] = ap->argval;
			com[1] = 0;
		}
		/* save remainder of the buffer */
		if(*out)
			left=stakcopy(out);
		if(cmd_completion && mode=='\\')
			out = strcopy(begin,path_basename(cp= *com++));
		else if(mode=='*')
		{
			if(ep->e_nlist && dir && var)
			{
				if(*cp==var)
					cp++;
				else
					*begin++ = var;
				out = strcopy(begin,cp);
				var = 0;
			}
			else
				out = strcopy(begin,fmtx(*com));
			com++;
		}
		else
			out = strcopy(begin,*com++);
		if(mode=='\\')
		{
			saveout= ++out;
			while (*com && *begin)
			{
				if(cmd_completion)
					out = overlaid(begin,path_basename(*com++),nocase);
				else
					out = overlaid(begin,*com++,nocase);
			}
			mode = (out==saveout);
			if(out[-1]==0)
				out--;
			if(mode && out[-1]!='/')
			{
				if(cmd_completion)
				{
					Namval_t *np;
					/* add as tracked alias */
					Pathcomp_t *pp;
					if(*cp=='/' && (pp=path_dirfind(ep->sh->pathlist,cp,'/')) && (np=nv_search(begin,ep->sh->track_tree,NV_ADD)))
						path_alias(np,pp);
					out = strcopy(begin,cp);
				}
				/* add quotes if necessary */
				if((cp=fmtx(begin))!=begin)
					out = strcopy(begin,cp);
				if(var=='$' && begin[-1]=='{')
					*out = '}';
				else
					*out = ' ';
				*++out = 0;
			}
			else if((cp=fmtx(begin))!=begin)
			{
				out = strcopy(begin,cp);
				if(out[-1] =='"' || out[-1]=='\'')
					  *--out = 0;
			}
			if(*begin==0)
				ed_ringbell();
		}
		else
		{
			while (*com)
			{
				*out++  = ' ';
				out = strcopy(out,fmtx(*com++));
			}
		}
		if(ep->e_nlist)
		{
			cp = com[-1];
			if(cp[strlen(cp)-1]!='/')
			{
				if(var=='$' && begin[-1]=='{')
					*out = '}';
				else
					*out = ' ';
				out++;
			}
			else if(out[-1] =='"' || out[-1]=='\'')
				out--;
			*out = 0;
		}
		*cur = (out-outbuff);
		/* restore rest of buffer */
		if(left)
			out = strcopy(out,left);
		*eol = (out-outbuff);
	}
 done:
	sh_offstate(SH_FCOMPLETE);
	if(!ep->e_nlist)
		stakset(ep->e_stkptr,ep->e_stkoff);
	if(nomarkdirs)
		sh_offoption(SH_MARKDIRS);
#if SHOPT_MULTIBYTE
	{
		register int c,n=0;
		/* first re-adjust cur */
		c = outbuff[*cur];
		outbuff[*cur] = 0;
		for(out=outbuff; *out;n++)
			mbchar(out);
		outbuff[*cur] = c;
		*cur = n;
		outbuff[*eol+1] = 0;
		*eol = ed_internal(outbuff,(genchar*)outbuff);
	}
#endif /* SHOPT_MULTIBYTE */
	return(rval);
}
Esempio n. 10
0
int
b_uname(int argc, char** argv, void* context)
{
	register long	flags = 0;
	register int	sep = 0;
	register int	n;
	register char*	s;
	char*		t;
	char*		e;
	char*		sethost = 0;
	int		list = 0;
	struct utsname	ut;
	char		buf[257];

	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 'a':
			flags |= OPT_all|((1L<<OPT_ALL)-1);
			continue;
		case 'b':
			flags |= OPT_base;
			continue;
		case 'c':
			flags |= OPT_vendor;
			continue;
		case 'd':
			flags |= OPT_domain;
			continue;
		case 'f':
			list = 1;
			continue;
		case 'h':
			flags |= OPT_hostid;
			continue;
		case 'i':
			flags |= OPT_implementation;
			continue;
		case 'm':
			flags |= OPT_machine;
			continue;
		case 'n':
			flags |= OPT_nodename;
			continue;
		case 'o':
			flags |= OPT_operating_system;
			continue;
		case 'p':
			flags |= OPT_processor;
			continue;
		case 'r':
			flags |= OPT_release;
			continue;
		case 's':
			flags |= OPT_system;
			continue;
		case 't':
			flags |= OPT_machine_type;
			continue;
		case 'v':
			flags |= OPT_version;
			continue;
		case 'x':
			flags |= OPT_extra;
			continue;
		case 'A':
			flags |= OPT_total|((1L<<OPT_TOTAL)-1);
			continue;
		case 'R':
			flags |= OPT_extended_release;
			continue;
		case 'S':
			sethost = opt_info.arg;
			continue;
		case ':':
			s = "/usr/bin/uname";
			if (!streq(argv[0], s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK)))
			{
				argv[0] = s;
				return sh_run(context, argc, argv);
			}
			error(2, "%s", opt_info.arg);
			break;
		case '?':
			error(ERROR_usage(2), "%s", opt_info.arg);
			break;
		}
		break;
	}
	argv += opt_info.index;
	if (error_info.errors || *argv && (flags || sethost) || sethost && flags)
		error(ERROR_usage(2), "%s", optusage(NiL));
	if (sethost)
	{
#if _lib_sethostname
		if (sethostname(sethost, strlen(sethost) + 1))
#else
#ifdef	ENOSYS
		errno = ENOSYS;
#else
		errno = EPERM;
#endif
#endif
		error(ERROR_system(1), "%s: cannot set host name", sethost);
	}
	else if (list)
		astconflist(sfstdout, NiL, ASTCONF_base|ASTCONF_defined|ASTCONF_lower|ASTCONF_quote|ASTCONF_matchcall, "CS|SI");
	else if (*argv)
	{
		e = &buf[sizeof(buf)-1];
		while (s = *argv++)
		{
			t = buf;
			*t++ = 'C';
			*t++ = 'S';
			*t++ = '_';
			while (t < e && (n = *s++))
				*t++ = islower(n) ? toupper(n) : n;
			*t = 0;
			sfprintf(sfstdout, "%s%c", *(t = astconf(buf, NiL, NiL)) ? t : *(t = astconf(buf+3, NiL, NiL)) ? t :  "unknown", *argv ? ' ' : '\n');
		}
	}
	else
	{
		s = buf;
		if (!flags)
			flags = OPT_system;
		memzero(&ut, sizeof(ut));
		if (uname(&ut) < 0)
			error(ERROR_usage(2), "information unavailable");
		output(OPT_system, ut.sysname, "sysname");
		if (flags & OPT_nodename)
		{
#if !_mem_nodeext_utsname && _lib_gethostname
			if (sizeof(ut.nodename) > 9 || gethostname(s, sizeof(buf)))
#endif
			s = ut.nodename;
			output(OPT_nodename, s, "nodename");
		}
		output(OPT_release, ut.release, "release");
		output(OPT_version, ut.version, "version");
		output(OPT_machine, ut.machine, "machine");
		if (flags & OPT_processor)
		{
			if (!*(s = astconf("ARCHITECTURE", NiL, NiL)))
				s = ut.machine;
			output(OPT_processor, s, "processor");
		}
		if (flags & OPT_implementation)
		{
			if (!*(s = astconf("PLATFORM", NiL, NiL)) && !*(s = astconf("HW_NAME", NiL, NiL)))
			{
				if (t = strchr(hosttype, '.'))
					t++;
				else
					t = (char*)hosttype;
				strncpy(s = buf, t, sizeof(buf) - 1);
			}
			output(OPT_implementation, s, "implementation");
		}
		if (flags & OPT_operating_system)
		{
			s = astconf("OPERATING_SYSTEM", NiL, NiL);
			if (!*s)
#ifdef _UNAME_os_DEFAULT
				s = _UNAME_os_DEFAULT;
#else
				s = ut.sysname;
#endif
			output(OPT_operating_system, s, "operating-system");
		}
		if (flags & OPT_extended_release)
		{
			s = astconf("RELEASE", NiL, NiL);
			output(OPT_extended_release, s, "extended-release");
		}
#if _mem_idnumber_utsname
		output(OPT_hostid, ut.idnumber, "hostid");
#else
		if (flags & OPT_hostid)
		{
			if (!*(s = astconf("HW_SERIAL", NiL, NiL)))
#if _lib_gethostid
				sfsprintf(s = buf, sizeof(buf), "%08x", gethostid());
#else
				/*NOP*/;
#endif
			output(OPT_hostid, s, "hostid");
		}
#endif
		if (flags & OPT_vendor)
		{
			s = astconf("HW_PROVIDER", NiL, NiL);
			output(OPT_vendor, s, "vendor");
		}
		if (flags & OPT_domain)
		{
			if (!*(s = astconf("SRPC_DOMAIN", NiL, NiL)))
#if _lib_getdomainname
				getdomainname(s, sizeof(buf));
#else
				/*NOP*/;
#endif
			output(OPT_domain, s, "domain");
		}
#if _mem_m_type_utsname
		s = ut.m_type;
#else
		s = astconf("MACHINE", NiL, NiL);
#endif
		output(OPT_machine_type, s, "m_type");
#if _mem_base_rel_utsname
		s = ut.base_rel;
#else
		s = astconf("BASE", NiL, NiL);
#endif
		output(OPT_base, s, "base_rel");
		if (flags & OPT_extra)
		{
			char*	last = (char*)&ut;

			extra(sysname);
			extra(nodename);
			extra(release);
			extra(version);
			extra(machine);
#if _mem_idnumber_utsname
			extra(idnumber);
#endif
#if _mem_m_type_utsname
			extra(m_type);
#endif
#if _mem_base_rel_utsname
			extra(base_rel);
#endif
			if (last < ((char*)(&ut + 1)))
			{
				s = t = last;
				while (s < (char*)(&ut + 1))
				{
					if (!(n = *s++))
					{
						if ((s - t) > 1)
						{
							if (sep)
								sfputc(sfstdout, ' ');
							else
								sep = 1;
							sfputr(sfstdout, t, -1);
						}
						t = s;
					}
					else if (!isprint(n))
						break;
				}
			}
		}
		if (sep)
			sfputc(sfstdout, '\n');
	}
	return error_info.errors;
}
Esempio n. 11
0
char*
pathshell(void)
{
	register char*	sh;
	int		ru;
	int		eu;
	int		rg;
	int		eg;
	struct stat	st;

	static char*	val;

	if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))
	{
		if (!(ru = getuid()) || !eaccess("/bin", W_OK))
		{
			if (stat(sh, &st))
				goto defshell;
			if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))
				goto defshell;
		}
		else
		{
			eu = geteuid();
			rg = getgid();
			eg = getegid();
			if (ru != eu || rg != eg)
			{
				char*	s;
				char	dir[PATH_MAX];

				s = sh;
				for (;;)
				{
					if (stat(s, &st))
						goto defshell;
					if (ru != eu && st.st_uid == ru)
						goto defshell;
					if (rg != eg && st.st_gid == rg)
						goto defshell;
					if (s != sh)
						break;
					if (strlen(s) >= sizeof(dir))
						goto defshell;
					strcpy(dir, s);
					if (!(s = strrchr(dir, '/')))
						break;
					*s = 0;
					s = dir;
				}
			}
		}
		return sh;
	}
 defshell:
	if (!(sh = val))
	{
		if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
			sh = "/bin/sh";
		val = sh;
	}
	return sh;
}
Esempio n. 12
0
static int
gl_attr(glob_t* gp, const char* path, int flags)
{
	return strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'c') ? GLOB_ICASE : 0;
}
Esempio n. 13
0
void bash_init(int mode)
{
	Shell_t		*shp = &sh;
	Sfio_t		*iop;
	Namval_t	*np;
	int		n=0,xtrace,verbose;
	if(mode>0)
		goto reinit;
	if(mode < 0)
	{
		/* termination code */
		if(sh_isoption(SH_LOGIN_SHELL) && !sh_isoption(SH_POSIX))
			sh_source(shp, NiL, sh_mactry(shp,(char*)e_bash_logout));
		return;	
	}

	if(sh_isstate(SH_PREINIT))
	{	/* pre-init stage */
		if(sh_isoption(SH_RESTRICTED))
			sh_onoption(SH_RESTRICTED2);
		sh_onoption(SH_HISTORY2);
		sh_onoption(SH_INTERACTIVE_COMM);
		sh_onoption(SH_SOURCEPATH);
		sh_onoption(SH_HISTAPPEND);
		sh_onoption(SH_CMDHIST);
		sh_onoption(SH_LITHIST);
		sh_onoption(SH_NOEMPTYCMDCOMPL);
		if(shp->login_sh==2)
			sh_onoption(SH_LOGIN_SHELL);
		if(strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
			sh_onoption(SH_POSIX);
		if(strcmp(astconf("UNIVERSE",0,0),"att")==0)
			sh_onoption(SH_XPG_ECHO);
		else
			sh_offoption(SH_XPG_ECHO);
		if(strcmp(astconf("PATH_RESOLVE",0,0),"physical")==0)
			sh_onoption(SH_PHYSICAL);
		else
			sh_offoption(SH_PHYSICAL);

		/* add builtins */
		sh_addbuiltin("shopt", b_shopt, &sh);

		/* set up some variables needed for --version
		 * needs to go here because --version option is parsed before the init script.
		 */
		if(np=nv_open("HOSTTYPE",shp->var_tree,0))
			nv_putval(np, BASH_HOSTTYPE, NV_NOFREE);
		if(np=nv_open("MACHTYPE",shp->var_tree,0))
			nv_putval(np, BASH_MACHTYPE, NV_NOFREE);
		if(np=nv_open("BASH_VERSION",shp->var_tree,0))
			nv_putval(np, BASH_VERSION, NV_NOFREE);
		if(np=nv_open("BASH_VERSINFO",shp->var_tree,0))
		{
			char *argv[7];
			argv[0] = BASH_MAJOR;
			argv[1] = BASH_MINOR;
			argv[2] = BASH_PATCH;
			argv[3] = BASH_BUILD;
			argv[4] = BASH_RELEASE;
			argv[5] = BASH_MACHTYPE;
			argv[6] = 0;
			nv_setvec(np, 0, 6, argv);
			nv_onattr(np,NV_RDONLY);
		}
		return;
	}

	/* rest of init stage */

	/* restrict BASH_ENV */
	if(np=nv_open("BASH_ENV",shp->var_tree,0))
	{
		const Namdisc_t *dp = nv_discfun(NV_DCRESTRICT);
		Namfun_t *fp = calloc(dp->dsize,1);
		fp->disc = dp;
		nv_disc(np, fp, 0);
	}

	/* open GLOBIGNORE node */
	if(np=nv_open("GLOBIGNORE",shp->var_tree,0))
	{
		const Namdisc_t *dp = &SH_GLOBIGNORE_disc;
		Namfun_t *fp = calloc(dp->dsize,1);
		fp->disc = dp;
		nv_disc(np, fp, 0);
	}

	/* set startup files */
	n=0;
	if(sh_isoption(SH_LOGIN_SHELL))
	{
		if(!sh_isoption(SH_POSIX))
		{
			login_files[n++] = (char*)e_bash_profile;
			login_files[n++] = (char*)e_bash_login;
		}
		login_files[n++] = (char*)e_profile;
	}
	shp->login_files = login_files;
reinit:
	xtrace = sh_isoption(SH_XTRACE);
	sh_offoption(SH_XTRACE);
	verbose = sh_isoption(SH_VERBOSE);
	sh_offoption(SH_VERBOSE);
	if(np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD))
		nv_offattr(np,NV_RDONLY);
	iop = sfopen(NULL, bash_pre_rc, "s");
	sh_eval(iop,0);
	if(xtrace)
		sh_offoption(SH_XTRACE);
	if(verbose)
		sh_offoption(SH_VERBOSE);
}
Esempio n. 14
0
static int
tw(register Ftw_t* ftw)
{
	Local_t*	lp;

	switch (ftw->info)
	{
	case FTW_NS:
		if (!state.info)
		{
			if (!state.pattern && !state.ignore)
				error(2, "%s: not found", ftw->path);
			return 0;
		}
		break;
	case FTW_DC:
		if (!state.info)
		{
			if (!state.ignore)
				error(2, "%s: directory causes cycle", ftw->path);
			return 0;
		}
		break;
	case FTW_DNR:
		if (!state.info)
		{
			if (!state.ignore)
				error(2, "%s: cannot read directory", ftw->path);
		}
		break;
	case FTW_DNX:
		if (!state.info)
		{
			if (!state.ignore)
				error(2, "%s: cannot search directory", ftw->path);
			ftw->status = FTW_SKIP;
		}
		break;
	case FTW_DP:
		if (!(state.ftwflags & FTW_TWICE) || (state.ftwflags & FTW_DOT) && stat(PATH(ftw), &ftw->statb))
			goto pop;
		break;
	case FTW_D:
		ftw->ignorecase = (state.icase || (!ftw->level || !ftw->parent->ignorecase) && strchr(astconf("PATH_ATTRIBUTES", ftw->name, NiL), 'c')) ? STR_ICASE : 0;
		break;
	default:
		ftw->ignorecase = ftw->level ? ftw->parent->ignorecase : (state.icase || strchr(astconf("PATH_ATTRIBUTES", ftw->name, NiL), 'c')) ? STR_ICASE : 0;
		break;
	}
	if (state.localfs && (ftw->info & FTW_D) && !ftwlocal(ftw))
		ftw->status = FTW_SKIP;
	else
	{
		if (state.select == ALL || eval(state.select, ftw) && ftw->status != FTW_SKIP)
			act(ftw, state.act);
 pop:
		if (state.localmem && (lp = (Local_t*)ftw->local.pointer))
		{
			lp->next = state.local;
			state.local = lp;
		}
		if ((state.ftwflags & (FTW_LIST|FTW_RECURSIVE)) == FTW_LIST)
			ftw->status = FTW_SKIP;
	}
	return 0;
}
Esempio n. 15
0
File: bash.c Progetto: att/ast
//
// mode = 0: init, called two times
//      before parsing shell args with SH_PREINIT state turned on
//      second time after sh_init() is through and with SH_PREINIT state turned off
// mode > 1: re-init
// mode < 0: shutdown
//
void bash_init(Shell_t *shp, int mode) {
    Sfio_t *iop;
    Namval_t *np;
    int n = 0, xtrace, verbose;

    if (mode > 0) goto reinit;
    if (mode < 0) {  // termination code
        if (sh_isoption(shp, SH_LOGIN_SHELL) && !sh_isoption(shp, SH_POSIX)) {
            sh_source(shp, NULL, sh_mactry(shp, (char *)e_bash_logout));
        }
        return;
    }

    if (sh_isstate(shp, SH_PREINIT)) {  // pre-init stage
        if (sh_isoption(shp, SH_RESTRICTED)) sh_onoption(shp, SH_RESTRICTED2);
        sh_onoption(shp, SH_HISTORY2);
        sh_onoption(shp, SH_INTERACTIVE_COMM);
        sh_onoption(shp, SH_SOURCEPATH);
        sh_onoption(shp, SH_HISTAPPEND);
        sh_onoption(shp, SH_CMDHIST);
        sh_onoption(shp, SH_LITHIST);
        sh_onoption(shp, SH_NOEMPTYCMDCOMPL);
        sh_onoption(shp, SH_POSIX);
        if (shp->login_sh == 2) sh_onoption(shp, SH_LOGIN_SHELL);
        if (strcmp(astconf("UNIVERSE", 0, 0), "att") == 0) {
            sh_onoption(shp, SH_XPG_ECHO);
        } else {
            sh_offoption(shp, SH_XPG_ECHO);
        }
        sh_offoption(shp, SH_PHYSICAL);

        // Add builtins.
        sh_addbuiltin(shp, "shopt", b_shopt, &sh);
        sh_addbuiltin(shp, "enable", b_builtin, &sh);

// Set up some variables needed for --version.
// Needs to go here because --version option is parsed before the init script.
#if 0
        /* This was causing a core dump when running set to display all variables */
                if(np=nv_open("HOSTTYPE",shp->var_tree,0))
                        nv_putval(np, BASH_HOSTTYPE, NV_NOFREE);
#endif
        np = nv_open("MACHTYPE", shp->var_tree, 0);
        if (np) nv_putval(np, BASH_MACHTYPE, NV_NOFREE);
        np = nv_open("BASH_VERSION", shp->var_tree, 0);
        if (np) nv_putval(np, BASH_VERSION, NV_NOFREE);
        np = nv_open("BASH_VERSINFO", shp->var_tree, 0);
        if (np) {
            char *argv[7];
            argv[0] = BASH_MAJOR;
            argv[1] = BASH_MINOR;
            argv[2] = BASH_PATCH;
            argv[3] = BASH_BUILD;
            argv[4] = BASH_RELEASE;
            argv[5] = BASH_MACHTYPE;
            argv[6] = 0;
            nv_setvec(np, 0, 6, argv);
            nv_onattr(np, NV_RDONLY);
        }
        return;
    }

    // Rest of init stage.

    // Restrict BASH_ENV.
    np = nv_open("BASH_ENV", shp->var_tree, 0);
    if (np) {
        const Namdisc_t *dp = nv_discfun(DISCFUN_RESTRICT);
        Namfun_t *fp = calloc(dp->dsize, 1);
        fp->disc = dp;
        nv_disc(np, fp, DISC_NOOP);
    }

    // Open GLOBIGNORE node.
    np = nv_open("GLOBIGNORE", shp->var_tree, 0);
    if (np) {
        const Namdisc_t *dp = &SH_GLOBIGNORE_disc;
        Namfun_t *fp = calloc(dp->dsize, 1);
        fp->disc = dp;
        nv_disc(np, fp, DISC_NOOP);
    }

    np = nv_open("BASH_EXECUTION_STRING", shp->var_tree, 0);
    if (np) {
        np->nvalue.cp = shp->comdiv;
        nv_onattr(np, NV_NOFREE);
    }

    // Set startup files.
    n = 0;
    if (sh_isoption(shp, SH_LOGIN_SHELL)) {
        if (!sh_isoption(shp, SH_POSIX)) {
            shp->gd->login_files[n++] = (char *)e_bash_profile;
            shp->gd->login_files[n++] = (char *)e_bash_login;
        }
        shp->gd->login_files[n++] = (char *)e_profile;
    }
    shp->gd->login_files = login_files;

reinit:
    xtrace = sh_isoption(shp, SH_XTRACE);
    sh_offoption(shp, SH_XTRACE);
    verbose = sh_isoption(shp, SH_VERBOSE);
    sh_offoption(shp, SH_VERBOSE);
    np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD);
    if (np) nv_offattr(np, NV_RDONLY);
    iop = sfopen(NULL, bash_pre_rc, "s");
    sh_eval(shp, iop, 0);
    if (xtrace) sh_offoption(shp, SH_XTRACE);
    if (verbose) sh_offoption(shp, SH_VERBOSE);
}