diff options
Diffstat (limited to 'src/qmail-tcpto.c')
-rw-r--r-- | src/qmail-tcpto.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/qmail-tcpto.c b/src/qmail-tcpto.c new file mode 100644 index 0000000..e148c55 --- /dev/null +++ b/src/qmail-tcpto.c @@ -0,0 +1,95 @@ +/* XXX: this program knows quite a bit about tcpto's internals */ + +#include <sys/socket.h> +#include <unistd.h> +#include "buffer.h" +#include "auto_qmail.h" +#include "fmt.h" +#include "ip.h" +#include "lock.h" +#include "error.h" +#include "exit.h" +#include "datetime.h" +#include "now.h" +#include "stralloc.h" +#include "open.h" +#include "logmsg.h" + +#define WHO "qmail-tcpto" + +void die(n) int n; { buffer_flush(buffer_1); _exit(n); } + +void warn(s) 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"); +} + +void die_chdir() { logmsg(WHO,110,FATAL,"unable to chdir"); } +void die_open() { logmsg(WHO,112,FATAL,"unable to open tcpto"); } +void die_lock() { logmsg(WHO,112,FATAL,"unable to lock tcpto"); } +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); +} |