aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-04-22 14:14:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-04-22 14:14:19 +0300
commitfb5b0949c246d03a50a68b77a41f8858bdb28371 (patch)
treede0ad33b8f84699c38509c533b03847b1e2f9cb5
parent441e0655ea9ac33828f039a700241bede621ddbd (diff)
downloadtagr-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.c21
-rw-r--r--src/main.c407
-rw-r--r--src/readconfig.c10
-rw-r--r--src/report.c4
-rw-r--r--src/report.h4
5 files changed, 275 insertions, 171 deletions
diff --git a/src/log.c b/src/log.c
index 7aa99d5..548b976 100644
--- a/src/log.c
+++ b/src/log.c
@@ -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);
}
diff --git a/src/main.c b/src/main.c
index 0751e3b..bc045d5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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

Return to:

Send suggestions and report system problems to the System administrator.