int b_kill(int argc,char *argv[],void *extra) { register char *signame; register int sig=SIGTERM, flag=0, n; register Shell_t *shp = ((Shbltin_t*)extra)->shp; NOT_USED(argc); while((n = optget(argv,sh_optkill))) switch(n) { case ':': if((signame=argv[opt_info.index++]) && (sig=sig_number(signame+1))>=0) goto endopts; opt_info.index--; errormsg(SH_DICT,2, "%s", opt_info.arg); break; case 'n': sig = (int)opt_info.num; goto endopts; case 's': flag |= S_FLAG; signame = opt_info.arg; goto endopts; case 'l': flag |= L_FLAG; break; case '?': errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); break; } endopts: argv += opt_info.index; if(*argv && strcmp(*argv,"--")==0 && strcmp(*(argv-1),"--")!=0) argv++; if(error_info.errors || flag==(L_FLAG|S_FLAG) || (!(*argv) && !(flag&L_FLAG))) errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0)); /* just in case we send a kill -9 $$ */ sfsync(sfstderr); if(flag&L_FLAG) { if(!(*argv)) sig_list(shp,0); else while(signame = *argv++) { if(isdigit(*signame)) sig_list(shp,((int)strtol(signame, (char**)0, 10)&0177)+1); else { if((sig=sig_number(signame))<0) { shp->exitval = 2; errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame); } sfprintf(sfstdout,"%d\n",sig); } } return(shp->exitval); } if(flag&S_FLAG) { if((sig=sig_number(signame)) < 0 || sig > shp->sigmax) errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame); } if(job_walk(sfstdout,job_kill,sig,argv)) shp->exitval = 1; return(shp->exitval); }
static char* translate(const char* locale, const char* id, const char* catalog, const char* msg) { register int c; register int i; register char* s; register char* t; register char* e; register char* r; static char buf[8 * 1024]; static char rot[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMabcdefghijklmnopqrstuvwxyzabcdefghijklm"; sfprintf(sfstdout, "id=%s catalog=%s text=\"%s\"\n", id, catalog, msg); i = !catalog; s = (char*)msg; t = buf; e = buf + sizeof(buf) - 1; while ((c = *s++) && t < e) { switch (c) { case '\\': if (t < e) *t++ = c; if (!(c = *s++)) s--; break; case '%': do { if (t >= e) break; *t++ = c; if (!(c = *s++)) { s--; break; } } while (!isalpha(c) || (!islower(c) || c == 'h' || c == 'l') && (t < e) && isalpha(*s)); break; case '\b': do { if (t >= e) break; *t++ = c; if (!(c = *s++)) { s--; break; } } while (c != '\b'); break; default: if (r = strchr(rot, c)) { c = *(r + 13); if (i) c = isupper(c) ? tolower(c) : toupper(c); } break; } *t++ = c; } *t = 0; return streq(buf, msg) ? (char*)msg : buf; }
// 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; }
int csclient(Cs_t* cs, int fd, const char* service, const char* prompt, char** argv, unsigned int flags) { register int i; char* s; Sfio_t* tmp; int done; int promptlen; int timeout; ssize_t n; int sdf[2]; Cspoll_t fds[2]; char buf[8 * 1024]; if (fd < 0 && (fd = csopen(cs, service, CS_OPEN_TEST)) < 0) { if (errno == ENOENT) error(3, "%s: server not running", service); else error(ERROR_SYSTEM|3, "%s: cannot open connect stream", service); } #if _hdr_termios if (flags & CS_CLIENT_RAW) { tcgetattr(0, &state.old_term); atexit(restore); state.new_term = state.old_term; state.new_term.c_iflag &= ~(BRKINT|IGNPAR|PARMRK|INLCR|IGNCR|ICRNL); state.new_term.c_lflag &= ~(ECHO|ECHOK|ICANON|ISIG); state.new_term.c_cc[VTIME] = 0; state.new_term.c_cc[VMIN] = 1; tcsetattr(0, TCSANOW, &state.new_term); } #endif sdf[0] = fd; sdf[1] = 1; if (argv && *argv) { fds[0].fd = 1; fds[0].events = CS_POLL_WRITE; } else { argv = 0; fds[0].fd = 0; fds[0].events = CS_POLL_READ; } fds[1].fd = fd; fds[1].events = CS_POLL_READ; done = 0; if (promptlen = (!argv && prompt && isatty(fds[0].fd) && isatty(1)) ? strlen(prompt) : 0) write(1, prompt, promptlen); timeout = CS_NEVER; tmp = 0; while (cspoll(cs, fds, elementsof(fds), timeout) > 0) for (i = 0; i < elementsof(fds); i++) if (fds[i].status & (CS_POLL_READ|CS_POLL_WRITE)) { if (!i && argv) { if (!*argv) { argv = 0; fds[0].fd = 0; if (flags & CS_CLIENT_ARGV) { if (done++) return 0; timeout = 500; } fds[0].events = CS_POLL_READ; continue; } if (!tmp && !(tmp = sfstropen())) error(ERROR_SYSTEM|3, "out of space"); for (;;) { s = *argv++; if ((flags & CS_CLIENT_SEP) && *s == ':' && !*(s + 1)) break; if (sfstrtell(tmp)) sfputc(tmp, ' '); sfprintf(tmp, "%s", s); if (!(flags & CS_CLIENT_SEP) || !*argv) break; } sfputc(tmp, '\n'); n = sfstrtell(tmp); s = sfstruse(tmp); } else if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) < 0) error(ERROR_SYSTEM|3, "/dev/fd/%d: read error", fds[i].fd); if (!n) { if (done++) return 0; if (!i) write(sdf[i], "quit\n", 5); continue; } if (!i) { #if _hdr_termios register char* u; register int m; s[n] = 0; if ((u = strchr(s, 035))) { if ((m = u - s) > 0 && write(sdf[i], s, m) != m) error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]); tcsetattr(0, TCSANOW, &state.old_term); if (promptlen) write(1, prompt, promptlen); if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) <= 0) { write(1, "\n", 1); return 0; } buf[n - 1] = 0; if (*u == 'q' || *u == 'Q') return 0; tcsetattr(0, TCSANOW, &state.new_term); if (*u) error(1, "%s: unknown command", u); continue; } #endif } if (write(sdf[i], s, n) != n) error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]); if (sdf[i] == 1 && promptlen) write(1, prompt, promptlen); } return error_info.errors != 0; }
int main(int argc, char** argv) { int n; int ext; int ostr; int str; int loop; Info_t* ip; char* s; char* command; char* usage; char** extra; char** oargv; #if NEW Optdisc_t disc; #endif error_info.id = "opt"; setlocale(LC_ALL, ""); error(-1, "test"); extra = 0; ext = 0; str = 0; while (command = *(argv + 1)) { if (*command == '=' && (s = strchr(command + 1, '='))) { argv++; *s++ = 0; command++; if (ip = newof(0, Info_t, 1, 0)) { ip->name = command; ip->value = s; ip->next = info; info = ip; } } else if (streq(command, "-")) { argv++; str = NEW; } else if (streq(command, "-+")) { argv++; #if NEW ast.locale.set |= (1<<AST_LC_MESSAGES); error_info.translate = translate; #endif } else if (streq(command, "+") && *(argv + 2)) { ext += 2; argv += 2; if (!extra) extra = argv; } else break; } if (!(command = *++argv) || !(usage = *++argv)) error(ERROR_USAGE|4, "[ - | + usage ... ] command-name usage-string [ arg ... ]"); argv += str; error_info.id = command; #if NEW memset(&disc, 0, sizeof(disc)); disc.version = OPT_VERSION; disc.infof = infof; opt_info.disc = &disc; #else memset(&opt_info, 0, sizeof(opt_info)); #endif loop = strncmp(usage, "[-1c", 4) ? 0 : 3; oargv= argv; ostr = str; for (;;) { for (;;) { if (!str) { if (!(n = optget(argv, usage))) break; } else if (!(n = optstr(*argv, usage))) { if (!*++argv) break; continue; } if (loop) sfprintf(sfstdout, "[%d] ", loop); if (n == '?') { sfprintf(sfstdout, "return=%c option=%s name=%s num=%I*d\n", n, opt_info.option, opt_info.name, sizeof(opt_info.number), opt_info.number); error(ERROR_USAGE|4, "%s", opt_info.arg); } else if (n == ':') { sfprintf(sfstdout, "return=%c option=%s name=%s num=%I*d", n, opt_info.option, opt_info.name, sizeof(opt_info.number), opt_info.number); if (!opt_info.option[0]) sfprintf(sfstdout, " str=%s", argv[opt_info.index - 1]); sfputc(sfstdout, '\n'); error(2, "%s", opt_info.arg); } else if (n > 0) sfprintf(sfstdout, "return=%c option=%s name=%s arg%-.1s=%s num=%I*d\n", n, opt_info.option, opt_info.name, &opt_info.assignment, opt_info.arg, sizeof(opt_info.number), opt_info.number); else sfprintf(sfstdout, "return=%d option=%s name=%s arg%-.1s=%s num=%I*d\n", n, opt_info.option, opt_info.name, &opt_info.assignment, opt_info.arg, sizeof(opt_info.number), opt_info.number); if (extra) { for (n = 0; n < ext; n += 2) optget(NiL, extra[n]); extra = 0; } } if (!str && *(argv += opt_info.index)) while (command = *argv++) { if (loop) sfprintf(sfstdout, "[%d] ", loop); sfprintf(sfstdout, "argument=%d value=\"%s\"\n", ++str, command); } if (--loop <= 0) break; argv = oargv; str = ostr; opt_info.index = 0; } return error_info.errors != 0; }
static void commands(void) { register Line_t* a1; register int c; register int n; char* s; int lastsep; for (;;) { trap(); if (ed.print & (REG_SUB_LIST|REG_SUB_NUMBER|REG_SUB_PRINT)) { ed.addr1 = ed.addr2 = ed.dot; print(); } if (!ed.global) { ed.evented = 0; if (ed.prompt > 0) sfputr(ed.msg, sfstrbase(ed.buffer.prompt), -1); } if ((c = getchr()) == ',' || c == ';') { ed.given = 1; ed.addr1 = (lastsep = c) == ',' ? ed.zero + 1 : ed.dot; a1 = ed.dol; c = getchr(); } else { ed.addr1 = 0; ed.peekc = c; c = '\n'; for (;;) { lastsep = c; a1 = address(); c = getchr(); if (c != ',' && c != ';') break; if (lastsep == ',') error(2, "invalid address"); if (!a1) { a1 = ed.zero + 1; if (a1 > ed.dol) a1--; } ed.addr1 = a1; if (c == ';') ed.dot = a1; } if (lastsep != '\n' && !a1) a1 = ed.dol; } if (!(ed.addr2 = a1)) { ed.given = 0; ed.addr2 = ed.dot; } else ed.given = 1; if (!ed.addr1) ed.addr1 = ed.addr2; switch (c) { case 'a': add(0); continue; case 'c': nonzero(); newline(); rdelete(ed.addr1, ed.addr2); append(getline, ed.addr1 - 1, NiL); continue; case 'd': nonzero(); newline(); rdelete(ed.addr1, ed.addr2); continue; case 'E': ed.modified = 0; c = 'e'; /*FALLTHROUGH*/ case 'e': setnoaddr(); if (ed.verbose && ed.modified) { ed.modified = 0; error(2, "modified data not written"); } /*FALLTHROUGH*/ case 'r': filename(c); setwide(); squeeze(0); c = ed.zero != ed.dol; append(getfile, ed.addr2, NiL); ed.modified = c; exfile(); continue; case 'f': setnoaddr(); filename(c); putrec(sfstrbase(ed.buffer.file)); continue; case 'G': global(1, 1); continue; case 'g': global(1, 0); continue; case 'H': ed.help = !ed.help; /*FALLTHROUGH*/ case 'h': setnoaddr(); newline(); if (ed.help || c == 'h') sfputr(ed.msg, sfstrbase(ed.buffer.help), '\n'); continue; case 'i': add(-1); continue; case 'j': if (!ed.given) ed.addr2++; newline(); join(); continue; case 'k': nonzero(); if ((c = getchr()) == EOF || (c -= MARK_MIN) < 0 || c >= elementsof(ed.marks)) error(2, "invalid mark"); newline(); ed.addr2->offset |= LINE_MARKED; ed.marks[c] = ed.addr2->offset & ~LINE_GLOBAL; ed.marked = 1; continue; case 'm': move(0); continue; case 'n': ed.print |= REG_SUB_NUMBER; newline(); print(); continue; case '\n': if (!a1) { a1 = ed.dot + 1; ed.addr2 = a1; ed.addr1 = a1; } if (lastsep == ';') ed.addr1 = a1; print(); continue; case 'l': ed.print |= REG_SUB_LIST; /*FALLTHROUGH*/ case 'p': newline(); print(); continue; case 'P': setnoaddr(); s = getrec(ed.buffer.line, '\n', 0); if (*s || !(ed.prompt = -ed.prompt) && (s = "*")) { sfstrseek(ed.buffer.prompt, 0, SEEK_SET); sfputr(ed.buffer.prompt, s, 0); ed.prompt = 1; } continue; case 'Q': ed.modified = 0; /*FALLTHROUGH*/ case 'q': setnoaddr(); newline(); quit(0); continue; case 'S': setnoaddr(); newline(); s = strchr(usage, '\n') + 5; sfprintf(ed.msg, "file=\"%s\"%s%s%s prompt=\"%s\" tmp=%lu%s event=%lu version=\"%-.*s\"\n", sfstrbase(ed.buffer.file), ed.modified ? " modified" : "", ed.help ? " help" : "", ed.verbose ? " verbose" : "", sfstrbase(ed.buffer.prompt), ed.tmpoff, ed.tmpoff > BLOCK_TMP ? "[file]" : "", ed.event, strchr(s, '\n') - s, s); continue; case 's': nonzero(); substitute(ed.global != 0); continue; case 't': move(1); continue; case 'u': setnoaddr(); newline(); undo(); continue; case 'V': global(0, 1); continue; case 'v': global(0, 0); continue; case 'W': case 'w': setwide(); squeeze(ed.dol > ed.zero); if ((n = getchr()) != 'q' && n != 'Q') { ed.peekc = n; n = 0; } filename(c); if (ed.dol > ed.zero) putfile(); exfile(); if (n == 'Q' || ed.addr1 <= ed.zero + 1 && ed.addr2 == ed.dol) ed.modified = 0; if (n) quit(0); continue; case 'z': nonzero(); page(); continue; case '=': setwide(); squeeze(0); newline(); sfprintf(ed.msg, "%d\n", ed.addr2 - ed.zero); continue; case '!': if (ed.restricted) error(2, "%c: restricted command", c); shell(); continue; case '#': setnoaddr(); getrec(ed.buffer.line, '\n', REC_IGNORE); continue; case EOF: return; } error(2, "unknown command"); } }
void ppbuiltin(void) { register int c; register char* p; register char* a; int n; int op; char* token; char* t; long number; long onumber; struct ppinstk* in; struct pplist* list; struct ppsymbol* sym; Sfio_t* sp; number = pp.state; pp.state |= DISABLE|FILEPOP|NOSPACE; token = pp.token; p = pp.token = pp.tmpbuf; *(a = pp.args) = 0; if ((c = pplex()) != T_ID) { error(2, "%s: #(<identifier>...) expected", p); *p = 0; } switch (op = (int)hashget(pp.strtab, p)) { case V_DEFAULT: n = 0; p = pp.token = pp.valbuf; if ((c = pplex()) == ',') { op = -1; c = pplex(); } pp.state &= ~NOSPACE; for (;;) { if (!c) { error(2, "%s in #(...) argument", pptokchr(c)); break; } if (c == '(') n++; else if (c == ')' && !n--) break; else if (c == ',' && !n && op > 0) op = 0; if (op) pp.token = pp.toknxt; c = pplex(); } *pp.token = 0; pp.token = token; pp.state = number; break; case V_EMPTY: p = pp.valbuf; if ((c = pplex()) == ')') *p = '1'; else { *p = '0'; n = 0; for (;;) { if (!c) { error(2, "%s in #(...) argument", pptokchr(c)); break; } if (c == '(') n++; else if (c == ')' && !n--) break; c = pplex(); } } *(p + 1) = 0; pp.token = token; pp.state = number; break; case V_ITERATE: n = 0; pp.token = pp.valbuf; if ((c = pplex()) != T_ID || !(sym = ppsymref(pp.symtab, pp.token)) || !sym->macro || sym->macro->arity != 1 || (c = pplex()) != ',') { error(2, "#(%s <macro(x)>, ...) expected", p); for (;;) { if (!c) { error(2, "%s in #(...) argument", pptokchr(c)); break; } if (c == '(') n++; else if (c == ')' && !n--) break; c = pplex(); } *pp.valbuf = 0; } else while (c != ')') { p = pp.token; if (pp.token > pp.valbuf) *pp.token++ = ' '; STRCOPY(pp.token, sym->name, a); *pp.token++ = '('; if (!c || !(c = pplex())) { pp.token = p; error(2, "%s in #(...) argument", pptokchr(c)); break; } pp.state &= ~NOSPACE; while (c) { if (c == '(') n++; else if (c == ')' && !n--) break; else if (c == ',' && !n) break; pp.token = pp.toknxt; c = pplex(); } *pp.token++ = ')'; pp.state |= NOSPACE; } p = pp.valbuf; pp.token = token; pp.state = number; break; default: pp.token = token; while (c != ')') { if (!c) { error(2, "%s in #(...) argument", pptokchr(c)); break; } if ((c = pplex()) == T_ID && !*a) strcpy(a, pp.token); } pp.state = number; switch (op) { case V_ARGC: c = -1; for (in = pp.in; in; in = in->prev) if ((in->type == IN_MACRO || in->type == IN_MULTILINE) && (in->symbol->flags & SYM_FUNCTION)) { c = *((unsigned char*)(pp.macp->arg[0] - 2)); break; } sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", c); break; case V_BASE: p = (a = strrchr(error_info.file, '/')) ? a + 1 : error_info.file; break; case V_DATE: if (!(p = pp.date)) { time_t tm; time(&tm); a = p = ctime(&tm) + 4; *(p + 20) = 0; for (p += 7; *p = *(p + 9); p++); pp.date = p = strdup(a); } break; case V_FILE: p = error_info.file; break; case V_LINE: sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", error_info.line); break; case V_PATH: p = pp.path; break; case V_SOURCE: p = error_info.file; for (in = pp.in; in->prev; in = in->prev) if (in->prev->type == IN_FILE && in->file) p = in->file; break; case V_STDC: p = pp.valbuf; p[0] = ((pp.state & (COMPATIBILITY|TRANSITION)) || (pp.mode & (HOSTED|HOSTEDTRANSITION)) == (HOSTED|HOSTEDTRANSITION)) ? '0' : '1'; p[1] = 0; break; case V_TIME: if (!(p = pp.time)) { time_t tm; time(&tm); p = ctime(&tm) + 11; *(p + 8) = 0; pp.time = p = strdup(p); } break; case V_VERSION: p = (char*)pp.version; break; case V_DIRECTIVE: pp.state |= NEWLINE; pp.mode |= RELAX; strcpy(p = pp.valbuf, "#"); break; case V_GETENV: if (!(p = getenv(a))) p = ""; break; case V_GETMAC: p = (sym = pprefmac(a, REF_NORMAL)) ? sym->macro->value : ""; break; case V_GETOPT: sfsprintf(p = pp.valbuf, MAXTOKEN, "%ld", ppoption(a)); break; case V_GETPRD: p = (list = (struct pplist*)hashget(pp.prdtab, a)) ? list->value : ""; break; case V__PRAGMA: if ((c = pplex()) == '(') { number = pp.state; pp.state |= NOSPACE|STRIP; c = pplex(); pp.state = number; if (c == T_STRING || c == T_WSTRING) { if (!(sp = sfstropen())) error(3, "temporary buffer allocation error"); sfprintf(sp, "#%s %s\n", dirname(PRAGMA), pp.token); a = sfstruse(sp); if ((c = pplex()) == ')') { pp.state |= NEWLINE; PUSH_BUFFER(p, a, 1); } sfstrclose(sp); } } if (c != ')') error(2, "%s: (\"...\") expected", p); return; case V_FUNCTION: #define BACK(a,p) ((a>p)?*--a:(number++?0:((p=pp.outbuf+PPBUFSIZ),(a=pp.outbuf+2*PPBUFSIZ),*--a))) #define PEEK(a,p) ((a>p)?*(a-1):(number?0:*(pp.outbuf+2*PPBUFSIZ-1))) number = pp.outbuf != pp.outb; a = pp.outp; p = pp.outb; op = 0; while (c = BACK(a, p)) { if (c == '"' || c == '\'') { op = 0; while ((n = BACK(a, p)) && n != c || PEEK(a, p) == '\\'); } else if (c == '\n') { token = a; while (c = BACK(a, p)) if (c == '\n') { a = token; break; } else if (c == '#' && PEEK(a, p) == '\n') break; } else if (c == ' ') /*ignore*/; else if (c == '{') /* '}' */ op = 1; else if (op == 1) { if (c == ')') { op = 2; n = 1; } else op = 0; } else if (op == 2) { if (c == ')') n++; else if (c == '(' && !--n) op = 3; } else if (op == 3) { if (ppisidig(c)) { for (t = p, token = a, onumber = number; ppisidig(PEEK(a, p)) && a >= p; BACK(a, p)); p = pp.valbuf + 1; if (a > token) { for (; a < pp.outbuf+2*PPBUFSIZ; *p++ = *a++); a = pp.outbuf; } for (; a <= token; *p++ = *a++); *p = 0; p = pp.valbuf + 1; if (streq(p, "for") || streq(p, "if") || streq(p, "switch") || streq(p, "while")) { op = 0; p = t; number = onumber; continue; } } else op = 0; break; } } if (op == 3) p = strncpy(pp.funbuf, p, sizeof(pp.funbuf) - 1); else if (*pp.funbuf) p = pp.funbuf; else p = "__FUNCTION__"; break; default: if (pp.builtin && (a = (*pp.builtin)(pp.valbuf, p, a))) p = a; break; } break; } if (strchr(p, MARK)) { a = pp.tmpbuf; strcpy(a, p); c = p != pp.valbuf; p = pp.valbuf + c; for (;;) { if (p < pp.valbuf + MAXTOKEN - 2) switch (*p++ = *a++) { case 0: break; case MARK: *p++ = MARK; /*FALLTHROUGH*/ default: continue; } break; } p = pp.valbuf + c; } if (p == pp.valbuf) PUSH_STRING(p); else { if (p == pp.valbuf + 1) *pp.valbuf = '"'; else { if (strlen(p) > MAXTOKEN - 2) error(1, "%-.16s: builtin value truncated", p); sfsprintf(pp.valbuf, MAXTOKEN, "\"%-.*s", MAXTOKEN - 2, p); } PUSH_QUOTE(pp.valbuf, 1); } }
int main(int argc, char** argv) { char* op; char* s; int n; char name[80]; char passwd[PATH_MAX]; SERVICE_TABLE_ENTRY table[] = { {NULL, (LPSERVICE_MAIN_FUNCTION)csmain}, {NULL, NULL} }; OSVERSIONINFO osinfo; log_command = "ucs"; log_level = 1; osinfo.dwOSVersionInfoSize = sizeof(osinfo); if (!GetVersionEx(&osinfo) || osinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { logmsg(LOG_STDERR+0, "not supported for this windows release"); return 1; } logopen(log_command, 0); if ((s = *++argv) && (!_stricmp(s, "--quiet") || !_stricmp(s, "-q") || !_stricmp(s, "quiet"))) { quiet = 1; s = *++argv; } if ((op = s) && _stricmp(op, "start")) { if (s = *++argv) { strncpy(name, s, sizeof(name)); s = *++argv; } else { sfprintf(sfstderr, "Enter Account Name: "); sfscanf(sfstdin, "%s", name); } if (!_stricmp(op, "install")) { if (s && !strcmp(s, "-")) { passwd[0] = 0; if ((n = read(0, passwd, sizeof(passwd))) < 0) { logerr(LOG_STDERR+0, "read error"); return 1; } passwd[n] = 0; s = passwd; } if (!installservice(name, s)) { logerr(LOG_ALL+0, "install %s failed", name); return 1; } logmsg(1, "installed %s", name); } else if (!_stricmp(op, "delete")) { if (!deleteservice(name)) { logerr(LOG_ALL+0, "delete %s failed", name); return 1; } logmsg(1, "deleted %s", name); } else { logmsg(LOG_STDERR+LOG_USAGE+0, "[ --quiet ] [ start | [ delete | install [ name [ password ] ] ] ]"); return 2; } } else { getservname(); table[0].lpServiceName = servname; if (!StartServiceCtrlDispatcher(table)) eventlog("StartServiceCtrlDispatcher failed"); } logclose(); return 0; }
void printrecords (void) { vertex_t *vp; edge_t *ep; poly_t *pp; int ei; SUmessage (1, "printrecords", "printing data structures"); for ( vp = (vertex_t *) dtflatten (vertexdict); vp; vp = (vertex_t *) dtlink (vertexdict, vp) ) { sfprintf (sfstdout, "vertex: %x %d %d\n", vp, vp->xy.x, vp->xy.y); for (ei = 0; ei < vp->edgepl; ei++) sfprintf (sfstdout, "\tedge %d\n", vp->edgeps[ei]->tlid); } for ( ep = (edge_t *) dtflatten (edgedict); ep; ep = (edge_t *) dtlink (edgedict, ep) ) { sfprintf ( sfstdout, "edge: %d %s %s\n", ep->tlid, ep->sp->str, cfccid2str (ep->cfccid) ); sfprintf (sfstdout, "\tzip %d %d\n", ep->zipl, ep->zipr); sfprintf ( sfstdout, "\tnpanxxloc %d %d\n", ep->npanxxlocl, ep->npanxxlocr ); sfprintf (sfstdout, "\tstate %d %d\n", ep->statel, ep->stater); sfprintf (sfstdout, "\tcounty %d %d\n", ep->countyl, ep->countyr); sfprintf (sfstdout, "\tctbna %d %d\n", ep->ctbnal, ep->ctbnar); sfprintf (sfstdout, "\tblk %d %d\n", ep->blkl, ep->blkr); sfprintf (sfstdout, "\tblks %d %d\n", ep->blksl, ep->blksr); sfprintf ( sfstdout, "\tvertices %x/%d %x/%d\n", ep->v0p, ep->v0i, ep->v1p, ep->v1i ); if (ep->p0p) sfprintf ( sfstdout, "\tl poly %d-%d/%d\n", ep->p0p->cenid, ep->p0p->polyid, ep->p0i ); if (ep->p1p) sfprintf ( sfstdout, "\tr poly %d-%d/%d\n", ep->p1p->cenid, ep->p1p->polyid, ep->p1i ); } for ( pp = (poly_t *) dtflatten (polydict); pp; pp = (poly_t *) dtlink (polydict, pp) ) { sfprintf (sfstdout, "poly: %d-%d\n", pp->cenid, pp->polyid); for (ei = 0; ei < pp->edgepl; ei++) sfprintf (sfstdout, "\tedge %d\n", pp->edgeps[ei]->tlid); } }
static int doldd(const char* filename) { STARTUPINFO si; HANDLE ph; DEBUG_EVENT event; struct spawndata sdata; char* av[2]; pid_t pid; int status; int r = 0; char dllname[PATH_MAX+1]; char dllpath[PATH_MAX+1]; memset(&sdata, 0, sizeof(sdata)); memset(&si, 0, sizeof(si)); sdata.start = &si; sdata.flags = DEBUG_PROCESS; si.cb = sizeof(si); si.dwFlags = STARTF_FORCEONFEEDBACK|STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; av[0] = (char*)filename; av[1] = 0; if ((pid = uwin_spawn(filename, av, NULL, &sdata)) < 0) { error(ERROR_system(0), "%s cannot create process", filename); return -1; } ph = sdata.handle; for (;;) { if (!WaitForDebugEvent(&event, 1500)) break; if (event.dwProcessId != uwin_ntpid(pid)) continue; switch(event.dwDebugEventCode) { case EXIT_PROCESS_DEBUG_EVENT: CloseHandle(ph); ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); wait(&status); return 0; case LOAD_DLL_DEBUG_EVENT: if (event.u.LoadDll.hFile) { if (modulenamepath(ph, &event.u.LoadDll, dllname, sizeof(dllname), dllpath, sizeof(dllpath)) < 0) r = -1; else sfprintf(sfstdout, "\t%s => %s\n", dllname, dllpath); } ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); break; case CREATE_PROCESS_DEBUG_EVENT: ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); break; case CREATE_THREAD_DEBUG_EVENT: case EXCEPTION_DEBUG_EVENT: kill(pid, SIGTERM); ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_TERMINATE_PROCESS); break; default: ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); break; } } return 0; }
static void genvalue(Sfio_t *out, Shclass_t *sp, int indent, Namval_t *npar) { Shfield_t *fp = sp->fields; Namval_t *np, **nodes= (Namval_t**)(sp+1); register int i,isarray; if(out) { sfwrite(out,"(\n",2); indent++; } for(i=0; i < sp->nelem; i++,fp++) { #if 0 /* handle recursive case */ #endif if(!(np=nodes[i]) && out) np = sh_newnode(fp,npar); if(np) { isarray=0; if(nv_isattr(np,NV_ARRAY)) { isarray=1; if(array_elem(nv_arrayptr(np))==0) isarray=2; else nv_putsub(np,(char*)0,ARRAY_SCAN); } sfnputc(out,'\t',indent); sfputr(out,fp->name,(isarray==2?'\n':'=')); if(isarray) { if(isarray==2) continue; sfwrite(out,"(\n",2); sfnputc(out,'\t',++indent); } while(1) { char *fmtq; if(isarray) { sfprintf(out,"[%s]",sh_fmtq(nv_getsub(np))); sfputc(out,'='); } if(!(fmtq=nv_getval(np)) || !(fmtq=sh_fmtq(fmtq))) fmtq = ""; sfputr(out,fmtq,'\n'); if(!nv_nextsub(np)) break; sfnputc(out,'\t',indent); } if(isarray) { sfnputc(out,'\t',--indent); sfwrite(out,")\n",2); } } } if(out) { if(indent>1) sfnputc(out,'\t',indent-1); sfputc(out,')'); } }
static void error_exit(const char *message) { sfprintf(sfstdout,"%s: %s\n",command,message); exit(126); }
int main(int argc, char** argv) { register Mc_t* mc; register char* s; register char* t; register int c; register int q; register int i; int num; char* b; char* e; char* catfile; char* msgfile; Sfio_t* sp; Sfio_t* mp; Sfio_t* tp; Xl_t* px; Xl_t* bp; Xl_t* xp = 0; int format = 0; int list = 0; int set = 0; NoP(argc); error_info.id = "msggen"; for (;;) { switch (optget(argv, usage)) { case 'f': format = list = 1; continue; case 'l': list = 1; continue; case 's': set = 1; continue; case '?': error(ERROR_USAGE|4, "%s", opt_info.arg); continue; case ':': error(2, "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors || !(catfile = *argv++)) error(ERROR_USAGE|4, "%s", optusage(NiL)); /* * set and list only need catfile */ if (set) { sfprintf(sfstdout, "%d\n", mcindex(catfile, NiL, NiL, NiL)); return error_info.errors != 0; } else if (list) { if (!(sp = sfopen(NiL, catfile, "r"))) error(ERROR_SYSTEM|3, "%s: cannot read catalog", catfile); if (!(mc = mcopen(sp))) error(ERROR_SYSTEM|3, "%s: catalog content error", catfile); sfclose(sp); if (format) { for (set = 1; set <= mc->num; set++) if (mc->set[set].num) { sfprintf(sfstdout, "$set %d\n", set); for (num = 1; num <= mc->set[set].num; num++) if (s = mc->set[set].msg[num]) sfprintf(sfstdout, "%d \"%s\"\n", num, fmtfmt(s)); } } else { if (*mc->translation) { ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$translation "); sfprintf(sfstdout, "%s", mc->translation); ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\n"); } ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$quote \"\n"); for (set = 1; set <= mc->num; set++) if (mc->set[set].num) { ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "$set %d\n", set); for (num = 1; num <= mc->set[set].num; num++) if (s = mc->set[set].msg[num]) { ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "%d \"", num); while (c = *s++) { /*INDENT...*/ switch (c) { case 0x22: /* " */ case 0x5C: /* \ */ sfputc(sfstdout, 0x5C); break; case 0x07: /* \a */ c = 0x61; sfputc(sfstdout, 0x5C); break; case 0x08: /* \b */ c = 0x62; sfputc(sfstdout, 0x5C); break; case 0x0A: /* \n */ c = 0x6E; sfputc(sfstdout, 0x5C); break; case 0x0B: /* \v */ c = 0x76; sfputc(sfstdout, 0x5C); break; case 0x0C: /* \f */ c = 0x66; sfputc(sfstdout, 0x5C); break; case 0x0D: /* \r */ c = 0x72; sfputc(sfstdout, 0x5C); break; } /*...UNDENT*/ sfputc(sfstdout, c); } ccsfprintf(CC_NATIVE, CC_ASCII, sfstdout, "\"\n"); } } } mcclose(mc); return error_info.errors != 0; } else if (!(msgfile = *argv++) || *argv) error(3, "exactly one message file must be specified"); /* * open the files and handles */ if (!(tp = sfstropen())) error(ERROR_SYSTEM|3, "out of space [string stream]"); if (!(mp = sfopen(NiL, msgfile, "r"))) error(ERROR_SYSTEM|3, "%s: cannot read message file", msgfile); sp = sfopen(NiL, catfile, "r"); if (!(mc = mcopen(sp))) error(ERROR_SYSTEM|3, "%s: catalog content error", catfile); if (sp) sfclose(sp); xp = translation(xp, mc->translation); /* * read the message file */ q = 0; set = 1; error_info.file = msgfile; while (s = sfgetr(mp, '\n', 1)) { error_info.line++; if (!*s) continue; if (*s == '$') { if (!*++s || isspace(*s)) continue; for (t = s; *s && !isspace(*s); s++); if (*s) *s++ = 0; if (streq(t, "delset")) { while (isspace(*s)) s++; num = (int)strtol(s, NiL, 0); if (num < mc->num && mc->set[num].num) for (i = 1; i <= mc->set[num].num; i++) mcput(mc, num, i, NiL); } else if (streq(t, "quote")) q = *s ? *s : 0; else if (streq(t, "set")) { while (isspace(*s)) s++; num = (int)strtol(s, &e, 0); if (e != s) set = num; else error(2, "set number expected"); } else if (streq(t, "translation")) xp = translation(xp, s); } else { t = s + sfvalue(mp); num = (int)strtol(s, &e, 0); if (e != s) { s = e; if (!*s) { if (mcput(mc, set, num, NiL)) error(2, "(%d,%d): cannot delete message", set, num); } else if (isspace(*s++)) { if (t > (s + 1) && *(t -= 2) == '\\') { sfwrite(tp, s, t - s); while (s = sfgetr(mp, '\n', 0)) { error_info.line++; t = s + sfvalue(mp); if (t <= (s + 1) || *(t -= 2) != '\\') break; sfwrite(tp, s, t - s); } if (!(s = sfstruse(tp))) error(ERROR_SYSTEM|3, "out of space"); } if (q) { if (*s++ != q) { error(2, "(%d,%d): %c quote expected", set, num, q); continue; } b = t = s; while (c = *s++) { if (c == '\\') { c = chresc(s - 1, &e); s = e; if (c) *t++ = c; else error(1, "nul character ignored"); } else if (c == q) break; else *t++ = c; } if (*s) { error(2, "(%d,%d): characters after quote not expected", set, num); continue; } *t = 0; s = b; } if (mcput(mc, set, num, s)) error(2, "(%d,%d): cannot add message", set, num); } else error(2, "message text expected"); } else error(2, "message number expected"); } } error_info.file = 0; error_info.line = 0; /* * fix up the translation record */ if (xp) { t = ""; for (;;) { for (bp = 0, px = xp; px; px = px->next) if (px->date && (!bp || strcoll(bp->date, px->date) < 0)) bp = px; if (!bp) break; sfprintf(tp, "%s%s %s", t, bp->name, bp->date); t = ", "; bp->date = 0; } if (!(mc->translation = sfstruse(tp))) error(ERROR_SYSTEM|3, "out of space"); } /* * dump the catalog to a local temporary * rename if no errors */ if (!(s = pathtemp(NiL, 0, "", error_info.id, NiL)) || !(sp = sfopen(NiL, s, "w"))) error(ERROR_SYSTEM|3, "%s: cannot write catalog file", catfile); if (mcdump(mc, sp) || mcclose(mc) || sfclose(sp)) { remove(s); error(ERROR_SYSTEM|3, "%s: temporary catalog file write error", s); } remove(catfile); if (rename(s, catfile)) error(ERROR_SYSTEM|3, "%s: cannot rename from temporary catalog file %s", catfile, s); return error_info.errors != 0; }
static int actionf(register Css_t* css, register Cssfd_t* fp, Cssdisc_t* disc) { register State_t* state = (State_t*)disc; register Connection_t* con; register char* s; register char* t; int n; int i; switch (fp->status) { case CS_POLL_CLOSE: if (con = (Connection_t*)fp->data) { if (con->service) error(ERROR_SYSTEM|3, "service termination exit"); free(con); } return 0; case CS_POLL_READ: con = (Connection_t*)fp->data; if ((n = csread(css->state, fp->fd, buf, sizeof(buf) - 1, CS_LINE)) <= 0) { if (con->service) error(ERROR_SYSTEM|3, "service termination exit"); return -1; } buf[n] = 0; for (s = buf; isspace(*s); s++); if (con->service) { for (i = 0; isdigit(*s); i = i * 10 + *s++ - '0'); for (; isspace(*s); s++); if (*s && cssfd(css, i, 0)) { n -= s - buf; if (cswrite(css->state, i, s, n) != n) cssfd(css, i, CS_POLL_CLOSE); } } else if (*s == '!') { if ((n -= ++s - buf) > 0 && cswrite(css->state, state->proc->wfd, s, n) != n) return -1; } else { for (t = s; *t && !isspace(*t); t++); for (; isspace(*t); t++); if (*s == 'Q' && !*t) { if (con->id.uid == geteuid()) error(3, "service quit exit"); } else { n = sfprintf(state->tmp, "%-.*s%d %s", t - s, s, fp->fd, t); if (!(s = sfstruse(state->tmp))) return -1; if (cswrite(css->state, state->proc->wfd, s, n) != n) return -1; } } return 1; } return 0; }
int b_uname(int argc, char** argv, void* context) { register long flags = 0; register int sep = 0; register int n; register char* s; char* t; char* e; char* sethost = 0; int list = 0; struct utsname ut; char buf[257]; cmdinit(argc, argv, context, ERROR_CATALOG, 0); for (;;) { switch (optget(argv, usage)) { case 'a': flags |= OPT_all|((1L<<OPT_ALL)-1); continue; case 'b': flags |= OPT_base; continue; case 'c': flags |= OPT_vendor; continue; case 'd': flags |= OPT_domain; continue; case 'f': list = 1; continue; case 'h': flags |= OPT_hostid; continue; case 'i': flags |= OPT_implementation; continue; case 'm': flags |= OPT_machine; continue; case 'n': flags |= OPT_nodename; continue; case 'o': flags |= OPT_operating_system; continue; case 'p': flags |= OPT_processor; continue; case 'r': flags |= OPT_release; continue; case 's': flags |= OPT_system; continue; case 't': flags |= OPT_machine_type; continue; case 'v': flags |= OPT_version; continue; case 'x': flags |= OPT_extra; continue; case 'A': flags |= OPT_total|((1L<<OPT_TOTAL)-1); continue; case 'R': flags |= OPT_extended_release; continue; case 'S': sethost = opt_info.arg; continue; case ':': s = "/usr/bin/uname"; if (!streq(argv[0], s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK))) { argv[0] = s; return sh_run(context, argc, argv); } error(2, "%s", opt_info.arg); break; case '?': error(ERROR_usage(2), "%s", opt_info.arg); break; } break; } argv += opt_info.index; if (error_info.errors || *argv && (flags || sethost) || sethost && flags) error(ERROR_usage(2), "%s", optusage(NiL)); if (sethost) { #if _lib_sethostname if (sethostname(sethost, strlen(sethost) + 1)) #else #ifdef ENOSYS errno = ENOSYS; #else errno = EPERM; #endif #endif error(ERROR_system(1), "%s: cannot set host name", sethost); } else if (list) astconflist(sfstdout, NiL, ASTCONF_base|ASTCONF_defined|ASTCONF_lower|ASTCONF_quote|ASTCONF_matchcall, "CS|SI"); else if (*argv) { e = &buf[sizeof(buf)-1]; while (s = *argv++) { t = buf; *t++ = 'C'; *t++ = 'S'; *t++ = '_'; while (t < e && (n = *s++)) *t++ = islower(n) ? toupper(n) : n; *t = 0; sfprintf(sfstdout, "%s%c", *(t = astconf(buf, NiL, NiL)) ? t : *(t = astconf(buf+3, NiL, NiL)) ? t : "unknown", *argv ? ' ' : '\n'); } } else { s = buf; if (!flags) flags = OPT_system; memzero(&ut, sizeof(ut)); if (uname(&ut) < 0) error(ERROR_usage(2), "information unavailable"); output(OPT_system, ut.sysname, "sysname"); if (flags & OPT_nodename) { #if !_mem_nodeext_utsname && _lib_gethostname if (sizeof(ut.nodename) > 9 || gethostname(s, sizeof(buf))) #endif s = ut.nodename; output(OPT_nodename, s, "nodename"); } output(OPT_release, ut.release, "release"); output(OPT_version, ut.version, "version"); output(OPT_machine, ut.machine, "machine"); if (flags & OPT_processor) { if (!*(s = astconf("ARCHITECTURE", NiL, NiL))) s = ut.machine; output(OPT_processor, s, "processor"); } if (flags & OPT_implementation) { if (!*(s = astconf("PLATFORM", NiL, NiL)) && !*(s = astconf("HW_NAME", NiL, NiL))) { if (t = strchr(hosttype, '.')) t++; else t = (char*)hosttype; strncpy(s = buf, t, sizeof(buf) - 1); } output(OPT_implementation, s, "implementation"); } if (flags & OPT_operating_system) { s = astconf("OPERATING_SYSTEM", NiL, NiL); if (!*s) #ifdef _UNAME_os_DEFAULT s = _UNAME_os_DEFAULT; #else s = ut.sysname; #endif output(OPT_operating_system, s, "operating-system"); } if (flags & OPT_extended_release) { s = astconf("RELEASE", NiL, NiL); output(OPT_extended_release, s, "extended-release"); } #if _mem_idnumber_utsname output(OPT_hostid, ut.idnumber, "hostid"); #else if (flags & OPT_hostid) { if (!*(s = astconf("HW_SERIAL", NiL, NiL))) #if _lib_gethostid sfsprintf(s = buf, sizeof(buf), "%08x", gethostid()); #else /*NOP*/; #endif output(OPT_hostid, s, "hostid"); } #endif if (flags & OPT_vendor) { s = astconf("HW_PROVIDER", NiL, NiL); output(OPT_vendor, s, "vendor"); } if (flags & OPT_domain) { if (!*(s = astconf("SRPC_DOMAIN", NiL, NiL))) #if _lib_getdomainname getdomainname(s, sizeof(buf)); #else /*NOP*/; #endif output(OPT_domain, s, "domain"); } #if _mem_m_type_utsname s = ut.m_type; #else s = astconf("MACHINE", NiL, NiL); #endif output(OPT_machine_type, s, "m_type"); #if _mem_base_rel_utsname s = ut.base_rel; #else s = astconf("BASE", NiL, NiL); #endif output(OPT_base, s, "base_rel"); if (flags & OPT_extra) { char* last = (char*)&ut; extra(sysname); extra(nodename); extra(release); extra(version); extra(machine); #if _mem_idnumber_utsname extra(idnumber); #endif #if _mem_m_type_utsname extra(m_type); #endif #if _mem_base_rel_utsname extra(base_rel); #endif if (last < ((char*)(&ut + 1))) { s = t = last; while (s < (char*)(&ut + 1)) { if (!(n = *s++)) { if ((s - t) > 1) { if (sep) sfputc(sfstdout, ' '); else sep = 1; sfputr(sfstdout, t, -1); } t = s; } else if (!isprint(n)) break; } } } if (sep) sfputc(sfstdout, '\n'); } return error_info.errors; }
/* * open the history file * if HISTNAME is not given and userid==0 then no history file. * if login_sh and HISTFILE is longer than HIST_MAX bytes then it is * cleaned up. * hist_open() returns 1, if history file is open */ int sh_histinit(void *sh_context) { Shell_t *shp = (Shell_t*)sh_context; register int fd; register History_t *hp; register char *histname; char *fname=0; int histmask, maxlines, hist_start=0; register char *cp; register off_t hsize = 0; if(shgd->hist_ptr=hist_ptr) return(1); if(!(histname = nv_getval(HISTFILE))) { int offset = staktell(); if(cp=nv_getval(HOME)) stakputs(cp); stakputs(hist_fname); stakputc(0); stakseek(offset); histname = stakptr(offset); } #ifdef future if(hp=wasopen) { /* reuse history file if same name */ wasopen = 0; shgd->hist_ptr = hist_ptr = hp; if(strcmp(histname,hp->histname)==0) return(1); else hist_free(); } #endif retry: cp = path_relative(shp,histname); if(!histinit) histmode = S_IRUSR|S_IWUSR; if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT,histmode))>=0) { hsize=lseek(fd,(off_t)0,SEEK_END); } if((unsigned)fd <=2) { int n; if((n=fcntl(fd,F_DUPFD,10))>=0) { close(fd); fd=n; } } /* make sure that file has history file format */ if(hsize && hist_check(fd)) { close(fd); hsize = 0; if(unlink(cp)>=0) goto retry; fd = -1; } if(fd < 0) { #if KSHELL /* don't allow root a history_file in /tmp */ if(shgd->userid) #endif /* KSHELL */ { if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*)))) return(0); fd = open(fname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR); } } if(fd<0) return(0); /* set the file to close-on-exec */ fcntl(fd,F_SETFD,FD_CLOEXEC); if(cp=nv_getval(HISTSIZE)) maxlines = (unsigned)strtol(cp, (char**)0, 10); else maxlines = HIST_DFLT; for(histmask=16;histmask <= maxlines; histmask <<=1 ); if(!(hp=new_of(History_t,(--histmask)*sizeof(off_t)))) { close(fd); return(0); } shgd->hist_ptr = hist_ptr = hp; hp->histshell = (void*)shp; hp->histsize = maxlines; hp->histmask = histmask; hp->histfp= sfnew(NIL(Sfio_t*),hp->histbuff,HIST_BSIZE,fd,SF_READ|SF_WRITE|SF_APPENDWR|SF_SHARE); memset((char*)hp->histcmds,0,sizeof(off_t)*(hp->histmask+1)); hp->histind = 1; hp->histcmds[1] = 2; hp->histcnt = 2; hp->histname = strdup(histname); hp->histdisc = hist_disc; if(hsize==0) { /* put special characters at front of file */ sfwrite(hp->histfp,(char*)hist_stamp,2); sfsync(hp->histfp); } /* initialize history list */ else { int first,last; off_t mark,size = (HIST_MAX/4)+maxlines*HIST_LINE; hp->histind = first = hist_nearend(hp,hp->histfp,hsize-size); histinit = 1; hist_eof(hp); /* this sets histind to last command */ if((hist_start = (last=(int)hp->histind)-maxlines) <=0) hist_start = 1; mark = hp->histmarker; while(first > hist_start) { size += size; first = hist_nearend(hp,hp->histfp,hsize-size); hp->histind = first; } histinit = hist_start; hist_eof(hp); if(!histinit) { sfseek(hp->histfp,hp->histcnt=hsize,SEEK_SET); hp->histind = last; hp->histmarker = mark; } histinit = 0; } if(fname) { unlink(fname); free((void*)fname); } if(hist_clean(fd) && hist_start>1 && hsize > HIST_MAX) { #ifdef DEBUG sfprintf(sfstderr,"%d: hist_trim hsize=%d\n",getpid(),hsize); sfsync(sfstderr); #endif /* DEBUG */ hp = hist_trim(hp,(int)hp->histind-maxlines); } sfdisc(hp->histfp,&hp->histdisc); #if KSHELL (HISTCUR)->nvalue.lp = (&hp->histind); #endif /* KSHELL */ sh_timeradd(1000L*(HIST_RECENT-30), 1, hist_touch, (void*)hp->histname); #if SHOPT_ACCTFILE if(sh_isstate(SH_INTERACTIVE)) acctinit(hp); #endif /* SHOPT_ACCTFILE */ #if SHOPT_AUDIT { char buff[SF_BUFSIZE]; hp->auditfp = 0; if(sh_isstate(SH_INTERACTIVE) && (hp->auditmask=sh_checkaudit(hp,SHOPT_AUDITFILE, buff, sizeof(buff)))) { if((fd=sh_open(buff,O_BINARY|O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR))>=0 && fd < 10) { int n; if((n = sh_fcntl(fd,F_DUPFD, 10)) >= 0) { sh_close(fd); fd = n; } } if(fd>=0) { fcntl(fd,F_SETFD,FD_CLOEXEC); hp->tty = strdup(ttyname(2)); hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE); } } } #endif return(1); }
static void shell(void) { register char* s; register char* f = 0; register int c; if (ed.given) squeeze(ed.dol > ed.zero); s = getrec(ed.buffer.line, '\n', 0); if (s[0] == '!' && !s[1]) { if (!*sfstrbase(ed.buffer.shell)) error(2, "no saved shell command"); f = sfstrbase(ed.buffer.file); } else if (!s[0]) error(2, "empty shell command"); else SWP(ed.buffer.shell, ed.buffer.line); s = sfstrbase(ed.buffer.shell); sfstrseek(ed.buffer.line, 0, SEEK_SET); sfputc(ed.buffer.line, '!'); while (c = *s++) { if (c == '\\') { if (*s != '%') sfputc(ed.buffer.line, c); sfputc(ed.buffer.line, *s++); } else if (c == '%') sfputr(ed.buffer.line, f = sfstrbase(ed.buffer.file), -1); else sfputc(ed.buffer.line, c); } if (ed.given) { if (!ed.tmpfile && !(ed.tmpfile = pathtemp(NiL, 0, NiL, error_info.id, NiL))) error(ERROR_SYSTEM|2, "cannot generate temp file name"); if (!(ed.iop = sfopen(NiL, ed.tmpfile, "w"))) error(ERROR_SYSTEM|2, "%s: cannot create temp file", ed.tmpfile); error_info.file = ed.tmpfile; if (ed.dol > ed.zero) putfile(); exfile(); ed.bytes = 0; ed.lines = 0; sfprintf(ed.buffer.line, " < %s", ed.tmpfile); if (!(s = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); if (!(ed.iop = sfpopen(NiL, s + 1, "r"))) error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s); error_info.file = s; rdelete(ed.addr1, ed.addr2); append(getfile, ed.dot, NiL); exfile(); remove(ed.tmpfile); } else { if (!(s = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); s++; if (f) putrec(s); if (!(ed.iop = sfpopen(NiL, s, ""))) error(ERROR_SYSTEM|2, "%s: cannot execute shell command", s); if (sfclose(ed.iop)) { ed.iop = 0; error(ERROR_SYSTEM|2, "%s: shell command exit error", s); } if (ed.verbose) putrec("!"); } }
int b_ulimit(int argc,char *argv[],void *extra) { register char *limit; register int mode=0, n; register unsigned long hit = 0; Shell_t *shp = ((Shbltin_t*)extra)->shp; #ifdef _lib_getrlimit struct rlimit rlp; #endif /* _lib_getrlimit */ const Limit_t* tp; char* conf; int label, unit, nosupport; rlim_t i; char tmp[32]; Optdisc_t disc; memset(&disc, 0, sizeof(disc)); disc.version = OPT_VERSION; disc.infof = infof; opt_info.disc = &disc; while((n = optget(argv,sh_optulimit))) switch(n) { case 'H': mode |= HARD; continue; case 'S': mode |= SOFT; continue; case 'a': hit = ~0; break; default: if(n < 0) hit |= (1L<<(-(n+1))); else errormsg(SH_DICT,2, e_notimp, opt_info.name); break; case ':': errormsg(SH_DICT,2, "%s", opt_info.arg); break; case '?': errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); break; } opt_info.disc = 0; /* default to -f */ limit = argv[opt_info.index]; if(hit==0) for(n=0; shtab_limits[n].option; n++) if(shtab_limits[n].index == RLIMIT_FSIZE) { hit |= (1L<<n); break; } /* only one option at a time for setting */ label = (hit&(hit-1)); if(error_info.errors || (limit && label) || argc>opt_info.index+1) errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0)); if(mode==0) mode = (HARD|SOFT); for(tp = shtab_limits; tp->option && hit; tp++,hit>>=1) { if(!(hit&1)) continue; nosupport = (n = tp->index) == RLIMIT_UNKNOWN; unit = shtab_units[tp->type]; if(limit) { if(shp->subshell && !shp->subshare) sh_subfork(); if(strcmp(limit,e_unlimited)==0) i = INFINITY; else { char *last; if((i=sh_strnum(limit,&last,2))==INFINITY || *last) errormsg(SH_DICT,ERROR_system(1),e_number,limit); i *= unit; } if(nosupport) errormsg(SH_DICT,ERROR_system(1),e_readonly,tp->name); else { #ifdef _lib_getrlimit if(getrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); if(mode&HARD) rlp.rlim_max = i; if(mode&SOFT) rlp.rlim_cur = i; if(setrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_overlimit,limit); #else if((i=vlimit(n,i)) < 0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); #endif /* _lib_getrlimit */ } } else { if(!nosupport) { #ifdef _lib_getrlimit if(getrlimit(n,&rlp) <0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); if(mode&HARD) i = rlp.rlim_max; if(mode&SOFT) i = rlp.rlim_cur; #else # ifdef _lib_ulimit n--; # endif /* _lib_ulimit */ i = -1; if((i=vlimit(n,i)) < 0) errormsg(SH_DICT,ERROR_system(1),e_number,limit); #endif /* _lib_getrlimit */ } if(label) { if(tp->type != LIM_COUNT) sfsprintf(tmp,sizeof(tmp),"%s (%ss)", tp->description, e_units[tp->type]); else sfsprintf(tmp,sizeof(tmp),"%s", tp->name); sfprintf(sfstdout,"%-30s (-%c) ",tmp,tp->option); } if(nosupport) { if(!tp->conf || !*(conf = astconf(tp->conf, NiL, NiL))) conf = (char*)e_nosupport; sfputr(sfstdout,conf,'\n'); } else if(i!=INFINITY) { i += (unit-1); sfprintf(sfstdout,"%I*d\n",sizeof(i),i/unit); } else sfputr(sfstdout,e_unlimited,'\n'); } } return(0); }
int main(int argc, char** argv) { char* s; NoP(argc); if (s = strrchr(*argv, '/')) s++; else s = *argv; ed.restricted = streq(s, "red"); error_info.id = s; error_info.write = helpwrite; init(); for (;;) { for (;;) { switch (optget(argv, usage)) { case 'O': ed.reflags |= REG_LENIENT; continue; case 'S': ed.reflags &= ~REG_LENIENT; continue; case 'h': ed.help = 1; continue; case 'o': ed.msg = sfstderr; sfstrseek(ed.buffer.file, 0, SEEK_SET); sfputr(ed.buffer.file, "/dev/stdout", 0); continue; case 'p': sfstrseek(ed.buffer.prompt, 0, SEEK_SET); sfputr(ed.buffer.prompt, opt_info.arg, 0); ed.prompt = 1; continue; case 'q': signal(SIGQUIT, SIG_DFL); ed.verbose = 1; continue; case 's': ed.verbose = 0; continue; case '?': ed.help++; error(ERROR_USAGE|4, "%s", opt_info.arg); ed.help--; break; case ':': ed.help++; error(2, "%s", opt_info.arg); ed.help--; continue; } break; } if (!*(argv += opt_info.index) || **argv != '-' || *(*argv + 1)) break; ed.verbose = 0; } if (*argv) { if (*(argv + 1)) error(ERROR_USAGE|4, "%s", optusage(NiL)); sfprintf(ed.buffer.global, "e %s", *argv); if (!(ed.global = sfstruse(ed.buffer.global))) error(ERROR_SYSTEM|3, "out of space"); } edit(); sfdcslow(sfstdin); setjmp(ed.again); commands(); quit(0); exit(0); }
static int savepolys (char *dir, char *prefix) { char *fname; Sfio_t *fp; item_t *itemp; int itempi; int indi; int pointi, pointj; fname = strdup (sfprints ("%s/%s_polys.ps", dir, prefix)); SUmessage (1, "savepolys", "saving file %s", fname); if (!(fp = sfopen (NULL, fname, "w"))) { SUwarning (1, "savepolys", "open failed for %s", fname); return -1; } sfprintf (fp, "%%!PS\n"); sfprintf (fp, "8 72 mul 10 72 mul scale 0 setlinewidth\n"); sfprintf (fp, "/n { newpath } def\n"); sfprintf (fp, "/m { moveto } def\n"); sfprintf (fp, "/l { lineto } def\n"); sfprintf (fp, "/p { /y exch def /x exch def x y moveto x y lineto } def\n"); sfprintf (fp, "/s { closepath stroke } def\n"); sfprintf (fp, "/f { closepath fill } def\n"); /* (x, y, z) of each point */ for (itempi = 0; itempi < itempn; itempi++) { itemp = itemps[itempi]; if (itemp->pointn == 0) continue; for (pointi = 0, indi = 0; indi < itemp->indn; indi++) { sfprintf ( fp, "n %f %f m\n", X (itemp->points[pointi].x), Y (itemp->points[pointi].y) ); pointi++; for (pointj = 1; pointj < itemp->inds[indi]; pointi++, pointj++) sfprintf ( fp, "%f %f l\n", X (itemp->points[pointi].x), Y (itemp->points[pointi].y) ); sfprintf (fp, "s\n"); } } sfprintf (fp, "showpage\n"); sfclose (fp); return 0; }
int b_date(int argc, register char** argv, void* context) { register int n; register char* s; register Fmt_t* f; char* t; unsigned long u; Time_t now; Time_t ts; Time_t te; Time_t e; char buf[1024]; Fmt_t* fmts; Fmt_t fmt; struct stat st; char* cmd = argv[0]; /* original command path */ char* format = 0; /* tmxfmt() format */ char* string = 0; /* date string */ int elapsed = 0; /* args are start/stop pairs */ int filetime = 0; /* use this st_ time field */ int increment = 0; /* incrementally adjust time */ int last = 0; /* display the last time arg */ Tm_zone_t* listzones = 0; /* known time zone table */ int network = 0; /* don't set network time */ int show = 0; /* show date and don't set */ int unelapsed = 0; /* fmtelapsed() => strelapsed */ cmdinit(argc, argv, context, ERROR_CATALOG, 0); tm_info.flags = TM_DATESTYLE; fmts = &fmt; fmt.format = ""; fmt.next = 0; for (;;) { switch (optget(argv, usage)) { case 'a': case 'c': case 'm': filetime = opt_info.option[1]; continue; case 'd': string = opt_info.arg; show = 1; continue; case 'e': format = "%#"; continue; case 'E': elapsed = 1; continue; case 'f': format = opt_info.arg; continue; case 'i': increment = 1; continue; case 'l': tm_info.flags |= TM_LEAP; continue; case 'L': last = 1; continue; case 'n': network = 1; continue; case 'p': if (!(f = newof(0, Fmt_t, 1, 0))) error(ERROR_SYSTEM|3, "out of space [format]"); f->next = fmts; f->format = opt_info.arg; fmts = f; continue; case 's': show = 1; continue; case 'u': tm_info.flags |= TM_UTC; continue; case 'U': unelapsed = (int)opt_info.num; continue; case 'z': listzones = tm_data.zone; continue; case '?': error(ERROR_USAGE|4, "%s", opt_info.arg); continue; case ':': error(2, "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors) error(ERROR_USAGE|4, "%s", optusage(NiL)); now = tmxgettime(); if (listzones) { s = "-"; while (listzones->standard) { if (listzones->type) s = listzones->type; sfprintf(sfstdout, "%3s %4s %4s %4d %4d\n", s, *listzones->standard ? listzones->standard : "-", listzones->daylight ? listzones->daylight : "-", listzones->west, listzones->dst); listzones++; show = 1; } } else if (elapsed) { e = 0; while (s = *argv++) { if (!(t = *argv++)) { argv--; t = "now"; } ts = convert(fmts, s, now); te = convert(fmts, t, now); if (te > ts) e += te - ts; else e += ts - te; } sfputr(sfstdout, fmtelapsed((unsigned long)tmxsec(e), 1), '\n'); show = 1; } else if (unelapsed) { while (s = *argv++) { u = strelapsed(s, &t, unelapsed); if (*t) error(3, "%s: invalid elapsed time", s); sfprintf(sfstdout, "%lu\n", u); } show = 1; } else if (filetime) { if (!*argv) error(ERROR_USAGE|4, "%s", optusage(NiL)); n = argv[1] != 0; while (s = *argv++) { if (stat(s, &st)) error(2, "%s: not found", s); else { switch (filetime) { case 'a': now = tmxgetatime(&st); break; case 'c': now = tmxgetctime(&st); break; default: now = tmxgetmtime(&st); break; } tmxfmt(buf, sizeof(buf), format, now); if (n) sfprintf(sfstdout, "%s: %s\n", s, buf); else sfprintf(sfstdout, "%s\n", buf); show = 1; } } } else { if ((s = *argv) && !format && *s == '+') { format = s + 1; argv++; s = *argv; } if (s || (s = string)) { if (*argv && string) error(ERROR_USAGE|4, "%s", optusage(NiL)); now = convert(fmts, s, now); if (*argv && (s = *++argv)) { show = 1; do { if (!last) { tmxfmt(buf, sizeof(buf), format, now); sfprintf(sfstdout, "%s\n", buf); } now = convert(fmts, s, now); } while (s = *++argv); } } else show = 1; if (format || show) { tmxfmt(buf, sizeof(buf), format, now); sfprintf(sfstdout, "%s\n", buf); } else if (settime(context, cmd, now, increment, network)) error(ERROR_SYSTEM|3, "cannot set system time"); } while (fmts != &fmt) { f = fmts; fmts = fmts->next; free(f); } tm_info.flags = 0; if (show && sfsync(sfstdout)) error(ERROR_system(0), "write error"); return error_info.errors != 0; }
static int printbbox (void) { sfprintf ( sfstdout, "bbox: %f %f 0 %f %f 0\n", minp.x, minp.y, maxp.x, maxp.y ); return 0; }
void errorv(const char* id, int level, va_list ap) { register int n; int fd; int flags; char* s; char* t; char* format; char* library; const char* catalog; int line; char* file; #if !_PACKAGE_astsa unsigned long d; struct tms us; #endif if (!error_info.init) { error_info.init = 1; stropt(getenv("ERROR_OPTIONS"), options, sizeof(*options), setopt, NiL); } if (level > 0) { flags = level & ~ERROR_LEVEL; level &= ERROR_LEVEL; } else flags = 0; if ((flags & (ERROR_USAGE|ERROR_NOID)) == ERROR_NOID) { format = (char*)id; id = 0; } else format = 0; if (id) { catalog = (char*)id; if (!*catalog || *catalog == ':') { catalog = 0; library = 0; } else if ((library = strchr(catalog, ':')) && !*++library) library = 0; } else { catalog = 0; library = 0; } if (catalog) id = 0; else { id = (const char*)error_info.id; catalog = error_info.catalog; } if (level < error_info.trace || (flags & ERROR_LIBRARY) && !(((error_info.set | error_info.flags) ^ error_info.clear) & ERROR_LIBRARY) || level < 0 && error_info.mask && !(error_info.mask & (1<<(-level - 1)))) { if (level >= ERROR_FATAL) (*error_info.exit)(level - 1); return; } if (error_info.trace < 0) flags |= ERROR_LIBRARY|ERROR_SYSTEM; flags |= error_info.set | error_info.flags; flags &= ~error_info.clear; if (!library) flags &= ~ERROR_LIBRARY; fd = (flags & ERROR_OUTPUT) ? va_arg(ap, int) : error_info.fd; if (error_info.write) { long off; char* bas; bas = stkptr(stkstd, 0); if (off = stktell(stkstd)) stkfreeze(stkstd, 0); file = error_info.id; if (error_state.prefix) sfprintf(stkstd, "%s: ", error_state.prefix); if (flags & ERROR_USAGE) { if (flags & ERROR_NOID) sfprintf(stkstd, " "); else sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "Usage")); if (file || opt_info.argv && (file = opt_info.argv[0])) print(stkstd, file, " "); } else { if (level && !(flags & ERROR_NOID)) { if (error_info.context && level > 0) context(stkstd, CONTEXT(error_info.flags, error_info.context)); if (file) print(stkstd, file, (flags & ERROR_LIBRARY) ? " " : ": "); if (flags & (ERROR_CATALOG|ERROR_LIBRARY)) { sfprintf(stkstd, "["); if (flags & ERROR_CATALOG) sfprintf(stkstd, "%s %s%s", catalog ? catalog : ERROR_translate(NiL, NiL, ast.id, "DEFAULT"), ERROR_translate(NiL, NiL, ast.id, "catalog"), (flags & ERROR_LIBRARY) ? ", " : ""); if (flags & ERROR_LIBRARY) sfprintf(stkstd, "%s %s", library, ERROR_translate(NiL, NiL, ast.id, "library")); sfprintf(stkstd, "]: "); } } if (level > 0 && error_info.line > ((flags & ERROR_INTERACTIVE) != 0)) { if (error_info.file && *error_info.file) sfprintf(stkstd, "\"%s\", ", error_info.file); sfprintf(stkstd, "%s %d: ", ERROR_translate(NiL, NiL, ast.id, "line"), error_info.line); } } #if !_PACKAGE_astsa if (error_info.time) { if ((d = times(&us)) < error_info.time || error_info.time == 1) error_info.time = d; sfprintf(stkstd, " %05lu.%05lu.%05lu ", d - error_info.time, (unsigned long)us.tms_utime, (unsigned long)us.tms_stime); } #endif switch (level) { case 0: flags &= ~ERROR_SYSTEM; break; case ERROR_WARNING: sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "warning")); break; case ERROR_PANIC: sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "panic")); break; default: if (level < 0) { s = ERROR_translate(NiL, NiL, ast.id, "debug"); if (error_info.trace < -1) sfprintf(stkstd, "%s%d:%s", s, level, level > -10 ? " " : ""); else sfprintf(stkstd, "%s: ", s); for (n = 0; n < error_info.indent; n++) { sfputc(stkstd, ' '); sfputc(stkstd, ' '); } } break; } if (flags & ERROR_SOURCE) { /* * source ([version], file, line) message */ file = va_arg(ap, char*); line = va_arg(ap, int); s = ERROR_translate(NiL, NiL, ast.id, "line"); if (error_info.version) sfprintf(stkstd, "(%s: \"%s\", %s %d) ", error_info.version, file, s, line); else sfprintf(stkstd, "(\"%s\", %s %d) ", file, s, line); }
static int whence(Shell_t *shp,char **argv, register int flags) { register const char *name; register Namval_t *np; register const char *cp; register int aflag,r=0; register const char *msg; int tofree; Dt_t *root; Namval_t *nq; char *notused; Pathcomp_t *pp=0; int notrack = 1; if(flags&Q_FLAG) flags &= ~A_FLAG; while(name= *argv++) { tofree=0; aflag = ((flags&A_FLAG)!=0); cp = 0; np = 0; if(flags&P_FLAG) goto search; if(flags&Q_FLAG) goto bltins; /* reserved words first */ if(sh_lookup(name,shtab_reserved)) { sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):""); if(!aflag) continue; aflag++; } /* non-tracked aliases */ if((np=nv_search(name,shp->alias_tree,0)) && !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED)) && (cp=nv_getval(np))) { if(flags&V_FLAG) { if(nv_isattr(np,NV_EXPORT)) msg = sh_translate(is_xalias); else msg = sh_translate(is_alias); sfprintf(sfstdout,msg,name); } sfputr(sfstdout,sh_fmtq(cp),'\n'); if(!aflag) continue; cp = 0; aflag++; } /* built-ins and functions next */ bltins: root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree; if(np= nv_bfsearch(name, root, &nq, ¬used)) { if(is_abuiltin(np) && nv_isnull(np)) goto search; cp = ""; if(flags&V_FLAG) { if(nv_isnull(np)) cp = sh_translate(is_ufunction); else if(is_abuiltin(np)) { if(nv_isattr(np,BLT_SPC)) cp = sh_translate(is_spcbuiltin); else cp = sh_translate(is_builtin); } else cp = sh_translate(is_function); } if(flags&Q_FLAG) continue; sfprintf(sfstdout,"%s%s\n",name,cp); if(!aflag) continue; cp = 0; aflag++; } search: if(sh_isstate(SH_DEFPATH)) { cp=0; notrack=1; } do { if(path_search(shp,name,&pp,2+(aflag>1))) { cp = name; if((flags&P_FLAG) && *cp!='/') cp = 0; } else { cp = stakptr(PATH_OFFSET); if(*cp==0) cp = 0; else if(*cp!='/') { cp = path_fullname(shp,cp); tofree=1; } } if(flags&Q_FLAG) { pp = 0; r |= !cp; } else if(cp) { if(flags&V_FLAG) { if(*cp!= '/') { if(!np && (np=nv_search(name,shp->track_tree,0))) sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(shp,0),cp); else if(!np || nv_isnull(np)) sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction)); continue; } sfputr(sfstdout,sh_fmtq(name),' '); /* built-in version of program */ if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0))) msg = sh_translate(is_builtver); /* tracked aliases next */ else if(aflag>1 || !notrack || strchr(name,'/')) msg = sh_translate("is"); else msg = sh_translate(is_talias); sfputr(sfstdout,msg,' '); } sfputr(sfstdout,sh_fmtq(cp),'\n'); if(aflag) { if(aflag<=1) aflag++; if (pp) pp = pp->next; } else pp = 0; if(tofree) { free((char*)cp); tofree = 0; } } else if(aflag<=1) { r |= 1; if(flags&V_FLAG) errormsg(SH_DICT,ERROR_exit(0),e_found,sh_fmtq(name)); } } while(pp); } return(r); }
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp) { Info_t* ip; for (ip = info; ip; ip = ip->next) if (streq(s, ip->name)) return sfprintf(sp, "%s", ip->value); if (*s == ':') return sfprintf(sp, "%s", *(s + 1) == 'n' ? "" : (s + 2)); if (streq(s, "options")) return sfprintf(sp, "[Z:zoom?Do it as fast as possible.]\fmore#1\f\fmore#2\f[B:boom?Dump into \afile\a.]:[file]"); if (streq(s, "zero")) return sfprintf(sp, "[+yabba?dabba][+doo?aroni]"); if (streq(s, "more#1")) return sfprintf(sp, "[C:cram?Cram as much as possible.]\fmore#3\f"); if (streq(s, "more#2")) return sfprintf(sp, "\fmore#4\f[D:dump?Dump as much as possible.]"); if (streq(s, "more#3")) return sfprintf(sp, "[K:kill?kill all processes.]"); if (streq(s, "more#4")) return sfprintf(sp, "[F:fudge?Fudge the statistics to satisfy everyone.]"); if (streq(s, "more#5")) return sfprintf(sp, "\bred\b, \borange\b, \byellow\b, \bgreen\b, \bblue\b, \bindigo\b, \bviolet\b"); if (streq(s, "more#6")) return sfprintf(sp, "\bred\b"); return sfprintf(sp, "<* %s info ok *>", s); }
char* translate(const char* loc, const char* cmd, const char* cat, const char* msg) { register char* r; char* t; int p; int oerrno; Catalog_t* cp; Message_t* mp; oerrno = errno; r = (char*)msg; /* * quick out */ if (!cmd && !cat) goto done; if (cmd && (t = strrchr(cmd, '/'))) cmd = (const char*)(t + 1); /* * initialize the catalogs dictionary */ if (!state.catalogs) { if (state.error) goto done; if (!(state.tmp = sfstropen())) { state.error = 1; goto done; } if (!(state.catalogs = dtopen(&state.catalog_disc, Dtset))) { sfclose(state.tmp); state.error = 1; goto done; } if (streq(loc, "debug")) state.debug = loc; } /* * get the message * or do we have to spell it out for you */ if ((!cmd || !(mp = match(cmd, msg))) && (!cat || !(mp = match(cat, msg))) && (!error_info.catalog || !(mp = match(error_info.catalog, msg))) && (!ast.id || !(mp = match(ast.id, msg))) || !(cp = mp->cat)) { #if DEBUG_trace > 1 sfprintf(sfstderr, "AHA#%d:%s cmd %s cat %s:%s id %s msg `%s'\n", __LINE__, __FILE__, cmd, cat, error_info.catalog, ast.id, msg); #endif goto done; } /* * adjust for the current locale */ #if DEBUG_trace sfprintf(sfstderr, "AHA#%d:%s cp->locale `%s' %p loc `%s' %p\n", __LINE__, __FILE__, cp->locale, cp->locale, loc, loc); #endif if (cp->locale != loc) { cp->locale = loc; if (cp->cat != NOCAT) catclose(cp->cat); if ((cp->cat = find(cp->locale, cp->name)) == NOCAT) cp->debug = streq(cp->locale, "debug"); else cp->debug = 0; #if DEBUG_trace sfprintf(sfstderr, "AHA#%d:%s cp->cat %p cp->debug %d NOCAT %p\n", __LINE__, __FILE__, cp->cat, cp->debug, NOCAT); #endif } if (cp->cat == NOCAT) { if (cp->debug) { p = tempget(state.tmp); sfprintf(state.tmp, "(%s,%d,%d)", cp->name, mp->set, mp->seq); r = tempuse(state.tmp, p); } else if (ast.locale.set & AST_LC_debug) { p = tempget(state.tmp); sfprintf(state.tmp, "(%s,%d,%d)%s", cp->name, mp->set, mp->seq, r); r = tempuse(state.tmp, p); } goto done; } /* * get the translated message */ r = catgets(cp->cat, mp->set, mp->seq, msg); if (ast.locale.set & AST_LC_translate) sfprintf(sfstderr, "translate locale=%s catalog=%s set=%d seq=%d \"%s\" => \"%s\"\n", cp->locale, cp->name, mp->set, mp->seq, msg, r == (char*)msg ? "NOPE" : r); if (r != (char*)msg) { if (streq(r, (char*)msg)) r = (char*)msg; else if (strcmp(fmtfmt(r), fmtfmt(msg))) { sfprintf(sfstderr, "locale %s catalog %s message %d.%d \"%s\" does not match \"%s\"\n", cp->locale, cp->name, mp->set, mp->seq, r, msg); r = (char*)msg; } } if (ast.locale.set & AST_LC_debug) { p = tempget(state.tmp); sfprintf(state.tmp, "(%s,%d,%d)%s", cp->name, mp->set, mp->seq, r); r = tempuse(state.tmp, p); } done: if (r == (char*)msg && loc == state.debug) { p = tempget(state.tmp); sfprintf(state.tmp, "(%s,%s,%s,\"%s\")", loc, cmd, cat, r); r = tempuse(state.tmp, p); } errno = oerrno; return r; }
/* * 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--; }
int b_hist(int argc,char *argv[], Shbltin_t *context) { register History_t *hp; register char *arg; register int flag,fdo; register Shell_t *shp = context->shp; Sfio_t *outfile; char *fname; int range[2], incr, index2, indx= -1; char *edit = 0; /* name of editor */ char *replace = 0; /* replace old=new */ int lflag = 0, nflag = 0, rflag = 0; #if SHOPT_HISTEXPAND int pflag = 0; #endif Histloc_t location; NOT_USED(argc); if(!sh_histinit((void*)shp)) errormsg(SH_DICT,ERROR_system(1),e_histopen); hp = shp->gd->hist_ptr; while((flag = optget(argv,sh_opthist))) switch(flag) { case 'e': edit = opt_info.arg; break; case 'n': nflag++; break; case 'l': lflag++; break; case 'r': rflag++; break; case 's': edit = "-"; break; #if SHOPT_HISTEXPAND case 'p': pflag++; break; #endif case 'N': if(indx<=0) { if((flag = hist_max(hp) - opt_info.num-1) < 0) flag = 1; range[++indx] = flag; break; } case ':': errormsg(SH_DICT,2, "%s", opt_info.arg); break; case '?': errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg); break; } if(error_info.errors) errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); argv += (opt_info.index-1); #if SHOPT_HISTEXPAND if(pflag) { hist_cancel(hp); pflag = 0; while(arg=argv[1]) { flag = hist_expand(arg,&replace); if(!(flag & HIST_ERROR)) sfputr(sfstdout, replace, '\n'); else pflag = 1; if(replace) free(replace); argv++; } return pflag; } #endif flag = indx; while(flag<1 && (arg=argv[1])) { /* look for old=new argument */ if(!replace && strchr(arg+1,'=')) { replace = arg; argv++; continue; } else if(isdigit(*arg) || *arg == '-') { /* see if completely numeric */ do arg++; while(isdigit(*arg)); if(*arg==0) { arg = argv[1]; range[++flag] = (int)strtol(arg, (char**)0, 10); if(*arg == '-') range[flag] += (hist_max(hp)-1); argv++; continue; } } /* search for last line starting with string */ location = hist_find(hp,argv[1],hist_max(hp)-1,0,-1); if((range[++flag] = location.hist_command) < 0) errormsg(SH_DICT,ERROR_exit(1),e_found,argv[1]); argv++; } if(flag <0) { /* set default starting range */ if(lflag) { flag = hist_max(hp)-16; if(flag<1) flag = 1; } else flag = hist_max(hp)-2; range[0] = flag; flag = 0; } index2 = hist_min(hp); if(range[0]<index2) range[0] = index2; if(flag==0) /* set default termination range */ range[1] = ((lflag && !edit)?hist_max(hp)-1:range[0]); if(range[1]>=(flag=(hist_max(hp) - !lflag))) range[1] = flag; /* check for valid ranges */ if(range[1]<index2 || range[0]>=flag) errormsg(SH_DICT,ERROR_exit(1),e_badrange,range[0],range[1]); if(edit && *edit=='-' && range[0]!=range[1]) errormsg(SH_DICT,ERROR_exit(1),e_eneedsarg); /* now list commands from range[rflag] to range[1-rflag] */ incr = 1; flag = rflag>0; if(range[1-flag] < range[flag]) incr = -1; if(lflag) { outfile = sfstdout; arg = "\n\t"; } else { if(!(fname=pathtmp(NIL(char*),0,0,NIL(int*)))) errormsg(SH_DICT,ERROR_exit(1),e_create,""); if((fdo=open(fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR)) < 0) errormsg(SH_DICT,ERROR_system(1),e_create,fname); outfile= sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fdo,SF_WRITE); arg = "\n"; nflag++; } while(1) { if(nflag==0) sfprintf(outfile,"%d\t",range[flag]); else if(lflag) sfputc(outfile,'\t'); hist_list(shp->gd->hist_ptr,outfile,hist_tell(shp->gd->hist_ptr,range[flag]),0,arg); if(lflag) sh_sigcheck(shp); if(range[flag] == range[1-flag]) break; range[flag] += incr; } if(lflag) return(0); sfclose(outfile); hist_eof(hp); arg = edit; if(!arg && !(arg=nv_getval(sh_scoped(shp,HISTEDIT))) && !(arg=nv_getval(sh_scoped(shp,FCEDNOD)))) { arg = (char*)e_defedit; if(*arg!='/') errormsg(SH_DICT,ERROR_exit(1),"ed not found set FCEDIT"); } #ifdef apollo /* * Code to support the FC using the pad editor. * Exampled of how to use: HISTEDIT=pad */ if (strcmp (arg, "pad") == 0) { extern int pad_create(char*); sh_close(fdo); fdo = pad_create(fname); pad_wait(fdo); unlink(fname); strcat(fname, ".bak"); unlink(fname); lseek(fdo,(off_t)0,SEEK_SET); } else { #endif /* apollo */ if(*arg != '-') { char *com[3]; com[0] = arg; com[1] = fname; com[2] = 0; error_info.errors = sh_eval(sh_sfeval(com),0); } fdo = sh_chkopen(fname); unlink(fname); free((void*)fname); #ifdef apollo } #endif /* apollo */ /* don't history fc itself unless forked */ error_info.flags |= ERROR_SILENT; if(!sh_isstate(SH_FORKED)) hist_cancel(hp); sh_onstate(SH_HISTORY); sh_onstate(SH_VERBOSE); /* echo lines as read */ if(replace) hist_subst(error_info.id,fdo,replace); else if(error_info.errors == 0) { char buff[IOBSIZE+1]; Sfio_t *iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fdo,SF_READ); /* read in and run the command */ if(shp->hist_depth++ > HIST_RECURSE) errormsg(SH_DICT,ERROR_exit(1),e_toodeep,"history"); sh_eval(iop,1); shp->hist_depth--; }
// Print option settings on standard output. // If mode is inclusive or of PRINT_*. // If <mask> is set, only options with this mask value are displayed. void sh_printopts(Shell_t *shp, Shopt_t oflags, int mode, Shopt_t *mask) { const Shtable_t *tp; const char *name; int on; int value; if (!(mode & PRINT_NO_HEADER)) sfputr(sfstdout, sh_translate(e_heading), '\n'); if (mode & PRINT_TABLE) { size_t w; int c; int r; int i; c = 0; for (tp = shtab_options; (value = tp->sh_number); tp++) { if (mask && !is_option(mask, value & 0xff)) continue; name = tp->sh_name; if (name[0] == 'n' && name[1] == 'o' && name[2] != 't') name += 2; if (c < (w = strlen(name))) c = w; } c += 4; w = ed_window(); if (w < 2 * c) w = 2 * c; r = w / c; i = 0; for (tp = shtab_options; (value = tp->sh_number); tp++) { if (mask && !is_option(mask, value & 0xff)) continue; on = is_option(&oflags, value); name = tp->sh_name; if (name[0] == 'n' && name[1] == 'o' && name[2] != 't') { name += 2; on = !on; } if (++i >= r) { i = 0; sfprintf(sfstdout, "%s%s\n", on ? "" : "no", name); } else { sfprintf(sfstdout, "%s%-*s", on ? "" : "no", on ? c : (c - 2), name); } } if (i) sfputc(sfstdout, '\n'); return; } if (!(mode & (PRINT_ALL | PRINT_VERBOSE))) { // only print set options if (mode & PRINT_SHOPT) { sfwrite(sfstdout, "shopt -s", 3); } else { sfwrite(sfstdout, "set --default", 13); } } for (tp = shtab_options; (value = tp->sh_number); tp++) { if (mask && !is_option(mask, value & 0xff)) continue; if (sh_isoption(shp, SH_BASH)) { if (!(mode & PRINT_SHOPT) != !(value & SH_BASHOPT)) continue; } else if (value & (SH_BASHEXTRA | SH_BASHOPT)) { continue; } on = is_option(&oflags, value); name = tp->sh_name; if (name[0] == 'n' && name[1] == 'o' && name[2] != 't') { name += 2; on = !on; } if (mode & PRINT_VERBOSE) { sfputr(sfstdout, name, ' '); sfnputc(sfstdout, ' ', 24 - strlen(name)); sfputr(sfstdout, on ? sh_translate(e_on) : sh_translate(e_off), '\n'); } else if (mode & PRINT_ALL) { // print unset options also if (mode & PRINT_SHOPT) { sfprintf(sfstdout, "shopt -%c %s\n", on ? 's' : 'u', name); } else { sfprintf(sfstdout, "set %co %s\n", on ? '-' : '+', name); } } else if (!(value & SH_COMMANDLINE) && is_option(&oflags, value & 0xff)) { sfprintf(sfstdout, " %s%s%s", (mode & PRINT_SHOPT) ? "" : "--", on ? "" : "no", name); } } if (!(mode & (PRINT_VERBOSE | PRINT_ALL))) sfputc(sfstdout, '\n'); }
static pid_t runve(int mode, const char* path, char* const* argv, char* const* envv) { register char* s; register char** p; register char** v; void* m1; void* m2; pid_t pid; int oerrno; int ux; int n; #if defined(_P_DETACH) && defined(_P_NOWAIT) int pgrp; #endif #if CONVERT char* d; char* t; int m; #endif struct stat st; char buf[PATH_MAX]; char tmp[PATH_MAX]; #if DEBUG static int trace; #endif #if defined(_P_DETACH) && defined(_P_NOWAIT) if (mode == _P_DETACH) { /* * 2004-02-29 cygwin _P_DETACH is useless: * spawn*() returns 0 instead of the spawned pid * spawned { pgid sid } are the same as the parent */ mode = _P_NOWAIT; pgrp = 1; } else pgrp = 0; #endif if (!envv) envv = (char* const*)environ; m1 = m2 = 0; oerrno = errno; #if DEBUG if (!trace) trace = (s = getenv("_AST_exec_trace")) ? *s : 'n'; #endif if (execrate(path, buf, sizeof(buf), 0)) { if (!_stat(buf, &st)) path = (const char*)buf; else errno = oerrno; } if (path != (const char*)buf && _stat(path, &st)) return -1; if (!S_ISREG(st.st_mode) || !(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) { errno = EACCES; return -1; } if (magic(path, &ux)) { #if _CYGWIN_fork_works errno = ENOEXEC; return -1; #else ux = 1; p = (char**)argv; while (*p++); if (!(v = (char**)malloc((p - (char**)argv + 2) * sizeof(char*)))) { errno = EAGAIN; return -1; } m1 = v; p = v; *p++ = (char*)path; *p++ = (char*)path; path = (const char*)pathshell(); if (*argv) argv++; while (*p++ = (char*)*argv++); argv = (char* const*)v; #endif } /* * the win32 dll search order is * (1) the directory of path * (2) . * (3) /c/(WINNT|WINDOWS)/system32 /c/(WINNT|WINDOWS) * (4) the directories on $PATH * there are no cygwin dlls in (3), so if (1) and (2) fail * to produce the required dlls its up to (4) * * the standard allows PATH to be anything once the path * to an executable is determined; this code ensures that PATH * contains /bin so that at least the cygwin dll, required * by all cygwin executables, will be found */ if (p = (char**)envv) { n = 1; while (s = *p++) if (strneq(s, "PATH=", 5)) { s += 5; do { s = pathcat(tmp, s, ':', NiL, ""); if (streq(tmp, "/usr/bin/") || streq(tmp, "/bin/")) { n = 0; break; } } while (s); if (n) { n = 0; snprintf(tmp, sizeof(tmp), "%s:/bin", *(p - 1)); *(p - 1) = tmp; } break; } if (n) { n = p - (char**)envv + 1; p = (char**)envv; if (v = (char**)malloc(n * sizeof(char*))) { m2 = v; envv = (char* const*)v; *v++ = strcpy(tmp, "PATH=/bin"); while (*v++ = *p++); } } #if CONVERT if (!ux && (d = getenv(convertvars[0]))) for (p = (char**)envv; s = *p; p++) if ((n = convert(d, s)) && (m = cygwin_posix_to_win32_path_list_buf_size(s + n)) > 0) { if (!(t = malloc(n + m + 1))) break; *p = t; memcpy(t, s, n); cygwin_posix_to_win32_path_list(s + n, t + n); } #endif } #if DEBUG if (trace == 'a' || trace == 'e') { sfprintf(sfstderr, "%s %s [", mode == _P_OVERLAY ? "_execve" : "_spawnve", path); for (n = 0; argv[n]; n++) sfprintf(sfstderr, " '%s'", argv[n]); if (trace == 'e') { sfprintf(sfstderr, " ] ["); for (n = 0; envv[n]; n++) sfprintf(sfstderr, " '%s'", envv[n]); } sfprintf(sfstderr, " ]\n"); sfsync(sfstderr); } #endif #if _lib_spawn_mode if (mode != _P_OVERLAY) { pid = _spawnve(mode, path, argv, envv); #if defined(_P_DETACH) && defined(_P_NOWAIT) if (pid > 0 && pgrp) setpgid(pid, 0); #endif } else #endif { #if defined(_P_DETACH) && defined(_P_NOWAIT) if (pgrp) setpgid(0, 0); #endif pid = _execve(path, argv, envv); } if (m1) free(m1); if (m2) free(m2); return pid; }