/*
#  This is version 0.3 of absent
#
#               Copyright (c) 1999 by AT&T.
#  Permission to use, copy, and modify this software without fee is
#  hereby granted, provided that this entire notice is included in all
#  copies of any software which is or includes a copy or modification
#  of this software and in all copies of the supporting documentation
#  for such software.
#
#  SOME PARTS OF ABSENT MAY BE RESTRICTED UNDER UNITED STATES EXPORT
#  REGULATIONS.
#
#  THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
#  IMPLIED WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE
#  ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
#  MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
#  PURPOSE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <signal.h>
#include <syslog.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include "absent.h"
#include "keys.h"

/* linux needs these.  stupid linux. */
#ifdef __linux__
#include <fcntl.h>
#include <time.h>
#define __need_timeval
#include <timebits.h>
#endif /* __linux__ */

/* irix doesn't define this.  stupid irix. */
#ifndef MAXADDRS
#define MAXADDRS 32
#endif  /* !MAXADDRS */

/* linux defines these.  stupid linux. */
#ifndef __linux__
union semun {
  long val;
  struct semid_ds *buf;
  ushort *array;
};
#endif /* __linux__ */

/* unix doesn't define this.  stupid unix. */
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif  /* !SHUT_RDWR */

/* defaults for the configuration file entries.  there's not really
   much point in adjusting these as they'll be overridden by the cf
   reader anyway. */
#define ABSENTD_DEFCPORT 4431
#define ABSENTD_DEFPPORT 4500
#define ABSENTD_DEFPFREQ 0
#define ABSENTD_DEFPOUT 30
#define ABSENTD_DEFCOUT 30
#define ABSENTD_DEFPNOID 1
#define ABSENTD_DEFMCON 256
#define ABSENTD_DEFBSIZ 32767
#define ABSENTD_DEFUSER -1
#define ABSENTD_DEFGROUP -1

/* logging control */
#define ABSENTD_IDENT "absentd"
#define ABSENTD_LOGOPT LOG_PID|LOG_NOWAIT
#define ABSENTD_LOGFAC LOG_LOCAL5

/* tunable: how long should closed sockets linger?  be careful with this. */
#define ABSENTD_LINGER  15           /* generally a safe value. */

/* the default location of the absentd configuration file.  This can
   be overridden by a command-line option. */
#ifndef ABSENTD_CFILE
#define ABSENTD_CFILE   "/usr/local/absent/absentd.cf"
#endif  /* !ABSENTD_CFILE */

/* just a useful debugging construct.  feel free to change the syslog here.
   it's probably best to leave this turned off unless you're actually
   debugging absentd.  calls to syslog ain't cheap. */
#ifdef DEBUG
#define DEBUGLOG0(fmt) syslog(LOG_DEBUG,fmt)
#define DEBUGLOG1(fmt,arg1) syslog(LOG_DEBUG,fmt,arg1)
#define DEBUGLOG2(fmt,arg1,arg2) syslog(LOG_DEBUG,fmt,arg1,arg2)
#define DEBUGLOG3(fmt,arg1,arg2,arg3) syslog(LOG_DEBUG,fmt,arg1,arg2,arg3)
#define DEBUGLOG4(fmt,arg1,arg2,arg3,arg4)\
                           syslog(LOG_DEBUG,fmt,arg1,arg2,arg3,arg4)
#define DEBUGLOG5(fmt,arg1,arg2,arg3,arg4,arg5)\
                           syslog(LOG_DEBUG,fmt,arg1,arg2,arg3,arg4,arg5)
#else
#define DEBUGLOG0(fmt)
#define DEBUGLOG1(fmt,arg1)
#define DEBUGLOG2(fmt,arg1,arg2)
#define DEBUGLOG3(fmt,arg1,arg2,arg3)
#define DEBUGLOG4(fmt,arg1,arg2,arg3,arg4)
#define DEBUGLOG5(fmt,arg1,arg2,arg3,arg4,arg5)
#endif /* DEBUG */

/* some type definitions.  */

typedef struct _cf {
  /* the absentd configuration file */
  char key[8];            /* the host key.  fixme - size should be macro */
  int control_port;       /* the port for the control channel */
  int data_port;          /* the port for client connections (badly named) */
  int pushweb_port;       /* the port for data connections from pushweb */
  char *absent;           /* absent's hostname (for pushweb connections) */
  char *pushweb;          /* pushweb's hostname */
  char *clienthost;       /* hostname on which we accept client connections */
  int pingfreq;           /* how often to ping, in seconds (never if 0) */
  int pingout;            /* how long to wait for ping responses, in secs */
  int ctimeout;           /* how long to tolerate silent clients */
  int user;               /* user to run as */
  int group;              /* group to run as */
  int paranoid;           /* double-reverse all names? */
  unsigned maxconn;       /* maximum number of connections */
  unsigned bsize;         /* buffer size */
  char *pwbaddrs[MAXADDRS+1];    /* addresses for pushweb */
  struct _cf *nextcf;
} absentd_cf;

/* some things not provided by header files */
extern int gethostname();
