diff --git a/ChangeLog b/ChangeLog index 8c027b5..8acdae2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-xx-yy Sami Kerola + * Release 2.2 + * No ranges defined -> crash bug fixed. + * Better error messages for command line options. + * File flushes more clean and error messages added. + * Possibility to limit what is printed out. + * Output limit update to man page. + 2006-03-13 Sami Kerola * Release 2.1 diff --git a/NEWS b/NEWS index d3e433e..8e8546d 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,13 @@ See the end for copying conditions. Please send dhcpd-pools bug reports to kerolasa@iki.fi. + +Version 2.2 +* Bugfixes: +*. No ranges in dhcpd.conf -> crash. +* Better error messages. +* Possibility to limit output. + Version 2.1 * Bugfixs: diff --git a/THANKS b/THANKS index 19fd414..5b49391 100644 --- a/THANKS +++ b/THANKS @@ -8,3 +8,5 @@ and exempt of errors. Otto J. Mäkelä Mika Paananen +Brian W. Kernighan +Rob Pike diff --git a/TODO b/TODO index 61a7af3..a9f01f3 100644 --- a/TODO +++ b/TODO @@ -8,8 +8,6 @@ Todo: using auto tools. Help needed. * Bad english to good english translation for all files that author has touched. Help needed. - * Output limit for pools / shared net / all. Bit mask will do - this quite nicely, copy idea from chmod. * Threshold values -> alarm possibility. * Bug perhaps not? ./dhcpd-pools -o /dev/null /dev/null: Inappropriate ioctl for device diff --git a/configure.in b/configure.in index 53aaae7..9c746fa 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([dhcpd-pools], [2.1], [kerolasa@iki.fi]) +AC_INIT([dhcpd-pools], [2.2], [kerolasa@iki.fi]) AM_INIT_AUTOMAKE([1.9 foreign]) @@ -40,6 +40,14 @@ AC_ARG_WITH(output-format, ) AC_SUBST(output_format) +AC_ARG_WITH(output-limit, + [ --with-output-limit=NRO Default output limit 00 - 77], + [ output_limit=$withval + CPPFLAGS="$CPPFLAGS -DOUTPUT_LIMIT='\"$withval\"'" ], + [ output_limit=$output_limit_default ] + ) +AC_SUBST(output_limit) + AC_CHECK_FUNCS(getopt_long inet_aton inet_addr, break) AC_CHECK_LIB(resolv, inet_ntoa) diff --git a/man/dhcpd-pools.1 b/man/dhcpd-pools.1 index ab3a500..b0fb041 100644 --- a/man/dhcpd-pools.1 +++ b/man/dhcpd-pools.1 @@ -2,7 +2,7 @@ .\" http://www.iki.fi/kerolasa/ .\" kerolasa@iki.fi .\" -.TH DHCPD-POOLS 1 "Mar 9 2006 - version 2.1" +.TH DHCPD-POOLS 1 "Mar 14 2006 - version 2.2" .SH NAME dhcpd-pools \- ISC dhcp pools usage analysis .SH SYNOPSIS @@ -26,6 +26,12 @@ Output format. Currently there is text, html and csv .I "\-o, \-\-output" File where output is directed. Default is stdout. .TP +.I "\-L, \-\-limit" +Limit what is printed. Syntax is similar to chmod permission +string. This limit string has two meaningful digits which can be +between 0 and 7. First digit limits output of headers and second +numeric analysis tables. +.TP .I "\-v, \-\-version" Print version information to standard output and exit successfully. .TP @@ -51,4 +57,5 @@ Sami Kerola http://dhcpd-pools.sourceforge.net/ .SH "SEE ALSO" .BR dhcpd.leases (5), -.BR dhcpd.conf (5) +.BR dhcpd.conf (5), +.BR chmod (1) diff --git a/src/analyze.c b/src/analyze.c index 42c34e2..4da386a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -104,6 +104,12 @@ do_counting (void) if (range_p->last_ip < leases[i]) { range_p++; + /* Break loop before trying to access memorory that is + * not allocated. */ + if (range_p - ranges > num_ranges) + { + break; + } block_size = range_p->last_ip - range_p->first_ip - 1; if (range_p->shared_net) { diff --git a/src/defaults.h b/src/defaults.h index a502c00..cc997aa 100644 --- a/src/defaults.h +++ b/src/defaults.h @@ -32,6 +32,9 @@ #ifndef OUTPUT_FORMAT # define OUTPUT_FORMAT "text" #endif +#ifndef OUTPUT_LIMIT +# define OUTPUT_LIMIT "77" +#endif /* Maximum line length in dhcpd.conf and dhcpd.leases */ static const int MAXLEN = 1024; diff --git a/src/dhcpd-pools.c b/src/dhcpd-pools.c index 25655b9..af260ce 100644 --- a/src/dhcpd-pools.c +++ b/src/dhcpd-pools.c @@ -45,6 +45,7 @@ int main (int argc, char **argv) { int c; + char *tmp; FILE *fopen_test; /* Options for getopt_long */ @@ -53,6 +54,7 @@ main (int argc, char **argv) {"leases", required_argument, 0, (int) 'l'}, {"format", required_argument, 0, (int) 'f'}, {"output", required_argument, 0, (int) 'o'}, + {"limit", required_argument, 0, (int) 'L'}, {"version", no_argument, 0, (int) 'v'}, {"help", no_argument, 0, (int) 'h'}, {0, 0, 0, 0} @@ -70,6 +72,10 @@ main (int argc, char **argv) strncpy (config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1); strncpy (config.dhcpdlease_file, DHCPDLEASE_FILE, MAXLEN - 1); + tmp = OUTPUT_LIMIT; + config.output_limit[0] = (int) (*tmp - '0'); + tmp++; + config.output_limit[1] = (int) (*tmp - '0'); /* Make sure some output format is selected by default */ strncpy (config.output_format, OUTPUT_FORMAT, 1); @@ -77,7 +83,7 @@ main (int argc, char **argv) /* Parse command line options */ while (1) { - c = getopt_long (argc, argv, "clfovh", long_options, (int *) 0); + c = getopt_long (argc, argv, "clfoLvh", long_options, (int *) 0); if (c == EOF) break; @@ -93,6 +99,7 @@ main (int argc, char **argv) } else { + eprintf ("main: for argument -c parameter not set"); print_help (); exit (EXIT_FAILURE); } @@ -104,6 +111,7 @@ main (int argc, char **argv) } else { + eprintf ("main: for argument -l parameter not set"); print_help (); exit (EXIT_FAILURE); } @@ -115,6 +123,7 @@ main (int argc, char **argv) } else { + eprintf ("main: for argument -f parameter not set"); print_help (); exit (EXIT_FAILURE); } @@ -127,19 +136,50 @@ main (int argc, char **argv) fopen_test = fopen (config.output_file, "w+"); if (fopen_test == NULL) { - eprintf ("%s:", config.output_file); - print_help (); + eprintf ("main: %s:", config.output_file); exit (EXIT_FAILURE); } fclose (fopen_test); if (errno) { - eprintf ("%s:", config.output_file); + eprintf ("main: %s:", config.output_file); exit (EXIT_FAILURE); } } else { + eprintf ("main: for argument -o parameter not set"); + print_help (); + exit (EXIT_FAILURE); + } + break; + case 'L': + if (argv[optind] != NULL) + { + if (argv[optind][0] >= '0' && argv[optind][0] < '8') + { + config.output_limit[0] = (int) argv[optind][0] - '0'; + } + else + { + eprintf ("main: output limit mask %s illegal", argv[optind]); + print_help (); + exit (EXIT_FAILURE); + } + if (argv[optind][1] >= '0' && argv[optind][1] < '8') + { + config.output_limit[1] = (int) argv[optind][1] - '0'; + } + else + { + eprintf ("main: output limit mask %s illegal", argv[optind]); + print_help (); + exit (EXIT_FAILURE); + } + } + else + { + eprintf ("main: for argument -L parameter not set"); print_help (); exit (EXIT_FAILURE); } @@ -173,6 +213,7 @@ main (int argc, char **argv) output_analysis = output_txt; break; default: + eprintf ("main: unknown ouput format"); print_help (); exit (EXIT_FAILURE); } diff --git a/src/dhcpd-pools.h b/src/dhcpd-pools.h index b6ffc3a..7897d2c 100644 --- a/src/dhcpd-pools.h +++ b/src/dhcpd-pools.h @@ -37,6 +37,7 @@ struct configuration_t char *dhcpdlease_file; char output_format[2]; char *output_file; + int output_limit[2]; }; struct shared_network_t { @@ -54,9 +55,13 @@ struct range_t /* External variables */ char *program_name; -static const float version_number = 2.1; +static const float version_number = 2.2; struct configuration_t config; +static int output_limit_bit_1 = 1; +static int output_limit_bit_2 = 2; +static int output_limit_bit_3 = 4; + struct shared_network_t *shared_networks; char *shared_net_names; unsigned int num_shared_networks; diff --git a/src/getdata.c b/src/getdata.c index db54491..44c38d6 100644 --- a/src/getdata.c +++ b/src/getdata.c @@ -84,7 +84,7 @@ parse_config (void) dhcpd_config = fopen (config.dhcpdconf_file, "r"); if (dhcpd_config == NULL) { - eprintf ("%s:", config.dhcpdconf_file); + eprintf ("parse_config: %s:", config.dhcpdconf_file); exit (EXIT_FAILURE); } @@ -162,8 +162,7 @@ parse_config (void) if (num_ranges > RANGES) { - fprintf (stderr, "Range space full!\n"); - fprintf (stderr, "Increase RANGES and recompile.\n"); + eprintf ("parse_config: Range space full! Increase RANGES and recompile."); exit (EXIT_FAILURE); } } @@ -173,9 +172,7 @@ parse_config (void) linelen = strlen (line); if (shared_name_p + linelen > last_shared) { - fprintf (stderr, "Shared network name space full!\n"); - fprintf (stderr, - "Increase SHARED_NETWORKS_NAMES and recompile\n"); + eprintf ("parse_config: Shared network name space full! Increase SHARED_NETWORKS_NAMES and recompile.\n"); exit (EXIT_FAILURE); } @@ -191,8 +188,7 @@ parse_config (void) if (num_shared_networks > SHARED_NETWORKS) { - fprintf (stderr, "Shared network space full!\n"); - fprintf (stderr, "Increase SHARED_NETWORKS and recompile\n"); + eprintf ("parse_config: Shared network space full! Increase SHARED_NETWORKS and recompile.\n"); exit (EXIT_FAILURE); } } @@ -215,7 +211,7 @@ parse_leases (void) dhcpd_leases = fopen (config.dhcpdlease_file, "r"); if (dhcpd_leases == NULL) { - eprintf ("%s:", config.dhcpdlease_file); + eprintf ("parse_leases: %s:", config.dhcpdlease_file); exit (EXIT_FAILURE); } @@ -226,7 +222,7 @@ parse_leases (void) * to hear about that. */ if (stat (config.dhcpdlease_file, &lease_file_stats)) { - eprintf ("%s:", config.dhcpdlease_file); + eprintf ("parse_leases: %s:", config.dhcpdlease_file); exit (EXIT_FAILURE); } leases = diff --git a/src/other.c b/src/other.c index 63e2bd3..d6ed626 100644 --- a/src/other.c +++ b/src/other.c @@ -44,7 +44,7 @@ safe_malloc (size_t size) void *ret = malloc (size); if (ret == NULL) { - eprintf ("malloc: "); + eprintf ("safe_malloc: malloc: "); exit (EXIT_FAILURE); } return ret; @@ -84,7 +84,17 @@ clean_up (void) free (shared_networks); /* Just in case there something in buffers */ fclose (stdout); + if (errno) + { + eprintf ("clean_up: stdout:"); + exit (EXIT_FAILURE); + } fclose (stderr); + if (errno) + { + eprintf ("clean_up: stderr:"); + exit (EXIT_FAILURE); + } } void @@ -114,6 +124,7 @@ This is ISC dhcpd pools usage analyzer.\n\ */ fprintf (stdout, "\ -o --output file output into a file\n\ + -L --limit nr output limit mask 77 - 00\n\ -v --version version information\n\ -h --help this screen\n\ \n\ diff --git a/src/output.c b/src/output.c index 9af8389..3bce983 100644 --- a/src/output.c +++ b/src/output.c @@ -47,7 +47,7 @@ output_txt (void) outfile = fopen (config.output_file, "w+"); if (outfile == NULL) { - eprintf ("%s:", config.output_file); + eprintf ("output_txt: %s:", config.output_file); exit (EXIT_FAILURE); } } @@ -59,58 +59,89 @@ output_txt (void) range_p = ranges; shared_p = shared_networks; - fprintf (outfile, "Ranges:\n"); - fprintf - (outfile, - "shared net name first ip last ip max cur percent\n"); - for (i = 0; i < num_ranges; i++) + if (config.output_limit[0] & output_limit_bit_1) { - first.s_addr = ntohl (range_p->first_ip + 1); - last.s_addr = ntohl (range_p->last_ip - 1); - - if (range_p->shared_net) + fprintf (outfile, "Ranges:\n"); + fprintf + (outfile, + "shared net name first ip last ip max cur percent\n"); + } + if (config.output_limit[1] & output_limit_bit_1) + { + for (i = 0; i < num_ranges; i++) { - fprintf (outfile, "%-20s", range_p->shared_net->name); + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "%-20s", range_p->shared_net->name); + } + else + { + fprintf (outfile, "not_defined "); + } + fprintf (outfile, "%-16s", inet_ntoa (first)); + fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n", + inet_ntoa (last), + range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } + fprintf (outfile, "\n"); + } + if (config.output_limit[0] & output_limit_bit_2) + { + fprintf (outfile, "Shared networks:\n"); + fprintf (outfile, "name max cur percent\n"); + } + if (config.output_limit[1] & output_limit_bit_2) + { + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", + shared_p->name, + shared_p->available, + shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } + fprintf (outfile, "\n"); + } + if (config.output_limit[0] & output_limit_bit_3) + { + fprintf (outfile, "Sum of all ranges:\n"); + fprintf (outfile, "name max cur percent\n"); + } + if (config.output_limit[1] & output_limit_bit_3) + { + fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", + shared_networks->name, + shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); + } + if (outfile == stdout) + { + fflush (stdout); + } + else + { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) + { + eprintf ("output_txt: %s:", config.output_file); } else { - fprintf (outfile, "not_defined "); + eprintf ("output_txt: stdout:"); } - fprintf (outfile, "%-16s", inet_ntoa (first)); - fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n", - inet_ntoa (last), - range_p->last_ip - range_p->first_ip - 1, - range_p->count, - (float) (100 * range_p->count) / (range_p->last_ip - - range_p->first_ip - 1)); - range_p++; - } - - fprintf (outfile, "\nShared networks:\n"); - fprintf (outfile, "name max cur percent\n"); - for (i = 0; i < num_shared_networks; i++) - { - shared_p++; - fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", - shared_p->name, - shared_p->available, - shared_p->used, - (float) (100 * shared_p->used) / shared_p->available); - } - - fprintf (outfile, "\nSum of all ranges:\n"); - fprintf (outfile, "name max cur percent\n"); - fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", - shared_networks->name, - shared_networks->available, - shared_networks->used, - (float) (100 * shared_networks->used) / - shared_networks->available); - - fclose (outfile); - if (errno) - { - eprintf ("%s:", config.output_file); exit (EXIT_FAILURE); } @@ -132,7 +163,7 @@ output_html (void) outfile = fopen (config.output_file, "w+"); if (outfile == NULL) { - eprintf ("%s:", config.output_file); + eprintf ("output_html: %s:", config.output_file); exit (EXIT_FAILURE); } } @@ -146,60 +177,89 @@ output_html (void) fprintf (outfile, "\n"); - fprintf (outfile, "\n"); - fprintf - (outfile, - "\n"); - for (i = 0; i < num_ranges; i++) + if (config.output_limit[0] & output_limit_bit_1) { - first.s_addr = ntohl (range_p->first_ip + 1); - last.s_addr = ntohl (range_p->last_ip - 1); - - if (range_p->shared_net) + fprintf (outfile, "\n"); + fprintf + (outfile, + "\n"); + } + if (config.output_limit[1] & output_limit_bit_1) + { + for (i = 0; i < num_ranges; i++) { - fprintf (outfile, "", range_p->shared_net->name); + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "", range_p->shared_net->name); + } + else + { + fprintf (outfile, ""); + } + fprintf (outfile, "", inet_ntoa (first)); + fprintf (outfile, + "\n", + inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } + } + if (config.output_limit[0] & output_limit_bit_2) + { + fprintf (outfile, "\n\n"); + fprintf (outfile, + "\n"); + } + if (config.output_limit[1] & output_limit_bit_2) + { + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, + "\n", + shared_p->name, shared_p->available, shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } + } + if (config.output_limit[0] & output_limit_bit_3) + { + fprintf (outfile, "\n\n"); + fprintf (outfile, + "\n"); + } + if (config.output_limit[1] & output_limit_bit_3) + { + fprintf (outfile, + "\n", + shared_networks->name, shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); + } + fprintf (outfile, "
Ranges:
shared net namefirst iplast ipmaxcurpercent
Ranges:
shared net namefirst iplast ipmaxcurpercent
%s
%s
not_defined%s%s%lu%lu%.3f
Shared networks:
namemaxcurpercent
%s%lu%lu%.3f
Sum of all ranges:
namemaxcurpercent
%s%lu%lu%.3f
\n"); + if (outfile == stdout) + { + fflush (stdout); + } + else + { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) + { + eprintf ("output_html: %s:", config.output_file); } else { - fprintf (outfile, "not_defined"); + eprintf ("output_html: stdout:"); } - fprintf (outfile, "%s", inet_ntoa (first)); - fprintf (outfile, - "%s%lu%lu%.3f\n", - inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1, - range_p->count, - (float) (100 * range_p->count) / (range_p->last_ip - - range_p->first_ip - 1)); - range_p++; - } - - fprintf (outfile, "\nShared networks:\n"); - fprintf (outfile, - "namemaxcurpercent\n"); - for (i = 0; i < num_shared_networks; i++) - { - shared_p++; - fprintf (outfile, - "%s%lu%lu%.3f\n", - shared_p->name, shared_p->available, shared_p->used, - (float) (100 * shared_p->used) / shared_p->available); - } - - fprintf (outfile, "\nSum of all ranges:\n"); - fprintf (outfile, - "namemaxcurpercent\n"); - fprintf (outfile, - "%s%lu%lu%.3f\n", - shared_networks->name, shared_networks->available, - shared_networks->used, - (float) (100 * shared_networks->used) / - shared_networks->available); - - fprintf (outfile, "\n"); - fclose (outfile); - if (errno) - { - eprintf ("%s:", config.output_file); exit (EXIT_FAILURE); } @@ -220,7 +280,7 @@ output_csv (void) outfile = fopen (config.output_file, "w+"); if (outfile == NULL) { - eprintf ("%s:", config.output_file); + eprintf ("output_csv: %s:", config.output_file); exit (EXIT_FAILURE); } } @@ -232,57 +292,91 @@ output_csv (void) range_p = ranges; shared_p = shared_networks; - fprintf (outfile, "\"Ranges:\"\n"); - fprintf - (outfile, - "\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n"); - for (i = 0; i < num_ranges; i++) + if (config.output_limit[0] & output_limit_bit_1) { - first.s_addr = ntohl (range_p->first_ip + 1); - last.s_addr = ntohl (range_p->last_ip - 1); - - if (range_p->shared_net) + fprintf (outfile, "\"Ranges:\"\n"); + fprintf + (outfile, + "\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n"); + } + if (config.output_limit[1] & output_limit_bit_1) + { + for (i = 0; i < num_ranges; i++) { - fprintf (outfile, "\"%s\",", range_p->shared_net->name); + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "\"%s\",", range_p->shared_net->name); + } + else + { + fprintf (outfile, "\"not_defined\","); + } + fprintf (outfile, "\"%s\",", inet_ntoa (first)); + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + inet_ntoa (last), + range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } + fprintf (outfile, "\n"); + } + if (config.output_limit[0] & output_limit_bit_2) + { + fprintf (outfile, "\"Shared networks:\"\n"); + fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); + } + if (config.output_limit[1] & output_limit_bit_2) + { + + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + shared_p->name, + shared_p->available, + shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } + fprintf (outfile, "\n"); + } + if (config.output_limit[0] & output_limit_bit_3) + { + fprintf (outfile, "\"Sum of all ranges:\"\n"); + fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); + } + if (config.output_limit[1] & output_limit_bit_3) + { + + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + shared_networks->name, + shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); + } + if (outfile == stdout) + { + fflush (stdout); + } + else + { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) + { + eprintf ("output_csv: %s:", config.output_file); } else { - fprintf (outfile, "\"not_defined\","); + eprintf ("output_csv: stdout:"); } - fprintf (outfile, "\"%s\",", inet_ntoa (first)); - fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", - inet_ntoa (last), - range_p->last_ip - range_p->first_ip - 1, - range_p->count, - (float) (100 * range_p->count) / (range_p->last_ip - - range_p->first_ip - 1)); - range_p++; - } - - fprintf (outfile, "\n\"Shared networks:\"\n"); - fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); - for (i = 0; i < num_shared_networks; i++) - { - shared_p++; - fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", - shared_p->name, - shared_p->available, - shared_p->used, - (float) (100 * shared_p->used) / shared_p->available); - } - - fprintf (outfile, "\n\"Sum of all ranges:\"\n"); - fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); - fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", - shared_networks->name, - shared_networks->available, - shared_networks->used, - (float) (100 * shared_networks->used) / - shared_networks->available); - fclose (outfile); - if (errno) - { - eprintf ("%s:", config.output_file); exit (EXIT_FAILURE); } diff --git a/src/output.c~ b/src/output.c~ new file mode 100644 index 0000000..2ce0e67 --- /dev/null +++ b/src/output.c~ @@ -0,0 +1,348 @@ +/* +** Copyright (C) 2006 Sami Kerola +** +** 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 2 of the License, 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, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "dhcpd-pools.h" + +/* There should be command line switches that can be used to + * limit output. Not always one wishes to see headers, ranges, + * shared networks or total. Perhaps this is fixed on next + * version. */ + +int +output_txt (void) +{ + unsigned int i; + struct in_addr first, last; + struct range_t *range_p; + struct shared_network_t *shared_p; + FILE *outfile; + + if (config.output_file[0]) + { + outfile = fopen (config.output_file, "w+"); + if (outfile == NULL) + { + eprintf ("output_txt: %s:", config.output_file); + exit (EXIT_FAILURE); + } + } + else + { + outfile = stdout; + } + + range_p = ranges; + shared_p = shared_networks; + +if (config.output_limit[0] & output_limit_bit_1) { + fprintf (outfile, "Ranges:\n"); + fprintf + (outfile, + "shared net name first ip last ip max cur percent\n"); +} +if (config.output_limit[1] & output_limit_bit_1) { + for (i = 0; i < num_ranges; i++) + { + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "%-20s", range_p->shared_net->name); + } + else + { + fprintf (outfile, "not_defined "); + } + fprintf (outfile, "%-16s", inet_ntoa (first)); + fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n", + inet_ntoa (last), + range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } +fprintf(outfile, "\n"); +} +if (config.output_limit[0] & output_limit_bit_2) { + fprintf (outfile, "Shared networks:\n"); + fprintf (outfile, "name max cur percent\n"); +} +if (config.output_limit[1] & output_limit_bit_2) { + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", + shared_p->name, + shared_p->available, + shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } +fprintf(outfile, "\n"); +} +if (config.output_limit[0] & output_limit_bit_3) { + fprintf (outfile, "Sum of all ranges:\n"); + fprintf (outfile, "name max cur percent\n"); +} +if (config.output_limit[1] & output_limit_bit_3) { + fprintf (outfile, "%-20s %5lu %5lu %10.3f\n", + shared_networks->name, + shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); +} + if (outfile == stdout) { + fflush(stdout); + } else { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) { + eprintf ("output_txt: %s:", config.output_file); + } else { + eprintf ("output_txt: stdout:"); + } + exit (EXIT_FAILURE); + } + + + return 0; +} + +int +output_html (void) +{ + unsigned int i; + struct in_addr first, last; + struct range_t *range_p; + struct shared_network_t *shared_p; + FILE *outfile; + + if (config.output_file[0]) + { + outfile = fopen (config.output_file, "w+"); + if (outfile == NULL) + { + eprintf ("output_html: %s:", config.output_file); + exit (EXIT_FAILURE); + } + } + else + { + outfile = stdout; + } + + range_p = ranges; + shared_p = shared_networks; + + fprintf (outfile, + "\n"); +if (config.output_limit[0] & output_limit_bit_1) { + fprintf (outfile, "\n"); + fprintf + (outfile, + "\n"); +} +if (config.output_limit[1] & output_limit_bit_1) { + for (i = 0; i < num_ranges; i++) + { + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "", range_p->shared_net->name); + } + else + { + fprintf (outfile, ""); + } + fprintf (outfile, "", inet_ntoa (first)); + fprintf (outfile, + "\n", + inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } +} +if (config.output_limit[0] & output_limit_bit_2) { + fprintf (outfile, "\n\n"); + fprintf (outfile, + "\n"); +} +if (config.output_limit[1] & output_limit_bit_2) { + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, + "\n", + shared_p->name, shared_p->available, shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } +} +if (config.output_limit[0] & output_limit_bit_3) { + fprintf (outfile, "\n\n"); + fprintf (outfile, + "\n"); +} +if (config.output_limit[1] & output_limit_bit_3) { + fprintf (outfile, + "\n", + shared_networks->name, shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); +} + fprintf (outfile, "
Ranges:
shared net namefirst iplast ipmaxcurpercent
%s
not_defined%s%s%lu%lu%.3f
Shared networks:
namemaxcurpercent
%s%lu%lu%.3f
Sum of all ranges:
namemaxcurpercent
%s%lu%lu%.3f
\n"); + if (outfile == stdout) { + fflush(stdout); + } else { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) { + eprintf ("output_html: %s:", config.output_file); + } else { + eprintf ("output_html: stdout:"); + } + exit (EXIT_FAILURE); + } + + return 0; +} + +int +output_csv (void) +{ + unsigned int i; + struct in_addr first, last; + struct range_t *range_p; + struct shared_network_t *shared_p; + FILE *outfile; + + if (config.output_file[0]) + { + outfile = fopen (config.output_file, "w+"); + if (outfile == NULL) + { + eprintf ("output_csv: %s:", config.output_file); + exit (EXIT_FAILURE); + } + } + else + { + outfile = stdout; + } + + range_p = ranges; + shared_p = shared_networks; + +if (config.output_limit[0] & output_limit_bit_1) { + fprintf (outfile, "\"Ranges:\"\n"); + fprintf + (outfile, + "\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n"); +} +if (config.output_limit[1] & output_limit_bit_1) { + for (i = 0; i < num_ranges; i++) + { + first.s_addr = ntohl (range_p->first_ip + 1); + last.s_addr = ntohl (range_p->last_ip - 1); + + if (range_p->shared_net) + { + fprintf (outfile, "\"%s\",", range_p->shared_net->name); + } + else + { + fprintf (outfile, "\"not_defined\","); + } + fprintf (outfile, "\"%s\",", inet_ntoa (first)); + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + inet_ntoa (last), + range_p->last_ip - range_p->first_ip - 1, + range_p->count, + (float) (100 * range_p->count) / (range_p->last_ip - + range_p->first_ip - 1)); + range_p++; + } +fprintf (outfile, "\n"); +} +if (config.output_limit[0] & output_limit_bit_2) { + fprintf (outfile, "\"Shared networks:\"\n"); + fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); +} +if (config.output_limit[1] & output_limit_bit_2) { + + for (i = 0; i < num_shared_networks; i++) + { + shared_p++; + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + shared_p->name, + shared_p->available, + shared_p->used, + (float) (100 * shared_p->used) / shared_p->available); + } +fprintf (outfile, "\n"); +} + if (config.output_limit[0] & output_limit_bit_3) { + fprintf (outfile, "\"Sum of all ranges:\"\n"); + fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n"); +} +if (config.output_limit[1] & output_limit_bit_3) { + + fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", + shared_networks->name, + shared_networks->available, + shared_networks->used, + (float) (100 * shared_networks->used) / + shared_networks->available); +} + if (outfile == stdout) { + fflush(stdout); + } else { + fclose (outfile); + } + if (errno) + { + if (config.output_file[0]) { + eprintf ("output_csv: %s:", config.output_file); + } else { + eprintf ("output_csv: stdout:"); + } + exit (EXIT_FAILURE); + } + + return 0; +}