This small patch modifies the matchup program to handle tai64 format dates. Lines that start with @ have dates translated to the older seconds.nanoseconds format that qmailanalog wants. Lines that don't start with @ are left alone, so that the pending file that matchup writes can be processed properly. I did it this way rather than updating the other scripts to use new dates, because the analysis code is all awk scripts subtracting one decimal timestamp from another to find out how long deliveries took. John Levine, johnl@iecc.com, Nov 2003 diff -C3 qmailanalog-dist/matchup.c qmailanalog-0.70/matchup.c *** qmailanalog-dist/matchup.c Tue Nov 4 17:50:09 2003 --- qmailanalog-0.70/matchup.c Wed Nov 5 11:56:33 2003 *************** *** 183,188 **** --- 183,229 ---- poolbytes = pool.len; /* redundant, but doesn't hurt */ } + /* turn TAI date into old fashioned date */ + /* dates without @ are left alone */ + + static char datebuf[FMT_ULONG+FMT_ULONG+2]; /* ssssssssss.ffffffffff\n */ + + char * + datize(s) + char *s; + { + int c; + int len; + unsigned long u; + unsigned long seconds = 0; + unsigned long nanoseconds = 0; + + if(*s != '@') return s; + s++; + + while ((c = *s++)) { + u = c - '0'; + if (u >= 10) { + u = c - 'a'; + if (u >= 6) break; + u += 10; + } + seconds <<= 4; + seconds += nanoseconds >> 28; + nanoseconds &= 0xfffffff; + nanoseconds <<= 4; + nanoseconds += u; + } + seconds -= 4611686018427387914ULL; + + len = fmt_ulong(datebuf, seconds); + datebuf[len++] = '.'; + len += fmt_uint0(datebuf+len, nanoseconds, 9); + datebuf[len] = 0; + + return datebuf; + } + stralloc line = {0}; int match; *************** *** 209,215 **** 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; --- 250,256 ---- dmsg.u[dpos] = m; dstart.u[dpos] = pool.len; ! if (!stralloc_cats(&pool,datize(line.s + field[0]))) nomem(); if (!stralloc_0(&pool)) nomem(); dchan.u[dpos] = pool.len; *************** *** 267,273 **** 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]); --- 308,314 ---- if (mpos != -1) { outs(pool.s + birth.u[mpos]); outs(" "); outs(pool.s + dstart.u[dpos]); ! outs(" "); outs(datize(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]); *************** *** 279,285 **** 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); --- 320,326 ---- else { outs(pool.s + dstart.u[dpos]); outs(" "); outs(pool.s + dstart.u[dpos]); ! outs(" "); outs(datize(line.s + field[0])); outs(" 0 ? "); outs(pool.s + dchan.u[dpos]); outs("."); outs(pool.s + drecip.u[dpos]); outs(" ? ? "); outs(reason); *************** *** 313,319 **** 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])); --- 354,360 ---- if (mpos == -1) return; outs("m "); outs(pool.s + birth.u[mpos]); ! outs(" "); outs(datize(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])); *************** *** 344,350 **** 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; --- 385,391 ---- numz.u[mpos] = 0; birth.u[mpos] = pool.len; ! if (!stralloc_cats(&pool,datize(line.s + field[0]))) nomem(); if (!stralloc_0(&pool)) nomem(); sender.u[mpos] = pool.len;