diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-22 14:14:19 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-22 14:14:19 +0300 |
commit | fb5b0949c246d03a50a68b77a41f8858bdb28371 (patch) | |
tree | de0ad33b8f84699c38509c533b03847b1e2f9cb5 | |
parent | 441e0655ea9ac33828f039a700241bede621ddbd (diff) | |
download | tagr-fb5b0949c246d03a50a68b77a41f8858bdb28371.tar.gz tagr-fb5b0949c246d03a50a68b77a41f8858bdb28371.tar.bz2 |
Bugfixes.
* src/log.c (vlogmsg): New function.
(logmsg, verbose): Call vlogmsg.
* src/main.c: Implement `reader' mode.
* src/readconfig.c (readconfig): Initialize preprocessor
command line before starting parsing.
Initialize sd_base once the parsing finished.
* src/report.c (report): Take timestamp as the second argument.
* src/report.h: Likewise.
-rw-r--r-- | src/log.c | 21 | ||||
-rw-r--r-- | src/main.c | 407 | ||||
-rw-r--r-- | src/readconfig.c | 10 | ||||
-rw-r--r-- | src/report.c | 4 | ||||
-rw-r--r-- | src/report.h | 4 |
5 files changed, 275 insertions, 171 deletions
@@ -60,18 +60,25 @@ char *level_str[] = { void -logmsg (int level, const char *fmt, ...) +vlogmsg (int level, const char *fmt, va_list ap) { - va_list ap; - - va_start (ap, fmt); if (grecs_log_to_stderr) { fprintf (stderr, "%s: %s: ", progname, level_str[level]); vfprintf (stderr, fmt, ap); fprintf (stderr, "\n"); } - vsyslog (syslog_level[level], fmt, ap); + else + vsyslog (syslog_level[level], fmt, ap); +} + +void +logmsg (int level, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vlogmsg (level, fmt, ap); va_end (ap); } @@ -97,9 +104,7 @@ verbose (int level, const char *fmt, ...) if (verbose_level < level) return; va_start (ap, fmt); - printf ("%s: ", progname); - vprintf (fmt, ap); - printf ("\n"); + vlogmsg (L_INFO, fmt, ap); va_end (ap); } @@ -70,7 +70,7 @@ int verbose_level; static int rebuild_option; static int import_option; - +static int read_option; static int list_option; static char *check_mode = 0; @@ -91,7 +91,8 @@ enum { OPT_NO_PREPROCESSOR, OPT_DUMP_GRAMMAR_TRACE, OPT_DUMP_LEX_TRACE, - OPT_CONFIG_HELP + OPT_CONFIG_HELP, + OPT_READ, }; static struct argp_option options[] = { @@ -108,6 +109,8 @@ static struct argp_option options[] = { {"import", OPT_IMPORT, NULL, 0, N_("import old (mrtg-style) log files from DIR (or the basedir, if not given)"), GRID+1 }, + {"read", OPT_READ, NULL, 0, + N_("read statistics from the given file or standard input") }, {"rebuild", 'b', NULL, 0, N_("rebuild graphs using existing statistics"), GRID+1}, {"list", 'l', NULL, 0, N_("list contents of the rate database"), GRID+1}, @@ -275,6 +278,10 @@ parse_opt (int key, char *arg, struct argp_state *state) grecs_preprocessor = arg; break; + case OPT_READ: + read_option = 1; + break; + case OPT_NO_PREPROCESSOR: grecs_preprocessor = NULL; break; @@ -434,9 +441,236 @@ change_user () } -#define CHECK_USAGE(cond, opt, mode_opt) \ - if (cond) \ - die (EX_USAGE, "%s is meaningless with %s", opt, mode_opt); +void +decode_buffer () +{ + int i; + Stat_reply *reply; + Stat *sp; + int child = 0; + + reply = (Stat_reply *) recv_buffer; + reply->n_addr = ntohl (reply->n_addr); + + if (reply->n_addr > MAXADDR) + { + logmsg (L_NOTICE, "got invalid packet: n_addr = %d", reply->n_addr); + return; + } + reply->timestamp = ntohl (reply->timestamp); + if (verbose_level) + { + char tbuf[sizeof("2009-04-01 00:00:00")]; + strftime (tbuf, sizeof tbuf, "%Y-%m-%d %H:%M:%S", + gmtime (&reply->timestamp)); + logmsg (L_INFO, "Received packet: %d %lu - %s", reply->n_addr, + (unsigned long) reply->timestamp, tbuf); + } + + sp = reply->stat; + + if (!single_process_option) + { + pid_t pid = fork (); + if (pid > 0) + return; + else if (pid < 0) + logmsg (L_ERR, "can't fork: %s", strerror (errno)); + else + { + signal (SIGHUP, SIG_IGN); + signal (SIGCHLD, SIG_IGN); + child = 1; + } + } + + open_db (); + for (i = 0; i < reply->n_addr; i++, sp++) + { + sp->in = ntohl (sp->in); + sp->out = ntohl (sp->out); + verbose (1, "Router %s: %lu %lu", sp->name, sp->in, sp->out); + report (sp, reply->timestamp); + } + close_db (); + + if (child) + exit (0); +} + + +void +read_input (const char *name) +{ + FILE *fp; + char *buf = NULL; + size_t bufsize = 0; + unsigned long line = 0; + unsigned long t; + + if (!name || strcmp (name, "-") == 0) + { + name = "-"; + fp = stdin; + } + else + { + fp = fopen (name, "r"); + if (!fp) + die (EX_OSERR, "cannot open file `%s': %s", name, strerror (errno)); + } + + verbose (2, "Reading `%s'", name); + + while (getline (&buf, &bufsize, fp) > 0) + { + char *p; + size_t i; + Stat st; + + line++; + for (p = buf; *p && isascii (*p) && isspace (*p); p++) + ; + if (*p == '#' || *p == 0) + continue; + + while (*p && !isspace (*p)) + { + if (i > MAX_NAME_LENGTH) + die (EX_DATAERR, "%s:%lu: ID too long", name, line); + st.name[i++] = *p++; + } + st.name[i] = 0; + + if (sscanf (buf, "%lu %lu %lu\n", &t, &st.in, &st.out) != 3) + die (EX_DATAERR, "%s:%lu: invalid input line", name, line); + report (&st, t); + } + fclose (fp); + verbose (2, "Finished reading `%s'", name); +} + +int +get_port (char *str) +{ + int pn; + + if (isdigit (str[0])) + pn = htons (atoi (str)); + else + { + struct servent *s = getservbyname (str, "udp"); + if (s) + pn = s->s_port; + else + { + logmsg (L_ERR, "no such service: %s", str); + return 0; + } + } + return pn; +} + +RETSIGTYPE +sig_quit (int sig) +{ + logmsg (L_INFO, "exiting on signal %d", sig); + unlink (pidfile); + exit (0); +} + +RETSIGTYPE +sig_fatal (int sig) +{ + logmsg (L_ERR, "FATAL: exiting on signal %d", sig); + unlink (pidfile); + exit (EX_UNAVAILABLE); +} + +RETSIGTYPE +sig_hup (int sig) +{ + signal (sig, sig_hup); +} + +RETSIGTYPE +sig_child (int sig) +{ + int status; + + waitpid ((pid_t) - 1, &status, WNOHANG); + signal (sig, sig_child); +} + +void +assign_string (char **pstr, const char *s) +{ + free (*pstr); + if (s) + { + *pstr = xmalloc (strlen (s) + 1); + strcpy (*pstr, s); + } + else + *pstr = NULL; +} + +void +assign_string_n (char **pstr, const char *s, size_t length) +{ + free (*pstr); + if (s) + { + *pstr = xmalloc (length + 1); + memcpy (*pstr, s, length); + (*pstr)[length] = 0; + } + else + *pstr = NULL; +} + +char * +mkfilename (char *dir, char *name, char *suffix) +{ + int ret; + int len = strlen (name) + strlen (suffix); + char *buf; + if (dir) + len += strlen (dir) + 1; + buf = malloc (len + 1); + if (buf) + { + buf[0] = 0; + if (dir) + { + strcat (buf, dir); + strcat (buf, "/"); + } + strcat (buf, name); + strcat (buf, suffix); + } + return buf; +} + +#define CHECK_USAGE(cond, opt, mode_opt) \ + do \ + if (cond) \ + die (EX_USAGE, "%s is meaningless with %s", opt, mode_opt); \ + while (0) + +#define CHECK_OPTION(opt, optname) \ + do \ + { \ + if (opt != import_option) \ + CHECK_USAGE (import_option, "--import", optname); \ + if (opt != rebuild_option) \ + CHECK_USAGE (rebuild_option, "--rebuild", optname); \ + if (opt != list_option) \ + CHECK_USAGE (list_option, "--list", optname); \ + if (opt != read_option) \ + CHECK_USAGE (read_option, "--read", optname); \ + } \ + while (0) int main (int argc, char **argv) @@ -467,6 +701,7 @@ main (int argc, char **argv) CHECK_USAGE (import_option, "--import", "--lint"); CHECK_USAGE (rebuild_option, "--rebuild", "--lint"); CHECK_USAGE (list_option, "--list", "--lint"); + CHECK_USAGE (read_option, "--read", "--lint"); exit (0); } @@ -475,6 +710,7 @@ main (int argc, char **argv) CHECK_USAGE (import_option, "--import", "--test-template"); CHECK_USAGE (rebuild_option, "--rebuild", "--test-template"); CHECK_USAGE (list_option, "--list", "--test-template"); + CHECK_USAGE (read_option, "--read", "--test-template"); exit (check_template ()); } @@ -484,6 +720,7 @@ main (int argc, char **argv) if (import_option) { + CHECK_USAGE (read_option, "--read", "--import"); if (argc) while (argc--) import (*argv++); @@ -491,13 +728,22 @@ main (int argc, char **argv) import (basedir); } + if (read_option) + { + if (argc) + while (argc--) + read_input (*argv++); + else + read_input (NULL); + } + if (rebuild_option) rebuild (); if (list_option) list_db (); - if (rebuild_option || import_option || list_option) + if (rebuild_option || import_option || list_option || read_option) exit (0); if (listen_sockaddr.sa == NULL) @@ -587,152 +833,3 @@ main (int argc, char **argv) } -void -decode_buffer () -{ - int i; - Stat_reply *reply; - Stat *sp; - int child = 0; - - reply = (Stat_reply *) recv_buffer; - reply->n_addr = ntohl (reply->n_addr); - - if (reply->n_addr > MAXADDR) - { - logmsg (L_NOTICE, "got invalid packet: n_addr = %d", reply->n_addr); - return; - } - reply->timestamp = ntohl (reply->timestamp); - sp = reply->stat; - - if (!single_process_option) - { - pid_t pid = fork (); - if (pid > 0) - return; - else if (pid < 0) - logmsg (L_ERR, "can't fork: %s", strerror (errno)); - else - { - signal (SIGHUP, SIG_IGN); - signal (SIGCHLD, SIG_IGN); - child = 1; - } - } - - open_db (); - for (i = 0; i < reply->n_addr; i++, sp++) - { - sp->in = ntohl (sp->in); - sp->out = ntohl (sp->out); - logmsg (L_NOTICE, "Received %s %lu %lu", sp->name, sp->in, sp->out); - report (sp); - } - close_db (); - - if (child) - exit (0); -} - -int -get_port (char *str) -{ - int pn; - - if (isdigit (str[0])) - pn = htons (atoi (str)); - else - { - struct servent *s = getservbyname (str, "udp"); - if (s) - pn = s->s_port; - else - { - logmsg (L_ERR, "no such service: %s", str); - return 0; - } - } - return pn; -} - -RETSIGTYPE -sig_quit (int sig) -{ - logmsg (L_INFO, "exiting on signal %d", sig); - unlink (pidfile); - exit (0); -} - -RETSIGTYPE -sig_fatal (int sig) -{ - logmsg (L_ERR, "FATAL: exiting on signal %d", sig); - unlink (pidfile); - exit (EX_UNAVAILABLE); -} - -RETSIGTYPE -sig_hup (int sig) -{ - signal (sig, sig_hup); -} - -RETSIGTYPE -sig_child (int sig) -{ - int status; - - waitpid ((pid_t) - 1, &status, WNOHANG); - signal (sig, sig_child); -} - -void -assign_string (char **pstr, const char *s) -{ - free (*pstr); - if (s) - { - *pstr = xmalloc (strlen (s) + 1); - strcpy (*pstr, s); - } - else - *pstr = NULL; -} - -void -assign_string_n (char **pstr, const char *s, size_t length) -{ - free (*pstr); - if (s) - { - *pstr = xmalloc (length + 1); - memcpy (*pstr, s, length); - (*pstr)[length] = 0; - } - else - *pstr = NULL; -} - -char * -mkfilename (char *dir, char *name, char *suffix) -{ - int ret; - int len = strlen (name) + strlen (suffix); - char *buf; - if (dir) - len += strlen (dir) + 1; - buf = malloc (len + 1); - if (buf) - { - buf[0] = 0; - if (dir) - { - strcat (buf, dir); - strcat (buf, "/"); - } - strcat (buf, name); - strcat (buf, suffix); - } - return buf; -} diff --git a/src/readconfig.c b/src/readconfig.c index c00e2fe..e38c295 100644 --- a/src/readconfig.c +++ b/src/readconfig.c @@ -263,10 +263,7 @@ readconfig () grecs_preprocessor = DEFAULT_PREPROCESSOR; grecs_log_to_stderr = log_to_stderr; - if (preprocess_only) - exit (grecs_preproc_run (configfile, grecs_preprocessor) ? EX_CONFIG : 0); - rc = grecs_parse (configfile); - if (rc == 0 && pp_cmd_stack_init && grecs_preprocessor) + if (pp_cmd_stack_init && grecs_preprocessor) { char *defs = obstack_finish (&pp_cmd_stack); char *cmd = xmalloc (strlen (grecs_preprocessor) + strlen (defs) + 1); @@ -275,6 +272,11 @@ readconfig () grecs_preprocessor = cmd; obstack_free (&pp_cmd_stack, NULL); } + if (preprocess_only) + exit (grecs_preproc_run (configfile, grecs_preprocessor) ? EX_CONFIG : 0); + rc = grecs_parse (configfile); + if (rc == 0) + sd_base = obstack_finish (&sd_stack); return rc; } diff --git a/src/report.c b/src/report.c index 2fb0e66..08989ec 100644 --- a/src/report.c +++ b/src/report.c @@ -214,7 +214,7 @@ list_db () } void -report (Stat *stat) +report (Stat *stat, time_t timestamp) { SD *sd = find_router_id (stat->name); @@ -224,7 +224,7 @@ report (Stat *stat) sd->in = stat->in; sd->out = stat->out; - sd->t = time (NULL); + sd->t = timestamp; read_db (sd, &tr); update_stats (sd, tr); write_db (sd, tr); diff --git a/src/report.h b/src/report.h index 6ce270a..039e507 100644 --- a/src/report.h +++ b/src/report.h @@ -1,5 +1,5 @@ /* This file is part of tagr. - Copyright (C) 2000, 2005, Max Bouglacoff, Sergey Poznyakoff + Copyright (C) 2000, 2005, 2009 Max Bouglacoff, Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,5 +45,5 @@ typedef struct #define reply_size(n) (sizeof(Stat_reply) + (n-1)*sizeof(Stat)) #define request_size(n) (sizeof(Stat_request + (n-1)*sizeof(unsigned long)) -void report (Stat * stat); +void report (Stat *stat, time_t timestamp); #endif |