diff options
author | Joern Engel <joern@logfs.org> | 2012-01-17 10:31:55 -0800 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2012-01-17 10:31:55 -0800 |
commit | 1c8f5e7187ec44133236198cbae7b0dae218aed2 (patch) | |
tree | e66e4c1cf95817324bfac7583b3d4cf31a63dfcb | |
parent | d3e3761bda56a89807f7fd1b24541aab9d332dbe (diff) | |
download | cancd-1c8f5e7187ec44133236198cbae7b0dae218aed2.tar.gz |
Copy data from ip-file to name-file
Also remove the "optimization" strcmp, as it was buggy.
Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r-- | cancd.c | 53 |
1 files changed, 49 insertions, 4 deletions
@@ -364,7 +364,7 @@ static struct source_ip *get_source_ip(struct sockaddr_in *addr) if (!sip) { sip = calloc(1, sizeof(*sip)); sip->had_newline = 1; - sip->filename = get_path(&addr->sin_addr); + sip->tmpfilename = get_path(&addr->sin_addr); err = btree_insert32(&btree, key, sip); assert(!err); sem_post(&dns_sem); @@ -372,13 +372,60 @@ static struct source_ip *get_source_ip(struct sockaddr_in *addr) return sip; } +/* + * Basically just returns the filename, but with a twist. The until the DNS + * resolver gives us a decent filename, we use a temporary one based on the + * IP address. Once we have a decent filename, we copy everything from the + * temporary file to the final one. So hopefully there is just a short + * window with IP filenames around and never should we lose data. + */ +static const char *copy_tmpfile(struct source_ip *sip) +{ + int fd, tmpfd; + const char *name, *tmpname; + + name = sip->filename; + tmpname = sip->tmpfilename; + if (name && tmpname) { + char buf[4096]; + ssize_t count; + + fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0600); + if (fd < 0) { + syslog(LOG_ERR, "Unable to open \"%s\": %s", name, + strerror(errno)); + goto out; + } + tmpfd = open(tmpname, O_RDONLY); + if (tmpfd < 0) { + syslog(LOG_ERR, "Unable to open \"%s\": %s", name, + strerror(errno)); + close(fd); + goto out; + } + while ((count = read(tmpfd, buf, sizeof(buf))) > 0) + do_write(fd, buf, count); + close(tmpfd); + close(fd); + unlink(tmpname); + sip->tmpfilename = NULL; + free((void *)tmpname); + } +out: + if (sip->tmpfilename) + return sip->tmpfilename; + if (sip->filename) + return sip->filename; + return NULL; +} + static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t socklen) { int fd; const char *name; struct source_ip *sip = get_source_ip(addr); - name = sip->filename; + name = copy_tmpfile(sip); if (!name) return; @@ -636,8 +683,6 @@ static void dns_visitor(void *_sip, long unused, u32 ip, size_t unused2) he = gethostbyaddr(&ip, 4, AF_INET); if (!he) return; - if (strcmp(he->h_name, sip->filename) == 0) - return; new = strdup(he->h_name); if (!new) return; |