#include #include #include #include "dat.h" #include "protos.h" typedef struct { uchar res; uchar cmd; uchar err; uchar cnt; } Hdr; enum { Ocmd, Oerr, Ocnt, Hsize = 4, }; static Field p_fields[] = { { "cmd", Fnum, Ocmd, "command", }, { "err", Fnum, Oerr, "error", }, { "cnt", Fnum, Ocnt, "count", }, nil }; static Mux p_mux[] = { { "aoemd", 0 }, { "aoemd", 1 }, nil }; static void p_compile(Filter *f) { Mux *m; if(f->op == '='){ compile_cmp(aoerr.name, f, p_fields); return; } for(m = p_mux; m->name; m++) if(strcmp(f->s, m->name) == 0){ f->pr = m->pr; f->ulv = m->val; f->subop = Ocmd; return; } sysfatal("unknown aoemask field: %s", f->s); } static int p_filter(Filter *f, Msg *m) { Hdr *h; if(m->pe - m->ps < Hsize) return 0; h = (Hdr*)m->ps; m->ps += Hsize; switch(f->subop){ case Ocmd: return h->cmd == f->ulv; case Oerr: return h->err == f->ulv; case Ocnt: return h->cnt == f->ulv; } return 0; } static char *ctab[] = { "read", "edit", }; static char *etab[] = { "", "bad", "full", }; static int p_seprint(Msg *m) { char *s, *t; Hdr *h; if(m->pe - m->ps < Hsize) return 0; h = (Hdr*)m->ps; m->ps += Hsize; demux(p_mux, h->cmd, h->cmd, m, &dump); s = "unk"; if(h->cmd < nelem(ctab)) s = ctab[h->cmd]; t = "unk"; if(h->err < nelem(etab)) s = etab[h->err]; m->p = seprint(m->p, m->e, "cmd=%d %s err=%d %s cnt=%d\n", h->cmd, s, h->err, t, h->cnt); return 0; } Proto aoemask = { "aoemask", p_compile, p_filter, p_seprint, p_mux, "%lud", p_fields, defaultframer, };