static void commit(Joblist_t* job, register char* s) { register char* t; register char* v; register Rule_t* r; Stat_t st; if (t = strrchr(s, '/')) { *t = 0; if (r = bindfile(NiL, s, 0)) { if (!r->view) { *t = '/'; return; } if (*(v = r->name) != '/') { sfprintf(internal.nam, "%s/%s", state.view[r->view].root, v); v = sfstruse(internal.nam); } if (stat(v, &st)) r = 0; } if (r || state.targetcontext && (!r || !r->time) && (st.st_mode = (S_IRWXU|S_IRWXG|S_IRWXO)) && tmxsetmtime(&st, state.start)) { /* * why not mkdir -p here? */ commit(job, s); if (((job->flags & CO_ALWAYS) || state.exec && state.touch) && (mkdir(s, st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || stat(s, &st))) error(1, "%s: cannot create target directory %s", job->target->name, s); if (state.mam.out) { Sfio_t* tmp = sfstropen(); sfprintf(tmp, "mkdir %s", s); dumpaction(state.mam.out, MAMNAME(job->target), sfstruse(tmp), NiL); sfstrclose(tmp); } r = makerule(s); if (r->dynamic & D_alias) oldname(r); r->view = 0; r->time = tmxgetmtime(&st); if (r->dynamic & D_scanned) unbind(NiL, (char*)r, NiL); } *t = '/'; } }
static int arraysort(const char *s1, const char *s2) { struct Sort *sp = Sp; Shell_t *shp = sp->shp; int r=0, cur=sp->cur; Namval_t *np1, *np2; Namfun_t fun; char *cp; memset(&fun,0,sizeof(Namfun_t)); if(!(np1 = ((struct Node*)s1)->nodes[sp->cur])) { sfprintf(shp->strbuf,"%s[%i].%s%c",sp->name,((struct Node*)s1)->index,sp->keys[sp->cur],0); cp = sfstruse(shp->strbuf); np1 = nv_create(cp,sp->root,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOSCOPE,&fun); ((struct Node*)s1)->nodes[sp->cur] = np1; } if(!(np2 = ((struct Node*)s2)->nodes[sp->cur])) { sfprintf( shp->strbuf,"%s[%i].%s%c",sp->name,((struct Node*)s2)->index,sp->keys[sp->cur],0); cp = sfstruse(shp->strbuf); np2 = nv_create(cp,sp->root,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOSCOPE,&fun); ((struct Node*)s2)->nodes[sp->cur] = np2; } if(sp->flags[sp->cur]&SORT_numeric) { Sfdouble_t d1 = np1?nv_getnum(np1):0; Sfdouble_t d2 = np2?nv_getnum(np2):0; if(d2<d1) r = 1; else if(d2>d1) r = -1; } else if(np1 && np2) { char *sp1 = nv_getval(np1); char *sp2 = nv_getval(np2); r = strcoll(sp1,sp2); } else if(np1) r = 1; else if(np2) r = -1; if(sp->flags[sp->cur]&SORT_reverse) r = -r; if(r==0 && sp->keys[++sp->cur]) r = arraysort(s1,s2); sp->cur = cur; return(r); }
Time_t tmxduration(const char* s, char** e) { Time_t ns; Time_t ts; Time_t now; char* last; char* t; char* x; Sfio_t* f; int i; now = TMX_NOW; while (isspace(*s)) s++; if (*s == 'P' || *s == 'p') ns = tmxdate(s, &last, now) - now; else { ns = strtod(s, &last) * TMX_RESOLUTION; if (*last && (f = sfstropen())) { sfprintf(f, "exact %s", s); t = sfstruse(f); ts = tmxdate(t, &x, now); if ((i = x - t - 6) > (last - s)) { last = (char*)s + i; ns = ts - now; } else { sfprintf(f, "p%s", s); t = sfstruse(f); ts = tmxdate(t, &x, now); if ((i = x - t - 1) > (last - s)) { last = (char*)s + i; ns = ts - now; } } sfstrclose(f); } } if (e) *e = last; return ns; }
void exerror(const char* format, ...) { Sfio_t* sp; if (expr.program->disc->errorf && !expr.program->errors && (sp = sfstropen())) { va_list ap; char* s; char buf[64]; expr.program->errors = 1; excontext(expr.program, buf, sizeof(buf)); sfputr(sp, buf, -1); va_start(ap, format); sfvprintf(sp, format, ap); va_end(ap); if (!(s = sfstruse(sp))) s = "out of space"; (*expr.program->disc->errorf)(expr.program, expr.program->disc, (expr.program->disc->flags & EX_FATAL) ? 3 : 2, "%s", s); sfclose(sp); } else if (expr.program->disc->flags & EX_FATAL) exit(1); }
static void splice(void) { char* s; int n; if (ed.spend) { if (!ed.spl && !(ed.spl = sfstropen())) error(ERROR_SYSTEM|3, "cannot initialize splice buffer"); sfwrite(ed.spl, ed.spbeg, ed.spend - ed.spbeg); ed.spend = 0; sfputc(ed.spl, '\n'); while (s = sfgetr(sfstdin, '\n', 1)) { if ((n = sfvalue(sfstdin) - 1) > 0 && s[n - 1] == '\r') n--; if (n > 0 && s[n - 1] == '\\') { sfwrite(ed.spl, s, n - 1); sfputc(ed.spl, '\n'); } else { sfwrite(ed.spl, s, n); break; } } if (!(s = sfstruse(ed.spl))) error(ERROR_SYSTEM|3, "out of space"); ed.input = s + (ed.input - ed.spbeg); } }
static char* getrec(register Sfio_t* sp, register int delimiter, register int flags) { register int c; register char* glob; sfstrseek(sp, 0, SEEK_SET); glob = ed.global; while ((c = getchr()) != delimiter) { if (c == '\n') { ed.peekc = c; break; } if (c == EOF) { if (glob) ed.peekc = (flags & REC_LINE) ? 0 : c; else if (delimiter != '\n' || (flags & (REC_LINE|REC_SPLICE))) error(2, "unexpected EOF"); else if (flags & REC_TEXT) return 0; break; } if (c == '\\' && ((c = getchr()) != delimiter || (flags & REC_SPLICE) && c != '\n') && c && !(flags & REC_IGNORE)) sfputc(sp, '\\'); if (!c) error(1, "null character ignored"); else if (!(flags & REC_IGNORE)) sfputc(sp, c); } if (flags & REC_TERMINATE) sfputc(sp, c); if (!(glob = sfstruse(sp))) error(ERROR_SYSTEM|3, "out of space"); return glob; }
char* exstash(Sfio_t* sp, Vmalloc_t* vp) { char* s; return ((s = sfstruse(sp)) && (!vp || (s = vmstrdup(vp, s)))) ? s : exnospace(); }
static int post(Css_t* css, Cssdisc_t* disc, Connection_t* from, register Connection_t* to, int channel, const char* format, ...) { State_t* state = (State_t*)disc; char* s; ssize_t n; Sfulong_t m; va_list ap; sfprintf(state->tmp, "%d", channel); if (from) sfprintf(state->tmp, ".%d", from->fp->fd); sfputc(state->tmp, ' '); va_start(ap, format); sfvprintf(state->tmp, format, ap); va_end(ap); sfputc(state->tmp, '\n'); n = sfstrtell(state->tmp); if (!(s = sfstruse(state->tmp))) error(ERROR_SYSTEM|3, "out of space"); m = CHAN_MASK(channel); state->logged = 0; if (!to) { for (to = state->all; to; to = to->next) if ((to->mask & m) && to != from) note(css, to, state->log, s, n, 0, disc); } else if (to->mask & m) note(css, to, state->log, s, n, 0, disc); return 0; }
static int intercept(Sfio_t* sp, int level, int flags) { register Rule_t* r; char* m; char* s; char* t; char* e; int n; int i; Sfio_t* tmp; NoP(sp); NoP(flags); if ((state.mam.level = level) > 0 && !state.hold && (r = internal.error) && (r->property & (P_functional|P_target)) == (P_functional|P_target) && !state.compileonly && !state.interrupt && (m = stakptr(0)) && (n = staktell()) > 0) { /* * make the error trap */ state.hold = m; while (*m && *m != ':') m++; while (isspace(*++m)); n -= m - state.hold; tmp = sfstropen(); sfprintf(tmp, "%d %-.*s", level, n, m); s = sfstruse(tmp); /* * return [ level | - ] [ message ] * level is new level or - to retain old * omitted message means it has been printed */ if (t = call(r, s)) { i = strtol(t, &e, 0); if (e > t) { t = e; level = i; } else if (*t == '-') t++; while (isspace(*t)) t++; } if (!t || !*t) { level |= ERROR_OUTPUT; message((-1, "suppressed %s message: `%-.*s'", level == 1 ? "warning" : "error", n, m)); } sfstrclose(tmp); state.hold = 0; } return level; }
char* costash(Sfio_t* sp) { char* s; if (!(s = sfstruse(sp))) errormsg(state.lib, ERROR_LIBRARY|2, "out of space"); return s; }
/* toUpper: * Convert characters to uppercase */ char *toUpper(Expr_t * pgm, char *s, Sfio_t* tmps) { int c; while ((c = *s++)) sfputc (tmps, toupper (c)); return exstring(pgm, sfstruse(tmps)); }
char* _re_putc(int c) { static Sfio_t* sp; if (!sp && !(sp = sfstropen())) return 0; if (!c) return sfstruse(sp); sfputc(sp, c); return 0; }
static int read_tree(Namval_t* np, Sfio_t *iop, int n, Namfun_t *dp) { Sfio_t *sp; char *cp; int c; if(n>=0) return(-1); while((c = sfgetc(iop)) && isblank(c)); sfungetc(iop,c); sfprintf(sh.strbuf,"%s=%c",nv_name(np),0); cp = sfstruse(sh.strbuf); sp = sfopen((Sfio_t*)0,cp,"s"); sfstack(iop,sp); c=sh_eval(iop,SH_READEVAL); return(c); }
static void join(void) { register Line_t* a1; char* s; nonzero(); sfstrseek(ed.buffer.work, 0, SEEK_SET); for (a1 = ed.addr1; a1 <= ed.addr2;) sfputr(ed.buffer.work, lineget((a1++)->offset), -1); a1 = ed.dot = ed.addr1; if (!(s = sfstruse(ed.buffer.work))) error(ERROR_SYSTEM|3, "out of space"); replace(a1, s); if (a1 < ed.addr2) rdelete(a1 + 1, ed.addr2); }
int vasprintf(char** s, const char* fmt, va_list args) { Sfio_t* f; int v; if (f = sfstropen()) { v = sfvprintf(f, fmt, args); if (!(*s = strdup(sfstruse(f)))) v = -1; sfstrclose(f); } else { *s = 0; v = -1; } return v; }
/* * Read single line from stream. * Return "" on EOF. */ char *readLine(Expr_t * ex, int fd) { Sfio_t *sp; int c; Sfio_t *tmps; char *line; if (fd < 0 || fd >= elementsof(ex->file) || !((sp = ex->file[fd]))) { exerror("readL: %d: invalid descriptor", fd); return ""; } tmps = sfstropen(); while (((c = sfgetc(sp)) > 0) && (c != '\n')) sfputc(tmps, c); if (c == '\n') sfputc(tmps, c); line = exstring(ex, sfstruse(tmps)); sfclose(tmps); return line; }
static void exfile(void) { if (sfclose(ed.iop)) error(ERROR_SYSTEM|1, "io error"); ed.iop = 0; if (ed.verbose) { if (ed.help) { sfprintf(ed.msg, "\"%s\" %lu line%s, %lu character%s", error_info.file, ed.lines, plural(ed.lines), ed.bytes, plural(ed.bytes)); if (ed.warn_null) { sfprintf(ed.msg, ", %lu null%s", ed.warn_null, plural(ed.warn_null)); ed.warn_null = 0; } if (ed.warn_newline) { sfprintf(ed.msg, ", newline appended"); ed.warn_newline = 0; } sfputc(ed.msg, '\n'); } else sfprintf(ed.msg, "%d\n", ed.bytes); } if (ed.warn_null || ed.warn_newline) { char* sep = ""; sfstrseek(ed.buffer.line, 0, SEEK_SET); if (ed.warn_null) { sfprintf(ed.buffer.line, "%d null character%s ignored", ed.warn_null, plural(ed.warn_null)); ed.warn_null = 0; sep = ", "; } if (ed.warn_newline) { sfprintf(ed.buffer.line, "%snewline appended to last line", sep); ed.warn_newline = 0; } if (!(sep = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); error(1, "%s", sep); } error_info.file = 0; }
void exwarn(const char *format, ...) { Sfio_t *sp; if (expr.program->disc->errorf && (sp = sfstropen())) { va_list ap; char *s; char buf[64]; excontext(expr.program, buf, sizeof(buf)); sfputr(sp, buf, -1); sfputr(sp, "\n -- ", -1); va_start(ap, format); sfvprintf(sp, format, ap); va_end(ap); s = sfstruse(sp); (*expr.program->disc->errorf) (expr.program, expr.program->disc, ERROR_WARNING, "%s", s); sfclose(sp); } }
static void handle(void) { register int c; char* s; char* b; mode_t mask; if (ed.caught == SIGINT) { ed.caught = 0; ed.lastc = '\n'; sfputc(ed.msg, '\n'); error(2, "interrupt"); } for (c = 0; c < elementsof(signals); c++) signal(signals[c], SIG_IGN); if (ed.dol > ed.zero) { ed.addr1 = ed.zero + 1; ed.addr2 = ed.dol; mask = umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); b = "ed.hup"; if (!(ed.iop = sfopen(NiL, b, "w")) && !ed.restricted && (s = getenv("HOME"))) { sfstrseek(ed.buffer.line, 0, SEEK_SET); sfprintf(ed.buffer.line, "%s/%s", s, b); if (!(b = sfstruse(ed.buffer.line))) error(ERROR_SYSTEM|3, "out of space"); ed.iop = sfopen(NiL, b, "w"); } umask(mask); if (!ed.iop) error(ERROR_SYSTEM|1, "%s: cannot save changes", b); else { error_info.file = b; putfile(); } } ed.modified = 0; quit(0); }
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 extoken_fn(register Expr_t* ex) { register int c; register char* s; register int q; char* e; if (ex->eof || ex->errors) return 0; again: for (;;) switch (c = lex(ex)) { case 0: goto eof; case '/': switch (q = lex(ex)) { case '*': for (;;) switch (lex(ex)) { case '\n': BUMP (error_info.line); continue; case '*': switch (lex(ex)) { case 0: goto eof; case '\n': BUMP (error_info.line); break; case '*': exunlex(ex, '*'); break; case '/': goto again; } break; } break; case '/': while ((c = lex(ex)) != '\n') if (!c) goto eof; break; default: goto opeq; } /*FALLTHROUGH*/ case '\n': BUMP (error_info.line); /*FALLTHROUGH*/ case ' ': case '\t': break; case '(': case '{': case '[': ex->input->nesting++; return exlval.op = c; case ')': case '}': case ']': ex->input->nesting--; return exlval.op = c; case '+': case '-': if ((q = lex(ex)) == c) return exlval.op = c == '+' ? INC : DEC; goto opeq; case '*': case '%': case '^': q = lex(ex); opeq: exlval.op = c; if (q == '=') c = '='; else if (q == '%' && c == '%') { if (ex->input->fp) ex->more = (const char*)ex->input->fp; else ex->more = ex->input->sp; goto eof; } else exunlex(ex, q); return c; case '&': case '|': if ((q = lex(ex)) == '=') { exlval.op = c; return '='; } if (q == c) c = c == '&' ? AND : OR; else exunlex(ex, q); return exlval.op = c; case '<': case '>': if ((q = lex(ex)) == c) { exlval.op = c = c == '<' ? LS : RS; if ((q = lex(ex)) == '=') c = '='; else exunlex(ex, q); return c; } goto relational; case '=': case '!': q = lex(ex); relational: if (q == '=') switch (c) { case '<': c = LE; break; case '>': c = GE; break; case '=': c = EQ; break; case '!': c = NE; break; } else exunlex(ex, q); return exlval.op = c; case '#': if (!ex->linewrap && !(ex->disc->flags & EX_PURE)) { s = ex->linep - 1; while (s > ex->line && isspace(*(s - 1))) s--; if (s == ex->line) { switch (extoken_fn(ex)) { case DYNAMIC: case ID: case NAME: s = exlval.id->name; break; default: s = ""; break; } if (streq(s, "include")) { if (extoken_fn(ex) != STRING) exerror("#%s: string argument expected", s); else if (!expush(ex, exlval.string, 1, NiL, NiL)) { setcontext(ex); goto again; } } else exerror("unknown directive"); } } return exlval.op = c; case '\'': case '"': q = c; sfstrset(ex->tmp, 0); ex->input->nesting++; while ((c = lex(ex)) != q) { if (c == '\\') { sfputc(ex->tmp, c); c = lex(ex); } if (!c) { exerror("unterminated %c string", q); goto eof; } if (c == '\n') { BUMP (error_info.line); } sfputc(ex->tmp, c); } ex->input->nesting--; s = sfstruse(ex->tmp); if (q == '"' || (ex->disc->flags & EX_CHARSTRING)) { if (!(exlval.string = vmstrdup(ex->vm, s))) goto eof; stresc(exlval.string); return STRING; } exlval.integer = chrtoi(s); return INTEGER; case '.': if (isdigit(c = lex(ex))) { sfstrset(ex->tmp, 0); sfputc(ex->tmp, '0'); sfputc(ex->tmp, '.'); goto floating; } exunlex(ex, c); return exlval.op = '.'; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': sfstrset(ex->tmp, 0); sfputc(ex->tmp, c); q = INTEGER; if ((c = lex(ex)) == 'x' || c == 'X') { sfputc(ex->tmp, c); for (;;) { switch (c = lex(ex)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': sfputc(ex->tmp, c); continue; } break; } } else { while (isdigit(c)) { sfputc(ex->tmp, c); c = lex(ex); } if (c == '#') { sfputc(ex->tmp, c); /* s = sfstruse(ex->tmp); */ /* b = strtol(s, NiL, 10); */ do { sfputc(ex->tmp, c); } while (isalnum(c = lex(ex))); } else { if (c == '.') { floating: q = FLOATING; sfputc(ex->tmp, c); while (isdigit(c = lex(ex))) sfputc(ex->tmp, c); } if (c == 'e' || c == 'E') { q = FLOATING; sfputc(ex->tmp, c); if ((c = lex(ex)) == '-' || c == '+') { sfputc(ex->tmp, c); c = lex(ex); } while (isdigit(c)) { sfputc(ex->tmp, c); c = lex(ex); } } } } s = sfstruse(ex->tmp); if (q == FLOATING) exlval.floating = strtod(s, &e); else { if (c == 'u' || c == 'U') { q = UNSIGNED; c = lex(ex); exlval.integer = strToL(s, &e); } else exlval.integer = strToL(s, &e); if (*e) { *--e = 1; exlval.integer *= strton(e, &e, NiL, 0); } } exunlex(ex, c); if (*e || isalpha(c) || c == '_' || c == '$') { exerror("%s: invalid numeric constant", s); goto eof; } return q; default: if (isalpha(c) || c == '_' || c == '$') { sfstrset(ex->tmp, 0); sfputc(ex->tmp, c); while (isalnum(c = lex(ex)) || c == '_' || c == '$') sfputc(ex->tmp, c); exunlex(ex, c); s = sfstruse(ex->tmp); if (!(exlval.id = (Exid_t*)dtmatch(ex->symbols, s))) { if (!(exlval.id = newof(0, Exid_t, 1, strlen(s) - EX_NAMELEN + 1))) { exerror("out of space"); goto eof; } strcpy(exlval.id->name, s); exlval.id->lex = NAME; dtinsert((ex->formals || !ex->symbols->view) ? ex->symbols : ex->symbols->view, exlval.id); } /* * lexical analyzer state controlled by the grammar */ switch (exlval.id->lex) { case DECLARE: if (exlval.id->index == CHAR) { /* * `char*' === `string' * the * must immediately follow char */ if (c == '*') { lex(ex); exlval.id = id_string; } } break; case NAME: /* * action labels are disambiguated from ?: * through the expr.nolabel grammar hook * the : must immediately follow labels */ if (c == ':' && !expr.nolabel) return LABEL; break; case PRAGMA: /* * user specific statement stripped and * passed as string */ { int b; int n; int pc = 0; int po; int t; /*UNDENT...*/ sfstrset(ex->tmp, 0); b = 1; n = 0; po = 0; t = 0; for (c = t = lex(ex);; c = lex(ex)) { switch (c) { case 0: goto eof; case '/': switch (q = lex(ex)) { case '*': for (;;) { switch (lex(ex)) { case '\n': BUMP (error_info.line); continue; case '*': switch (lex(ex)) { case 0: goto eof; case '\n': BUMP (error_info.line); continue; case '*': exunlex(ex, '*'); continue; case '/': break; default: continue; } break; } if (!b++) goto eof; sfputc(ex->tmp, ' '); break; } break; case '/': while ((c = lex(ex)) != '\n') if (!c) goto eof; BUMP (error_info.line); b = 1; sfputc(ex->tmp, '\n'); break; default: b = 0; sfputc(ex->tmp, c); sfputc(ex->tmp, q); break; } continue; case '\n': BUMP (error_info.line); b = 1; sfputc(ex->tmp, '\n'); continue; case ' ': case '\t': if (!b++) goto eof; sfputc(ex->tmp, ' '); continue; case '(': case '{': case '[': b = 0; if (!po) { switch (po = c) { case '(': pc = ')'; break; case '{': pc = '}'; break; case '[': pc = ']'; break; } n++; } else if (c == po) n++; sfputc(ex->tmp, c); continue; case ')': case '}': case ']': b = 0; if (!po) { exunlex(ex, c); break; } sfputc(ex->tmp, c); if (c == pc && --n <= 0) { if (t == po) break; po = 0; } continue; case ';': b = 0; if (!n) break; sfputc(ex->tmp, c); continue; case '\'': case '"': b = 0; sfputc(ex->tmp, c); ex->input->nesting++; q = c; while ((c = lex(ex)) != q) { if (c == '\\') { sfputc(ex->tmp, c); c = lex(ex); } if (!c) { exerror("unterminated %c string", q); goto eof; } if (c == '\n') { BUMP (error_info.line); } sfputc(ex->tmp, c); } ex->input->nesting--; continue; default: b = 0; sfputc(ex->tmp, c); continue; } break; } (*ex->disc->reff)(ex, NiL, exlval.id, NiL, sfstruse(ex->tmp), 0, ex->disc); /*..INDENT*/ } goto again; } return exlval.id->lex; } return exlval.op = c; } eof: ex->eof = 1; return exlval.op = ';'; }
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; }
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("!"); } }
void filein(register Archive_t* ap, register File_t* f) { register off_t c; register int n; register char* s; int dfd; int wfd; long checksum; Filter_t* fp; Proc_t* pp; Tv_t t1; Tv_t t2; struct stat st; if (f->skip) goto skip; else if (state.list) { if (fp = filter(ap, f)) { for (n = 0; s = fp->argv[n]; n++) { while (*s) if (*s++ == '%' && *s == '(') break; if (*s) { s = fp->argv[n]; listprintf(state.tmp.str, ap, f, s); if (!(fp->argv[n] = sfstruse(state.tmp.str))) nospace(); break; } } pp = procopen(*fp->argv, fp->argv, NiL, NiL, PROC_WRITE); if (s) fp->argv[n] = s; if (!pp) { error(2, "%s: %s: cannot execute filter %s", ap->name, f->path, *fp->argv); goto skip; } if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, pp->wfd)) { checksum = 0; for (c = f->st->st_size; c > 0; c -= n) { n = (c > state.buffersize) ? state.buffersize : c; if (!(s = bget(ap, n, NiL))) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (write(pp->wfd, s, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } if (ap->format->checksum) checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum); } } if (ap->format->checksum && checksum != f->checksum) error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum); /* * explicitly ignore exit status */ procclose(pp); return; } listentry(f); goto skip; } else switch (f->delta.op) { case DELTA_create: if (f->delta.base) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); if (ap->delta->format->flags & PSEUDO) goto regular; if ((wfd = openout(ap, f)) < 0) goto skip; else paxdelta(NiL, ap, f, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, f->st->st_size, 0); break; case DELTA_update: if (!f->delta.base || (unsigned long)f->delta.base->mtime.tv_sec >= (unsigned long)f->st->st_mtime) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); c = f->st->st_size; if ((wfd = openout(ap, f)) < 0) goto skip; if (state.ordered) { if (!f->delta.base->uncompressed) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap->delta->base, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0)) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); } else if (!f->delta.base->uncompressed) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); else if (!paxdelta(NiL, ap, f, DELTA_DEL|DELTA_FD|DELTA_OFFSET|DELTA_SIZE, ap->delta->base->io->fd, f->delta.base->offset, f->delta.base->size, DELTA_TAR|DELTA_TEMP|DELTA_OUTPUT, &dfd, 0)) paxdelta(NiL, ap, f, DELTA_SRC|DELTA_FD|DELTA_SIZE|DELTA_FREE, dfd, f->delta.base->uncompressed, DELTA_TAR|DELTA_FD|DELTA_FREE|DELTA_OUTPUT|DELTA_COUNT, wfd, DELTA_DEL|DELTA_BIO|DELTA_SIZE, ap, c, 0); break; case DELTA_verify: if (!f->delta.base || f->delta.base->mtime.tv_sec != f->st->st_mtime) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); if ((*state.statf)(f->name, &st)) error(2, "%s: not copied from base archive", f->name); else if (st.st_size != f->delta.base->size || state.modtime && tvcmp(tvmtime(&t1, &st), tvmtime(&t2, f->st))) error(1, "%s: changed from base archive", f->name); break; case DELTA_delete: if (!f->delta.base) error(3, "%s: base archive mismatch [%s#%d]", f->name, __FILE__, __LINE__); /*FALLTHROUGH*/ default: regular: wfd = openout(ap, f); if (wfd >= 0) { holeinit(wfd); if (!ap->format->getdata || !(*ap->format->getdata)(&state, ap, f, wfd)) { checksum = 0; for (c = f->st->st_size; c > 0; c -= n) { n = (c > state.buffersize) ? state.buffersize : c; if (!(s = bget(ap, n, NiL))) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (holewrite(wfd, s, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } if (ap->format->checksum) checksum = (*ap->format->checksum)(&state, ap, f, s, n, checksum); } } holedone(wfd); closeout(ap, f, wfd); setfile(ap, f); if (ap->format->checksum && checksum != f->checksum) error(1, "%s: %s checksum error (0x%08x != 0x%08x)", f->name, ap->format->name, checksum, f->checksum); } else if (ap->format->getdata) (*ap->format->getdata)(&state, ap, f, wfd); else { if (wfd < -1) listentry(f); goto skip; } break; } listentry(f); return; skip: fileskip(ap, f); }
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; }
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 pzheadwrite(Pz_t* pz, Sfio_t* op) { register size_t i; register size_t m; register size_t n; register char* s; if (pz->flags & PZ_HEAD) return 0; pz->oop = op; if (!(pz->flags & PZ_NOGZIP)) sfdcgzip(op, 0); if (pz->flags & PZ_NOPZIP) return 0; sfputc(op, PZ_MAGIC_1); sfputc(op, PZ_MAGIC_2); if (sfsync(op)) return -1; sfputc(op, pz->major = PZ_MAJOR); sfputc(op, pz->minor = PZ_MINOR); sfputu(op, pz->win); if (pz->disc->comment) { sfputc(op, PZ_HDR_comment); m = strlen(pz->disc->comment) + 1; sfputu(op, m); sfwrite(op, pz->disc->comment, m); } if (pz->det && (m = sfstrtell(pz->det))) { sfputc(op, PZ_HDR_options); if (!(s = sfstruse(pz->det))) { if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "out of space"); return -1; } m++; sfputu(op, m); sfwrite(op, s, m); } if (i = pz->prefix.count) { sfputc(op, PZ_HDR_prefix); if (pz->prefix.terminator >= 0) { m = 0; while (i-- > 0) { if (!(s = sfgetr(pz->io, pz->prefix.terminator, 0))) { if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s"); return -1; } m += n = sfvalue(pz->io); sfwrite(pz->tmp, s, n); } s = sfstrseek(pz->tmp, 0, SEEK_SET); } else { m = i; if (!(s = (char*)sfreserve(pz->io, m, 0))) { if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s"); return -1; } } sfputu(op, m); sfwrite(op, s, m); } pz->flags |= PZ_HEAD; return pzpartwrite(pz, op); }
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); }
void copy(register Archive_t* ap, register int (*copyfile)(Ftw_t*)) { register char* s; register char* t; register char* v; register int c; unsigned long flags; char* mode; char* mtime; if (ap) { deltabase(ap); if (ap->delta && ap->delta->format != ap->expected && ap->expected) error(3, "%s: archive format %s does not match requested format %s", ap->name, ap->delta->format->name, ap->expected->name); if (state.append || state.update) { ap->format = ap->delta->format; if (!(ap->format->flags & APPEND)) error(3, "%s: archive format %s does support append/update", ap->name, ap->format->name); if (state.update) ap->update = ap->delta->tab; ap->delta = 0; ap->parent = 0; ap->volume--; } putprologue(ap, state.append || state.update); } if (state.files) ftwalk((char*)state.files, copyfile, state.ftwflags|FTW_MULTIPLE, state.exact ? (Ftw_cmp_t)0 : cmpftw); else { sfopen(sfstdin, NiL, "rt"); sfset(sfstdin, SF_SHARE, 0); mode = state.mode; mtime = state.mtime; for (;;) { if (s = state.peekfile) { state.peekfile = 0; c = state.peeklen; } else if (!(s = sfgetr(sfstdin, '\n', 1))) break; else c = sfvalue(sfstdin) - 1; sfwrite(state.tmp.lst, s, c); if (!(s = sfstruse(state.tmp.lst))) nospace(); flags = state.ftwflags; if (state.filter.line) { if (!(c = *s++)) continue; state.filter.options = s; if (!(s = skip(s, c))) continue; *s++ = 0; state.filter.command = s; if (!(s = skip(s, c))) continue; *s++ = 0; state.filter.path = s; if (!(s = skip(s, c))) state.filter.name = state.filter.path; else { *s++ = 0; state.filter.name = s; if (s = skip(s, c)) *s = 0; } s = state.filter.options; for (;;) { if (t = strchr(s, ',')) *t = 0; if (v = strchr(s, '=')) { *v++ = 0; c = strtol(v, NiL, 0); } else c = 1; if (s[0] == 'n' && s[1] == 'o') { s += 2; c = !c; } if (streq(s, "logical") || streq(s, "physical")) { if (s[0] == 'p') c = !c; if (c) flags &= ~(FTW_META|FTW_PHYSICAL); else { flags &= ~(FTW_META); flags |= FTW_PHYSICAL; } } else if (streq(s, "mode")) state.mode = v; else if (streq(s, "mtime")) state.mtime = v; if (!t) break; s = t + 1; } s = state.filter.path; state.filter.line = *state.filter.name ? 2 : 1; } c = *s ? ftwalk(s, copyfile, flags, NiL) : 0; state.mode = mode; state.mtime = mtime; if (c) { error(2, "%s: not completely copied", s); break; } } } if (ap) { deltadelete(ap); putepilogue(ap); } }
int b_mime(int argc, char** argv, Shbltin_t* context) { Mime_t* mp; char* s; Sfio_t* sp; int silent; Mimedisc_t disc; cmdinit(argc, argv, context, ERROR_CATALOG, 0); silent = 0; for (;;) { switch (optget(argv, usage)) { case 0: break; case 's': silent = 1; continue; case ':': error(2, "%s", opt_info.arg); continue; case '?': error(ERROR_usage(2), "%s", opt_info.arg); continue; } break; } argc -= opt_info.index; argv += opt_info.index; if (error_info.errors || argc > 1 && argc < 3) error(ERROR_usage(2), "%s", optusage(NiL)); disc.version = MIME_VERSION; disc.flags = 0; disc.errorf = errorf; if (!(mp = mimeopen(&disc))) error(ERROR_exit(1), "mime library error"); if (mimeload(mp, NiL, 0)) { mimeclose(mp); error(ERROR_exit(1), "mime load error"); } if (argc <= 1) mimelist(mp, sfstdout, argv[0]); else if (!(sp = sfstropen())) error(ERROR_exit(1), "out of space"); else { for (argc = 3; s = argv[argc]; argc++) sfputr(sp, s, ';'); if (!(s = sfstruse(sp))) error(ERROR_exit(1), "out of space"); if (!(s = mimeview(mp, argv[0], argv[1], argv[2], s))) { if (silent) exit(1); error(ERROR_exit(1), "no %s view for mime type %s", argv[0], argv[2]); } else sfputr(sfstdout, s, '\n'); sfclose(sp); } mimeclose(mp); return 0; }