make range allocation dynamic
[debian/dhcpd-pools.git] / src / dhcpd-pools.c
index 78a6ce0..db8495b 100644 (file)
@@ -1,19 +1,18 @@
-/*
-** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
-**  
-** This program is free software; you can redistribute it and/or modify
+/* http://dhcpd-pools.sourceforge.net/
+** Copyright 2006- Sami Kerola <kerolasa@iki.fi>
+**
+** 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
+** the Free Software Foundation, either version 3 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.
+** along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #ifdef HAVE_CONFIG_H
@@ -27,7 +26,6 @@
 #ifdef  HAVE_STDLIB_H
 #include <stdlib.h>
 #else                          /* Not STDC_HEADERS */
-extern void exit();
 extern char *malloc();
 #endif                         /* STDC_HEADERS */
 #ifdef  HAVE_STRING_H
@@ -37,13 +35,14 @@ extern char *malloc();
 #endif
 #include <getopt.h>
 #include <errno.h>
+#include <err.h>
 
 #include "dhcpd-pools.h"
 #include "defaults.h"
 
 int main(int argc, char **argv)
 {
-       int c, sorts = 0;
+       int i, c, sorts = 0;
        int option_index = 0;
        char *tmp;
        struct range_t *tmp_ranges;
@@ -62,17 +61,13 @@ int main(int argc, char **argv)
                {0, 0, 0, 0}
        };
 
-       program_name = argv[0];
-       atexit(clean_up);
-
-       /* TODO: make either dynamic or find out max path lenght that auto config
-        * provides */
+       /* FIXME: make these allocations dynamic up on need. */
        config.dhcpdconf_file = safe_malloc(sizeof(char) * MAXLEN);
        config.dhcpdlease_file = safe_malloc(sizeof(char) * MAXLEN);
        config.output_file = safe_malloc(sizeof(char) * MAXLEN);
 
-       /* Make sure string has zero lenght if there is no command line
-        * option */
+       /* Make sure string has zero lenght if there is no
+        * command line option */
        config.output_file[0] = '\0';
 
        /* File location defaults */
