mod_export int dosetopt(int optno, int value, int force) { if(!optno) return -1; if(optno < 0) { optno = -optno; value = !value; } if (optno == RESTRICTED) { if (isset(RESTRICTED)) return value ? 0 : -1; if (value) { char **s; for (s = rparams; *s; s++) restrictparam(*s); } } else if(!force && optno == EXECOPT && !value && interact) { /* cannot set noexec when interactive */ return -1; } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN || optno == SINGLECOMMAND)) { if (opts[optno] == value) return 0; /* it is not permitted to change the value of these options */ return -1; } else if(!force && optno == USEZLE && value) { /* we require a terminal in order to use ZLE */ if(!interact || SHTTY == -1 || !shout) return -1; } else if(optno == PRIVILEGED && !value) { /* unsetting PRIVILEGED causes the shell to make itself unprivileged */ #ifdef HAVE_SETUID setuid(getuid()); setgid(getgid()); #endif /* HAVE_SETUID */ #ifndef JOB_CONTROL } else if(optno == MONITOR && value) { return -1; #endif /* not JOB_CONTROL */ #ifdef GETPWNAM_FAKED } else if(optno == CDABLEVARS && value) { return -1; #endif /* GETPWNAM_FAKED */ } else if ((optno == EMACSMODE || optno == VIMODE) && value) { (*zlesetkeymapptr)(optno); opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; } opts[optno] = value; if (optno == BANGHIST || optno == SHINSTDIN) inittyptab(); return 0; }
mod_export int dosetopt(int optno, int value, int force, char *new_opts) { if(!optno) return -1; if(optno < 0) { optno = -optno; value = !value; } if (optno == RESTRICTED) { if (isset(RESTRICTED)) return value ? 0 : -1; if (value) { char **s; for (s = rparams; *s; s++) restrictparam(*s); } } else if(!force && optno == EXECOPT && !value && interact) { /* cannot set noexec when interactive */ return -1; } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN || optno == SINGLECOMMAND)) { if (new_opts[optno] == value) return 0; /* it is not permitted to change the value of these options */ return -1; } else if(!force && optno == USEZLE && value) { /* we require a terminal in order to use ZLE */ if(!interact || SHTTY == -1 || !shout) return -1; } else if(optno == PRIVILEGED && !value) { /* unsetting PRIVILEGED causes the shell to make itself unprivileged */ #ifdef HAVE_SETUID setuid(getuid()); setgid(getgid()); if (setuid(getuid())) { zwarn("failed to change user ID: %e", errno); return -1; } else if (setgid(getgid())) { zwarn("failed to change group ID: %e", errno); return -1; } #else zwarn("setuid not available"); return -1; #endif /* not HAVE_SETUID */ #ifdef JOB_CONTROL } else if (!force && optno == MONITOR && value) { if (new_opts[optno] == value) return 0; if (SHTTY != -1) { origpgrp = GETPGRP(); acquire_pgrp(); } else return -1; #else } else if(optno == MONITOR && value) { return -1; #endif /* not JOB_CONTROL */ #ifdef GETPWNAM_FAKED } else if(optno == CDABLEVARS && value) { return -1; #endif /* GETPWNAM_FAKED */ } else if ((optno == EMACSMODE || optno == VIMODE) && value) { if (sticky && sticky->emulation) return -1; zleentry(ZLE_CMD_SET_KEYMAP, optno); new_opts[(optno == EMACSMODE) ? VIMODE : EMACSMODE] = 0; } else if (optno == SUNKEYBOARDHACK) { /* for backward compatibility */ keyboardhackchar = (value ? '`' : '\0'); } new_opts[optno] = value; if (optno == BANGHIST || optno == SHINSTDIN) inittyptab(); return 0; }
int bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun) { int action, optno, match = 0; /* With no arguments or options, display options. */ if (!*args) { scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun); return 0; } /* loop through command line options (begins with "-" or "+") */ while (*args && (**args == '-' || **args == '+')) { action = (**args == '-') ^ isun; if(!args[0][1]) *args = "--"; while (*++*args) { if(**args == Meta) *++*args ^= 32; /* The pseudo-option `--' signifies the end of options. */ if (**args == '-') { args++; goto doneoptions; } else if (**args == 'o') { if (!*++*args) args++; if (!*args) { zwarnnam(nam, "string expected after -o"); inittyptab(); return 1; } if(!(optno = optlookup(*args))) zwarnnam(nam, "no such option: %s", *args); else if(dosetopt(optno, action, 0, opts)) zwarnnam(nam, "can't change option: %s", *args); break; } else if(**args == 'm') { match = 1; } else { if (!(optno = optlookupc(**args))) zwarnnam(nam, "bad option: -%c", **args); else if(dosetopt(optno, action, 0, opts)) zwarnnam(nam, "can't change option: -%c", **args); } } args++; } doneoptions: if (!match) { /* Not globbing the arguments -- arguments are simply option names. */ while (*args) { if(!(optno = optlookup(*args++))) zwarnnam(nam, "no such option: %s", args[-1]); else if(dosetopt(optno, !isun, 0, opts)) zwarnnam(nam, "can't change option: %s", args[-1]); } } else { /* Globbing option (-m) set. */ while (*args) { Patprog pprog; char *s, *t; t = s = dupstring(*args); while (*t) if (*t == '_') chuck(t); else { /* See comment in optlookup() */ if (*t >= 'A' && *t <= 'Z') *t = (*t - 'A') + 'a'; t++; } /* Expand the current arg. */ tokenize(s); if (!(pprog = patcompile(s, PAT_STATIC, NULL))) { zwarnnam(nam, "bad pattern: %s", *args); continue; } /* Loop over expansions. */ scanmatchtable(optiontab, pprog, 0, 0, OPT_ALIAS, setoption, !isun); args++; } } inittyptab(); return 0; }
int init_term(void) { #ifndef TGETENT_ACCEPTS_NULL static char termbuf[2048]; /* the termcap buffer */ #endif if (!*term) return termok = TERM_BAD; /* unset zle if using zsh under emacs */ if (!strcmp(term, "emacs")) opts[USEZLE] = 0; #ifdef TGETENT_ACCEPTS_NULL /* If possible, we let tgetent allocate its own termcap buffer */ if (tgetent(NULL, term) != 1) { #else if (tgetent(termbuf, term) != 1) { #endif if (isset(INTERACTIVE)) zerr("can't find termcap info for %s", term, 0); errflag = 0; return termok = TERM_BAD; } else { char tbuf[1024], *pp; int t0; termok = TERM_OK; for (t0 = 0; t0 != TC_COUNT; t0++) { pp = tbuf; zsfree(tcstr[t0]); /* AIX tgetstr() ignores second argument */ if (!(pp = tgetstr(tccapnams[t0], &pp))) tcstr[t0] = NULL, tclen[t0] = 0; else { tclen[t0] = strlen(pp); tcstr[t0] = (char *) zalloc(tclen[t0] + 1); memcpy(tcstr[t0], pp, tclen[t0] + 1); } } /* check whether terminal has automargin (wraparound) capability */ hasam = tgetflag("am"); /* if there's no termcap entry for cursor up, use single line mode: * * this is flagged by termok which is examined in zle_refresh.c * */ if (!tccan(TCUP)) { tcstr[TCUP] = NULL; termok = TERM_NOUP; } /* if there's no termcap entry for cursor left, use \b. */ if (!tccan(TCLEFT)) { tcstr[TCLEFT] = ztrdup("\b"); tclen[TCLEFT] = 1; } /* if the termcap entry for down is \n, don't use it. */ if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n') { tclen[TCDOWN] = 0; zsfree(tcstr[TCDOWN]); tcstr[TCDOWN] = NULL; } /* if there's no termcap entry for clear, use ^L. */ if (!tccan(TCCLEARSCREEN)) { tcstr[TCCLEARSCREEN] = ztrdup("\14"); tclen[TCCLEARSCREEN] = 1; } } return termok; } /* Initialize lots of global variables and hash tables */ /**/ void setupvals(void) { struct passwd *pswd; struct timezone dummy_tz; char *ptr; #ifdef HAVE_GETRLIMIT int i; #endif noeval = 0; curhist = 0; histsiz = DEFAULT_HISTSIZE; inithist(); clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *)); cmdstack = (unsigned char *) zalloc(256); cmdsp = 0; bangchar = '!'; hashchar = '#'; hatchar = '^'; termok = TERM_BAD; curjob = prevjob = coprocin = coprocout = -1; gettimeofday(&shtimer, &dummy_tz); /* init $SECONDS */ srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */ hostnam = (char *) zalloc(256); gethostname(hostnam, 256); /* Set default path */ path = (char **) zalloc(sizeof(*path) * 5); path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin"); path[2] = ztrdup("/usr/ucb"); path[3] = ztrdup("/usr/local/bin"); path[4] = NULL; cdpath = mkarray(NULL); manpath = mkarray(NULL); fignore = mkarray(NULL); fpath = mkarray(NULL); mailpath = mkarray(NULL); watch = mkarray(NULL); psvar = mkarray(NULL); #ifdef DYNAMIC module_path = mkarray(ztrdup(MODULE_DIR)); modules = newlinklist(); #endif /* Set default prompts */ if (opts[INTERACTIVE]) { prompt = ztrdup("%m%# "); prompt2 = ztrdup("%_> "); } else { prompt = ztrdup(""); prompt2 = ztrdup(""); } prompt3 = ztrdup("?# "); prompt4 = ztrdup("+ "); sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? "); ifs = ztrdup(DEFAULT_IFS); wordchars = ztrdup(DEFAULT_WORDCHARS); postedit = ztrdup(""); underscore = ztrdup(""); zoptarg = ztrdup(""); zoptind = 1; schedcmds = NULL; ppid = (long) getppid(); mypid = (long) getpid(); term = ztrdup(""); #ifdef TIOCGWINSZ if (!(columns = shttyinfo.winsize.ws_col)) columns = 80; if (columns < 2) opts[USEZLE] = 0; if (!(lines = shttyinfo.winsize.ws_row)) lines = 24; if (lines < 2) opts[SINGLELINEZLE] = 1; #else columns = 80; lines = 24; #endif /* The following variable assignments cause zsh to behave more * * like Bourne and Korn shells when invoked as "sh" or "ksh". * * NULLCMD=":" and READNULLCMD=":" */ if (emulation == EMULATE_KSH || emulation == EMULATE_SH) { nullcmd = ztrdup(":"); readnullcmd = ztrdup(":"); } else { nullcmd = ztrdup("cat"); readnullcmd = ztrdup("more"); } /* We cache the uid so we know when to * * recheck the info for `USERNAME' */ cached_uid = getuid(); /* Get password entry and set info for `HOME' and `USERNAME' */ if ((pswd = getpwuid(cached_uid))) { home = metafy(pswd->pw_dir, -1, META_DUP); cached_username = ztrdup(pswd->pw_name); } else { home = ztrdup("/"); cached_username = ztrdup(""); } /* Try a cheap test to see if we can * * initialize `PWD' from `HOME' */ if (ispwd(home)) pwd = ztrdup(home); else if ((ptr = zgetenv("PWD")) && ispwd(ptr)) pwd = ztrdup(ptr); else pwd = metafy(zgetcwd(), -1, META_REALLOC); oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */ #ifdef __EMX__ *cdrive = _getdrive(); strcat(cdrive+1,":"); #endif inittyptab(); /* initialize the ztypes table */ initlextabs(); /* initialize lexing tables */ createreswdtable(); /* create hash table for reserved words */ createaliastable(); /* create hash table for aliases */ createcmdnamtable(); /* create hash table for external commands */ createshfunctable(); /* create hash table for shell functions */ createbuiltintable(); /* create hash table for builtin commands */ createnameddirtable(); /* create hash table for named directories */ createparamtable(); /* create paramater hash table */ #ifdef ZLE_MODULE add_dep("compctl", "zle"); addbuiltin("bindkey", 0, NULL, 0, -1, "zle"); addbuiltin("vared", 0, NULL, 1, 7, "zle"); addbuiltin("compctl", 0, NULL, 0, -1, "compctl"); #endif #ifdef HAVE_GETRLIMIT for (i = 0; i != RLIM_NLIMITS; i++) { getrlimit(i, current_limits + i); limits[i] = current_limits[i]; } #endif breaks = loops = 0; lastmailcheck = time(NULL); locallist = NULL; locallevel = sourcelevel = 0; trapreturn = 0; noerrexit = 0; nohistsave = 1; dirstack = newlinklist(); bufstack = newlinklist(); hsubl = hsubr = NULL; lastpid = 0; bshin = SHIN ? fdopen(SHIN, "r") : stdin; if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) { #ifdef _IONBF setvbuf(stdin, NULL, _IONBF, 0); #else setlinebuf(stdin); #endif } times(&shtms); } /* Initialize signal handling */ /**/ void init_signals(void) { intr(); #ifndef QDEBUG signal_ignore(SIGQUIT); #endif install_handler(SIGHUP); install_handler(SIGCHLD); if (interact) { install_handler(SIGALRM); #ifdef SIGWINCH install_handler(SIGWINCH); #endif signal_ignore(SIGTERM); } if (jobbing) { long ttypgrp; #ifndef __EMX__ while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp) kill(0, SIGTTIN); #endif if (ttypgrp == -1) { opts[MONITOR] = 0; } else { #ifndef __EMX__ signal_ignore(SIGTTOU); signal_ignore(SIGTSTP); signal_ignore(SIGTTIN); #endif signal_ignore(SIGPIPE); attachtty(mypgrp); } } if (islogin) { signal_setmask(signal_mask(0)); } else if (interact) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); sigaddset(&set, SIGQUIT); signal_unblock(set); } }