/* * 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); }
/* The dowhich() is by: * Andreas Luik <*****@*****.**> * I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung * Azenberstr. 35 * D-7000 Stuttgart 1 * West-Germany * Thanks!! */ int cmd_expand(Char *cmd, Char **str) { struct wordent lexp[3]; struct varent *vp; int rv = TRUE; lexp[0].next = &lexp[1]; lexp[1].next = &lexp[2]; lexp[2].next = &lexp[0]; lexp[0].prev = &lexp[2]; lexp[1].prev = &lexp[0]; lexp[2].prev = &lexp[1]; lexp[0].word = STRNULL; lexp[2].word = STRret; if ((vp = adrof1(cmd, &aliases)) != NULL && vp->vec != NULL) { if (str == NULL) { xprintf(CGETS(22, 1, "%S: \t aliased to "), cmd); blkpr(vp->vec); xputchar('\n'); } else *str = blkexpand(vp->vec); } else { lexp[1].word = cmd; rv = tellmewhat(lexp, str); } return rv; }
/*ARGSUSED*/ void dowhich(Char **v, struct command *c) { struct wordent lexw[3]; struct varent *vp; lexw[0].next = &lexw[1]; lexw[1].next = &lexw[2]; lexw[2].next = &lexw[0]; lexw[0].prev = &lexw[2]; lexw[1].prev = &lexw[0]; lexw[2].prev = &lexw[1]; lexw[0].word = STRNULL; lexw[2].word = STRret; while (*++v) { if ((vp = adrof1(*v, &aliases)) != NULL) { (void)fprintf(cshout, "%s: \t aliased to ", vis_str(*v)); blkpr(cshout, vp->vec); (void)fputc('\n', cshout); set(STRstatus, Strsave(STR0)); } else { lexw[1].word = *v; set(STRstatus, Strsave(tellmewhat(lexw, NULL) ? STR0 : STR1)); } } }
/*ARGSUSED*/ void docomplete(Char **v, struct command *t) { struct varent *vp; Char *p; Char **pp; USE(t); v++; p = *v++; if (p == 0) tw_prlist(&completions); else if (*v == 0) { vp = adrof1(strip(p), &completions); if (vp && vp->vec) tw_pr(vp->vec), xputchar('\n'); else { #ifdef TDEBUG xprintf("tw_find(%s) \n", short2str(strip(p))); #endif /* TDEBUG */ pp = tw_find(strip(p), &completions, FALSE); if (pp) tw_pr(pp), xputchar('\n'); } } else set1(strip(p), saveblk(v), &completions, VAR_READWRITE); } /* end docomplete */
Char * value1(Char *var, struct varent *head) { struct varent *vp; vp = adrof1(var, head); return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]); }
void unsetv(Char *var) { struct varent *vp; if ((vp = adrof1(var, &shvhed)) == 0) udvar(var); unsetv1(vp); }
Char * value1(Char *var, struct varent *head) { struct varent *vp; if (!var || !head) /* PWP: extra error checking */ return (STRNULL); vp = adrof1(var, head); return ((vp == NULL || vp->vec == NULL || vp->vec[0] == NULL) ? STRNULL : vp->vec[0]); }
static void asyn3(struct wordent *p1, struct wordent *p2) { struct varent *ap; struct wordent alout; int redid; if (p1 == p2) return; if (p1->word[0] == '(') { for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev) if (p2 == p1) return; if (p2 == p1->next) return; asyn0(p1->next, p2); return; } ap = adrof1(p1->word, &aliases); if (ap == 0) return; alhistp = p1->prev; alhistt = p2; alvec = ap->vec; redid = lex(&alout); alhistp = alhistt = 0; alvec = 0; if (seterr) { freelex(&alout); stderror(ERR_OLD); } if (p1->word[0] && eq(p1->word, alout.next->word)) { Char *cp; cp = alout.next->word; alout.next->word = Strspl(STRQNULL, cp); xfree((ptr_t) cp); } p1 = freenod(p1, redid ? p2 : p1->next); if (alout.next != &alout) { p1->next->prev = alout.prev->prev; alout.prev->prev->next = p1->next; alout.next->prev = p1; p1->next = alout.next; xfree((ptr_t)alout.prev->word); xfree((ptr_t)(alout.prev)); } reset(); /* throw! */ }
/* * 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); }
/* * 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); }
static int tellmewhat(struct wordent *lexp, Char *str) { struct biltins *bptr; struct wordent *sp; Char *cmd, *s0, *s1, *s2; int i; int aliased, found; Char qc; aliased = 0; sp = lexp->next; if (adrof1(sp->word, &aliases)) { alias(lexp); sp = lexp->next; aliased = 1; } s0 = sp->word; /* to get the memory freeing right... */ /* handle quoted alias hack */ if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE) (sp->word)++; /* do quoting, if it hasn't been done */ s1 = s2 = sp->word; while (*s2) switch (*s2) { case '\'': case '"': qc = *s2++; while (*s2 && *s2 != qc) *s1++ = (Char)(*s2++ | QUOTE); if (*s2) s2++; break; case '\\': if (*++s2) *s1++ = (Char)(*s2++ | QUOTE); break; default: *s1++ = *s2++; } *s1 = '\0'; for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) { if (eq(sp->word, str2short(bptr->bname))) { if (str == NULL) { if (aliased) prlex(cshout, lexp); (void)fprintf(cshout, "%s: shell built-in command.\n", vis_str(sp->word)); } else (void)Strcpy(str, sp->word); sp->word = s0; /* we save and then restore this */ return 1; } } sp->word = cmd = globone(sp->word, G_IGNORE); if ((i = iscommand(sp->word)) != 0) { Char **pv; struct varent *v; int slash = any(short2str(sp->word), '/'); v = adrof(STRpath); if (v == 0 || v->vec[0] == 0 || slash) pv = justabs; else pv = v->vec; while (--i) pv++; if (pv[0][0] == 0 || eq(pv[0], STRdot)) { if (!slash) { sp->word = Strspl(STRdotsl, sp->word); prlex(cshout, lexp); free(sp->word); } else prlex(cshout, lexp); } else { s1 = Strspl(*pv, STRslash); sp->word = Strspl(s1, sp->word); free(s1); if (str == NULL) prlex(cshout, lexp); else (void)Strcpy(str, sp->word); free(sp->word); } found = 1; } else { if (str == NULL) { if (aliased) prlex(cshout, lexp); (void)fprintf(csherr, "%s: Command not found.\n", vis_str(sp->word)); } else (void)Strcpy(str, sp->word); found = 0; } sp->word = s0; /* we save and then restore this */ free(cmd); return found; }
/* * Execute command f, arg list t. * Record error message if not found. * Also do shell scripts here. */ static void texec(Char *sf, Char **st) { struct varent *v; Char *lastsh[2], **vp, *st0, **ost; char *f, **t; int fd; unsigned char c = '\0'; /* The order for the conversions is significant */ t = short2blk(st); f = short2str(sf); Vt = t; errno = 0; /* don't use a previous error */ (void)execve(f, t, environ); Vt = 0; blkfree((Char **)t); switch (errno) { case ENOEXEC: /* * From: [email protected] (Casper H.S. Dik) If we could not execute * it, don't feed it to the shell if it looks like a binary! */ if ((fd = open(f, O_RDONLY)) != -1) { if (read(fd, (char *)&c, 1) == 1) { if (!Isprint(c) && (c != '\n' && c != '\t')) { (void)close(fd); /* * We *know* what ENOEXEC means. */ stderror(ERR_ARCH, f, strerror(errno)); } } #ifdef _PATH_BSHELL else c = '#'; #endif (void)close(fd); } /* * If there is an alias for shell, then put the words of the alias in * front of the argument list replacing the command name. Note no * interpretation of the words at this point. */ v = adrof1(STRshell, &aliases); if (v == 0) { vp = lastsh; vp[0] = adrof(STRshell) ? value(STRshell) : STR_SHELLPATH; vp[1] = NULL; #ifdef _PATH_BSHELL if (fd != -1 && c != '#') vp[0] = STR_BSHELL; #endif } else vp = v->vec; st0 = st[0]; st[0] = sf; ost = st; st = blkspl(vp, st); /* Splice up the new arglst */ ost[0] = st0; sf = *st; /* The order for the conversions is significant */ t = short2blk(st); f = short2str(sf); free(st); Vt = t; (void)execve(f, t, environ); Vt = 0; blkfree((Char **)t); /* FALLTHROUGH */ case ENOMEM: stderror(ERR_SYSTEM, f, strerror(errno)); /* NOTREACHED */ case ENOENT: break; default: if (exerr == 0) { exerr = strerror(errno); if (expath) free(expath); expath = Strsave(sf); Vexpath = expath; } } }
/* * Execute command f, arg list t. * Record error message if not found. * Also do shell scripts here. */ void texec(struct command *cmd, tchar *f, tchar **t) { int pfstatus = 0; struct varent *v; tchar **vp; tchar *lastsh[2]; #ifdef TRACE tprintf("TRACE- texec()\n"); #endif /* convert cfname and cargs from tchar to char */ tconvert(cmd, f, t); if (pfcshflag == 1) { pfstatus = secpolicy_pfexec((const char *)(cmd->cfname), cmd->cargs, (const char **)NULL); if (pfstatus != NOATTRS) { errno = pfstatus; } } if ((pfcshflag == 0) || (pfstatus == NOATTRS)) { execv(cmd->cfname, cmd->cargs); } /* * exec returned, free up allocations from above * tconvert(), zero cfname and cargs to prevent * duplicate free() in freesyn() */ xfree(cmd->cfname); chr_blkfree(cmd->cargs); cmd->cfname = (char *)0; cmd->cargs = (char **)0; switch (errno) { case ENOEXEC: /* check that this is not a binary file */ { int ff = open_(f, 0); tchar ch[MB_LEN_MAX]; if (ff != -1 && read_(ff, ch, 1) == 1 && !isprint(ch[0]) && !isspace(ch[0])) { printf("Cannot execute binary file.\n"); Perror(f); (void) close(ff); unsetfd(ff); return; } (void) close(ff); unsetfd(ff); } /* * If there is an alias for shell, then * put the words of the alias in front of the * argument list replacing the command name. * Note no interpretation of the words at this point. */ v = adrof1(S_shell /* "shell" */, &aliases); if (v == 0) { #ifdef OTHERSH int ff = open_(f, 0); tchar ch[MB_LEN_MAX]; #endif vp = lastsh; vp[0] = adrof(S_shell /* "shell" */) ? value(S_shell /* "shell" */) : S_SHELLPATH /* SHELLPATH */; vp[1] = (tchar *) NULL; #ifdef OTHERSH if (ff != -1 && read_(ff, ch, 1) == 1 && ch[0] != '#') vp[0] = S_OTHERSH /* OTHERSH */; (void) close(ff); unsetfd(ff); #endif } else vp = v->vec; t[0] = f; t = blkspl(vp, t); /* Splice up the new arglst */ f = *t; tconvert(cmd, f, t); /* convert tchar to char */ /* * now done with tchar arg list t, * free the space calloc'd by above blkspl() */ xfree((char *)t); execv(cmd->cfname, cmd->cargs); /* exec the command */ /* exec returned, same free'ing as above */ xfree(cmd->cfname); chr_blkfree(cmd->cargs); cmd->cfname = (char *)0; cmd->cargs = (char **)0; /* The sky is falling, the sky is falling! */ case ENOMEM: Perror(f); case ENOENT: break; default: if (exerr == 0) { exerr = strerror(errno); setname(f); } } }