/* XXX: this program knows quite a bit about tcpto's internals */ #include #include #include "buffer.h" #include "error.h" #include "exit.h" #include "fmt.h" #include "ip.h" #include "lock.h" #include "logmsg.h" #include "open.h" #include "stralloc.h" #include "datetime.h" #include "now.h" #ifdef USE_CONFIG #include "fehsqm-config.h" #else #include "auto_qmail.h" #endif #define WHO "qmail-tcpto" static void die(int n) { buffer_flush(buffer_1); _exit(n); } static void warn(char *s) { char *x; x = error_str(errno); buffer_puts(buffer_1, s); buffer_puts(buffer_1, ": "); buffer_puts(buffer_1, x); buffer_puts(buffer_1, "\n"); } static void die_chdir() { logmsg(WHO, 110, FATAL, "unable to chdir"); } static void die_open() { logmsg(WHO, 112, FATAL, "unable to open tcpto"); } static void die_lock() { logmsg(WHO, 112, FATAL, "unable to lock tcpto"); } static void die_read() { logmsg(WHO, 112, FATAL, "unable to read tcpto"); } char tcpto_buf[1024]; char tmp[FMT_ULONG + IPFMT]; int main(void) { int fdlock; int fd; int r; int i; char *record; char ip4[4]; char ip6[16]; datetime_sec when; datetime_sec start; if (chdir(auto_qmail) == -1) die_chdir(); if (chdir("queue/lock") == -1) die_chdir(); fdlock = open_write("tcpto"); if (fdlock == -1) die_open(); fd = open_read("tcpto"); if (fd == -1) die_open(); if (lock_ex(fdlock) == -1) die_lock(); r = read(fd, tcpto_buf, sizeof(tcpto_buf)); close(fd); close(fdlock); if (r == -1) die_read(); r >>= 5; /* 32 bit read */ start = now(); record = tcpto_buf; for (i = 0; i < r; ++i) { if (record[4] >= 1) { when = (unsigned long)(unsigned char)record[11]; when = (when << 8) + (unsigned long)(unsigned char)record[10]; when = (when << 8) + (unsigned long)(unsigned char)record[9]; when = (when << 8) + (unsigned long)(unsigned char)record[8]; if (record[0] == AF_INET) { byte_copy(&ip4, 4, record + 16); buffer_put(buffer_1, tmp, ip4_fmt(tmp, ip4)); } else { byte_copy(&ip6, 16, record + 16); buffer_put(buffer_1, tmp, ip6_fmt(tmp, ip6)); } buffer_puts(buffer_1, " timed out "); buffer_put(buffer_1, tmp, fmt_ulong(tmp, (unsigned long)(start - when))); buffer_puts(buffer_1, " seconds ago; # recent timeouts: "); buffer_put(buffer_1, tmp, fmt_ulong(tmp, (unsigned long)(unsigned char)record[4])); buffer_puts(buffer_1, "\n"); } record += 32; } die(0); }