static int dump_reports(void) { int fd; FILE *fp; char fname[128]; char tname[128]; if (disk_is_full()) { syslog(LOG_NOTICE, "%s", "Not enough free disk space to write XML files"); return 1; } #if HAVE_LIBNCAP snprintf(fname, 128, "%d.dscdata.xml", Ncap_finish_time()); #else snprintf(fname, 128, "%d.dscdata.xml", Pcap_finish_time()); #endif snprintf(tname, 128, "%s.XXXXXXXXX", fname); fd = mkstemp(tname); if (fd < 0) { syslog(LOG_ERR, "%s: %s", tname, strerror(errno)); return 1; } fp = fdopen(fd, "w"); if (NULL == fp) { syslog(LOG_ERR, "%s: %s", tname, strerror(errno)); close(fd); return 1; } if (debug_flag) fprintf(stderr, "writing to %s\n", tname); fprintf(fp, "<dscdata>\n"); /* amalloc_report(); */ pcap_report(fp); dns_message_report(fp); ip_message_report(fp); fprintf(fp, "</dscdata>\n"); /* * XXX need chmod because files are written as root, but may be processed * by a non-priv user */ fchmod(fd, 0664); fclose(fp); if (debug_flag) fprintf(stderr, "renaming to %s\n", fname); rename(tname, fname); return 0; }
static int dump_report(md_array_printer * printer) { int fd; FILE *fp; char fname[128]; char tname[128]; if (disk_is_full()) { dsyslogf(LOG_NOTICE, "Not enough free disk space to write %s files", printer->format); return 1; } snprintf(fname, 128, "%d.dscdata.%s", Pcap_finish_time(), printer->extension); snprintf(tname, 128, "%s.XXXXXXXXX", fname); fd = mkstemp(tname); if (fd < 0) { dsyslogf(LOG_ERR, "%s: %s", tname, strerror(errno)); return 1; } fp = fdopen(fd, "w"); if (NULL == fp) { dsyslogf(LOG_ERR, "%s: %s", tname, strerror(errno)); close(fd); return 1; } dfprintf(0, "writing to %s", tname); fputs(printer->start_file, fp); /* amalloc_report(); */ pcap_report(fp, printer); dns_message_report(fp, printer); fputs(printer->end_file, fp); /* * XXX need chmod because files are written as root, but may be processed * by a non-priv user */ fchmod(fd, 0664); fclose(fp); dfprintf(0, "renaming to %s", fname); if (rename(tname, fname)) { dsyslogf(LOG_ERR, "unable to move report from %s to %s: %s", tname, fname, strerror(errno)); } return 0; }
int main(int argc, char *argv[]) { int x; extern DMC dns_message_handle; progname = xstrdup(strrchr(argv[0], '/') ? strchr(argv[0], '/') + 1 : argv[0]); if (NULL == progname) return 1; srandom(time(NULL)); openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((x = getopt(argc, argv, "pd")) != -1) { switch (x) { case 'p': promisc_flag = 0; break; case 'd': debug_flag = 1; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc != 1) usage(); dns_message_init(); ParseConfig(argv[0]); cip_net_indexer_init(); if (!debug_flag) daemonize(); write_pid_file(); /* * I'm using fork() in this loop, (a) out of laziness, and (b) * because I'm worried we might drop packets. Making sure each * child collector runs for a small amount of time (60 secodns) * means I can be lazy about memory management (leaks). To * minimize the chance for dropped packets, I'd like to spawn * a new collector as soon as (or even before) the current * collector exits. */ if (!debug_flag) { syslog(LOG_INFO, "Sleeping for %d seconds", 60 - (int) (time(NULL) % 60)); sleep(60 - (time(NULL) % 60)); } syslog(LOG_INFO, "Running"); for (;;) { pid_t cpid = fork(); if (0 == cpid) { Pcap_run(dns_message_handle, ip_message_handle); if (0 == fork()) { dns_message_report(); ip_message_report(); } _exit(0); } else { int cstatus = 0; syslog(LOG_DEBUG, "waiting for child pid %d", (int) cpid); while (waitpid(cpid, &cstatus, 0) < 0) (void) 0; if (WIFSIGNALED(cstatus)) syslog(LOG_NOTICE, "child exited with signal %d, status %d", WTERMSIG(cstatus), WEXITSTATUS(cstatus)); } if (debug_flag) break; } Pcap_close(); return 0; }