diff options
author | Joern Engel <joern@logfs.org> | 2012-01-17 07:18:42 -0800 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2012-01-17 07:18:42 -0800 |
commit | 585f32119a017e6fc381d0407a7a3a31dc5328b4 (patch) | |
tree | 5adf633c9e8650b77af1feca35edaf0ca3e6e3ae | |
parent | b0802bcf4bb0a76df5561ce506996554e83018d1 (diff) | |
download | cancd-585f32119a017e6fc381d0407a7a3a31dc5328b4.tar.gz |
Add per-ip cache
Currently used for newlines and filename.
Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r-- | cancd.c | 46 |
1 files changed, 37 insertions, 9 deletions
@@ -26,6 +26,7 @@ #include <features.h> #include <arpa/inet.h> +#include <assert.h> #include <errno.h> #include <fcntl.h> #include <getopt.h> @@ -45,6 +46,7 @@ #include <unistd.h> #include "kernel-list.h" +#include "btree.h" #ifndef VERSION #define VERSION "0.1.0" @@ -83,6 +85,14 @@ static int daemonize = 1; /* What signal did we catch? */ sig_atomic_t caught_sig = 0; +struct btree_head32 btree; + +struct source_ip { + const char *filename; + const char *tmpfilename; + int had_newline; +}; + void handler(int signum) { caught_sig = signum; @@ -297,7 +307,7 @@ static int do_write(int fd, const void *buf, size_t count) return 0; } -static int write_formatted(int fd, char *buf, int count) +static int write_formatted(int fd, struct source_ip *sip, char *buf, int count) { const char *format = "%b %d %H:%M:%S "; char *end; @@ -305,7 +315,6 @@ static int write_formatted(int fd, char *buf, int count) size_t n, len, err; time_t now = time(NULL); struct tm *tm = localtime(&now); - int had_newline = 0; /* * buf must be NUL-terminated. We add 1 to count for the terminating @@ -314,7 +323,7 @@ static int write_formatted(int fd, char *buf, int count) */ count += 1; while (count > 1) { - if (had_newline) { + if (sip->had_newline) { n = strftime(timestr, sizeof(timestr), format, tm); err = do_write(fd, timestr, n); if (err) @@ -324,7 +333,7 @@ static int write_formatted(int fd, char *buf, int count) if (!end) { /* no newline, just write what we have */ do_write(fd, buf, count - 1); - had_newline = 0; + sip->had_newline = 0; break; } len = end - buf + 1; @@ -333,17 +342,36 @@ static int write_formatted(int fd, char *buf, int count) return err; buf += len; count -= len; - had_newline = 1; + sip->had_newline = 1; } return 0; } +static struct source_ip *get_source_ip(struct sockaddr_in *addr) +{ + u32 key = addr->sin_addr.s_addr; + struct source_ip *sip; + int err; + + sip = btree_lookup32(&btree, key); + if (!sip) { + sip = calloc(1, sizeof(*sip)); + sip->had_newline = 1; + sip->filename = get_path(&addr->sin_addr); + err = btree_insert32(&btree, key, sip); + assert(!err); + } + return sip; +} + static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t socklen) { int fd, rc; - char *name, *tmp, *dir; + const char *name; + char *tmp, *dir; + struct source_ip *sip = get_source_ip(addr); - name = get_path(&addr->sin_addr); + name = sip->filename; if (!name) return; @@ -364,10 +392,9 @@ static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t so if (fd < 0) syslog(LOG_ERR, "Unable to open \"%s\": %s", name, strerror(errno)); else { - write_formatted(fd, buf, len); + write_formatted(fd, sip, buf, len); close(fd); } - free(name); } static int set_blocking(int blocking) @@ -610,6 +637,7 @@ int main(int argc, char *argv[]) { int rc; + btree_init32(&btree); rc = parse_options(argc, argv); if (rc) return rc; |