/* fastdaemon2.c */

/* Copyright 2000 by Eberhard Mattes <em-gw@windhager.de>
   Donated to the public domain.  No warranty.

   2000-05-27 Initial version */

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "firewall.h"
#include "libemfw.h"

/* firewall.h lacks some declarations. */

int str_to_port (char *);

void parse_fastdaemon (struct fastdaemon_args *a, int *pargc, char ***pargv)
{
  int argc = *pargc;
  char **argv = *pargv;
  char *s, *p;

  a->hostname = NULL;
  a->ipaddr = NULL;
  s = argv[2];
  argc -= 2; argv += 2;
  p = strchr (s, ':');
  if (p != NULL)
    {
      a->hostname = xstrndup (s, p - s);
      s = p + 1;
    }
  a->port = str_to_port (s);

  if (argc >= 3 && strcmp (argv[1], "-pf") == 0)
    {
      create_pid_file (argv[2]);
      argc -= 2; argv += 2;
    }
  *pargc = argc; *pargv = argv;
}

static int maybe_ip_addr (const char *s)
{
  while (*s == '.' || (*s >= '0' && *s <= '9'))
    ++s;
  return *s == 0;
}

void fastdaemon_sockaddr (struct sockaddr_in *sa, struct fastdaemon_args *a)
{
  memset (&sa->sin_addr, 0, sizeof (sa->sin_addr));
  sa->sin_port = htons (a->port);
  if (a->hostname)
    {
      unsigned long n;
      if (maybe_ip_addr (a->hostname)
	  && (n = inet_addr (a->hostname)) != htonl ((unsigned long)-1))
	{
	  a->ipaddr = a->hostname;
	  sa->sin_addr.s_addr = n;
	}
      else
	{
	  struct hostent *h = gethostbyname (a->hostname);
	  if (h == NULL)
	    {
	      syslog (LLEV, "fwtkcfgerr: cannot get IP address for host %s",
		      a->hostname);
	      exit (1);
	    }
	  memcpy (&sa->sin_addr.s_addr, h->h_addr,
		  sizeof (sa->sin_addr.s_addr));
	  a->ipaddr = xstrdup (inet_ntoa (sa->sin_addr));
	}
    }
  if (a->hostname)
    syslog (LLEV, "Starting fast daemon mode on host %s (%s) port %d",
	    a->hostname, a->ipaddr, a->port);
  else
    syslog (LLEV, "Starting fast daemon mode on port %d", a->port);
}

void fastdaemon_ready (const struct fastdaemon_args *a)
{
  if (a->ipaddr)
    syslog (LLEV, "Now ready on IP address %s port %d", a->ipaddr, a->port);
  else
    syslog (LLEV, "Now ready on port %d", a->port);
}
