#include "stralloc.h"
#include "gen_alloc.h"
#include "gen_allocdefs.h"
#include "strerr.h"
#include "getln.h"
#include "substdio.h"
#include "subfd.h"
#include "readwrite.h"
#include "exit.h"
#include "str.h"
#include "fmt.h"
#include "scan.h"
#include "case.h"
#define FATAL "matchup: fatal: "
void nomem() { strerr_die2x(111,FATAL,"out of memory"); }
void die_read() { strerr_die2sys(111,FATAL,"unable to read input: "); }
void die_write() { strerr_die2sys(111,FATAL,"unable to write output: "); }
void die_write5() { strerr_die2sys(111,FATAL,"unable to write fd 5: "); }
void out(buf,len) char *buf; int len;
{ if (substdio_put(subfdout,buf,len) == -1) die_write(); }
void outs(buf) char *buf;
{ if (substdio_puts(subfdout,buf) == -1) die_write(); }
char buf5[512];
substdio ss5 = SUBSTDIO_FDBUF(write,5,buf5,sizeof buf5);
void out5(buf,len) char *buf; int len;
{ if (substdio_put(&ss5,buf,len) == -1) die_write5(); }
void outs5(buf) char *buf;
{ if (substdio_puts(&ss5,buf) == -1) die_write5(); }
GEN_ALLOC_typedef(ulongalloc,unsigned long,u,len,a)
GEN_ALLOC_ready(ulongalloc,unsigned long,u,len,a,i,n,x,30,ulongalloc_ready)
GEN_ALLOC_readyplus(ulongalloc,unsigned long,u,len,a,i,n,x,30,ulongalloc_readyplus)
char strnum[FMT_ULONG];
stralloc pool = {0};
unsigned int poolbytes = 0;
int nummsg = 0;
ulongalloc msg = {0};
ulongalloc bytes = {0};
ulongalloc qp = {0};
ulongalloc uid = {0};
ulongalloc numk = {0};
ulongalloc numd = {0};
ulongalloc numz = {0};
ulongalloc sender = {0};
ulongalloc birth = {0};
int msg_find(m)
unsigned long m;
{
int i;
for (i = 0;i < nummsg;++i) if (msg.u[i] == m) return i;
return -1;
}
int msg_add(m)
unsigned long m;
{
int i;
for (i = 0;i < nummsg;++i) if (msg.u[i] == m) return i;
i = nummsg++;
if (!ulongalloc_ready(&msg,nummsg)) nomem();
if (!ulongalloc_ready(&bytes,nummsg)) nomem();
if (!ulongalloc_ready(&qp,nummsg)) nomem();
if (!ulongalloc_ready(&uid,nummsg)) nomem();
if (!ulongalloc_ready(&numk,nummsg)) nomem();
if (!ulongalloc_ready(&numd,nummsg)) nomem();
if (!ulongalloc_ready(&numz,nummsg)) nomem();
if (!ulongalloc_ready(&sender,nummsg)) nomem();
if (!ulongalloc_ready(&birth,nummsg)) nomem();
msg.u[i] = m;
return i;
}
int msg_kill(i)
int i;
{
poolbytes -= str_len(pool.s + sender.u[i]) + 1;
poolbytes -= str_len(pool.s + birth.u[i]) + 1;
--nummsg;
msg.u[i] = msg.u[nummsg];
bytes.u[i] = bytes.u[nummsg];
qp.u[i] = qp.u[nummsg];
uid.u[i] = uid.u[nummsg];
numk.u[i] = numk.u[nummsg];
numd.u[i] = numd.u[nummsg];
numz.u[i] = numz.u[nummsg];
sender.u[i] = sender.u[nummsg];
birth.u[i] = birth.u[nummsg];
}
int numdel = 0;
ulongalloc del = {0};
ulongalloc dmsg = {0};
ulongalloc dchan = {0};
ulongalloc drecip = {0};
ulongalloc dstart = {0};
int del_find(d)
unsigned long d;
{
int i;
for (i = 0;i < numdel;++i) if (del.u[i] == d) return i;
return -1;
}
int del_add(d)
unsigned long d;
{
int i;
for (i = 0;i < numdel;++i) if (del.u[i] == d) return i;
i = numdel++;
if (!ulongalloc_ready(&del,numdel)) nomem();
if (!ulongalloc_ready(&dmsg,numdel)) nomem();
if (!ulongalloc_ready(&dchan,numdel)) nomem();
if (!ulongalloc_ready(&drecip,numdel)) nomem();
if (!ulongalloc_ready(&dstart,numdel)) nomem();
del.u[i] = d;
return i;
}
void del_kill(i)
int i;
{
poolbytes -= str_len(pool.s + dchan.u[i]) + 1;
poolbytes -= str_len(pool.s + drecip.u[i]) + 1;
poolbytes -= str_len(pool.s + dstart.u[i]) + 1;
--numdel;
del.u[i] = del.u[numdel];
dmsg.u[i] = dmsg.u[numdel];
dchan.u[i] = dchan.u[numdel];
drecip.u[i] = drecip.u[numdel];
dstart.u[i] = dstart.u[numdel];
}
stralloc pool2 = {0};
void garbage()
{
int i;
char *x;
if (pool.len - poolbytes < poolbytes + 4096) return;
if (!stralloc_copys(&pool2,"")) nomem();
for (i = 0;i < nummsg;++i) {
x = pool.s + birth.u[i];
birth.u[i] = pool2.len;
if (!stralloc_cats(&pool2,x)) nomem();
if (!stralloc_0(&pool2)) nomem();
x = pool.s + sender.u[i];
sender.u[i] = pool2.len;
if (!stralloc_cats(&pool2,x)) nomem();
if (!stralloc_0(&pool2)) nomem();
}
for (i = 0;i < numdel;++i) {
x = pool.s + dstart.u[i];
dstart.u[i] = pool2.len;
if (!stralloc_cats(&pool2,x)) nomem();
if (!stralloc_0(&pool2)) nomem();
x = pool.s + dchan.u[i];
dchan.u[i] = pool2.len;
if (!stralloc_cats(&pool2,x)) nomem();
if (!stralloc_0(&pool2)) nomem();
x = pool.s + drecip.u[i];
drecip.u[i] = pool2.len;
if (!stralloc_cats(&pool2,x)) nomem();
if (!stralloc_0(&pool2)) nomem();
}
if (!stralloc_copy(&pool,&pool2)) nomem();
poolbytes = pool.len; /* redundant, but doesn't hurt */
}
stralloc line = {0};
int match;
#define FIELDS 20
int field[FIELDS];
void clear()
{
while (numdel > 0) del_kill(0);
garbage();
}
void starting()
{
unsigned long d;
unsigned long m;
int dpos;
scan_ulong(line.s + field[3],&d);
scan_ulong(line.s + field[5],&m);
dpos = del_add(d);
dmsg.u[dpos] = m;
dstart.u[dpos] = pool.len;
if (!stralloc_cats(&pool,line.s + field[0])) nomem();
if (!stralloc_0(&pool)) nomem();
dchan.u[dpos] = pool.len;
if (!stralloc_cats(&pool,line.s + field[7])) nomem();
if (!stralloc_0(&pool)) nomem();
drecip.u[dpos] = pool.len;
if (!stralloc_cats(&pool,line.s + field[8])) nomem();
if (!stralloc_0(&pool)) nomem();
case_lowers(pool.s + drecip.u[dpos]);
poolbytes += pool.len - dstart.u[dpos];
}
void delivery()
{
unsigned long d;
unsigned long m;
int dpos;
int mpos;
char *result = "?";
char *reason = "";
scan_ulong(line.s + field[2],&d);
dpos = del_find(d);
if (dpos == -1) return;
m = dmsg.u[dpos];
mpos = msg_find(m);
if (str_start(line.s + field[3],"succ")) {
if (mpos != -1) ++numk.u[mpos];
result = "d k ";
reason = line.s + field[4];
}
else if (str_start(line.s + field[3],"fail")) {
if (mpos != -1) ++numd.u[mpos];
result = "d d ";
reason = line.s + field[4];
}
else if (str_start(line.s + field[3],"defer")) {
if (mpos != -1) ++numz.u[mpos];
result = "d z ";
reason = line.s + field[4];
}
else if (str_start(line.s + field[3],"report")) {
if (mpos != -1) ++numz.u[mpos];
result = "d z ";
reason = "report_mangled";
}
outs(result);
if (mpos != -1) {
outs(pool.s + birth.u[mpos]);
outs(" "); outs(pool.s + dstart.u[dpos]);
outs(" "); outs(line.s + field[0]);
outs(" "); out(strnum,fmt_ulong(strnum,bytes.u[mpos]));
outs(" "); outs(pool.s + sender.u[mpos]);
outs(" "); outs(pool.s + dchan.u[dpos]);
outs("."); outs(pool.s + drecip.u[dpos]);
outs(" "); out(strnum,fmt_ulong(strnum,qp.u[mpos]));
outs(" "); out(strnum,fmt_ulong(strnum,uid.u[mpos]));
outs(" "); outs(reason);
}
else {
outs(pool.s + dstart.u[dpos]);
outs(" "); outs(pool.s + dstart.u[dpos]);
outs(" "); outs(line.s + field[0]);
outs(" 0 ? "); outs(pool.s + dchan.u[dpos]);
outs("."); outs(pool.s + drecip.u[dpos]);
outs(" ? ? "); outs(reason);
}
outs("\n");
del_kill(dpos);
garbage();
}
void newmsg()
{
unsigned long m;
int mpos;
scan_ulong(line.s + field[3],&m);
mpos = msg_find(m);
if (mpos == -1) return;
msg_kill(mpos);
garbage();
}
void endmsg()
{
unsigned long m;
int mpos;
scan_ulong(line.s + field[3],&m);
mpos = msg_find(m);
if (mpos == -1) return;
outs("m "); outs(pool.s + birth.u[mpos]);
outs(" "); outs(line.s + field[0]);
outs(" "); out(strnum,fmt_ulong(strnum,bytes.u[mpos]));
outs(" "); out(strnum,fmt_ulong(strnum,numk.u[mpos]));
outs(" "); out(strnum,fmt_ulong(strnum,numd.u[mpos]));
outs(" "); out(strnum,fmt_ulong(strnum,numz.u[mpos]));
outs(" "); outs(pool.s + sender.u[mpos]);
outs(" "); out(strnum,fmt_ulong(strnum,qp.u[mpos]));
outs(" "); out(strnum,fmt_ulong(strnum,uid.u[mpos]));
outs("\n");
msg_kill(mpos);
garbage();
}
void info()
{
unsigned long m;
int mpos;
scan_ulong(line.s + field[3],&m);
mpos = msg_add(m);
scan_ulong(line.s + field[5],&bytes.u[mpos]);
scan_ulong(line.s + field[9],&qp.u[mpos]);
scan_ulong(line.s + field[11],&uid.u[mpos]);
numk.u[mpos] = 0;
numd.u[mpos] = 0;
numz.u[mpos] = 0;
birth.u[mpos] = pool.len;
if (!stralloc_cats(&pool,line.s + field[0])) nomem();
if (!stralloc_0(&pool)) nomem();
sender.u[mpos] = pool.len;
if (!stralloc_cats(&pool,line.s + field[7])) nomem();
if (!stralloc_0(&pool)) nomem();
case_lowers(pool.s + sender.u[mpos]);
poolbytes += pool.len - birth.u[mpos];
}
void extra()
{
unsigned long m;
int mpos;
scan_ulong(line.s + field[2],&m);
mpos = msg_find(m);
if (mpos == -1) return;
scan_ulong(line.s + field[3],&numk.u[mpos]);
scan_ulong(line.s + field[4],&numz.u[mpos]);
scan_ulong(line.s + field[5],&numd.u[mpos]);
}
void pending()
{
int i;
for (i = 0;i < nummsg;++i) {
outs5(pool.s + birth.u[i]);
outs5(" info msg ");
out5(strnum,fmt_ulong(strnum,msg.u[i]));
outs5(": bytes ");
out5(strnum,fmt_ulong(strnum,bytes.u[i]));
outs5(" from ");
outs5(pool.s + sender.u[i]);
outs5(" qp ");
out5(strnum,fmt_ulong(strnum,qp.u[i]));
outs5(" uid ");
out5(strnum,fmt_ulong(strnum,uid.u[i]));
outs5("\n");
outs5(pool.s + birth.u[i]);
outs5(" extra ");
out5(strnum,fmt_ulong(strnum,msg.u[i]));
outs5(" ");
out5(strnum,fmt_ulong(strnum,numk.u[i]));
outs5(" ");
out5(strnum,fmt_ulong(strnum,numz.u[i]));
outs5(" ");
out5(strnum,fmt_ulong(strnum,numd.u[i]));
outs5("\n");
}
for (i = 0;i < numdel;++i) {
outs5(pool.s + dstart.u[i]);
outs5(" starting delivery ");
out5(strnum,fmt_ulong(strnum,del.u[i]));
outs5(": msg ");
out5(strnum,fmt_ulong(strnum,dmsg.u[i]));
outs5(" to ");
outs5(pool.s + dchan.u[i]);
outs5(" ");
outs5(pool.s + drecip.u[i]);
outs5("\n");
}
out5(line.s,line.len);
if (substdio_flush(&ss5) == -1) die_write5();
}
stralloc outline = {0};
void fix_taia()
{
stralloc tai = {0};
stralloc tmp = {0};
char *p = line.s+field[0]+1;
unsigned long secs;
unsigned long nanosecs;
unsigned long u;
char ch;
secs = 0;
nanosecs = 0;
for (;;) {
ch = *p++;
u = ch - '0';
if (u >= 10) {
u = ch - 'a';
if (u >= 6) break;
u += 10;
}
secs <<= 4;
secs += nanosecs >> 28;
nanosecs &= 0xfffffff;
nanosecs <<= 4;
nanosecs += u;
}
secs -= 4611686018427387914ULL;
if (!stralloc_copyb(&tai, strnum,fmt_ulong(strnum,secs))) nomem();
if (!stralloc_cats(&tai,".")) nomem();
if (!stralloc_catb(&tai, strnum,fmt_ulong(strnum,nanosecs))) nomem();
if (!stralloc_0(&tai)) nomem();
if (!stralloc_copy(&tmp,&tai)) nomem();
while (tmp.len < field[1])
if (!stralloc_cats(&tmp," ")) nomem();
if (!stralloc_cats(&tmp,line.s + field[1])) nomem();
if (!stralloc_copy(&line,&tmp)) nomem();
if (!stralloc_0(&line)) nomem();
}
void main()
{
int i;
int j;
char ch;
if (!stralloc_copys(&pool,"")) nomem();
if (!ulongalloc_ready(&msg,1)) nomem();
if (!ulongalloc_ready(&bytes,1)) nomem();
if (!ulongalloc_ready(&qp,1)) nomem();
if (!ulongalloc_ready(&uid,1)) nomem();
if (!ulongalloc_ready(&numk,1)) nomem();
if (!ulongalloc_ready(&numd,1)) nomem();
if (!ulongalloc_ready(&numz,1)) nomem();
if (!ulongalloc_ready(&del,1)) nomem();
if (!ulongalloc_ready(&dmsg,1)) nomem();
for (;;) {
if (getln(subfdin,&line,&match,'\n') == -1) die_read();
if (!match) break;
if (!stralloc_copy(&outline,&line)) nomem();
for (i = 0;i < line.len;++i) {
ch = line.s[i];
if ((ch == '\n') || (ch == ' ') || (ch == '\t')) line.s[i] = 0;
}
j = 0;
for (i = 0;i < FIELDS;++i) {
while (j < line.len) if (line.s[j]) break; else ++j;
field[i] = j;
while (j < line.len) if (!line.s[j]) break; else ++j;
}
if (!stralloc_0(&line)) nomem();
if ((line.s[field[0]]) == '@') fix_taia();
if (str_equal(line.s + field[1],"status:")) ;
else if (str_equal(line.s + field[1],"starting")) starting();
else if (str_equal(line.s + field[1],"delivery")) delivery();
else if (str_equal(line.s + field[1],"new")) newmsg();
else if (str_equal(line.s + field[1],"end")) endmsg();
else if (str_equal(line.s + field[1],"info")) info();
else if (str_equal(line.s + field[1],"extra")) extra();
else if (str_equal(line.s + field[1],"running")) clear();
else if (str_equal(line.s + field[1],"exiting")) clear();
else if (str_equal(line.s + field[1],"number")) ;
else if (str_equal(line.s + field[1],"local")) ;
else if (str_equal(line.s + field[1],"remote")) ;
else if (str_equal(line.s + field[1],"warning:")) out(outline.s,outline.len);
else if (str_equal(line.s + field[1],"alert:")) out(outline.s,outline.len);
else {
outs("? ");
out(outline.s,outline.len);
}
}
if (substdio_flush(subfdout) == -1) die_write();
pending();
_exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1