/* Entry for the GNATS system.
   Copyright (C) 1993 Free Software Foundation, Inc.
   Contributed by Tim Wicinski (wicinski@barn.com).

This file is part of GNU GNATS.

GNU GNATS 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, or (at your option)
any later version.

GNU GNATS 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 GNU GNATS; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "config.h"

#include <stdio.h>
#include <sys/types.h>

#include <getopt.h>
#include <ansidecl.h>
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif

#include <signal.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "gnats.h"
#include "globals.h"

static void version		PARAMS((void));

/* Name of this program.  */
char *program_name;

/* Whether or not to automatically create a directory for an unrecognized
   category.  Not used (yet).  */
int flag_autocreate = FALSE;

#ifdef LOG_LEVEL
/* Level to log syslog messages at, if we have that ability.  */
int log_level = LOG_LEVEL;
#endif

/* Program used to check whether a PR was analyzed within the agreed
   response time or not.  */
char *at_pr = NULL;

struct option long_options[] =
{
  {"directory", 1, NULL, 'd'},
  {"file", 1, NULL, 'f'},
  {"version", 0, NULL, 'V'},
#if 0
  {"mailer", 1, NULL, 'm'},
  {"autocreate", 0, NULL, 'A'},
#endif
  {"debug", 0, NULL, 'D'},
  {"help", 0, NULL, 'h'},
  {NULL, 0, NULL, 0}
};

void
unlock_death ()
{
  signal (SIGSEGV, SIG_DFL);
  signal (SIGHUP, SIG_DFL);
  signal (SIGTERM, SIG_DFL);
  signal (SIGINT, SIG_DFL);
  signal (SIGQUIT, SIG_DFL);
#ifdef SIGIOT
  signal (SIGIOT, SIG_DFL);
#endif
#ifdef SIGILL
  signal (SIGILL, SIG_DFL);
#endif
#ifdef SIGABRT
  signal (SIGABRT, SIG_DFL);
#endif

  /* Tell queue-pr to leave the queue file there.  */
  punt (1, "caught a signal", program_name);
}

static char USAGE[] = "\
Usage: file-pr [-DVh] [-d gnats-root] [-f filename] [--directory=gnats-root]\n\
       [--file=filename] [--debug] [--version] [--help]\n";

void
main (argc, argv)
     int argc;
     char **argv;
{
  char *logging = NULL;
  FILE *fp = stdin;
  int option;

  /* Path to a PR if the message being processed is a reply.  */
  char *pr_path;

  program_name = basename (argv[0]);
  configure ();

  /* Note: `A' isn't included here yet.  */
  while ((option = getopt_long (argc, argv, "d:f:VDh",
				long_options, (int *)0)) != EOF)
    {
      switch (option)
	{
	case 'd':
	  gnats_root = optarg;
	  configure ();
	  break;

	case 'f':
	  fp = fopen (optarg, "r");
	  if (fp == (FILE *)NULL)
	    punt (1, "gnats couldn't read the queue file (%s)", optarg);
	  break;

#if 0
	  /* Don't let them do this yet.  */
	case 'A':
	  flag_autocreate = TRUE;
	  break;
#endif

	case 'D':
	  debug_level = LOG_INFO;
	  break;

	case 'V':
	  version ();
	  exit (0);

	case 'h':
	  fprintf (stderr, USAGE);
	  exit (0);

	default:
	  log_msg (LOG_INFO, 0, USAGE);
	  exit (3);
	}
    }

  /* Check the options after processing.  Currently, check logging options.  */
  if (logging != NULL)
    {
      if (strcmp (logging, "SYSLOG") == 0)
#ifdef HAVE_SYSLOG_H
	log_method = SYSLOG;
#else
	log_method = MAIL; /* FIXME */
#endif
      else if (strcmp (logging, "MAIL") == 0)
	log_method = MAIL;
      else if (strcmp (logging, "STDERR") == 0)
	log_method = STDERR;
    }

  switch (log_method)
    {
    case MAIL:
      /* FIXME */
      gnats_logfile = open_mail_file (gnats_admin);
      if (gnats_logfile == (FILE *)NULL)
	punt (1, "can not open mail agent. ");

      fprintf (gnats_logfile, "To: %s\n", gnats_admin);
      fprintf (gnats_logfile, "Subject: gnats log file\n\n");
      break;
#ifdef HAVE_SYSLOG_H
    case SYSLOG:
      /* Old syslog only takes two arguments and doesn't have facilities
	 like LOG_USER.  The new syslog does.  */
#ifdef LOG_USER
      openlog (program_name, LOG_PID, log_level);
#else
      openlog (program_name, LOG_PID);
#endif
      break;
#endif
    case STDERR:
      gnats_logfile = stderr;
      break;
    default:
      break;
    }


  /* initialize the whole thing, before locking. */
  init_gnats ();

  if (!init_responsibles ())
    punt (1, "can not initialize the responsible chain");

  signal (SIGSEGV, unlock_death);
  signal (SIGHUP, unlock_death);
  signal (SIGTERM, unlock_death);
  signal (SIGINT, unlock_death);
  signal (SIGQUIT, unlock_death);
#ifdef SIGIOT
  signal (SIGIOT, unlock_death);
#endif
#ifdef SIGILL
  signal (SIGILL, unlock_death);
#endif
#ifdef SIGABRT
  signal (SIGABRT, unlock_death);
#endif

  /* lock the whole thing. */
  lock_gnats ();

  /* Read the message header in.  */
  read_header (fp);

  /* Check if the message is a reply to an existing PR; if it is, then
     just append this message to the end of that PR.  Otherwise, process
     it normally.  */
  pr_path = check_if_reply (fp);
  if (pr_path)
    {
      /* Before inserting the reply, see if someone's got the PR
	 locked; if they do, then try it at the next run of the queue.  */
      char *buf = (char *) xmalloc (strlen (pr_path) + 6);
      sprintf (buf, "%s.lock", pr_path);
      if (access (buf, R_OK) == 0)
	{
	  unlock_gnats ();
	  exit (1);
	}
      append_report (fp, pr_path);
    }
  else
    gnats (fp);

  /* Clean up.  */
  if (log_method == MAIL)
    close_mail_file (gnats_logfile);
#ifdef HAVE_SYSLOG_H
  else if (log_method == SYSLOG)
    closelog ();
#endif

  /* unlock the whole thing. */
  unlock_gnats ();
  exit (0);
}

static void
version ()
{
  fprintf (stderr, "file-pr version %s.\n", version_string);
}
