/*
 * sic.c: testing...
 *
 * Copyright(c) 1997-2000 - All Rights Reserved
 *
 * See the COPYRIGHT file.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: sic.c,v 1.24 2000/08/01 02:22:16 kalt Exp $";
#endif

#include "os.h"

#include "struct.h"
#include "window.h"
#include "server.h"
#include "input.h"
#include "term.h"
#include "option.h"
#include "config.h"
#include "counter.h"
#include "adns.h"

extern const char version[];

static int do_resize = 0, do_reinit = 0, do_intr = 0, cnt_intr = 0;

/* sic_sigwinch: shared SIGWINCH/SIGCONT handler */
static void
sic_sigwinch(sig)
int sig;
{
  do_resize += 1;
  if (sig == SIGCONT)
      do_reinit += 1;
}

/* sic_sigint: SIGINT handler */
static void
sic_sigint(sig)
int sig;
{
  static time_t last = 0;

  if (time(NULL) - last > 5)
      cnt_intr = 0;
  cnt_intr += 1;
  do_intr = 1;
  last = time(NULL);
}

/* sic_sigign: SIG_IGN to allow SA_INTERRUPT to work */
static void
sic_sigign(sig)
int sig;
{}

/* sic_signals: setup our own signal handlers */
static void
sic_signals()
{
  struct sigaction sa;

  sigemptyset(&sa.sa_mask);
#if defined(SA_INTERRUPT)
  sa.sa_flags = SA_INTERRUPT;
#else
  sa.sa_flags = 0;
#endif
  sa.sa_handler = sic_sigwinch;
  sigaction(SIGWINCH, &sa, NULL);
  sigaction(SIGCONT, &sa, NULL);
  sa.sa_handler = sic_sigint;
  sigaction(SIGINT, &sa, NULL);
  sa.sa_handler = sic_sigign;
  sigaction(SIGUSR1, &sa, NULL);
  sa.sa_flags = 0;
  sigaction(SIGPIPE, &sa, NULL);
}

/* main: you know, main! */
int
main (argc, argv)
  int argc;
  char *argv[];
{
  int o;
  char doconn = 1, err = 0, newenv[256], *startup = NULL;
  time_t now, next_counter = time(NULL) + 60;

  extern char *optarg;
  extern int opterr;

  opterr = 0;
  while ((o = getopt(argc, argv, "c:i:l:nr:v")) != EOF)
      switch (o) {
    case 'c':
	sprintf(newenv, "SICDIR=%s", optarg);
	putenv(newenv);
	break;
    case 'i':
	sprintf(newenv, "SICIP=%s", optarg);
	putenv(newenv);
	break;
    case 'l':
	sprintf(newenv, "SICLOG=%s", optarg);
	putenv(newenv);
	break;
    case 'n':
	doconn = 0;
	break;
    case 'r':
	startup = strdup(optarg); /* is strdup needed? */
	break;
    case 'v':
	printf("sic %s, Copyright (C) 1997-2000 Christophe Kalt <kalt@stealth.net>\n", version);
#if defined(USE_GNU_RX)
	printf("\tLinked with %s\n", rx_version_string);
#endif
	exit(0);
    default:
	err++;
	break;
      }
  if (err)
    {
      printf("sic [-c <config>] [-i <IP address>] [-l <logdir>] [-n] [-r <boot script>] [-v]\n");
      printf("\t-c\tDefine the directory where configuration files live\n");
      printf("\t-i\tUse a specific IP address for connections\n");
      printf("\t-l\tDefine the directory where log files go\n");
      printf("\t-n\tDon't auto-connect upon start.\n");
      printf("\t-r\tRun this file upon start.\n");
      printf("\t-v\tPrint version and exits\n\n");
      exit(0);
    }

  /* no window/lastlog ability */
  dns_init();		/* initialize the resolver thread */
  opt_init();		/* initialize global options */
  counter_init();	/* init counters */
  sic_signals();	/* setup signals */
  term_init();		/* initialize window/lastlog */
  sic_newwin();		/* create a window */
  /* window/lastlog initialized */
  cfg_init();		/* error messages will be in the lastlog */
  opt_cfg();		/* read options files */

  if (doconn)
      cmd_server("0"); /* connect! */
  if (startup)
      cmd_run(startup);
  else if (doconn)
      cmd_run("startup");

  while (1)
    {
      select_active(NULL, 2);
      if (do_reinit)
	{
	  term_reinit();
	  vsic_slog(LOG_DEBUG, "--- term_reinit() called");
	  do_reinit = 0;
	}
      if (do_resize)
	{
	  switch (term_size())
	    {
	    case -2:
		sic_slog(LOG_CLIENT, "--- Window size unknown.");
		break;
	    case -1:
		vsic_slog(LOG_CLIENT,
			 "--- ioctl(\"/dev/tty\", TIOCGWINSZ) failed: %s",
			 strerror(errno));
		break;
	    case 0:
		sic_slog(LOG_DEBUG, "--- Got SIGWINCH, but same size.");
		break;
	    case 1:
		vsic_slog(LOG_DEBUG, "--- New window size: %dx%d", CO, LI);
		sic_redowin(1);		/* clear window and redraw lastlog */
		display_status();	/* redraw status line */
		display_input();	/* redraw input line */
		break;
	    default:
		abort();
	    }
	  do_resize = 0;
	}
      if (do_intr)
	{
	  switch (cnt_intr)
	    {
	    case 1:
		sic_slog(LOG_CLIENT, "--- Ouch! Are you sure?");
		break;
	    case 2:
		sic_slog(LOG_CLIENT, "--- Aiiie.. Really?");
		break;
	    case 3:
		sic_slog(LOG_CLIENT, "--- Okay, okay..");
		term_end();
		exit(0);
	    default:
		abort();
	    }
	  do_intr = 0;
	}

      if (sic_select() > 0)
	  sic_getch();

      dns_process();

      now = time(NULL);
#if defined(HAVE_REGEXP)
      if (now > next_counter)
	{
	  next_counter = now + 60;
	  counter_expire(-1);
	}
#endif
    }
  /* we can never get here anymore.. */
  term_end();
  exit(0);
}
