/*-
 * Copyright (c) 2004 Free (Olivier Beyssac)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include <syslog.h>
#include "options.h"


/* Defaults to put in options when initializing */
#define DEFAULT_PORT "2905"
#define DEFAULT_LIST_SIZE (2000)
#define DEFAULT_INTERVAL (30)
#define DEFAULT_MAX_REQ (10)
#define DEFAULT_BLACKLIST_SIZE (1000)
#define DEFAULT_BLACKLIST_EXPIRATION (900)
#define DEFAULT_DUMP_DELAY (60)
#define DEFAULT_LOG_LEVEL (1)
#define DEFAULT_WORKING_DIR VARRUN
#define DEFAULT_WL_FILENAME DEFAULT_WORKING_DIR"/"PROGNAME"_iplist.dump"
#define DEFAULT_BL_FILENAME DEFAULT_WORKING_DIR"/"PROGNAME"_blacklist.dump"
#define DEFAULT_PID_FILENAME VARRUN"/"PROGNAME".pid"
#define DEFAULT_ACL_FILENAME ETC_LOCATION"/"PROGNAME"_acl.conf"
#define DEFAULT_WHITELIST_FILENAME ETC_LOCATION"/"PROGNAME"_whitelist.conf"
#define DEFAULT_LISTENING_IP "127.0.0.1"
#define DEFAULT_DAEMON_MODE (1)
#define DEFAULT_CLIENT_TIMEOUT (60)
#define DEFAULT_UID NULL
#define DEFAULT_GID NULL
#define DEFAULT_CONFIG_FILE ETC_LOCATION"/bld.conf"
#define DEFAULT_NOTIFY_HOST NULL
#define DEFAULT_NOTIFY_TIMEOUT (10)
#define DEFAULT_CONNECT_TIMEOUT (10)


extern struct options opt;


/* > 0 */
#define GTZERO  0
/* >= 0 */
#define GEZERO  1
/* > 1 */
#define GEONE   2
/* 0 or 1 */
#define ZEROONE 3


static unsigned int checktab[] = { ZEROONE, /* daemon */
				   GEZERO,  /* log_level */
				   GTZERO,  /* interval */
				   GTZERO,  /* max_req */
				   GTZERO,  /* list_size */
				   GTZERO,  /* blacklist_size */
				   GTZERO,  /* blacklist_expiration */
				   GTZERO   /* client_timeout */
                                 };


/* Initialize options/parameters */
extern void options_init(char *progname)
{
  opt.port = DEFAULT_PORT;
  opt.list_size = DEFAULT_LIST_SIZE;
  opt.interval = DEFAULT_INTERVAL;
  opt.max_req = DEFAULT_MAX_REQ;
  opt.blacklist_size = DEFAULT_BLACKLIST_SIZE;
  opt.blacklist_expiration = DEFAULT_BLACKLIST_EXPIRATION;
  opt.dump_delay = DEFAULT_DUMP_DELAY;
  opt.last_dump = time(NULL);
  opt.log_level = DEFAULT_LOG_LEVEL;
  opt.wl_filename = DEFAULT_WL_FILENAME;
  opt.bl_filename = DEFAULT_BL_FILENAME;
  opt.pid_filename = DEFAULT_PID_FILENAME;
  opt.daemon = DEFAULT_DAEMON_MODE;
  opt.start_time = time(NULL);
  opt.progname = progname;
  opt.working_dir = DEFAULT_WORKING_DIR;
  opt.listening_ip = DEFAULT_LISTENING_IP;
  opt.acl_filename = DEFAULT_ACL_FILENAME;
  opt.acl_mtime = 0;
  opt.acl = netlist_init();
  opt.whitelist_filename = DEFAULT_WHITELIST_FILENAME;
  opt.whitelist_mtime = 0;
  opt.whitelist = netlist_init();
  opt.client_timeout = DEFAULT_CLIENT_TIMEOUT;
  opt.submissions = 0;
  opt.blqueries = 0;
  opt.positive_blqueries = 0;
  opt.insertqueries = 0;
  opt.bad_requests = 0;
  opt.denied_requests = 0;
  opt.config_file = DEFAULT_CONFIG_FILE;
  opt.config_mtime = 0;
  opt.notify_hosts = DEFAULT_NOTIFY_HOST;
  opt.notify_timeout = DEFAULT_NOTIFY_TIMEOUT;
  opt.connect_timeout = DEFAULT_CONNECT_TIMEOUT;
  opt.notifies = 0;
  opt.syslog = 0;
}


/* Show runtime options/parameters */
extern void options_log(void)
{
  int i;
  
  syslog(LOG_INFO, "starting with following parameters:");
  syslog(LOG_INFO, "start time: %lu", (unsigned long)opt.start_time);
  syslog(LOG_INFO, "Listening IP:port: %s:%s", opt.listening_ip, opt.port);
  syslog(LOG_INFO, "IP list size: %d", opt.list_size);
  syslog(LOG_INFO, "Max submissions / time interval : %d / %lu secs",
	 (int)opt.max_req, (unsigned long)opt.interval);
  syslog(LOG_INFO, "Blacklist size: %d", opt.blacklist_size);
  syslog(LOG_INFO, "Blacklist expiration: %lu",
         (unsigned long)opt.blacklist_expiration);
  syslog(LOG_INFO, "Stats dump delay: %lu", (unsigned long)opt.dump_delay);
  syslog(LOG_INFO, "Log level: %d", opt.log_level);
  syslog(LOG_INFO, "IP list filename: %s", opt.wl_filename);
  syslog(LOG_INFO, "Blacklist filename: %s", opt.bl_filename);
  syslog(LOG_INFO, "Configuration filename: %s", opt.config_file);
  syslog(LOG_INFO, "PID filename = %s", opt.pid_filename);
  syslog(LOG_INFO, "Daemon mode: %d", opt.daemon);
  syslog(LOG_INFO, "Working dir: %s", opt.working_dir);
  syslog(LOG_INFO, "ACL file: %s (mtime: %lu)",
	 opt.acl_filename, (unsigned long)opt.acl_mtime);
  syslog(LOG_INFO, "Whitelist file: %s (mtime: %lu)",
	 opt.whitelist_filename, (unsigned long)opt.whitelist_mtime);
  syslog(LOG_INFO, "Client timeout: %lu secs",
	 (unsigned long)opt.client_timeout);
  syslog(LOG_INFO, "Dump delay: %lu secs", (unsigned long)opt.dump_delay);
  syslog(LOG_INFO, "uid / gid : %s / %s",
	 opt.uid ? opt.uid : "(not specified)",
	 opt.gid ? opt.gid : "(not specified)");
  if (opt.notify_hosts)
    for (i = 0; opt.notify_hosts[i]; i += 2)
      syslog(LOG_INFO, "Notify host: %s:%s\n",
	     opt.notify_hosts[i], opt.notify_hosts[i+1]);
}


/* Check an option value and return 1 if correct */
extern int options_check(const int option, const int value)
{
  if (checktab[option] == GTZERO && value > 0)
    return 1;
  if (checktab[option] == GEZERO && value >= 0)
    return 1;
  if (checktab[option] == GEONE && value >= 1)
    return 1;
  if (checktab[option] == ZEROONE && (value == 0 || value == 1))
    return 1;

  return 0;
}


