/* This file is part of tagr. 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 the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #ifndef TAGR_ARG_UNUSED # define TAGR_ARG_UNUSED __attribute__ ((__unused__)) #endif #ifndef TAGR_PRINTFLIKE # define TAGR_PRINTFLIKE(fmt,narg) \ __attribute__ ((__format__ (__printf__, fmt, narg))) #endif #define TAGR_CONFIGFILE SYSCONFDIR "/tagr.conf" #define TAGR_TEMPLATE SYSCONFDIR "/tagr.tmpl" #define TAGR_PIDFILE "/var/run/tagr.pid" #define TAGR_DBNAME "tagr.db" #define TAGR_DBMODE 0600 #define TAGR_CUT_OUT 1.5 #define _(s) gettext (s) #define N_(s) s #define gettext(s) s #define ngettext(s,p,c) ((c) == 1 ? (s) : (p)) struct monitor { char *id; char *name; char *dir; char *rate_unit; unsigned long max_rate; double scale; double ystep; int swap; }; extern int preprocess_only; extern int log_to_stderr; extern char *pidfile; extern unsigned update_interval; extern int single_process_option; extern double cut_out_fraction; extern unsigned lock_retry_count_option; extern unsigned lock_retry_timeout_option; extern unsigned stream_idle_timeout; extern char *hostname; extern char *user; extern char *basedir; extern char *configfile; extern int foreground; extern char *html_template; extern char *html_input_file; extern int html_input_line; extern int verbose_level; extern char *rate_unit; extern int percent_option; extern int transparent_option; extern int zero_unknown_option; extern int fill_incoming_option; extern int color_background[3]; extern int color_light[3]; extern int color_dark[3]; extern int color_major[3]; extern int color_in[3]; extern int color_out[3]; extern int color_grid[3]; extern int color_in_max[3]; extern int color_out_max[3]; extern int color_percent[3]; extern char **number_suffix; extern size_t number_suffix_count; int readconfig (void); void config_help (void); void define_symbol (char *s); struct monitor *find_monitor (const char *name); struct monitor *find_monitor_id (const char *id); /* html.gram.y */ void begin_eval (); void end_eval (); int html_open (char *file); void html_close (); int yyerror (char *s); typedef enum { unspecified_value, numeric_value, string_value } value_type; union value { double number; char *string; }; typedef void (*value_format_fn) (FILE *, union value, const char *, int); typedef struct { value_type type; int prec; char *fmt; value_format_fn format; union value v; } pp_value_t; typedef struct pp_value_list { struct pp_value_list *next; char *name; pp_value_t value; } pp_tab_t; int read_symtab (pp_tab_t **tab, const char *name); int write_symtab (pp_tab_t *tab, const char *name); void init_value (pp_value_t *p, value_type type, union value *v); pp_value_t *add_numeric_value (pp_tab_t ** ptab, const char *name, double number); pp_value_t *add_string_value (pp_tab_t ** ptab, const char *name, const char *string); int find_value (char *name, pp_value_t * val); void free_tab (pp_tab_t ** ptab); int create_html (pp_tab_t * tab, char *file, char *dest); int check_template (); /* Logging */ extern int log_facility; extern char *log_tag; extern int log_print_severity; #define L_DEBUG 0 #define L_INFO 1 #define L_NOTICE 2 #define L_WARNING 3 #define L_ERR 4 #define L_CRIT 5 void init_syslog (char *tag); void logmsg (int level, const char *fmt, ...) TAGR_PRINTFLIKE(2,3); void die (int code, const char *fmt, ...) TAGR_PRINTFLIKE(2,3); void verbose (int level, const char *fmt, ...) TAGR_PRINTFLIKE(2,3); /* Traffic history */ #define DAY_COUNT (600) /* 400 samples is 33.33 hours */ #define DAY_SAMPLE (5*60) /* Sample every 5 minutes */ #define WEEK_COUNT (600) /* 400 samples is 8.33 days */ #define WEEK_SAMPLE (30*60) /* Sample every 30 minutes */ #define MONTH_COUNT (600) /* 400 samples is 33.33 days */ #define MONTH_SAMPLE (2*60*60) /* Sample every 2 hours */ #define YEAR_COUNT (2 * 366) /* 1 sample / day, 366 days, 2 years */ #define YEAR_SAMPLE (24*60*60) /* Sample every 24 hours */ /* One 'rounding error' per sample period, so add 4 to total */ #define MAX_HISTORY (DAY_COUNT+WEEK_COUNT+MONTH_COUNT+YEAR_COUNT+4+4) struct traffic_history { time_t time; double inrate; double outrate; }; typedef struct stat_queue queue_t; struct stat_queue { int head; int tail; int size; struct traffic_history *queue; }; struct traffic_sample { time_t time; unsigned long in, out; }; struct avg_acc { time_t time; unsigned count; double inrate; double outrate; }; struct traffic_record { struct traffic_sample last; /* Lastly taken sample */ struct traffic_history last_rates; /* Average accumulators */ struct avg_acc week_avg; struct avg_acc month_avg; struct avg_acc year_avg; /* History arrays */ queue_t day_hist; queue_t week_hist; queue_t month_hist; queue_t year_hist; struct traffic_history history[MAX_HISTORY]; }; /* report.c */ #define TAGR_DB_RD 0 #define TAGR_DB_WR 1 int open_db (int); void close_db (); void read_db (struct monitor *mon, struct traffic_record **tr); void write_db (struct monitor *mon, struct traffic_record *tr); void list_db (void); void tr_init (struct traffic_record *tr); #define TAGR_UPD_FORCE 0x0001 #define TAGR_UPD_LASTTIME 0x0002 void rebuild (int flags); /* stat.c */ void update_stats (struct monitor *mon, struct traffic_sample *sample, struct traffic_record *tr); void import (const char *dir); /* queue.c */ void queue_clear (queue_t *q); int queue_count (queue_t *q); struct traffic_history *queue_get_ptr (queue_t *q, int index); struct traffic_history *queue_get_tail (queue_t *q); void queue_put (queue_t *q, struct traffic_history *elt); int queue_xchg (queue_t *q, struct traffic_history *elt); char *mkfilename (const char *dir, const char *name, const char *suffix); /* output.c */ void scale_sample (struct monitor *mon, const struct traffic_history *in, struct traffic_history *out); int update_output (struct monitor *mon, struct traffic_record *tr, time_t timestamp, int flags); /* graph.c */ typedef struct grid *grid_t; struct grid_class { void *(*create) (grid_t, void *); double (*next) (grid_t, char **, int *); void (*dealloc) (void *); }; grid_t grid_create (struct grid_class *, queue_t *, double, double, void *); double grid_next (grid_t, char **, int *); void grid_destroy (grid_t); extern struct grid_class grid_class_y; extern struct grid_class grid_class_x_2h; extern struct grid_class grid_class_x_wday; extern struct grid_class grid_class_x_week; extern struct grid_class grid_class_x_month; int draw_graph (FILE *fp, struct monitor *mon, queue_t *dataq, const struct avg_acc *avg, time_t now, int xstep, unsigned long xmax, int growright, struct grid_class *xgrid, struct grid_class *ygrid); /* server.c */ enum tagr_server_type { tagr_udp_server, tagr_tcp_server }; void register_server (const char *id, enum tagr_server_type type, struct grecs_sockaddr addr); void open_servers (void); void close_servers (void); void server_loop (void); void trim_crlf (char *buf); int tagr_idle (void); char *tagr_local_hostname (void); const char *tagr_auth_init (void); int tagr_auth (const char *username, const char *authstr); /* udb.c */ extern char *tagr_udb_name; int udb_get_password (const char *username, char **password); void udb_free_password (char *pass);