static int fixedopen(Dssfile_t* file, Dssdisc_t* disc) { if (file->flags & DSS_FILE_READ) { if (!sfreserve(file->io, file->skip, 0)) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "header read error"); return -1; } if (!(file->data = (void*)vmnewof(file->dss->vm, 0, State_t, 1, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } ((State_t*)file->data)->swap = file->ident; } else if (!(file->flags & DSS_FILE_APPEND)) { Fixedheader_t hdr; memset(&hdr, 0, sizeof(hdr)); hdr.magic.magic = MAGICID; strcpy(hdr.magic.name, MAGIC_NAME); strcpy(hdr.magic.type, MAGIC_TYPE); hdr.magic.version = MAGIC_VERSION; hdr.magic.size = sizeof(Netflow_t); sfwrite(file->io, &hdr, sizeof(hdr)); } return 0; }
static int textfopen(Dssfile_t* file, Dssdisc_t* disc) { if (!(file->data = vmnewof(file->dss->vm, 0, Cxvalue_t, ((Text_t*)file->dss->meth->data)->vars, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } return 0; }
static int pstat_init(Pss_t* pss) { register State_t* state; if (!(state = vmnewof(pss->vm, 0, State_t, 1, 0))) { if (pss->disc->errorf) (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space"); return -1; } pss->data = state; return 1; }
static int tableopen(Dssfile_t* file, Dssdisc_t* disc) { Tablestate_t* state; if (!(state = vmnewof(file->dss->vm, 0, Tablestate_t, 1, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } state->route[0].bits = -1; state->v6 = file->caller == file; file->data = (void*)state; return 0; }
static int dumpfopen(Dssfile_t* file, Dssdisc_t* disc) { State_t* state; if (!(state = vmnewof(file->dss->vm, 0, State_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } file->data = state; if (file->flags & DSS_FILE_WRITE) state->data = (char*)(state + 1); return 0; }
static int ftfopen(Dssfile_t* file, Dssdisc_t* disc) { State_t* state; if (!sfreserve(file->io, file->ident & ((1<<20)-1), 0)) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "heaxder read error"); return -1; } if (!(state = vmnewof(file->dss->vm, 0, State_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } file->data = state; state->swap = (file->ident >> 28) & ((1<<4)-1); state->version = (file->ident >> 20) & ((1<<8)-1); switch (state->version) { case 1: state->size = sizeof(Rec_1_t); break; case 5: state->size = sizeof(Rec_5_t); break; case 6: state->size = sizeof(Rec_6_t); break; case 7: state->size = sizeof(Rec_7_t); break; } state->chunk = (1024 * 1024 + state->size - 1) / state->size; if (file->flags & DSS_FILE_WRITE) state->data = (char*)(state + 1); state->record.version = state->version; return 0; }
int pssttyadd(register Pss_t* pss, const char* name, Pss_dev_t dev) { register Tty_t* tty; if (!dtmatch(pss->ttybyname, name)) { if (!(tty = vmnewof(pss->vm, 0, Tty_t, 1, strlen(name)))) { if (pss->disc->errorf) (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space"); return -1; } strcpy(tty->name, name); tty->dev = dev; dtinsert(pss->ttybyname, tty); if (!dtmatch(pss->ttybydev, &dev)) dtinsert(pss->ttybydev, tty); } return 0; }
Pss_t* pssopen(Pssdisc_t* disc) { register Pss_t* pss; Vmalloc_t* vm; if (!disc) return 0; if (!(vm = vmopen(Vmdcheap, Vmbest, 0)) || !(pss = vmnewof(vm, 0, Pss_t, 1, 0))) goto bad; pss->id = lib; pss->disc = disc; pss->vm = vm; pss->ttybynamedisc.key = offsetof(Tty_t, name); pss->ttybynamedisc.size = 0; pss->ttybynamedisc.link = offsetof(Tty_t, byname); pss->ttybydevdisc.key = offsetof(Tty_t, dev); pss->ttybydevdisc.size = sizeof(Pss_dev_t); pss->ttybydevdisc.link = offsetof(Tty_t, bydev); if (!(pss->ttybyname = dtnew(pss->vm, &pss->ttybynamedisc, Dtset)) || !(pss->ttybydev = dtnew(pss->vm, &pss->ttybydevdisc, Dtset))) goto bad; pss->meth = (_pss_ps && ((disc->flags & PSS_PS) || getenv("_PSS_ps"))) ? _pss_ps : _pss_method; while (pss->meth->initf && (*pss->meth->initf)(pss) <= 0) if (pss->meth == _pss_ps || !(pss->meth = _pss_ps)) { vmclose(vm); return 0; } return pss; bad: if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); if (vm) vmclose(vm); return 0; }
Dssfile_t* dssfopen(Dss_t* dss, const char* path, Sfio_t* io, Dssflags_t flags, Dssformat_t* format) { Dssfile_t* file; Vmalloc_t* vm; char* s; size_t n; int i; struct stat st; Sfdisc_t top; char buf[PATH_MAX]; if (flags & DSS_FILE_WRITE) { if (io) { memset(&top, 0, sizeof(top)); if (sfdisc(io, &top)) { n = top.disc == &dss->state->compress_preferred; sfdisc(io, SF_POPDISC); if (n) { sfdisc(io, SF_POPDISC); sfdczip(io, path, dss->meth->compress ? dss->meth->compress : "gzip", dss->disc->errorf); } } } if (dss->flags & DSS_APPEND) flags |= DSS_FILE_APPEND; } if (!path || !*path || streq(path, "-")) { if (flags & DSS_FILE_WRITE) { if (io) path = "output-stream"; else { path = "/dev/stdout"; io = sfstdout; } } else if (io) path = "input-stream"; else { path = "/dev/stdin"; io = sfstdin; } flags |= DSS_FILE_KEEP; } else if (io) flags |= DSS_FILE_KEEP; else if (flags & DSS_FILE_WRITE) { if (!(io = sfopen(NiL, path, (flags & DSS_FILE_APPEND) ? "a" : "w"))) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot open", path); return 0; } } else if (!(io = dssfind(path, "", DSS_VERBOSE, buf, sizeof(buf), dss->disc))) return 0; else path = (const char*)buf; if (!(vm = vmopen(Vmdcheap, Vmbest, 0))) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space"); return 0; } if (!(file = vmnewof(vm, 0, Dssfile_t, 1, strlen(path) + 1))) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space"); if (!(flags & DSS_FILE_KEEP)) sfclose(io); vmclose(vm); return 0; } strcpy(file->path = (char*)(file + 1), path); file->dss = dss; file->vm = vm; file->io = io; file->flags = flags; if (flags & DSS_FILE_WRITE) { if (!(file->format = format) && !(file->format = dss->format)) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "output method format must be specified"); if (!(flags & DSS_FILE_KEEP)) sfclose(io); return 0; } file->readf = noreadf; file->writef = file->format->writef; } else { if (sfsize(file->io) || !fstat(sffileno(file->io), &st) && (S_ISFIFO(st.st_mode) #ifdef S_ISSOCK || S_ISSOCK(st.st_mode) #endif )) { if (sfdczip(file->io, file->path, NiL, dss->disc->errorf) < 0) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: inflate error", file->path); dssfclose(file); return 0; } s = sfreserve(file->io, SF_UNBOUND, SF_LOCKR); n = sfvalue(file->io); if (!s) { if (n && dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot peek", file->path); dssfclose(file); return 0; } for (file->format = (Dssformat_t*)dtfirst(dss->meth->formats); file->format && !(i = (*file->format->identf)(file, s, n, dss->disc)); file->format = (Dssformat_t*)dtnext(dss->meth->formats, file->format)); sfread(file->io, s, 0); if (!file->format) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: unknown %s format", file->path, dss->meth->name); dssfclose(file); return 0; } if (i < 0) return 0; if (format && format != file->format) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s file format %s incompatible with %s", file->path, dss->meth->name, file->format->name, format->name); dssfclose(file); return 0; } if ((dss->flags & DSS_VERBOSE) && dss->disc->errorf) (*dss->disc->errorf)(dss, dss->disc, 1, "%s: %s method %s format", file->path, dss->meth->name, file->format->name); file->readf = file->format->readf; } else { file->format = format ? format : dss->format ? dss->format : (Dssformat_t*)dtfirst(dss->meth->formats); file->readf = nullreadf; } file->writef = nowritef; if (!dss->format) dss->format = file->format; } if (!file->format) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s method did not set file format", file->path, dss->meth->name); dssfclose(file); return 0; } file->record.file = file; if ((*file->format->openf)(file, dss->disc)) { dssfclose(file); return 0; } return file; }
Pssent_t* pssread(register Pss_t* pss, Pss_id_t pid) { register unsigned long fields = pss->meth->fields; register unsigned long flags = pss->disc->flags; register Pssent_t* pe; Pssmatch_t* mp; Pssdata_t* dp; unsigned long x; int i; for (;;) { if ((*pss->meth->readf)(pss, pid) <= 0) return 0; if (!pss->ent && !(pss->ent = vmnewof(pss->vm, 0, Pssent_t, 1, 0))) { if (pss->disc->errorf) (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space"); return 0; } pe = pss->ent; if ((i = (*pss->meth->partf)(pss, pe)) < 0) return 0; if (!i) { memset(pe, 0, sizeof(*pe)); pe->pid = pss->pid; goto next; } if (pid) pe->pss = PSS_EXPLICIT; else if (flags & PSS_ALL) pe->pss = PSS_MATCHED; else { if (flags & (PSS_ATTACHED|PSS_DETACHED|PSS_LEADER|PSS_NOLEADER|PSS_TTY|PSS_UID)) { if ((flags & PSS_TTY) && pe->tty != TTYMAP(pss, pss->disc->tty)) goto next; if ((flags & PSS_UID) && pe->uid != pss->disc->uid) goto next; switch (flags & (PSS_ATTACHED|PSS_DETACHED)) { case PSS_ATTACHED: if (pe->tty == PSS_NODEV) goto next; break; case PSS_DETACHED: if (pe->tty != PSS_NODEV) goto next; break; } switch (flags & (PSS_LEADER|PSS_NOLEADER)) { case PSS_LEADER: if ((fields & PSS_sid) && pe->pid != pe->sid) goto next; if ((fields & PSS_tgrp) && pe->pid != pe->tgrp) goto next; break; case PSS_NOLEADER: if ((fields & PSS_sid) && pe->pid == pe->sid) goto next; if ((fields & PSS_tgrp) && pe->pid == pe->tgrp) goto next; break; } pe->pss = PSS_MATCHED; } if (mp = pss->disc->match) { do { switch (mp->field) { case PSS_gid: x = pe->gid; break; case PSS_pgrp: x = pe->pgrp; break; case PSS_sid: x = pe->sid; break; case PSS_tgrp: x = pe->tgrp; break; case PSS_tty: x = pe->tty; if (pss->meth->ttymapf) for (dp = mp->data; dp; dp = dp->next) dp->data = TTYMAP(pss, dp->data); break; case PSS_uid: x = pe->uid; break; default: if (pss->disc->errorf) (*pss->disc->errorf)(pss, pss->disc, 2, "%08lx selection not implemented", mp->field); return 0; } for (dp = mp->data; dp; dp = dp->next) if (dp->data == x) break; } while (!dp && (mp = mp->next)); if (!mp) goto next; pe->pss = PSS_MATCHED; } } break; next: if (flags & PSS_UNMATCHED) { pe->pss = 0; break; } if (pid) return 0; } if (pss->meth->fullf && (*pss->meth->fullf)(pss, pe) <= 0) return 0; if (pe->pid <= 1 && pe->ppid > 1) { pe->ppid = 0; if (pe->pid == 0) pe->args = pe->command = "sched"; } return pe; }
int pzheadread(register Pz_t* pz) { register int i; register int n; register unsigned char* s; size_t m; Pzpart_t* pp; if (pz->flags & PZ_HEAD) return 0; /* * check the header magic */ if (s = (unsigned char*)sfreserve(pz->io, 4, 1)) { i = s[0]; n = s[1]; } else i = n = 0; if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzheadread: f=%08x i=%02x n=%02x partition=%s%s", pz->path, pz->flags, i, n, pz->disc->partition, s ? "" : " (nil)"); if (i != PZ_MAGIC_1 || n != PZ_MAGIC_2 || s[2] == 0 || s[3] >= 10) { sfread(pz->io, s, 0); if (pz->flags & PZ_SPLIT) return 0; if (pz->flags & PZ_DISC) { pz->flags &= ~PZ_POP; return -1; } if (!(pz->flags & (PZ_READ|PZ_WRITE|PZ_STAT)) && (m = pz->prefix.count)) { if (pz->prefix.terminator >= 0) { while (m-- > 0) { if (!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; } } } else if (!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; } } if (!(n = pz->row)) { if ((pz->flags & PZ_ACCEPT) || !sfsize(pz->io)) n = 1; else if ((n = pzfixed(pz, pz->io, NiL, 0)) <= 0 && pz->disc->partition) { pz->flags |= PZ_ROWONLY; if (!pzpartition(pz, pz->disc->partition)) n = pz->row; pz->flags &= ~PZ_ROWONLY; } } if (n <= 0) { if (!(pz->flags & PZ_DELAY) && (pz->disc->partition || !(pz->flags & PZ_FORCE))) { if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, 2, "%s: unknown input format", pz->path); return -1; } pz->flags |= PZ_UNKNOWN; n = 1; } if (!(pp = vmnewof(pz->vm, 0, Pzpart_t, 1, 0))) return -1; pz->major = PZ_MAJOR; pz->minor = PZ_MINOR; pp->name = ""; pp->row = n; return pzpartinit(pz, pp, NiL); } sfread(pz->io, s, 2); pz->flags &= ~PZ_FORCE; pz->major = sfgetc(pz->io); pz->minor = sfgetc(pz->io); switch (pz->major) { case 1: if (pz->minor <= 2) goto noway; break; case 2: pz->win = sfgetu(pz->io); break; default: goto noway; } pz->flags |= PZ_HEAD; return pzpartread(pz); noway: if (pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, 2, "%s: data %d.%d not supported by implementation %d.%d", pz->path, pz->major, pz->minor, PZ_MAJOR, PZ_MINOR); return -1; }
int dssprintf(Dss_t* dss, Cx_t* cx, Sfio_t* sp, const char* format, Dssrecord_t* record) { register char* s; register char* t; register char* d; register char* v; register int n; register int q; register Arg_t* ap; int l; int x; char* f; char* o; char* w; Format_t* fp; Fmt_t fmt; if (!cx) cx = dss->cx; for (fp = dss->print; fp && fp->oformat != (char*)format; fp = fp->next); if (!fp) { if (f = s = (char*)format) { char* details['z' - 'a' + 1]; memset(details, 0, sizeof(details)); d = 0; l = 0; n = 0; q = 0; w = 0; for (;;) { switch (*s++) { case 0: if (q) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: format character omitted", f); return -1; } break; case '%': if (*s != '%') { q = 1; n++; f = s - 1; } continue; case '(': if (q == 1) { q++; for (;;) { switch (*s++) { case 0: s--; break; case '(': q++; continue; case ')': if (--q == 1) break; continue; case ':': if (*s == ':') s++; else if (!d) d = s; continue; default: continue; } break; } if (d) { l += s - d + 1; d = 0; } } continue; case 'c': case 'd': case 'e': case 'f': case 'g': case 'o': case 's': case 'u': case 'x': if (q == 1) q = 0; continue; default: continue; } break; } if (!(fp = vmnewof(dss->vm, 0, Format_t, 1, (n - 1) * sizeof(Arg_t) + strlen(format) + 2 * n + l + 2))) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space"); return -1; } fp->oformat = (char*)format; fp->next = dss->print; dss->print = fp; ap = &fp->arg[0]; s = t = fp->nformat = (char*)(&fp->arg[n]); strcpy(t, format); f = t + strlen(format) + 2 * n + 1; q = 0; d = 0; l = 0; for (;;) { switch (*t++ = *s++) { case 0: *(t - 1) = '\n'; *t = 0; break; case '%': if (*s == '%') *t++ = *s++; else q = 1; continue; case '(': if (q == 1) { q++; t--; x = 0; v = s; for (;;) { switch (*s++) { case 0: if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %(...) imbalance", fp->oformat); return -1; case '(': if (!d) x = 1; q++; continue; case ')': if (--q == 1) break; continue; case ':': if (*s == ':') s++; else if (!d && q == 2) d = s; continue; case ',': if (!d) x = 1; continue; default: if (!d && cx->table->opcode[*(unsigned char*)(s - 1)]) x = 1; continue; } break; } if (d) *(d - 1) = 0; *(s - 1) = 0; if (*v) { if (x) { void* pop; if (!(pop = cxpush(cx, NiL, NiL, v, (d ? d : s) - v, 0))) return -1; ap->expr = cxcomp(cx); cxpop(cx, pop); if (!ap->expr) return -1; } else if (cx->referencef) { Cxoperand_t a; Cxoperand_t b; Cxoperand_t r; a.type = cx->state->type_string; a.value.string.size = s - v - 1; a.value.string.data = v; b.type = a.type; if ((*cx->referencef)(cx, NiL, &r, &b, &a, NiL, cx->disc)) return -1; ap->variable = r.value.variable; } else if (!(ap->variable = cxvariable(cx, v, NiL, cx->disc))) return -1; } else if (d) { w = d; d = 0; } } continue; case 'c': if (q == 1) { ap->type = DSS_FORMAT_char; ap->cast = cx->state->type_number; goto set; } continue; case 'd': case 'o': case 'u': case 'x': if (q == 1) { if (l > 1 || ap->variable && (ap->variable->format.width == 8 || ap->variable->type->format.width == 8)) { n = *(t - 1); *(t - 1) = 'l'; *t++ = 'l'; *t++ = n; ap->type = DSS_FORMAT_long; } else ap->type = DSS_FORMAT_int; ap->cast = cx->state->type_number; goto set; } continue; case 'e': case 'f': case 'g': if (q == 1) { ap->type = DSS_FORMAT_float; ap->cast = cx->state->type_number; goto set; } continue; case 'h': if (q == 1) t--; continue; case 'l': if (q == 1) { t--; l++; } continue; case 's': if (q == 1) { ap->type = DSS_FORMAT_string; ap->cast = cx->state->type_string; set: if (w) { details[*(s-1) - 'a'] = w; w = 0; fp->nformat = t = s; continue; } if (!ap->variable && !ap->expr) { if (dss->disc->errorf) { *t = 0; (*dss->disc->errorf)(NiL, dss->disc, 2, "%s: (variable) omitted in format", fp->nformat); } return -1; } l = 0; q = 0; if (d || (d = details[*(s-1) - 'a']) || (d = cx->state->type_string->format.details)) { ap->fmt = FMT_ALWAYS|FMT_ESCAPED; while (*d) { o = 0; v = d; while (*d) if (*d++ == ':') { *(o = d - 1) = 0; break; } if (strneq(v, "edit=", 5)) { if (o) *o = ':'; if (ap->edit = cxedit(cx, v + 5, dss->disc)) { d = v + 5 + ap->edit->re.re_npat; if (d == o) d++; } } else if (strneq(v, "endquote=", 8)) { ap->qe = v += 8; while (*f++ = *v++); } else if (streq(v, "expand")) { ap->fmt |= FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE; continue; } else if (strneq(v, "expand=", 7)) { v += 7; while (*v) { if (*v == '|' || *v == ',') { v++; continue; } if (strneq(v, "all", 3)) { ap->fmt |= FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE; break; } else if (strneq(v, "char", 4)) { v += 4; ap->fmt |= FMT_EXP_CHAR; } else if (strneq(v, "line", 4)) { v += 4; ap->fmt |= FMT_EXP_LINE; } else if (strneq(v, "nocr", 4)) { v += 4; ap->fmt |= FMT_EXP_NOCR; } else if (strneq(v, "nonl", 4)) { v += 4; ap->fmt |= FMT_EXP_NONL; } else if (strneq(v, "wide", 4)) { v += 4; ap->fmt |= FMT_EXP_WIDE; } else while (*v && *v != '|' && *v != ',') v++; } continue; } else if (streq(v, "escape")) ap->fmt &= ~FMT_ESCAPED; else if (strneq(v, "opt", 3)) ap->fmt &= ~FMT_ALWAYS; else if (streq(v, "quote") || strneq(v, "quote=", 6)) { if (v[5]) { ap->qb = v += 6; while (*f++ = *v++); } else ap->qb = "\""; if (!ap->qe) ap->qe = ap->qb; } else if (streq(v, "shell") || strneq(v, "shell=", 6)) { ap->fmt |= FMT_SHELL; if (v[5]) { ap->qb = v += 6; while (*f++ = *v++); } else ap->qb = "$'"; if (!ap->qe) ap->qe = "'"; } else if (streq(v, "wide")) ap->fmt |= FMT_WIDE; else { if (*d) *(d - 1) = ':'; d = v; break; } ap->flags |= DSS_FORMAT_quote; } ap->details = f; while (*f++ = *d++); d = 0; } if (ap->variable && !ap->edit && cxisstring(ap->variable->type) && ap->variable->format.map && ap->variable->format.map->part && ap->variable->format.map->part->edit) ap->edit = ap->variable->format.map->part->edit; ap++; } continue; case 'L': if (q == 1) { t--; l += 2; } continue; default: continue; } break; } } else { Cxvariable_t* vp; n = q = 0; if (dss->meth->cx->fields) { for (vp = (Cxvariable_t*)dtfirst(dss->meth->cx->fields); vp; vp = (Cxvariable_t*)dtnext(dss->meth->cx->fields, vp), n++) if (!(vp->header.flags & CX_DEPRECATED) && q < (l = strlen(vp->name))) q = l; } else if (dss->meth->data) { for (vp = (Cxvariable_t*)dss->meth->data; vp->name; vp++, n++) if (!(vp->header.flags & CX_DEPRECATED) && q < (l = strlen(vp->name))) q = l; } q += 2; if (!(fp = vmnewof(dss->vm, 0, Format_t, 1, n * sizeof(Arg_t) + n * (q + 3) + 2))) { if (dss->disc->errorf) (*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space"); return -1; } fp->oformat = 0; fp->next = dss->print; dss->print = fp; ap = &fp->arg[0]; s = fp->nformat = (char*)(&fp->arg[n]); *s++ = '\n'; vp = dss->meth->cx->fields ? (Cxvariable_t*)dtfirst(dss->meth->cx->fields) : dss->meth->data ? (Cxvariable_t*)dss->meth->data : 0; if (vp) for (;;) { if (dss->meth->cx->fields) { if (!vp) break; } else if (!vp->name) break; if (!(vp->header.flags & CX_DEPRECATED)) { s += sfsprintf(s, q + 4, "%-*s%%s\n", q, vp->name); ap->variable = vp; ap->type = DSS_FORMAT_string; ap->cast = cx->state->type_string; if (cxisstring(vp->type) && vp->format.map && vp->format.map->part && vp->format.map->part->edit) ap->edit = vp->format.map->part->edit; ap++; } if (dss->meth->cx->fields) vp = (Cxvariable_t*)dtnext(dss->meth->cx->fields, vp); else vp++; } *s = 0; } if (!sp) return 0; } memset(&fmt, 0, sizeof(fmt)); fmt.fmt.version = SFIO_VERSION; fmt.fmt.form = fp->nformat; fmt.fmt.extf = getfmt; fmt.cx = cx; fmt.data = record; fmt.ap = &fp->arg[0]; n = sfprintf(sp, "%!", &fmt); return !sp ? 0 : (fmt.errors || n <= 0 && sp && sferror(sp)) ? -1 : n; }
static int validate_sel(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc) { register State_t* state = (State_t*)expr->data; register Field_t* field; register Cxconstraint_t*constraint; Cxoperand_t o; Cxinstruction_t x; Invalid_t key; Invalid_t* ip; size_t n; for (field = state->field; field; field = field->next) { x.data.variable = field->variable; if ((*state->getf)(cx, &x, &o, NiL, NiL, data, disc)) return -1; if (field->variable->format.map) { if (cxisstring(field->variable->type)) { if (cxstr2num(cx, &field->variable->format, o.value.string.data, o.value.string.size, NiL)) { if (state->verbose && disc->errorf) (*disc->errorf)(NiL, disc, 1, "%s%s: %-.*s: unknown map name", cxlocation(cx, data), field->variable->name, o.value.string.size, o.value.string.data); goto invalid; } } else if (cxisnumber(field->variable->type)) { if (cxnum2str(cx, &field->variable->format, (Cxinteger_t)o.value.number, NiL)) { if (state->verbose && disc->errorf) (*disc->errorf)(NiL, disc, 1, "%s%s: %I*d: unknown map value", cxlocation(cx, data), field->variable->name, sizeof(Cxinteger_t), (Cxinteger_t)o.value.number); goto invalid; } } } if (constraint = field->variable->format.constraint) { if (constraint->constraintf) ; if (cxisnumber(field->variable->type)) { if (constraint->min && o.value.number < constraint->min->number) { if (state->verbose && disc->errorf) (*disc->errorf)(NiL, disc, 1, "%s%s: %1.15Lg violates min constraint %1.15Lg", cxlocation(cx, data), field->variable->name, o.value.number, constraint->min->number); goto invalid; } if (constraint->max && o.value.number > constraint->max->number) { if (state->verbose && disc->errorf) (*disc->errorf)(NiL, disc, 1, "%s%s: %1.15Lg violates max constraint %1.15Lg", cxlocation(cx, data), field->variable->name, o.value.number, constraint->max->number); goto invalid; } } if (constraint->expression) ; if (constraint->pattern) ; } continue; invalid: if (state->invalid) { key.variable = field->variable; key.value = o.value; if (!(ip = (Invalid_t*)dtsearch(state->invalid, &key))) { n = cxsize(field->variable->type, &o.value); if (!(ip = vmnewof(state->vm, 0, Invalid_t, 1, n))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } *ip = key; ip->value = o.value; if (n) { ip->value.buffer.data = (void*)(ip + 1); memcpy(ip->value.buffer.data, o.value.buffer.data, n); } dtinsert(state->invalid, ip); ip->count = 0; } ip->count++; } if (state->setf && constraint && constraint->def) { o.type = field->variable->type; o.value = *constraint->def; if ((*state->setf)(cx, &x, &o, &o, NiL, data, disc)) return -1; field->repaired++; } else if (state->discard) { field->discarded++; return 0; } else field->invalid++; } return 1; }
static int validate_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc) { char** argv = (char**)data; int errors = error_info.errors; char* s; State_t* state; Cxvariable_t* variable; register Field_t* field; Field_t* lastfield; Cxconstraint_t* constraint; int all; int list; Vmalloc_t* vm; if (!(vm = vmopen(Vmdcheap, Vmlast, 0)) || !(state = vmnewof(vm, 0, State_t, 1, 0))) { if (vm) vmclose(vm); if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } state->vm = vm; list = 0; sfprintf(cx->buf, "%s%s", strchr(dss_lib_validate.description, '['), validate_usage); s = sfstruse(cx->buf); for (;;) { switch (optget(argv, s)) { case 'd': state->discard = 1; continue; case 'l': list = 1; continue; case 'r': if (!(state->setf = cxcallout(cx, CX_SET, cx->state->type_void, cx->state->type_void, cx->disc))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, 3, "reair requires CX_SET callout"); return -1; } continue; case 's': state->summary = 1; continue; case 'v': state->summary = state->verbose = 1; continue; case '?': if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg); else return -1; continue; case ':': if (disc->errorf) (*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg); else return -1; continue; } break; } if (error_info.errors > errors) goto bad; argv += opt_info.index; if (all = !*argv) variable = 0; do { if (all) { if (!(variable = (Cxvariable_t*)(variable ? dtnext(cx->fields, variable) : dtfirst(cx->fields)))) break; } else if (!(variable = cxvariable(cx, *argv, NiL, disc))) goto bad; if (variable->format.constraint || variable->format.map) { if (!(field = vmnewof(vm, 0, Field_t, 1, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); goto bad; } field->variable = variable; if (state->field) lastfield = lastfield->next = field; else lastfield = state->field = field; } } while (all || *++argv); if (!state->field && disc->errorf) (*disc->errorf)(NiL, disc, 1, "no field has constraints or maps"); if (list) { for (field = state->field; field; field = field->next) { sfprintf(expr->op, "%16s", field->variable->name); if (field->variable->format.map) sfprintf(expr->op, " map"); if (constraint = field->variable->format.constraint) { if (constraint->name) sfprintf(expr->op, " name=%s", constraint->name); if (constraint->constraintf) sfprintf(expr->op, " external"); if (cxisnumber(field->variable->type)) { if (constraint->def) number(expr->op, "default", constraint->def->number, &field->variable->format); if (constraint->min) number(expr->op, "min", constraint->min->number, &field->variable->format); if (constraint->max) number(expr->op, "max", constraint->max->number, &field->variable->format); } else if (cxisstring(field->variable->type) && constraint->def) sfprintf(expr->op, " default=\"%-.*s\"", constraint->def->string.size, constraint->def->string.data); if (constraint->expression) sfprintf(expr->op, " expression=\"%s\"", constraint->expression); if (constraint->pattern) sfprintf(expr->op, " pattern=\"%s\"", constraint->pattern); } sfprintf(expr->op, "\n"); } goto bad; } if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout"); goto bad; } if (!state->verbose) { state->invaliddisc.comparf = invalidcmp; if (!(state->invalid = dtnew(vm, &state->invaliddisc, Dtoset))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout"); goto bad; } } expr->data = state; return 0; bad: vmclose(vm); return -1; }
static int merge_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc) { register State_t* state; register File_t* file; char** argv = (char**)data; char** files = expr->files; Dss_t* dss = DSS(cx); int errors = error_info.errors; int i; int k; int n; int r; char* path; char* u; char** v; Cxvariable_t* variable; Cxoperand_t* operands; Key_t* key; Key_t* lastkey; Key_t* keys; Vmalloc_t* vm; if (!(vm = vmopen(Vmdcheap, Vmbest, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); return -1; } r = -1; k = 0; keys = 0; sfprintf(cx->buf, "%s%s", strchr(dss_lib_merge.description, '['), merge_usage); u = sfstruse(cx->buf); for (;;) { switch (i = optget(argv, u)) { case 'k': case 'r': if (!(variable = cxvariable(cx, opt_info.arg, NiL, disc))) goto bad; if (!(key = vmnewof(vm, 0, Key_t, 1, 0))) { if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space"); goto bad; } key->variable = variable; key->sense = (i == 'r') ? -1 : 1; if (keys) lastkey = lastkey->next = key; else lastkey = keys = key; k++; continue; case '?': if (disc->errorf) (*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg); else return -1; continue; case ':': if (disc->errorf) (*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg); else return -1; continue; } break; } if (error_info.errors > errors) goto bad; argv += opt_info.index; for (v = argv; *v; v++); n = v - argv; if (files) { for (v = files; *v; v++); n += v - files; } if (!n) n = 1; if (!(state = vmnewof(vm, 0, State_t, 1, (n - 1) * sizeof(File_t))) || !(operands = vmnewof(vm, 0, Cxoperand_t, n * k, 0))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space"); goto bad; } state->cx = cx; if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, 2, "CX_GET callout required"); goto bad; } state->nfiles = n; state->nkeys = k; state->keys = keys; for (n = 0; n < state->nfiles; n++) { state->files[n].data = operands; operands += k; } state->orderdisc.comparf = ordercmp; if (!(state->order = dtnew(vm, &state->orderdisc, Dtoset))) { if (cx->disc->errorf) (*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space"); goto bad; } n = 0; if (path = *argv) argv++; else if (files) { argv = files; files = 0; if (path = *argv) argv++; } for (;;) { if (!(state->files[n].file = dssfopen(dss, path, NiL, DSS_FILE_READ, NiL))) goto drop; enter(dss, state, &state->files[n]); n++; if (!(path = *argv++)) { if (!files) break; argv = files; files = 0; if (!(path = *argv++)) break; } } expr = expr->pass; if (dssbeg(dss, expr)) goto drop; while (file = (File_t*)dtfirst(state->order)) { if (dsseval(dss, expr, file->record) < 0) goto drop; enter(dss, state, file); } if (error_info.errors == errors) r = 0; drop: for (n = 0; n < state->nfiles; n++) if (state->files[n].file) dssfclose(state->files[n].file); bad: vmclose(vm); return r; }