/* * Like eval, only using the current file descriptors */ static void doeval1(Char **v) { struct eval1_state state; Char **gv; int gflag; gflag = tglob(v); if (gflag) { gv = v = globall(v, gflag); if (v == 0) stderror(ERR_NOMATCH); v = copyblk(v); } else { gv = NULL; v = copyblk(v); trim(v); } if (gv) cleanup_push(gv, blk_cleanup); state.evalvec = evalvec; state.evalp = evalp; evalvec = v; evalp = 0; cleanup_push(&state, eval1_cleanup); process(0); cleanup_until(&state); if (gv) cleanup_until(gv); }
/*ARGSUSED*/ void douniverse(Char **v, struct command *c) { Char *cp = v[1]; Char *cp2; /* dunno how many elements v comes in with */ char ubuf[100]; if (cp == 0) { (void) getuniverse(ubuf); xprintf("%s\n", ubuf); } else { cp2 = v[2]; if (cp2 == 0) { if (*cp == '\0' || setuniverse(short2str(cp)) != 0) stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); } else { (void) getuniverse(ubuf); if (*cp == '\0' || setuniverse(short2str(cp)) != 0) stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); cleanup_push(ubuf, setuniverse_cleanup); if (setintr) { pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); } lshift(v, 2); if (setintr) cleanup_until(&pintr_disabled); reexecute(c); cleanup_until(ubuf); } } }
/* PrintOne(): * Print the specified key and its associated * function specified by val */ void printOne(const Char *key, const XmapVal *val, int ntype) { struct KeyFuncs *fp; static const char *fmt = "%s\n"; xprintf("%-15S-> ", key); if (val != NULL) switch (ntype) { case XK_STR: case XK_EXE: { unsigned char *p; p = unparsestring(&val->str, ntype == XK_STR ? STRQQ : STRBB); cleanup_push(p, xfree); xprintf(fmt, p); cleanup_until(p); break; } case XK_CMD: for (fp = FuncNames; fp->name; fp++) if (val->cmd == fp->func) xprintf(fmt, fp->name); break; default: abort(); break; } else xprintf(fmt, CGETS(9, 7, "no input")); }
static Char * globtilde(Char *s) { Char *name, *u, *home, *res; u = s; for (s++; *s && *s != '/' && *s != ':'; s++) continue; name = Strnsave(u + 1, s - (u + 1)); cleanup_push(name, xfree); home = gethdir(name); if (home == NULL) { if (adrof(STRnonomatch)) { cleanup_until(name); return u; } if (*name) stderror(ERR_UNKUSER, short2str(name)); else stderror(ERR_NOHOME); } cleanup_until(name); if (home[0] == '/' && home[1] == '\0' && s[0] == '/') res = Strsave(s); else res = Strspl(home, s); xfree(home); xfree(u); return res; }
/*ARGSUSED*/ void dosettc(Char **v, struct command *c) { char *tv[2]; USE(c); if (!GotTermCaps) GetTermCaps(); tv[0] = strsave(short2str(v[1])); cleanup_push(tv[0], xfree); tv[1] = strsave(short2str(v[2])); cleanup_push(tv[1], xfree); SetTC(tv[0], tv[1]); cleanup_until(tv[0]); }
/* PrintXKey(): * Print the binding associated with Xkey key. * Print entire Xmap if null */ void PrintXkey(const CStr *key) { struct Strbuf buf = Strbuf_INIT; CStr cs; if (key) { cs.buf = key->buf; cs.len = key->len; } else { cs.buf = STRNULL; cs.len = 0; } /* do nothing if Xmap is empty and null key specified */ if (Xmap == NULL && cs.len == 0) return; Strbuf_append1(&buf, '"'); cleanup_push(&buf, Strbuf_cleanup); if (Lookup(&buf, &cs, Xmap) <= -1) /* key is not bound */ xprintf(CGETS(9, 4, "Unbound extended key \"%S\"\n"), cs.buf); cleanup_until(&buf); }
/* * Karl Kleinpaste, 18 Jan 1984. * Added period_cmd(), which executes the alias "periodic" every * $tperiod minutes. Useful for occasional checking of msgs and such. */ void period_cmd(void) { Char *vp; time_t t, interval; pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); if (periodic_active) { /* an error must have been caught */ aliasrun(2, STRunalias, STRperiodic); xprintf("%s", CGETS(22, 6, "Faulty alias 'periodic' removed.\n")); goto leave; } periodic_active = 1; if (!whyles && adrof1(STRperiodic, &aliases)) { vp = varval(STRtperiod); if (vp == STRNULL) { aliasrun(1, STRperiodic, NULL); goto leave; } interval = getn(vp); (void) time(&t); if (t - t_period >= interval * 60) { t_period = t; aliasrun(1, STRperiodic, NULL); } } leave: periodic_active = 0; cleanup_until(&pintr_disabled); }
static Char * dgoto(Char *cp) { Char *dp, *ret; if (!ABSOLUTEP(cp)) { Char *p, *q; size_t cwdlen; cwdlen = Strlen(dcwd->di_name); if (cwdlen == 1) /* root */ cwdlen = 0; dp = xmalloc((cwdlen + Strlen(cp) + 2) * sizeof(Char)); for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';) continue; if (cwdlen) p[-1] = '/'; else p--; /* don't add a / after root */ Strcpy(p, cp); xfree(cp); cp = dp; dp += cwdlen; } else dp = cp; #if defined(WINNT_NATIVE) return agetcwd(); #elif defined(__CYGWIN__) if (ABSOLUTEP(cp) && cp[1] == ':') { /* Only DOS paths are treated that way */ return agetcwd(); } else { cleanup_push(cp, xfree); ret = dcanon(cp, dp); cleanup_ignore(cp); cleanup_until(cp); } #else /* !WINNT_NATIVE */ cleanup_push(cp, xfree); ret = dcanon(cp, dp); cleanup_ignore(cp); cleanup_until(cp); #endif /* WINNT_NATIVE */ return ret; }
static void stack_socket_close(UNUSED_PARAM(ssh_session session), struct event_fd_data_struct *event_fd_data) { if (event_fd_data->stacked != 1) { _ssh_log(SSH_LOG_FUNCTIONS, "=== stack_socket_close", "Closing fd = %d sockets_cnt = %d", *event_fd_data->p_fd, sockets_cnt); event_fd_data->stacked = 1; cleanup_push(&cleanup_stack, event_fd_data); } }
void dotitle(Char **vc, struct command * c) { int k; char titlebuf[512]; char errbuf[128],err2[128]; char **v; Char **nvc; UNREFERENCED_PARAMETER(c); vc++; nvc = glob_all_or_error(vc); if (nvc == NULL) return; if (nvc != vc) cleanup_push(nvc, blk_cleanup); if ((k = GetConsoleTitle(titlebuf, sizeof(titlebuf))) != 0) { setcopy(STRoldtitle,str2short(titlebuf), VAR_READWRITE|VAR_NOGLOB); } titlebuf[0] = '\0'; v = short2blk(nvc); if (nvc != vc) cleanup_until(nvc); cleanup_push((Char **)v, blk_cleanup); for (k = 0; v[k] != NULL ; k++){ __try { StringCbCat(titlebuf,sizeof(titlebuf),v[k]); StringCbCat(titlebuf,sizeof(titlebuf)," "); } __except(GetExceptionCode()) { stderror(ERR_TOOMANY); } } if (!SetConsoleTitle(titlebuf) ) { make_err_str(GetLastError(),errbuf,128); (void)StringCbPrintf(err2,sizeof(err2),"%s",v[k]); stderror(ERR_SYSTEM,err2,errbuf); } cleanup_until((Char **)v); return; }
/* * Print the termcap string out with variable substitution */ void EchoTC(Char **v) { Char **globbed; char cv[BUFSIZE];/*FIXBUF*/ int verbose = 0, silent = 0; static char *fmts = "%s\n", *fmtd = "%d\n"; int li,co; setname("echotc"); v = glob_all_or_error(v); globbed = v; cleanup_push(globbed, blk_cleanup); if (!v || !*v || *v[0] == '\0') goto end; if (v[0][0] == '-') { switch (v[0][1]) { case 'v': verbose = 1; break; case 's': silent = 1; break; default: stderror(ERR_NAME | ERR_TCUSAGE); break; } v++; } if (!*v || *v[0] == '\0') goto end; (void) StringCbCopy(cv,sizeof(cv), short2str(*v)); GetSize(&li,&co); if(!lstrcmp(cv,"rows") || !lstrcmp(cv,"lines") ) { xprintf(fmtd,T_Lines); goto end; } else if(!lstrcmp(cv,"cols") ) { xprintf(fmtd,T_ActualWindowSize); goto end; } else if(!lstrcmp(cv,"buffer") ) { xprintf(fmtd,T_Cols); goto end; } else stderror(ERR_SYSTEM, "EchoTC","Sorry, this function is not supported"); end: cleanup_until(globbed); }
void setcopy(const Char *var, const Char *val, int flags) { Char *copy; copy = Strsave(val); cleanup_push(copy, xfree); setv(var, copy, flags); cleanup_ignore(copy); cleanup_until(copy); }
static char * xgetpass(const char *prm) { static struct strbuf pass; /* = strbuf_INIT; */ int fd; sigset_t oset, set; struct sigaction sa, osa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; (void)sigaction(SIGINT, &sa, &osa); sigemptyset(&set); sigaddset(&set, SIGINT); (void)sigprocmask(SIG_UNBLOCK, &set, &oset); cleanup_push(&osa, sigint_cleanup); cleanup_push(&oset, sigprocmask_cleanup); (void) Rawmode(); /* Make sure, cause we want echo off */ fd = xopen("/dev/tty", O_RDWR|O_LARGEFILE); if (fd == -1) fd = SHIN; else cleanup_push(&fd, open_cleanup); xprintf("%s", prm); flush(); pass.len = 0; for (;;) { char c; if (xread(fd, &c, 1) < 1 || c == '\n') break; strbuf_append1(&pass, c); } strbuf_terminate(&pass); cleanup_until(&osa); return pass.s; }
Char * globone(Char *str, int action) { Char *v[2], **vl, **vo; int gflg, noglob; noglob = adrof(STRnoglob) != 0; v[0] = str; v[1] = 0; gflg = tglob(v); if (gflg == G_NONE) return (strip(Strsave(str))); if (gflg & G_CSH) { /* * Expand back-quote, tilde and brace */ vo = globexpand(v, noglob); if (noglob || (gflg & G_GLOB) == 0) { vl = vo; goto result; } cleanup_push(vo, blk_cleanup); } else if (noglob || (gflg & G_GLOB) == 0) return (strip(Strsave(str))); else vo = v; vl = libglob(vo); if (gflg & G_CSH) { if (vl != vo) cleanup_until(vo); else cleanup_ignore(vo); } if (vl == NULL) { setname(short2str(str)); stderror(ERR_NAME | ERR_NOMATCH); } result: if (vl && vl[0] == NULL) { xfree(vl); return (Strsave(STRNULL)); } if (vl && vl[1]) return (handleone(str, vl, action)); else { str = strip(*vl); xfree(vl); return (str); } }
/* put_color(): */ static void put_color(const Str *color) { size_t i; const char *c = color->s; int original_output_raw = output_raw; output_raw = TRUE; cleanup_push(&original_output_raw, output_raw_restore); for (i = color->len; 0 < i; i--) xputchar(*c++); cleanup_until(&original_output_raw); }
static void asx(Char *vp, int subscr, Char *p) { struct varent *v = getvx(vp, subscr); Char *prev; if (v->v_flags & VAR_READONLY) stderror(ERR_READONLY|ERR_NAME, v->v_name); prev = v->vec[subscr - 1]; cleanup_push(prev, xfree); v->vec[subscr - 1] = globone(p, G_APPEND); cleanup_until(prev); }
/*ARGSUSED*/ void doinlib(Char **v, struct command *c) { Char **globbed; setname(short2str(*v++)); v = glob_all_or_error(v); globbed = v; cleanup_push(globbed, blk_cleanup); while (v && *v) llib(*v++); cleanup_until(globbed); }
/*ARGSUSED*/ void doucb(Char **v, struct command *c) { Char *cp = v[1]; char ubuf[100]; if (cp == 0) (void) setuniverse("ucb"); else { (void) getuniverse(ubuf); (void) setuniverse("ucb"); cleanup_push(ubuf, setuniverse_cleanup); if (setintr) { pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); } lshift(v, 1); if (setintr) cleanup_until(&pintr_disabled); reexecute(c); cleanup_until(ubuf); } }
void loaddirs(Char *fname) { static Char *loaddirs_cmd[] = { STRsource, NULL, NULL }; bequiet = 1; cleanup_push(&bequiet, bequiet_cleanup); if (fname) loaddirs_cmd[1] = fname; else if ((fname = varval(STRdirsfile)) != STRNULL) loaddirs_cmd[1] = fname; else loaddirs_cmd[1] = STRtildotdirs; dosource(loaddirs_cmd, NULL); cleanup_until(&bequiet); }
/* * Joachim Hoenig 07/16/91 Added beep_cmd, run every time tcsh wishes * to beep the terminal bell. Useful for playing nice sounds instead. */ void beep_cmd(void) { pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); if (beepcmd_active) { /* an error must have been caught */ aliasrun(2, STRunalias, STRbeepcmd); xprintf("%s", CGETS(22, 5, "Faulty alias 'beepcmd' removed.\n")); } else { beepcmd_active = 1; if (!whyles && adrof1(STRbeepcmd, &aliases)) aliasrun(1, STRbeepcmd, NULL); } beepcmd_active = 0; cleanup_until(&pintr_disabled); }
/* * Paul Placeway 11/24/87 Added cwd_cmd by hacking precmd() into * submission... Run every time $cwd is set (after it is set). Useful * for putting your machine and cwd (or anything else) in an xterm title * space. */ void cwd_cmd(void) { pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); if (cwdcmd_active) { /* an error must have been caught */ aliasrun(2, STRunalias, STRcwdcmd); xprintf("%s", CGETS(22, 4, "Faulty alias 'cwdcmd' removed.\n")); goto leave; } cwdcmd_active = 1; if (!whyles && adrof1(STRcwdcmd, &aliases)) aliasrun(1, STRcwdcmd, NULL); leave: cwdcmd_active = 0; cleanup_until(&pintr_disabled); }
static void exportpath(Char **val) { struct Strbuf buf = Strbuf_INIT; Char *exppath; if (val) while (*val) { Strbuf_append(&buf, *val++); if (*val == 0 || eq(*val, STRRparen)) break; Strbuf_append1(&buf, PATHSEP); } exppath = Strbuf_finish(&buf); cleanup_push(exppath, xfree); tsetenv(STRKPATH, exppath); cleanup_until(exppath); }
/* * GrP Greg Parker May 2001 * Added job_cmd(), which is run every time a job is started or * foregrounded. The command is passed a single argument, the string * used to start the job originally. With precmd, useful for setting * xterm titles. * Cloned from cwd_cmd(). */ void job_cmd(Char *args) { pintr_disabled++; cleanup_push(&pintr_disabled, disabled_cleanup); if (jobcmd_active) { /* an error must have been caught */ aliasrun(2, STRunalias, STRjobcmd); xprintf("%s", CGETS(22, 14, "Faulty alias 'jobcmd' removed.\n")); goto leave; } jobcmd_active = 1; if (!whyles && adrof1(STRjobcmd, &aliases)) { struct process *pp = pcurrjob; /* put things back after the hook */ aliasrun(2, STRjobcmd, args); pcurrjob = pp; } leave: jobcmd_active = 0; cleanup_until(&pintr_disabled); }
int Gnmatch(const Char *string, const Char *pattern, const Char **endstr) { Char ***fblk, **p; const Char *tstring = string; int gpol = 1, gres = 0; if (*pattern == '^') { gpol = 0; pattern++; } fblk = xmalloc(sizeof(Char ***)); *fblk = xmalloc(GLOBSPACE * sizeof(Char *)); (*fblk)[0] = Strsave(pattern); (*fblk)[1] = NULL; cleanup_push(fblk, blk_indirect_cleanup); expbrace(fblk, NULL, GLOBSPACE); if (endstr == NULL) /* Exact matches only */ for (p = *fblk; *p; p++) gres |= t_pmatch(string, *p, &tstring, 1) == 2 ? 1 : 0; else { const Char *end; /* partial matches */ end = Strend(string); for (p = *fblk; *p; p++) if (t_pmatch(string, *p, &tstring, 1) != 0) { gres |= 1; if (end > tstring) end = tstring; } *endstr = end; } cleanup_until(fblk); return(gres == gpol); }
static void dgetstack(void) { int i = 0; Char **dblk, **dbp; struct directory *dn; if (adrof(STRdirstack) == NULL) return; for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, i++) continue; dbp = dblk = xmalloc((i + 1) * sizeof(Char *)); for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, dbp++) *dbp = Strsave(dn->di_name); *dbp = NULL; cleanup_push(dblk, blk_cleanup); setq(STRdirstack, dblk, &shvhed, VAR_READWRITE); cleanup_ignore(dblk); cleanup_until(dblk); }
/* * Expand and glob the words after an i/o redirection. * If more than one word is generated, then update the command vector. * * This is done differently in all the shells: * 1. in the bourne shell and ksh globbing is not performed * 2. Bash/csh say ambiguous * 3. zsh does i/o to/from all the files * 4. itcsh concatenates the words. * * I don't know what is best to do. I think that Ambiguous is better * than restructuring the command vector, because the user can get * unexpected results. In any case, the command vector restructuring * code is present and the user can choose it by setting noambiguous */ static Char * splicepipe(struct command *t, Char *cp) { Char *blk[2]; if (adrof(STRnoambiguous)) { Char **pv; int gflag; blk[0] = Dfix1(cp); /* expand $ */ blk[1] = NULL; gflag = tglob(blk); if (gflag) { pv = globall(blk, gflag); if (pv == NULL) { setname(short2str(blk[0])); xfree(blk[0]); stderror(ERR_NAME | ERR_NOMATCH); } if (pv[1] != NULL) { /* we need to fix the command vector */ Char **av = blkspl(t->t_dcom, &pv[1]); xfree(t->t_dcom); t->t_dcom = av; } xfree(blk[0]); blk[0] = pv[0]; xfree(pv); } } else { Char *buf; buf = Dfix1(cp); cleanup_push(buf, xfree); blk[0] = globone(buf, G_ERROR); cleanup_until(buf); } return(blk[0]); }
static void update_vars(Char *vp) { if (eq(vp, STRpath)) { struct varent *p = adrof(STRpath); if (p == NULL) stderror(ERR_NAME | ERR_UNDVAR); else { exportpath(p->vec); dohash(NULL, NULL); } } else if (eq(vp, STRnoclobber)) { struct varent *p = adrof(STRnoclobber); if (p == NULL) stderror(ERR_NAME | ERR_UNDVAR); else no_clobber = set_noclobber(p->vec); } else if (eq(vp, STRhistchars)) { Char *pn = varval(vp); HIST = *pn++; if (HIST) HISTSUB = *pn; else HISTSUB = HIST; } else if (eq(vp, STRpromptchars)) { Char *pn = varval(vp); PRCH = *pn++; if (PRCH) PRCHROOT = *pn; else PRCHROOT = PRCH; } else if (eq(vp, STRhistlit)) { HistLit = 1; } else if (eq(vp, STRuser)) { tsetenv(STRKUSER, varval(vp)); tsetenv(STRLOGNAME, varval(vp)); } else if (eq(vp, STRgroup)) { tsetenv(STRKGROUP, varval(vp)); } else if (eq(vp, STRwordchars)) { word_chars = varval(vp); } else if (eq(vp, STRloginsh)) { loginsh = 1; } else if (eq(vp, STRanyerror)) { anyerror = 1; } else if (eq(vp, STRsymlinks)) { Char *pn = varval(vp); if (eq(pn, STRignore)) symlinks = SYM_IGNORE; else if (eq(pn, STRexpand)) symlinks = SYM_EXPAND; else if (eq(pn, STRchase)) symlinks = SYM_CHASE; else symlinks = 0; } else if (eq(vp, STRterm)) { Char *cp = varval(vp); tsetenv(STRKTERM, cp); #ifdef DOESNT_WORK_RIGHT cp = getenv("TERMCAP"); if (cp && (*cp != '/')) /* if TERMCAP and not a path */ Unsetenv(STRTERMCAP); #endif /* DOESNT_WORK_RIGHT */ GotTermCaps = 0; if (noediting && Strcmp(cp, STRnetwork) != 0 && Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) { editing = 1; noediting = 0; setNS(STRedit); } ed_Init(); /* reset the editor */ } else if (eq(vp, STRhome)) { Char *cp, *canon; cp = Strsave(varval(vp)); /* get the old value back */ cleanup_push(cp, xfree); /* * convert to cononical pathname (possibly resolving symlinks) */ canon = dcanon(cp, cp); cleanup_ignore(cp); cleanup_until(cp); cleanup_push(canon, xfree); setcopy(vp, canon, VAR_READWRITE); /* have to save the new val */ /* and now mirror home with HOME */ tsetenv(STRKHOME, canon); /* fix directory stack for new tilde home */ dtilde(); cleanup_until(canon); } else if (eq(vp, STRedit)) { editing = 1; noediting = 0; /* PWP: add more stuff in here later */ } else if (eq(vp, STRvimode)) { VImode = 1; update_wordchars(); } else if (eq(vp, STRshlvl)) { tsetenv(STRKSHLVL, varval(vp)); } else if (eq(vp, STRignoreeof)) { Char *cp; numeof = 0; for ((cp = varval(STRignoreeof)); cp && *cp; cp++) { if (!Isdigit(*cp)) { numeof = 0; break; } numeof = numeof * 10 + *cp - '0'; } if (numeof <= 0) numeof = 26; /* Sanity check */ } else if (eq(vp, STRbackslash_quote)) { bslash_quote = 1; } else if (eq(vp, STRcompat_expr)) { compat_expr = 1; } else if (eq(vp, STRdirstack)) { dsetstack(); } else if (eq(vp, STRrecognize_only_executables)) { tw_cmd_free(); } else if (eq(vp, STRkillring)) { SetKillRing((int)getn(varval(vp))); } else if (eq(vp, STRhistory)) { sethistory((int)getn(varval(vp))); } #ifndef HAVENOUTMP else if (eq(vp, STRwatch)) { resetwatch(); } #endif /* HAVENOUTMP */ else if (eq(vp, STRimplicitcd)) { implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1); } else if (eq(vp, STRcdtohome)) { cdtohome = 1; } #ifdef COLOR_LS_F else if (eq(vp, STRcolor)) { set_color_context(); } #endif /* COLOR_LS_F */ #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) { update_dspmbyte_vars(); } #endif #ifdef NLS_CATALOGS else if (eq(vp, STRcatalog)) { nlsclose(); nlsinit(); } #if defined(FILEC) && defined(TIOCSTI) else if (eq(vp, STRfilec)) filec = 1; #endif #endif /* NLS_CATALOGS */ }
/*ARGSUSED*/ void dolet(Char **v, struct command *dummy) { Char *p; Char *vp, c, op; int hadsub; int subscr; USE(dummy); v++; p = *v++; if (p == 0) { prvars(); return; } do { hadsub = 0; vp = p; if (letter(*p)) for (; alnum(*p); p++) continue; if (vp == p || !letter(*vp)) stderror(ERR_NAME | ERR_VARBEGIN); if (*p == '[') { hadsub++; p = getinx(p, &subscr); } if (*p == 0 && *v) p = *v++; if ((op = *p) != 0) *p++ = 0; else stderror(ERR_NAME | ERR_ASSIGN); /* * if there is no expression after the '=' then print a "Syntax Error" * message - strike */ if (*p == '\0' && *v == NULL) stderror(ERR_NAME | ERR_ASSIGN); vp = Strsave(vp); cleanup_push(vp, xfree); if (op == '=') { c = '='; p = xset(p, &v); } else { c = *p++; if (any("+-", c)) { if (c != op || *p) stderror(ERR_NAME | ERR_UNKNOWNOP); p = Strsave(STR1); } else { if (any("<>", op)) { if (c != op) stderror(ERR_NAME | ERR_UNKNOWNOP); stderror(ERR_NAME | ERR_SYNTAX); } if (c != '=') stderror(ERR_NAME | ERR_UNKNOWNOP); p = xset(p, &v); } } cleanup_push(p, xfree); if (op == '=') { if (hadsub) asx(vp, subscr, p); else setv(vp, p, VAR_READWRITE); cleanup_ignore(p); } else if (hadsub) { struct varent *gv = getvx(vp, subscr); Char *val; val = operate(op, gv->vec[subscr - 1], p); cleanup_push(val, xfree); asx(vp, subscr, val); cleanup_ignore(val); cleanup_until(val); } else { Char *val; val = operate(op, varval(vp), p); cleanup_push(val, xfree); setv(vp, val, VAR_READWRITE); cleanup_ignore(val); cleanup_until(val); } update_vars(vp); cleanup_until(vp); } while ((p = *v++) != NULL); }
/*ARGSUSED*/ void doset(Char **v, struct command *c) { Char *p; Char *vp; Char **vecp; int hadsub; int subscr; int flags = VAR_READWRITE; int first_match = 0; int last_match = 0; int changed = 0; USE(c); v++; do { changed = 0; /* * Readonly addition From: Tim P. Starrin <*****@*****.**> */ if (*v && eq(*v, STRmr)) { flags = VAR_READONLY; v++; changed = 1; } if (*v && eq(*v, STRmf) && !last_match) { first_match = 1; v++; changed = 1; } if (*v && eq(*v, STRml) && !first_match) { last_match = 1; v++; changed = 1; } } while(changed); p = *v++; if (p == 0) { plist(&shvhed, flags); return; } do { hadsub = 0; vp = p; if (!letter(*p)) stderror(ERR_NAME | ERR_VARBEGIN); do { p++; } while (alnum(*p)); if (*p == '[') { hadsub++; p = getinx(p, &subscr); } if (*p != '\0' && *p != '=') stderror(ERR_NAME | ERR_VARALNUM); if (*p == '=') { *p++ = '\0'; if (*p == '\0' && *v != NULL && **v == '(') p = *v++; } else if (*v && eq(*v, STRequal)) { if (*++v != NULL) p = *v++; } if (eq(p, STRLparen)) { Char **e = v; if (hadsub) stderror(ERR_NAME | ERR_SYNTAX); for (;;) { if (!*e) stderror(ERR_NAME | ERR_MISSING, ')'); if (**e == ')') break; e++; } p = *e; *e = 0; vecp = saveblk(v); if (first_match) flags |= VAR_FIRST; else if (last_match) flags |= VAR_LAST; set1(vp, vecp, &shvhed, flags); *e = p; v = e + 1; } else if (hadsub) { Char *copy; copy = Strsave(p); cleanup_push(copy, xfree); asx(vp, subscr, copy); cleanup_ignore(copy); cleanup_until(copy); } else setv(vp, Strsave(p), flags); update_vars(vp); } while ((p = *v++) != NULL); }
/* fix_version(): * Print a reasonable version string, printing all compile time * options that might affect the user. */ void fix_version(void) { #ifdef WIDE_STRINGS # define SSSTR "wide" #elif defined (SHORT_STRINGS) # define SSSTR "8b" #else # define SSSTR "7b" #endif #ifdef NLS # define NLSSTR ",nls" #else # define NLSSTR "" #endif #ifdef LOGINFIRST # define LFSTR ",lf" #else # define LFSTR "" #endif #ifdef DOTLAST # define DLSTR ",dl" #else # define DLSTR "" #endif #ifdef VIDEFAULT # define VISTR ",vi" #else # define VISTR "" #endif #ifdef TESLA # define DTRSTR ",dtr" #else # define DTRSTR "" #endif #ifdef KAI # define BYESTR ",bye" #else # define BYESTR "" #endif #ifdef AUTOLOGOUT # define ALSTR ",al" #else # define ALSTR "" #endif #ifdef KANJI # define KANSTR ",kan" #else # define KANSTR "" #endif #ifdef SYSMALLOC # define SMSTR ",sm" #else # define SMSTR "" #endif #ifdef HASHBANG # define HBSTR ",hb" #else # define HBSTR "" #endif #ifdef NEWGRP # define NGSTR ",ng" #else # define NGSTR "" #endif #ifdef REMOTEHOST # define RHSTR ",rh" #else # define RHSTR "" #endif #ifdef AFS # define AFSSTR ",afs" #else # define AFSSTR "" #endif #ifdef NODOT # define NDSTR ",nd" #else # define NDSTR "" #endif #ifdef COLOR_LS_F # define COLORSTR ",color" #else /* ifndef COLOR_LS_F */ # define COLORSTR "" #endif /* COLOR_LS_F */ #ifdef DSPMBYTE # define DSPMSTR ",dspm" #else # define DSPMSTR "" #endif #ifdef COLORCAT # define CCATSTR ",ccat" #else # define CCATSTR "" #endif #if defined(FILEC) && defined(TIOCSTI) # define FILECSTR ",filec" #else # define FILECSTR "" #endif /* if you want your local version to say something */ #ifndef LOCALSTR # define LOCALSTR "" #endif /* LOCALSTR */ char *version; const Char *machtype = tgetenv(STRMACHTYPE); const Char *vendor = tgetenv(STRVENDOR); const Char *ostype = tgetenv(STROSTYPE); if (vendor == NULL) vendor = STRunknown; if (machtype == NULL) machtype = STRunknown; if (ostype == NULL) ostype = STRunknown; version = xasprintf( "%s" #ifdef CATCH_EXEC "(%s)" #endif " %d.%.2d.%.2d (%s) %s (%S-%S-%S) options %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", PROG_NAME, #ifdef CATCH_EXEC GDI_VERSION, #endif REV, VERS, PATCHLEVEL, ORIGIN, DATE, machtype, vendor, ostype, SSSTR, NLSSTR, LFSTR, DLSTR, VISTR, DTRSTR, BYESTR, ALSTR, KANSTR, SMSTR, HBSTR, NGSTR, RHSTR, AFSSTR, NDSTR, COLORSTR, DSPMSTR, CCATSTR, FILECSTR, LOCALSTR); cleanup_push(version, xfree); setcopy(STRversion, str2short(version), VAR_READWRITE); cleanup_until(version); version = xasprintf("%d.%.2d.%.2d", REV, VERS, PATCHLEVEL); cleanup_push(version, xfree); setcopy(STRtcsh, str2short(version), VAR_READWRITE); cleanup_until(version); }