/*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); } } }
static int format_bsd(const uint8_t *p, size_t plen, off_t flen, const char *path) { char buf[7] = "00000 \0"; if (plen != 2) { fputs("Digest incompatible to output format\n", stderr); return 1; } short2str(buf, p[0] << 8 | p[1]); fputs(buf, stdout); /* Implementation restriction: Can only hash files with up to 64 MiB */ if (flen >= UINT16_MAX * 1024) { fputs("File too large for this format\n", stderr); fputs("?????", stdout); printpath(path); return 1; } else { flen = (flen + 1023) >> 10; memset(buf, ' ', 5); short2str(buf, flen); buf[5] = '\0'; fputs(buf, stdout); printpath(path); return 0; } }
static Char filetype(Char *dir, Char *file) { Char path[PATH_MAX]; struct stat statb; Strlcpy(path, dir, sizeof path/sizeof(Char)); catn(path, file, sizeof(path) / sizeof(Char)); if (lstat(short2str(path), &statb) == 0) { switch (statb.st_mode & S_IFMT) { case S_IFDIR: return ('/'); case S_IFLNK: if (stat(short2str(path), &statb) == 0 && /* follow it out */ S_ISDIR(statb.st_mode)) return ('>'); else return ('@'); case S_IFSOCK: return ('='); default: if (statb.st_mode & 0111) return ('*'); } } return (' '); }
/* * executable() examines the pathname obtained by concatenating dir and name * (dir may be NULL), and returns 1 either if it is executable by us, or * if dir_ok is set and the pathname refers to a directory. * This is a bit kludgy, but in the name of optimization... */ static int executable(Char *dir, Char *name, bool dir_ok) { struct stat stbuf; Char path[PATH_MAX], *dp, *sp; char *strname; if (dir && *dir) { for (dp = path, sp = dir; *sp; *dp++ = *sp++) if (dp == &path[PATH_MAX]) { *--dp = '\0'; break; } for (sp = name; *sp; *dp++ = *sp++) if (dp == &path[PATH_MAX]) { *--dp = '\0'; break; } *dp = '\0'; strname = short2str(path); } else strname = short2str(name); return (stat(strname, &stbuf) != -1 && ((S_ISREG(stbuf.st_mode) && /* save time by not calling access() in the hopeless case */ (stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) && access(strname, X_OK) == 0) || (dir_ok && S_ISDIR(stbuf.st_mode)))); }
static int format_sysv(const uint8_t *p, size_t plen, off_t flen, const char *path) { char buf[7]; buf[5] = ' '; buf[6] = '\0'; if (plen != 2) { fputs("Digest incompatible to output format\n", stderr); return 1; } fputs(short2str(buf, p[0] << 8 | p[1]), stdout); /* Implementation restriction: Can only hash files with up to 32 MiB */ if (flen > UINT16_MAX * 512) { fputs("File too large for this format\n", stderr); fputs("?????", stdout); printpath(path); return 1; } else { flen = (flen + 511) >> 9; buf[5] = '\0'; fputs(short2str(buf, flen), stdout); printpath(path); return 0; } }
/* * dfollow - change to arg directory; fall back on cdpath if not valid */ static Char * dfollow(Char *cp) { Char *dp; struct varent *c; char ebuf[PATH_MAX]; int serrno; cp = globone(cp, G_ERROR); /* * if we are ignoring symlinks, try to fix relatives now. */ dp = dnormalize(cp); if (chdir(short2str(dp)) >= 0) { free(cp); return dgoto(dp); } else { free(dp); if (chdir(short2str(cp)) >= 0) return dgoto(cp); serrno = errno; } if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp) && (c = adrof(STRcdpath))) { Char **cdp; Char *p; Char buf[PATH_MAX]; for (cdp = c->vec; *cdp; cdp++) { for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';) continue; dp[-1] = '/'; for (p = cp; (*dp++ = *p++) != '\0';) continue; if (chdir(short2str(buf)) >= 0) { printd = 1; free(cp); cp = Strsave(buf); return dgoto(cp); } } } dp = value(cp); if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) { free(cp); cp = Strsave(dp); printd = 1; return dgoto(cp); } (void) strlcpy(ebuf, short2str(cp), sizeof ebuf); free(cp); stderror(ERR_SYSTEM, ebuf, strerror(serrno)); return (NULL); }
/* tw_match(): * Match a string against the pattern given. * and return the number of matched characters * in a prefix of the string. */ static int tw_match(const Char *str, const Char *pat, int exact) { const Char *estr; int rv = exact ? Gmatch(estr = str, pat) : Gnmatch(str, pat, &estr); #ifdef TDEBUG xprintf("G%smatch(%s, ", exact ? "" : "n", short2str(str)); xprintf("%s, ", short2str(pat)); xprintf("%s) = %d [%" TCSH_PTRDIFF_T_FMT "d]\n", short2str(estr), rv, estr - str); #endif /* TDEBUG */ return (int) (rv ? estr - str : -1); }
void setalarm(int lck) { struct varent *vp; Char *cp; unsigned alrm_time = 0, logout_time, lock_time; time_t cl, nl, sched_dif; if ((vp = adrof(STRautologout)) != NULL && vp->vec != NULL) { if ((cp = vp->vec[0]) != 0) { if ((logout_time = (unsigned) atoi(short2str(cp)) * 60) > 0) { #ifdef SOLARIS2 /* * Solaris alarm(2) uses a timer based in clock ticks * internally so it multiplies our value with CLK_TCK... * Of course that can overflow leading to unexpected * results, so we clip it here. Grr. Where is that * documented folks? */ if (logout_time >= 0x7fffffff / CLK_TCK) logout_time = 0x7fffffff / CLK_TCK; #endif /* SOLARIS2 */ alrm_time = logout_time; alm_fun = auto_logout; } } if ((cp = vp->vec[1]) != 0) { if ((lock_time = (unsigned) atoi(short2str(cp)) * 60) > 0) { if (lck) { if (alrm_time == 0 || lock_time < alrm_time) { alrm_time = lock_time; alm_fun = auto_lock; } } else /* lock_time always < alrm_time */ if (alrm_time) alrm_time -= lock_time; } } } if ((nl = sched_next()) != -1) { (void) time(&cl); sched_dif = nl > cl ? nl - cl : 0; if ((alrm_time == 0) || ((unsigned) sched_dif < alrm_time)) { alrm_time = ((unsigned) sched_dif) + 1; alm_fun = sched_run; } } alrmcatch_disabled = 0; (void) alarm(alrm_time); /* Autologout ON */ }
/*ARGSUSED*/ void dochngd(Char **v, struct command *c) { Char *cp; struct directory *dp; int dflag = skipargs(&v, "plvn", "[-|<dir>]"); USE(c); printd = 0; cp = (dflag & DIR_OLD) ? varval(STRowd) : *v; if (cp == NULL) { if (!cdtohome) stderror(ERR_NAME | ERR_TOOFEW); else if ((cp = varval(STRhome)) == STRNULL || *cp == 0) stderror(ERR_NAME | ERR_NOHOMEDIR); if (chdir(short2str(cp)) < 0) stderror(ERR_NAME | ERR_CANTCHANGE); cp = Strsave(cp); } else if ((dflag & DIR_OLD) == 0 && v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(cp)) != 0) { char *tmp; printd = 1; if (chdir(tmp = short2str(dp->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); dcwd->di_prev->di_next = dcwd->di_next; dcwd->di_next->di_prev = dcwd->di_prev; dfree(dcwd); dnewcwd(dp, dflag); return; } else if ((cp = dfollow(cp, dflag & DIR_OLD)) == NULL) return; dp = xcalloc(sizeof(struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_next = dcwd->di_next; dp->di_prev = dcwd->di_prev; dp->di_prev->di_next = dp; dp->di_next->di_prev = dp; dfree(dcwd); dnewcwd(dp, dflag); }
/* * dopushd - push new directory onto directory stack. * with no arguments exchange top and second. * with numeric argument (+n) bring it to top. */ void /*ARGSUSED*/ dopushd(Char **v, struct command *t) { struct directory *dp; skipargs(&v, " [<dir>|+<n>]"); printd = 1; if (*v == NULL) { char *tmp; if ((dp = dcwd->di_prev) == &dhead) dp = dhead.di_prev; if (dp == dcwd) stderror(ERR_NAME | ERR_NODIR); if (chdir(tmp = short2str(dp->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); dp->di_prev->di_next = dp->di_next; dp->di_next->di_prev = dp->di_prev; dp->di_next = dcwd->di_next; dp->di_prev = dcwd; dcwd->di_next->di_prev = dp; dcwd->di_next = dp; } else if (v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(*v)) != NULL) { char *tmp; if (chdir(tmp = short2str(dp->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); } else { Char *ccp; ccp = dfollow(*v); dp = xcalloc(1, sizeof(struct directory)); dp->di_name = ccp; dp->di_count = 0; dp->di_prev = dcwd; dp->di_next = dcwd->di_next; dcwd->di_next = dp; dp->di_next->di_prev = dp; } dnewcwd(dp); }
/*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]); }
static Char * handleone(Char *str, Char **vl, int action) { size_t chars; Char **t, *p, *strp; switch (action) { case G_ERROR: setname(short2str(str)); blkfree(vl); stderror(ERR_NAME | ERR_AMBIG); break; case G_APPEND: chars = 0; for (t = vl; (p = *t++) != NULL; chars++) chars += Strlen(p); str = xmalloc(chars * sizeof(Char)); for (t = vl, strp = str; (p = *t++) != '\0'; chars++) { while (*p) *strp++ = *p++ & TRIM; *strp++ = ' '; } *--strp = '\0'; blkfree(vl); break; case G_IGNORE: str = Strsave(strip(*vl)); blkfree(vl); break; default: break; } return (str); }
/*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 */
/* tw_prlist(): * Pretty print a list of variables */ static void tw_prlist(struct varent *p) { struct varent *c; for (;;) { while (p->v_left) p = p->v_left; x: if (p->v_parent == 0) /* is it the header? */ break; if (setintr) { int old_pintr_disabled; pintr_push_enable(&old_pintr_disabled); cleanup_until(&old_pintr_disabled); } xprintf("%s\t", short2str(p->v_name)); if (p->vec) tw_pr(p->vec); xputchar('\n'); if (p->v_right) { p = p->v_right; continue; } do { c = p; p = p->v_parent; } while (p->v_right == c); goto x; } } /* end tw_prlist */
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; }
/* * XXX: Should we worry about QUOTE'd chars? */ char * vis_str(Char *cp) { static char *sdst = NULL; static size_t dstsize = 0; size_t n; Char *dp; if (cp == NULL) return (NULL); for (dp = cp; *dp++;) continue; n = ((dp - cp) << 2) + 1; /* 4 times + NULL */ if (dstsize < n) { sdst = (char *) (dstsize ? xrealloc(sdst, (size_t) n * sizeof(char)) : xmalloc((size_t) n * sizeof(char))); dstsize = n; } /* * XXX: When we are in AsciiOnly we want all characters >= 0200 to * be encoded, but currently there is no way in vis to do that. */ (void) strnvis(sdst, short2str(cp), dstsize, VIS_NOSLASH); return (sdst); }
/* * dopopd - pop a directory out of the directory stack * with a numeric argument just discard it. */ void /*ARGSUSED*/ dopopd(Char **v, struct command *t) { struct directory *dp, *p = NULL; skipargs(&v, " [+<n>]"); printd = 1; if (*v == NULL) dp = dcwd; else if (v[1] != NULL) stderror(ERR_NAME | ERR_TOOMANY); else if ((dp = dfind(*v)) == 0) stderror(ERR_NAME | ERR_BADDIR); if (dp->di_prev == &dhead && dp->di_next == &dhead) stderror(ERR_NAME | ERR_EMPTY); if (dp == dcwd) { char *tmp; if ((p = dp->di_prev) == &dhead) p = dhead.di_prev; if (chdir(tmp = short2str(p->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); } dp->di_prev->di_next = dp->di_next; dp->di_next->di_prev = dp->di_prev; if (dp == dcwd) dnewcwd(p); else { printdirs(); } dfree(dp); }
int executable(const Char *dir, const Char *name, int dir_ok) { struct stat stbuf; Char path[MAXPATHLEN + 1]; char *strname; char extension[MAXPATHLEN]; char *ptr, *p2 ; int has_ext = 0; extern void copyn(Char *, const Char *, size_t); extern void catn(Char *, const Char *, int); (void) memset(path, 0, sizeof(path)); if (dir && *dir) { copyn(path, dir, MAXPATHLEN); catn(path, name, MAXPATHLEN); p2 = ptr = short2str(path); while (*ptr++) continue; --ptr; while(ptr > p2) { if (*ptr == '/') break; if (*ptr == '.') { has_ext = 1; StringCbCopy(extension,MAXPATHLEN,ptr+1); break; } ptr--; } if (!has_ext && (nt_stat(p2, &stbuf) == -1)) catn(path, STRdotEXE, MAXPATHLEN); strname = short2str(path); } else strname = short2str(name); return (stat(strname, &stbuf) != -1 && ((dir_ok && S_ISDIR(stbuf.st_mode)) || (S_ISREG(stbuf.st_mode) && (is_nt_executable(strname,extension) || (stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR))) ))); }
/* * dochngd - implement chdir command. */ void /*ARGSUSED*/ dochngd(Char **v, struct command *t) { Char *cp; struct directory *dp; skipargs(&v, " [<dir>]"); printd = 0; if (*v == NULL) { if ((cp = value(STRhome)) == NULL || *cp == 0) stderror(ERR_NAME | ERR_NOHOMEDIR); if (chdir(short2str(cp)) < 0) stderror(ERR_NAME | ERR_CANTCHANGE); cp = Strsave(cp); } else if (v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(*v)) != 0) { char *tmp; printd = 1; if (chdir(tmp = short2str(dp->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); dcwd->di_prev->di_next = dcwd->di_next; dcwd->di_next->di_prev = dcwd->di_prev; dfree(dcwd); dnewcwd(dp); return; } else cp = dfollow(*v); dp = xcalloc(1, sizeof(struct directory)); dp->di_name = cp; dp->di_count = 0; dp->di_next = dcwd->di_next; dp->di_prev = dcwd->di_prev; dp->di_prev->di_next = dp; dp->di_next->di_prev = dp; dfree(dcwd); dnewcwd(dp); }
/* * Source to the file which is the catenation of the argument names. */ static int srccat(Char *cp, Char *dp) { Char *ep = Strspl(cp, dp); char *ptr = short2str(ep); xfree(ep); return srcfile(ptr, mflag ? 0 : 1, 0); }
/* * 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); }
static int llib(Char *s) { short len = Strlen(s); status_$t st; char *t; loader_$inlib(t = short2str(s), len, &st); if (st.all != status_$ok) stderror(ERR_SYSTEM, t, apperr(&st)); }
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); } }
int getv(Char *v) { if (eq(v, STRbsd43)) return(1); else if (eq(v, STRsys53)) return(0); else stderror(ERR_NAME | ERR_SYSTEM, short2str(v), CGETS(23, 28, "Invalid system type")); /*NOTREACHED*/ return(0); }
/*ARGSUSED*/ void dosetxvers(Char **v, struct command *c) { char *xvers; ++v; if (!*v || *v[0] == '\0') xvers = ""; else xvers = short2str(*v); if (setxvers(xvers) == -1) stderror(ERR_SYSTEM, "setxvers", strerror(errno)); }
/*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 dorootnode(Char **v, struct command *c) { name_$dir_type_t dirtype = name_$node_dir_type; uid_$t uid; status_$t st; char *name; short namelen; setname(short2str(*v++)); name = short2str(*v); namelen = strlen(name); name_$resolve(name, &namelen, &uid, &st); if (st.all != status_$ok) stderror(ERR_SYSTEM, name, apperr(&st)); namelen = 0; name_$set_diru(&uid, "", &namelen, &dirtype, &st); if (st.all != status_$ok) stderror(ERR_SYSTEM, name, apperr(&st)); dohash(NULL, NULL); }
/*ARGSUSED*/ void dowarp(Char **v, struct command *c) { int warp, oldwarp; struct warpent *we; volatile struct sigaction old_sigsys_handler; char *newwarp; if (setjmp(sigsys_buf)) { sigaction(SIGSYS, &old_sigsys_handler, NULL); stderror(ERR_NAME | ERR_STRING, CGETS(23, 8, "You're trapped in a universe you never made")); return; } sigaction(SIGSYS, NULL, &old_sigsys_handler); signal(SIGSYS, catch_sigsys); warp = getwarp(); v++; if (*v == 0) { /* display warp value */ if (warp < 0) stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed")); we = getwarpbyvalue(warp); if (we) printf("%s\n", we->w_name); else printf("%d\n", warp); } else { /* set warp value */ oldwarp = warp; newwarp = short2str(*v); if (Isdigit(*v[0])) warp = atoi(newwarp); else { we = getwarpbyname(newwarp); if (we) warp = we->w_value; else warp = -1; } if ((warp < 0) || (warp >= WARP_MAXLINK)) stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp")); if ((setwarp(warp) < 0) || (getwarp() != warp)) { (void) setwarp(oldwarp); stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed")); } } sigaction(SIGSYS, &old_sigsys_handler, NULL); }
void prusage(FILE *fp, struct rusage *r0, struct rusage *r1, struct timespec *e, struct timespec *b) { struct varent *vp; const char *cp; vp = adrof(STRtime); if (vp && vp->vec[0] && vp->vec[1]) cp = short2str(vp->vec[1]); else cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; prusage1(fp, cp, r0, r1, e, b); }
void unset1(Char *v[], struct varent *head) { struct varent *vp; int cnt; while (*++v) { cnt = 0; while ((vp = madrof(*v, head)) != NULL) if (vp->v_flags & VAR_READONLY) stderror(ERR_READONLY|ERR_NAME, vp->v_name); else unsetv1(vp), cnt++; if (cnt == 0) setname(short2str(*v)); } }