@@ -101,59 +96,34 @@ int main(int argc, char **argv)
                        break;
 
                switch (c) {
-               case 0:
-                       break;
                case 'c':
                        /* config file */
-                       if (optarg != NULL) {
-                               strncpy(config.dhcpdconf_file, optarg,
-                                       (size_t) MAXLEN - 1);
-                       } else {
-                               eprintf
-                                   ("main: for argument configuration file parameter not set");
-                               usage(EXIT_FAILURE);
-                       }
+                       strncpy(config.dhcpdconf_file, optarg,
+                               (size_t) MAXLEN - 1);
                        break;
                case 'l':
                        /* lease file */
-                       if (optarg != NULL) {
-                               strncpy(config.dhcpdlease_file, optarg,
-                                       (size_t) MAXLEN - 1);
-                       } else {
-                               eprintf
-                                   ("main: for argument lease file parameter not set");
-                               usage(EXIT_FAILURE);
-                       }
+                       strncpy(config.dhcpdlease_file, optarg,
+                               (size_t) MAXLEN - 1);
                        break;
                case 'f':
                        /* Output format */
-                       if (optarg != NULL) {
-                               strncpy(config.output_format, optarg,
-                                       (size_t) 1);
-                       } else {
-                               eprintf
-                                   ("main: for argument output format parameter not set");
-                               usage(EXIT_FAILURE);
-                       }
+                       strncpy(config.output_format, optarg, (size_t) 1);
                        break;
                case 's':
                        /* Output sorting option */
-                       if (optarg != NULL) {
-                               sorts = strlen(optarg);
-                               if (5 < sorts) {
-                                       eprintf
-                                           ("main: only 5 first sort orders will be used");
-                                       strncpy(config.sort, optarg,
-                                               (size_t) 5);
-                                       sorts = 5;
-                               } else {
-                                       strncpy(config.sort, optarg,
-                                               (size_t) sorts);
-                               }
+                       sorts = strlen(optarg);
+                       if (5 < sorts) {
+                               warnx
+                                   ("main: only first 5 sort orders will be used");
+                               strncpy(config.sort, optarg, (size_t) 5);
+                               sorts = 5;
                        } else {
-                               eprintf
-                                   ("main: for argument sort order parameter not set");
-                               usage(EXIT_FAILURE);
+                               strncpy(config.sort, optarg,
+                                       (size_t) sorts);
+                       }
+                       for (i = 0; i < sorts; i++) {
+                               field_selector(config.sort[i]);
                        }
                        break;
                case 'r':
@@ -162,51 +132,32 @@ int main(int argc, char **argv)
                        break;
                case 'o':
                        /* Output file */
-                       if (optarg != NULL) {
-                               strncpy(config.output_file, optarg,
-                                       (size_t) MAXLEN - 1);
-                       } else {
-                               eprintf
-                                   ("main: for argument output file parameter not set");
-                               usage(EXIT_FAILURE);
-                       }
+                       strncpy(config.output_file, optarg,
+                               (size_t) MAXLEN - 1);
                        break;
                case 'L':
                        /* Specification what will be printed */
-                       if (optarg != NULL) {
-                               if (optarg[0] >= '0' && optarg[0] < '8') {
-                                       config.output_limit[0] =
-                                           (int) optarg[0] - '0';
-                               } else {
-                                       eprintf
-                                           ("main: output mask %s illegal",
-                                            argv[optind]);
-                                       usage(EXIT_FAILURE);
-                               }
-                               if (optarg[1] >= '0' && optarg[1] < '8') {
-                                       config.output_limit[1] =
-                                           (int) optarg[1] - '0';
+                       for (i = 0; i < 2; i++) {
+                               if (optarg[i] >= '0' && optarg[i] < '8') {
+                                       config.output_limit[i] =
+                                           (int) optarg[i] - '0';
                                } else {
-                                       eprintf
-                                           ("main: output mask %s illegal",
+                                       errx(EXIT_FAILURE,
+                                            "main: output mask `%s' is illegal",
                                             optarg);
-                                       usage(EXIT_FAILURE);
                                }
-                       } else {
-                               eprintf
-                                   ("main: for argument output mask parameter not set");
-                               usage(EXIT_FAILURE);
                        }
                        break;
                case 'v':
                        /* Print version */
                        print_version();
-                       exit(EXIT_SUCCESS);
                case 'h':
                        /* Print help */
                        usage(EXIT_SUCCESS);
                default:
-                       usage(EXIT_FAILURE);
+                       errx(EXIT_FAILURE,
+                            "Try `%s --help' for more information.",
+                            program_invocation_short_name);
                }
        }
 
@@ -231,13 +182,9 @@ int main(int argc, char **argv)
        case 'c':
                output_analysis = output_csv;
                break;
-       case 's':
-               /* output_analysis = output_snmp; */
-               output_analysis = output_txt;
-               break;
        default:
-               eprintf("main: unknown ouput format");
-               usage(EXIT_FAILURE);
+               errx(EXIT_FAILURE, "main: unknown output format `%c'",
+                    config.output_format[0]);
        }
 
        /* Do the job */
@@ -246,11 +193,6 @@ int main(int argc, char **argv)
                     shared_net_names + strlen(shared_net_names) + 1,
                     shared_networks);
 
-       if ((config.output_format[0] == 'x')
-           || (config.output_format[0] == 'X')) {
-               printf("<dhcpstatus>\n");
-       };
-
        parse_leases();
        prepare_data();
        do_counting();
@@ -263,25 +205,15 @@ int main(int argc, char **argv)
        }
        free(tmp_ranges);
        output_analysis();
-       /* After fopen in ouput ioctl does like /dev/null which
-        * cause ENOTTY, and clean_up will see that without this
-        * reset. At least linux does this, and possibly some
-        * other systems. There's a report from FreeBSD 8.0 which
-        * matches quite well with the symptom. */
-       if (errno == 25)
-               errno = 0;
-
-       if ((config.output_format[0] == 'x')
-           || (config.output_format[0] == 'X')) {
-               printf("</dhcpstatus>\n");
-       };
 
-       exit(EXIT_SUCCESS);
+       clean_up();
+       return (EXIT_SUCCESS);
 }
 
 /* Global allocations, counter resets etc */
 int prepare_memory()
 {
+       RANGES = 64;
        num_ranges = num_shared_networks = 0;
        shared_networks =
            safe_malloc(sizeof(struct shared_network_t) * SHARED_NETWORKS);
@@ -289,6 +221,7 @@ int prepare_memory()
            safe_malloc(sizeof(char) * SHARED_NETWORKS_NAMES);
 
        ranges = safe_malloc(sizeof(struct range_t) * RANGES);
+       macaddr = NULL;
 
        /* First shared network entry is all networks */
        strcpy(shared_net_names, "All networks");