Пример #1
0
Файл: args.c Проект: 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;
}
Пример #2
0
int init_jobs(lflag)
{
	register int pid;
	register int dev;
	struct stat statbuf;
	jobstat.mypid = pid = getpid();
	savepgrp = getpgrp(pid);
	if(ioctl(2,SXTIOCSTAT,&status2) < 0)
		return(-1);
	if(ioctl(2,TCGETA,&my_stty) < 0)
		return(-1);
	if(fstat(2,&statbuf) < 0)
		return(-1);
	dev = statbuf.st_rdev&0xff;
	/* must be channel 0 */
	if(dev&07)
		return(-1);
	dev >>= 3;
	sxt[10] = '0' + (dev%10);
	sxt[9] = '0' + dev/10;
	my_stty.c_cc[VSWTCH] = CSWTCH;
	if(ioctl(2,TCSETAF,&my_stty) < 0)
		return(-1);
	setpgrp(pid,pid);
	jobstat.maxjob = MAXPCHAN;
	on_option(MONITOR);
	return(0);
}
Пример #3
0
Gobby::ClosableFrame::ClosableFrame(const Glib::ustring& title,
                                    const Glib::ustring& icon_name,
                                    Preferences::Option<bool>& option):
	m_option(option), m_allow_visible(true)
{
	CloseButton* button = Gtk::manage(new CloseButton);

	button->set_hexpand(true);
	button->set_halign(Gtk::ALIGN_END);

	button->signal_clicked().connect(
		sigc::mem_fun(*this, &ClosableFrame::on_clicked));
	m_option.signal_changed().connect(
		sigc::mem_fun(*this, &ClosableFrame::on_option));

	button->show();

	Gtk::Image* image = Gtk::manage(
		new Gtk::Image);
	image->set_from_icon_name(icon_name, Gtk::ICON_SIZE_MENU);
	image->show();

	Gtk::Label* label_title = Gtk::manage(
		new Gtk::Label(title, Gtk::ALIGN_START));
	label_title->show();

	m_grid.set_border_width(6);
	m_grid.set_column_spacing(6);
	m_grid.set_row_spacing(6);
	m_grid.attach(*image, 0, 0, 1, 1);
	m_grid.attach(*label_title, 1, 0, 1, 1);
	m_grid.attach(*button, 2, 0, 1, 1);
	m_grid.show();

	add(m_grid);

	on_option();
}
Пример #4
0
int init_jobs(lflag)
{
	int ldisc;
	register int ntry = 0;
	register int pid;
	jobstat.mypid = pid = getpid();
	savepgrp = getpgrp(pid);
# ifdef version8
	if((ldisc = ioctl (2, FIOLOOKLD, 0)) <0)
# else
	if(ioctl(2,TIOCGETD,&ldisc) !=0)
# endif /* version8 */
		return(-1);
	if(ldisc!=NTTYDISC && ldisc!=OTTYDISC)
	{
		/* no job control when running with MPX */
# ifdef VSH
		on_option(VIRAW);
# endif /* VSH */
		return(-1);
	}
retry:
	signal(SIGTTOU,SIG_IGN);
	if(ioctl(2,TIOCGPGRP,&savetgrp) !=0)
	{
		fputs(j_not_tty,output);
		return(-1);
	}
	/* This shell must be in foreground to change state */
	if(savetgrp != savepgrp)
	{
		signal(SIGTTOU,SIG_DFL);
		kill(pid,SIGTTOU);
		/* wait for continue and try again */
		if(ntry++ > 100)
		{
			fputs(j_no_start,output);
			return(-1);
		}
		goto retry;
	}
	if(ldisc == OTTYDISC)
	{
		ldisc = NTTYDISC;
# ifdef version8
		ioctl(2,TIOCGETP,&my_stty);
		if (ioctl(2, FIOPOPLD, 0) < 0)
			return(-1);
		if (ioctl(2, FIOPUSHLD, &ldisc, 0) < 0)
		{
			ldisc = OTTYDISC;
			 ioctl(2, FIOPUSHLD, &ldisc, 0);
			return(-1);
		}
		ioctl(2,TIOCSETN,&my_stty);
# else
		if(ioctl(2,TIOCSETD,&ldisc) !=0)
			return(-1);
# endif /* version8 */
		if(lflag==0)
		{
			fputs(j_newtty,output);
			old_driver++;
		}
	}
	on_option(MONITOR);
	signal(SIGCHLD,fault);
	signal(SIGTSTP,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	setpgrp(pid,pid);
	set_ttygrp(pid);
	return(0);
}
Пример #5
0
Файл: args.c Проект: att/ast
// This routine turns options on and off.
// The options "PDicr" are illegal from set command.
// The -o option is used to set option by name.
// This routine returns the number of non-option arguments.
int sh_argopts(int argc, char *argv[], void *context) {
    Shell_t *shp = context;
    int n, o;
    Arg_t *ap = shp->arg_context;
    Lex_t *lp = shp->lex_context;
    Shopt_t newflags;
    int setflag = 0, action = 0, trace = (int)sh_isoption(shp, SH_XTRACE);
    Namval_t *np = NULL;
    const char *sp;
    char *keylist = NULL;
    int verbose, f, unsetnp = 0;
    Optdisc_t disc;

    newflags = shp->options;
    memset(&disc, 0, sizeof(disc));
    disc.version = OPT_VERSION;
    disc.infof = infof;
    opt_info.disc = &disc;

    if (argc > 0) {
        setflag = 4;
    } else {
        argc = -argc;
    }

    while ((n = optget(argv, setflag ? sh_optset : sh_optksh))) {
        o = 0;
        f = *opt_info.option == '-' && (opt_info.num || opt_info.arg);
        switch (n) {
            case 'A': {
                np = nv_open(opt_info.arg, shp->var_tree, NV_ARRAY | NV_VARNAME);
                if (f) unsetnp = 1;
                continue;
            }
            case 'K': {
                keylist = opt_info.arg;
                continue;
            }
#if SHOPT_BASH
            case 'O': {  // shopt options, only in bash mode
                if (!sh_isoption(shp, SH_BASH)) {
                    errormsg(SH_DICT, ERROR_exit(1), e_option, opt_info.name);
                    __builtin_unreachable();
                }
            }
#endif
            // FALLTHRU
            case 'o': {  // set options
            byname:
                if (!opt_info.arg || !*opt_info.arg || *opt_info.arg == '-') {
                    action = PRINT;
                    // print style: -O => shopt options.
                    // bash => print unset options also, no heading.
                    verbose = (f ? PRINT_VERBOSE : PRINT_NO_HEADER) | (n == 'O' ? PRINT_SHOPT : 0) |
                              (sh_isoption(shp, SH_BASH) ? PRINT_ALL | PRINT_NO_HEADER : 0) |
                              ((opt_info.arg && (!*opt_info.arg || *opt_info.arg == '-'))
                                   ? (PRINT_TABLE | PRINT_NO_HEADER)
                                   : 0);
                    continue;
                }
                o = sh_lookopt(opt_info.arg, &f);
                if (o <= 0 || (!sh_isoption(shp, SH_BASH) && (o & SH_BASHEXTRA)) ||
                    ((!sh_isoption(shp, SH_BASH) || n == 'o') && (o & SH_BASHOPT))

                    || (setflag && (o & SH_COMMANDLINE))) {
                    errormsg(SH_DICT, 2, e_option, opt_info.arg);
                    error_info.errors++;
                }
                o &= 0xff;
                if (sh_isoption(shp, SH_RESTRICTED) && !f && o == SH_RESTRICTED) {
                    errormsg(SH_DICT, ERROR_exit(1), e_restricted, opt_info.arg);
                    __builtin_unreachable();
                }
                break;
            }
#if SHOPT_BASH
            case -1: {  // --rcfile
                shp->gd->rcfile = opt_info.arg;
                continue;
            }
            case -2: {  // --noediting
                if (!f) {
                    off_option(&newflags, SH_VI);
                    off_option(&newflags, SH_EMACS);
                    off_option(&newflags, SH_GMACS);
                }
                continue;
            }
            case -3: {  // --profile
                n = 'l';
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
            case -4: {  // --posix
                // Mask lower 8 bits to find char in optksh string.
                n &= 0xff;
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
            case -5: {  // --version
                sfputr(sfstdout, "ksh bash emulation, version ", -1);
                np = nv_open("BASH_VERSION", shp->var_tree, 0);
                sfputr(sfstdout, nv_getval(np), -1);
                np = nv_open("MACHTYPE", shp->var_tree, 0);
                sfprintf(sfstdout, " (%s)\n", nv_getval(np));
                sh_exit(shp, 0);
            }
#endif
            case -6: {  // --default
                const Shtable_t *tp;
                for (tp = shtab_options; (o = tp->sh_number); tp++) {
                    if (!(o & SH_COMMANDLINE) && is_option(&newflags, o & 0xff)) {
                        off_option(&newflags, o & 0xff);
                    }
                }
                continue;
            }
            case -7: {
                f = 0;
                goto byname;
            }
            case 'D': {
                on_option(&newflags, SH_NOEXEC);
                // Cppcheck doesn't recognize the "goto" in the preceding case and thus thinks we
                // might fall through and call strchr() with n == -7.  Even though this it
                // technically a bug in cppcheck it is one reason why `goto` shouldn't be used; at
                // least inside `switch` blocks.
                // cppcheck-suppress invalidFunctionArg
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
            case 'T': {
                if (opt_info.num) {
                    shp->test |= opt_info.num;
                } else {
                    shp->test = 0;
                }
                continue;
            }
            case 's': {
                if (setflag) {
                    action = SORT;
                    continue;
                }
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
            case 'R': {
                if (setflag) {
                    n = ':';
                } else {
                    ap->kiafile = opt_info.arg;
                    n = 'n';
                }
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
            case ':': {
                if (opt_info.name[0] == '-' && opt_info.name[1] == '-') {
                    opt_info.arg = argv[opt_info.index - 1] + 2;
                    f = 1;
                    goto byname;
                }
                errormsg(SH_DICT, 2, "%s", opt_info.arg);
                continue;
            }
            case '?': {
                errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg);
                return -1;
            }
            default: {
                sp = strchr(optksh, n);
                if (sp) o = flagval[sp - optksh];
                break;
            }
        }
        if (f) {
            if (o == SH_VI || o == SH_EMACS || o == SH_GMACS) {
                off_option(&newflags, SH_VI);
                off_option(&newflags, SH_EMACS);
                off_option(&newflags, SH_GMACS);
            }
            on_option(&newflags, o);
            off_option(&shp->offoptions, o);
        } else {
            if (o == SH_RESTRICTED && sh_isoption(shp, SH_RESTRICTED)) {
                errormsg(SH_DICT, ERROR_exit(1), e_restricted, "r");
                __builtin_unreachable();
            }
            if (o == SH_XTRACE) trace = 0;
            off_option(&newflags, o);
            if (setflag == 0) on_option(&shp->offoptions, o);
        }
    }
    if (error_info.errors) {
        errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL));
        __builtin_unreachable();
    }
    // Check for '-' or '+' argument.
    sp = argv[opt_info.index];
    if (sp && sp[1] == 0 && (*sp == '+' || *sp == '-') && strcmp(argv[opt_info.index - 1], "--")) {
        opt_info.index++;
        off_option(&newflags, SH_XTRACE);
        off_option(&newflags, SH_VERBOSE);
        trace = 0;
    }
    if (trace) sh_trace(shp, argv, 1);
    argc -= opt_info.index;
    argv += opt_info.index;
    if (action == PRINT) sh_printopts(shp, newflags, verbose, 0);
    if (setflag) {
        if (action == SORT) {
            int (*sortfn)(const char *, const char *) = strcoll;
            Namarr_t *arp;
            struct Value *args;
            unsigned char *bits;
            if (argc > 0) {
                strsort(argv, argc, sortfn);
            } else if (np && (arp = nv_arrayptr(np)) && (args = nv_aivec(np, &bits))) {
                char *cp;
                int i, c, keys = 0;

                if (keylist) {
                    for (cp = keylist; (c = *cp); cp++) {
                        if (c == ',') keys++;
                    }
                    keys++;
                } else {
                    keylist = "";
                }
                arp->nelem = nv_aipack(arp);
                cp = nv_name(np);
                c = strlen(cp);
                // This used to multiply by `(keys - 1)` but `keys` can be zero which means the
                // nodesize can be less than `sizeof(struct Node)` which is obviously wrong.
                // Whether multiplying by `keys` is correct is unclear.
                // See issue #824.
                size_t nodesize = sizeof(struct Node) + keys * sizeof(Namval_t *);
                struct Sort *sp =
                    malloc(sizeof(struct Sort) + strlen(keylist) + (sizeof(char *) + 1) * keys +
                           (arp->nelem + 1) * (nodesize + sizeof(void *)) + c + 3);
                sp->shp = shp;
                sp->np = np;
                if (!(sp->root = shp->last_root)) sp->root = shp->var_tree;
                sp->vp = args;
                sp->cur = 0;
                sp->nodes = (struct Node *)&sp->keys[keys + 2];
                memset(sp->nodes, 0, arp->nelem * nodesize);
                sp->nptrs = (struct Node **)((char *)sp->nodes + arp->nelem * nodesize);
                sp->flags = (char *)&sp->nptrs[arp->nelem + 1];
                memset(sp->flags, 0, keys + 1);
                sp->name = sp->flags + keys + 1;
                memcpy(sp->name, cp, c + 1);
                sp->keys[0] = sp->name + c + 1;
                strcpy(sp->keys[0], keylist);
                cp = (char *)sp->nodes;
                for (c = 0; c < arp->nelem; c++) {
                    if (*keylist && *keylist != ':') {
                        struct Namval *np = FETCH_VT(args[c], np);
                        ((struct Node *)cp)->index = strtol(np->nvname, NULL, 10);
                        ((struct Node *)cp)->bits = bits[c];
                    } else {
                        ((struct Node *)cp)->index = c;
                    }
                    ((struct Node *)cp)->vp = args[c];
                    sp->nptrs[c] = (struct Node *)cp;
                    cp += nodesize;
                }
                if (!(cp = sp->keys[0])) cp = keylist;
                for (keys = 0; (c = *cp); cp++) {
                    if (c == ',') {
                        *cp++ = 0;
                        sp->keys[++keys] = cp;
                        sp->flags[keys] = 0;
                    } else if (c == ':') {
                    again:
                        *cp++ = 0;
                        c = *cp;
                        if (c == 'r') {
                            sp->flags[keys] |= SORT_reverse;
                            c = cp[1];
                        } else if (c == 'n') {
                            sp->flags[keys] |= SORT_numeric;
                            c = cp[1];
                        }
                        if (c == 'n' || c == 'r') goto again;
                    }
                }
                sp->keys[++keys] = 0;
                Sp = sp;
                if (sp->keys[0] && *sp->keys[0]) {
                    sortfn = arraysort;
                } else if (sp->flags[0] & SORT_numeric) {
                    sortfn = numsort;
                } else {
                    sortfn = alphasort;
                }
                strsort((char **)sp->nptrs, arp->nelem, sortfn);
                cp = (char *)sp->nodes;
                for (c = 0; c < arp->nelem; c++) {
                    i = (char *)sp->nptrs[c] - (char *)&sp->nodes[0];
                    if (i / nodesize != c) {
                        args[c] = ((struct Node *)(cp + i))->vp;
                        bits[c] = ((struct Node *)(cp + i))->bits;
                    }
                }
                free(sp);
                nv_close(np);
                np = NULL;
            } else {
                strsort(shp->st.dolv + 1, shp->st.dolc, sortfn);
            }
        }
        if (np) {
            if (unsetnp) nv_unset(np);
            nv_setvec(np, 0, argc, argv);
            nv_close(np);
        } else if (argc > 0 || ((sp = argv[-1]) && strcmp(sp, "--") == 0)) {
            sh_argset(ap, argv - 1);
        }
    } else if (is_option(&newflags, SH_CFLAG)) {
        if (!(shp->comdiv = *argv++)) {
            errormsg(SH_DICT, 2, e_cneedsarg);
            errormsg(SH_DICT, ERROR_usage(2), optusage(NULL));
            __builtin_unreachable();
        }
        argc--;
    }
    // Handling SH_INTERACTIVE and SH_PRIVILEGED has been moved to
    // sh_applyopts(), so that the code can be reused from b_shopt(), too.
    sh_applyopts(shp, newflags);
    if (!ap->kiafile) return argc;

    if (!argv[0]) {
        errormsg(SH_DICT, ERROR_usage(2), "-R requires scriptname");
        __builtin_unreachable();
    }
    if (!(lp->kiafile = sfopen(NULL, ap->kiafile, "w+"))) {
        errormsg(SH_DICT, ERROR_system(3), e_create, ap->kiafile);
        __builtin_unreachable();
    }
    if (!(lp->kiatmp = sftmp(2 * SF_BUFSIZE))) {
        errormsg(SH_DICT, ERROR_system(3), e_tmpcreate);
        __builtin_unreachable();
    }
    sfputr(lp->kiafile, ";vdb;CIAO/ksh", '\n');
    lp->kiabegin = sftell(lp->kiafile);
    lp->entity_tree = dtopen(&_Nvdisc, Dtbag);
    lp->scriptname = strdup(sh_fmtq(argv[0]));
    lp->script = kiaentity(lp, lp->scriptname, -1, 'p', -1, 0, 0, 's', 0, "");
    lp->fscript = kiaentity(lp, lp->scriptname, -1, 'f', -1, 0, 0, 's', 0, "");
    lp->unknown = kiaentity(lp, "<unknown>", -1, 'p', -1, 0, 0, '0', 0, "");
    kiaentity(lp, "<unknown>", -1, 'p', 0, 0, lp->unknown, '0', 0, "");
    lp->current = lp->script;
    ap->kiafile = NULL;

    return argc;
}
Пример #6
0
/*
 *  This routine turns options on and off
 *  The options "PDicr" are illegal from set command.
 *  The -o option is used to set option by name
 *  This routine returns the number of non-option arguments
 */
int sh_argopts(int argc,register char *argv[], void *context)
{
	Shell_t		*shp = (Shell_t*)context;
	register int	n,o;
	register Arg_t	*ap = (Arg_t*)(shp->arg_context);
	Lex_t		*lp = (Lex_t*)(shp->lex_context);
	Shopt_t		newflags;
	int setflag=0, action=0, trace=(int)sh_isoption(SH_XTRACE);
	Namval_t *np = NIL(Namval_t*);
	const char *cp;
	int verbose,f;
	Optdisc_t disc;
	newflags=ap->sh->options;
	memset(&disc, 0, sizeof(disc));
	disc.version = OPT_VERSION;
	disc.infof = infof;
	opt_info.disc = &disc;

	if(argc>0)
		setflag = 4;
	else
		argc = -argc;
	while((n = optget(argv,setflag?sh_optset:sh_optksh)))
	{
		o=0;
		f=*opt_info.option=='-' && (opt_info.num || opt_info.arg);
		switch(n)
		{
	 	    case 'A':
			np = nv_open(opt_info.arg,ap->sh->var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME);
			if(f)
				nv_unset(np);
			continue;
#if SHOPT_BASH
		    case 'O':	/* shopt options, only in bash mode */
			if(!sh_isoption(SH_BASH))
				errormsg(SH_DICT,ERROR_exit(1), e_option, opt_info.name);
#endif
		    case 'o':	/* set options */
		    byname:
			if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
			{
				action = PRINT;
				/* print style: -O => shopt options
				 * bash => print unset options also, no heading
				 */
				verbose = (f?PRINT_VERBOSE:PRINT_NO_HEADER)|
					  (n=='O'?PRINT_SHOPT:0)|
					  (sh_isoption(SH_BASH)?PRINT_ALL|PRINT_NO_HEADER:0)|
					  ((opt_info.arg&&(!*opt_info.arg||*opt_info.arg=='-'))?(PRINT_TABLE|PRINT_NO_HEADER):0);
				continue;
			}
			o = sh_lookopt(opt_info.arg,&f);
			if(o<=0
				|| (!sh_isoption(SH_BASH) && (o&SH_BASHEXTRA))
				|| ((!sh_isoption(SH_BASH) || n=='o') && (o&SH_BASHOPT))

				|| (setflag && (o&SH_COMMANDLINE)))
			{
				errormsg(SH_DICT,2, e_option, opt_info.arg);
				error_info.errors++;
			}
			o &= 0xff;
			if(sh_isoption(SH_RESTRICTED) && !f && o==SH_RESTRICTED)
				errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
			break;
#if SHOPT_BASH
		    case -1:	/* --rcfile */
			ap->sh->gd->rcfile = opt_info.arg;
			continue;
		    case -2:	/* --noediting */
			if (!f)
			{
				off_option(&newflags,SH_VI);
				off_option(&newflags,SH_EMACS);
				off_option(&newflags,SH_GMACS);
			}
			continue;
		    case -3:	/* --profile */
			n = 'l';
			goto skip;
		    case -4:	/* --posix */
			/* mask lower 8 bits to find char in optksh string */
			n&=0xff;
			goto skip;
		    case -5:	/* --version */
			sfputr(sfstdout, "ksh bash emulation, version ",-1);
			np = nv_open("BASH_VERSION",ap->sh->var_tree,0);
			sfputr(sfstdout, nv_getval(np),-1);
			np = nv_open("MACHTYPE",ap->sh->var_tree,0);
			sfprintf(sfstdout, " (%s)\n", nv_getval(np));
			sh_exit(0);
#endif
		    case -6:	/* --default */
			{
				register const Shtable_t *tp;
				for(tp=shtab_options; o = tp->sh_number; tp++)
					if(!(o&SH_COMMANDLINE) && is_option(&newflags,o&0xff))
						off_option(&newflags,o&0xff);
			}
		    	continue;
	 	    case -7:
			f = 0;
		    	goto byname;
	 	    case 'D':
			on_option(&newflags,SH_NOEXEC);
			goto skip;
		    case 'T':
			if (opt_info.num)
				ap->sh->test |= opt_info.num;
			else
				ap->sh->test = 0;
		    	continue;
		    case 's':
			if(setflag)
			{
				action = SORT;
				continue;
			}
#if SHOPT_KIA
			goto skip;
		    case 'R':
			if(setflag)
				n = ':';
			else
			{
				ap->kiafile = opt_info.arg;
				n = 'n';
			}
			/*FALLTHROUGH*/
#endif /* SHOPT_KIA */
#if SHOPT_REGRESS
			goto skip;
		    case 'I':
			continue;
#endif /* SHOPT_REGRESS */
		    skip:
		    default:
			if(cp=strchr(optksh,n))
				o = flagval[cp-optksh];
			break;
		    case ':':
			if(opt_info.name[0]=='-'&&opt_info.name[1]=='-')
			{
				opt_info.arg = argv[opt_info.index-1] + 2;
				f = 1;
				goto byname;
			}
			errormsg(SH_DICT,2, "%s", opt_info.arg);
			continue;
		    case '?':
			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
			return(-1);
		}
		if(f)
		{
			if(o==SH_VI || o==SH_EMACS || o==SH_GMACS)
			{
				off_option(&newflags,SH_VI);
				off_option(&newflags,SH_EMACS);
				off_option(&newflags,SH_GMACS);
			}
			on_option(&newflags,o);
			off_option(&ap->sh->offoptions,o);
		}
		else
		{
			if(o==SH_XTRACE)
				trace = 0;
			off_option(&newflags,o);
			if(setflag==0)
				on_option(&ap->sh->offoptions,o);
		}
	}
	if(error_info.errors)
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
	/* check for '-' or '+' argument */
	if((cp=argv[opt_info.index]) && cp[1]==0 && (*cp=='+' || *cp=='-') &&
		strcmp(argv[opt_info.index-1],"--"))
	{
		opt_info.index++;
		off_option(&newflags,SH_XTRACE);
		off_option(&newflags,SH_VERBOSE);
		trace = 0;
	}
	if(trace)
		sh_trace(shp,argv,1);
	argc -= opt_info.index;
	argv += opt_info.index;
	if(action==PRINT)
		sh_printopts(newflags,verbose,0);
	if(setflag)
	{
		if(action==SORT)
		{
			if(argc>0)
				strsort(argv,argc,strcoll);
			else
				strsort(ap->sh->st.dolv+1,ap->sh->st.dolc,strcoll);
		}
		if(np)
		{
			nv_setvec(np,0,argc,argv);
			nv_close(np);
		}
		else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0))
			sh_argset(ap,argv-1);
	}
	else if(is_option(&newflags,SH_CFLAG))
	{
		if(!(ap->sh->comdiv = *argv++))
		{
			errormsg(SH_DICT,2,e_cneedsarg);
			errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
		}
		argc--;
	}
Пример #7
0
int     b_shopt(int argc,register char *argv[],void *extra)
{
        Shell_t *shp = (Shell_t*)extra;
	int n, f, ret=0;
	Shopt_t newflags=shp->options, opt;
	int verbose=PRINT_SHOPT|PRINT_ALL|PRINT_NO_HEADER|PRINT_VERBOSE;
	int setflag=0, quietflag=0, oflag=0;
	memset(&opt,0,sizeof(opt));
#if SHOPT_RAWONLY
	on_option(&newflags,SH_VIRAW);
#endif
	while((n = optget(argv,sh_optshopt)))
	{
		switch(n)
		{
		case 'p':
			verbose&=~PRINT_VERBOSE;
			break;
		case 's':
		case 'u':
			setflag|=n=='s'?SET_SET:SET_UNSET;
			if(setflag==(SET_SET|SET_UNSET))
			{
				errormsg(SH_DICT,ERROR_ERROR,"cannot set and unset options simultaneously");
				error_info.errors++;
			}
			break;
		case 'q':
			quietflag=1;
			break;
		case 'o':
			oflag=1;
			verbose&=~PRINT_SHOPT;
			break;
		case ':':
			errormsg(SH_DICT,2, "%s", opt_info.arg);
			continue;
		case '?':
			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
			return(-1);
		}
	}
	if(error_info.errors)
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
	argc -= opt_info.index;
	if(argc==0)
	{
		/* no args, -s => mask=current options, -u mask=~(current options)
		   else mask=all bits */
		if(setflag&SET_SET)
			opt=newflags;
		else if(setflag&SET_UNSET)
			for(n=0;n<4;n++)
				opt.v[n]=~newflags.v[n];
		else
			memset(&opt,0xff,sizeof(opt));
		setflag=SET_NOARGS;
	}
	while(argc>0)
	{
		f=1;
		n=sh_lookopt(argv[opt_info.index],&f);
		if(n<=0||(setflag 
			&& (is_option(&opt,SH_INTERACTIVE)
			    || is_option(&opt,SH_RESTRICTED)
			    || is_option(&opt,SH_RESTRICTED2)
			    || is_option(&opt,SH_BASH)
			    || is_option(&opt,SH_LOGIN_SHELL)))
			||(oflag&&(n&SH_BASHOPT)))
		{
			errormsg(SH_DICT,ERROR_ERROR, e_option, argv[opt_info.index]);
			error_info.errors++;
			ret=1;
		}
		else if(f)
			on_option(&opt,n&0xff);
		else
			off_option(&opt,n&0xff);
		opt_info.index++;
		argc--;
	}
	if(setflag&(SET_SET|SET_UNSET))
	{
		if(setflag&SET_SET)
		{
			if(sh_isoption(SH_INTERACTIVE))
				off_option(&opt,SH_NOEXEC);
			if(is_option(&opt,SH_VI)||is_option(&opt,SH_EMACS)||is_option(&opt,SH_GMACS))
			{
				off_option(&newflags,SH_VI);
				off_option(&newflags,SH_EMACS);
				off_option(&newflags,SH_GMACS);
			}
			for(n=0;n<4;n++)
				newflags.v[n] |= opt.v[n];
		}
		else if(setflag&SET_UNSET)
			for(n=0;n<4;n++)
				newflags.v[n] &= ~opt.v[n];
		sh_applyopts(shp,newflags);
		shp->options = newflags;
		if(is_option(&newflags,SH_XTRACE))
			sh_trace(argv,1);
	}
	else if(!(setflag&SET_NOARGS)) /* no -s,-u but args, ret=0 if opt&mask==mask */
	{
		for(n=0;n<4;n++)
			ret+=((newflags.v[n]&opt.v[n])!=opt.v[n]);
	}
	if(!quietflag&&!(setflag&(SET_SET|SET_UNSET)))
		sh_printopts(newflags,verbose,&opt);
	return(ret);
}
Пример #8
0
/*
 *  This routine turns options on and off
 *  The options "PDicr" are illegal from set command.
 *  The -o option is used to set option by name
 *  This routine returns the number of non-option arguments
 */
int sh_argopts(int argc,register char *argv[], void *context)
{
	Shell_t		*shp = (Shell_t*)context;
	register int	n,o;
	register Arg_t	*ap = (Arg_t*)(shp->arg_context);
	Lex_t		*lp = (Lex_t*)(shp->lex_context);
	Shopt_t		newflags;
	int setflag=0, action=0, trace=(int)sh_isoption(shp,SH_XTRACE);
	Namval_t *np = NIL(Namval_t*);
	const char *sp;
	char *keylist=0;
	int verbose,f,unsetnp=0;
	Optdisc_t disc;
	newflags=shp->options;
	memset(&disc, 0, sizeof(disc));
	disc.version = OPT_VERSION;
	disc.infof = infof;
	opt_info.disc = &disc;

	if(argc>0)
		setflag = 4;
	else
		argc = -argc;
	while((n = optget(argv,setflag?sh_optset:sh_optksh)))
	{
		o=0;
		f=*opt_info.option=='-' && (opt_info.num || opt_info.arg);
		switch(n)
		{
	 	    case 'A':
			np = nv_open(opt_info.arg,shp->var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME);
			if(f)
				unsetnp=1;
			continue;
	 	    case 'K':
			keylist = opt_info.arg;
			continue;
#if SHOPT_BASH
		    case 'O':	/* shopt options, only in bash mode */
			if(!sh_isoption(shp,SH_BASH))
				errormsg(SH_DICT,ERROR_exit(1), e_option, opt_info.name);
#endif
		    case 'o':	/* set options */
		    byname:
			if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
			{
				action = PRINT;
				/* print style: -O => shopt options
				 * bash => print unset options also, no heading
				 */
				verbose = (f?PRINT_VERBOSE:PRINT_NO_HEADER)|
					  (n=='O'?PRINT_SHOPT:0)|
					  (sh_isoption(shp,SH_BASH)?PRINT_ALL|PRINT_NO_HEADER:0)|
					  ((opt_info.arg&&(!*opt_info.arg||*opt_info.arg=='-'))?(PRINT_TABLE|PRINT_NO_HEADER):0);
				continue;
			}
			o = sh_lookopt(opt_info.arg,&f);
			if(o<=0
				|| (!sh_isoption(shp,SH_BASH) && (o&SH_BASHEXTRA))
				|| ((!sh_isoption(shp,SH_BASH) || n=='o') && (o&SH_BASHOPT))

				|| (setflag && (o&SH_COMMANDLINE)))
			{
				errormsg(SH_DICT,2, e_option, opt_info.arg);
				error_info.errors++;
			}
			o &= 0xff;
			if(sh_isoption(shp,SH_RESTRICTED) && !f && o==SH_RESTRICTED)
				errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
			break;
#if SHOPT_BASH
		    case -1:	/* --rcfile */
			shp->gd->rcfile = opt_info.arg;
			continue;
		    case -2:	/* --noediting */
			if (!f)
			{
				off_option(&newflags,SH_VI);
				off_option(&newflags,SH_EMACS);
				off_option(&newflags,SH_GMACS);
			}
			continue;
		    case -3:	/* --profile */
			n = 'l';
			goto skip;
		    case -4:	/* --posix */
			/* mask lower 8 bits to find char in optksh string */
			n&=0xff;
			goto skip;
		    case -5:	/* --version */
			sfputr(sfstdout, "ksh bash emulation, version ",-1);
			np = nv_open("BASH_VERSION",shp->var_tree,0);
			sfputr(sfstdout, nv_getval(np),-1);
			np = nv_open("MACHTYPE",shp->var_tree,0);
			sfprintf(sfstdout, " (%s)\n", nv_getval(np));
			sh_exit(shp,0);
#endif
		    case -6:	/* --default */
			{
				register const Shtable_t *tp;
				for(tp=shtab_options; o = tp->sh_number; tp++)
					if(!(o&SH_COMMANDLINE) && is_option(&newflags,o&0xff))
						off_option(&newflags,o&0xff);
			}
		    	continue;
	 	    case -7:
			f = 0;
		    	goto byname;
	 	    case 'D':
			on_option(&newflags,SH_NOEXEC);
			goto skip;
		    case 'T':
			if (opt_info.num)
				shp->test |= opt_info.num;
			else
				shp->test = 0;
		    	continue;
		    case 's':
			if(setflag)
			{
				action = SORT;
				continue;
			}
#if SHOPT_KIA
			goto skip;
		    case 'R':
			if(setflag)
				n = ':';
			else
			{
				ap->kiafile = opt_info.arg;
				n = 'n';
			}
			/*FALLTHROUGH*/
#endif /* SHOPT_KIA */
#if SHOPT_REGRESS
			goto skip;
		    case 'I':
			continue;
#endif /* SHOPT_REGRESS */
		    skip:
		    default:
			if(sp=strchr(optksh,n))
				o = flagval[sp-optksh];
			break;
		    case ':':
			if(opt_info.name[0]=='-'&&opt_info.name[1]=='-')
			{
				opt_info.arg = argv[opt_info.index-1] + 2;
				f = 1;
				goto byname;
			}
			errormsg(SH_DICT,2, "%s", opt_info.arg);
			continue;
		    case '?':
			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
			return(-1);
		}
		if(f)
		{
			if(o==SH_VI || o==SH_EMACS || o==SH_GMACS)
			{
				off_option(&newflags,SH_VI);
				off_option(&newflags,SH_EMACS);
				off_option(&newflags,SH_GMACS);
			}
			on_option(&newflags,o);
			off_option(&shp->offoptions,o);
		}
		else
		{
			if(o==SH_XTRACE)
				trace = 0;
			off_option(&newflags,o);
			if(setflag==0)
				on_option(&shp->offoptions,o);
		}
	}
	if(error_info.errors)
		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
	/* check for '-' or '+' argument */
	if((sp=argv[opt_info.index]) && sp[1]==0 && (*sp=='+' || *sp=='-') &&
		strcmp(argv[opt_info.index-1],"--"))
	{
		opt_info.index++;
		off_option(&newflags,SH_XTRACE);
		off_option(&newflags,SH_VERBOSE);
		trace = 0;
	}
	if(trace)
		sh_trace(shp,argv,1);
	argc -= opt_info.index;
	argv += opt_info.index;
	if(action==PRINT)
		sh_printopts(shp,newflags,verbose,0);
	if(setflag)
	{
		if(action==SORT)
		{
			int	(*sortfn)(const char*,const char*) = strcoll;
			Namarr_t	*arp;
			union Value	*args;
			unsigned char	*bits;
			if(argc>0)
				strsort(argv,argc,sortfn);
			else if(np && (arp=nv_arrayptr(np)) && (args = nv_aivec(np,&bits)))
			{
				struct Sort	*sp;
				char		*cp;
				int		i, c, keys=0;
				size_t		nodesize;
				if(keylist)
				{
					for(cp=keylist;c= *cp; cp++)
					{
						if(c==',')
							keys++;
					}
					keys++;
				}
				else
					keylist = Empty;
				arp->nelem = nv_aipack(arp);;
				cp = nv_name(np);
				c = strlen(cp);
				nodesize = sizeof(struct Node)+(keys-1)*sizeof(Namval_t*);
				sp = (struct Sort*)malloc(sizeof(struct Sort)+strlen(keylist)+(sizeof(char*)+1)*keys+(arp->nelem+1)*(nodesize+sizeof(void*))+c+3);
				sp->shp = shp;
				sp->np = np;
				if(!(sp->root = shp->last_root))
					sp->root = shp->var_tree;
				sp->vp = args;
				sp->cur = 0;
				sp->nodes = (struct Node*)&sp->keys[keys+2];
				memset(sp->nodes, 0, arp->nelem*nodesize);
				sp->nptrs = (struct Node**)((char*)sp->nodes+arp->nelem*nodesize);
				sp->flags = (char*)&sp->nptrs[arp->nelem+1];
				memset(sp->flags,0,keys+1);
				sp->name = sp->flags + keys+1;
				memcpy(sp->name,cp,c+1);
				sp->keys[0] = sp->name+c+1;
				strcpy(sp->keys[0],keylist);
				cp = (char*)sp->nodes;
				for(c=0; c < arp->nelem; c++)
				{
					if(keylist!=Empty && *keylist!=':')
					{
						((struct Node*)cp)->index = strtol(args[c].np->nvname,NULL,10);
						((struct Node*)cp)->bits = bits[c];
					}
					else
						((struct Node*)cp)->index = c;
					((struct Node*)cp)->vp = args[c];
					sp->nptrs[c] = (struct Node*)cp;
					cp += nodesize;
				}
				if(!(cp = sp->keys[0]))
					cp = keylist;
				for(keys=0;c= *cp; cp++)
				{
					if(c==',')
					{
						*cp++ = 0;
						sp->keys[++keys] = cp;
						sp->flags[keys] = 0;
					}
					else if(c==':')
					{
					again:
						*cp++ = 0;
						if((c= *cp) == 'r')
						{
							sp->flags[keys] |= SORT_reverse; 
							c = cp[1];
						}
						else if(c=='n')
						{
							sp->flags[keys] |= SORT_numeric; 
							c = cp[1];
						}
						if(c=='n' || c=='r')
							goto again;
						 
					}
				}
				sp->keys[++keys] = 0;
				Sp = sp;
				if(sp->keys[0] && *sp->keys[0])
					sortfn = arraysort;
				else if(sp->flags[0]&SORT_numeric)
					sortfn = numsort;
				else
					sortfn = alphasort;
				strsort((char**)sp->nptrs,arp->nelem,sortfn);
				cp = (char*)sp->nodes;
				for(c=0; c < arp->nelem; c++)
				{
					i = (char*)sp->nptrs[c]-(char*)&sp->nodes[0];
					if(i/nodesize !=c)
					{
						args[c] = ((struct Node*)(cp+i))->vp;
						bits[c] = ((struct Node*)(cp+i))->bits;
					}
				}
				free(sp);
				nv_close(np);
				np = 0;
			}
			else
				strsort(shp->st.dolv+1,shp->st.dolc,sortfn);
		}
		if(np)
		{
			if(unsetnp)
				nv_unset(np);
			nv_setvec(np,0,argc,argv);
			nv_close(np);
		}
		else if(argc>0 || ((sp=argv[-1]) && strcmp(sp,"--")==0))
			sh_argset(ap,argv-1);
	}
	else if(is_option(&newflags,SH_CFLAG))
	{
		if(!(shp->comdiv = *argv++))
		{
			errormsg(SH_DICT,2,e_cneedsarg);
			errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
		}
		argc--;
	}