/*                                                                           */
/*  * Copyright (c) 1991 by the University of Washington                     */
/*  *                                                                        */
/*  * For copying and distribution information, please see the file          */
/*  * <copyright.h>.                                                         */

/*                                                                           */
/*  * Archie client using the Prospero protocol.                             */
/*  *                                                                        */
/*  * Suggestions and improvements to Brendan Kehoe (brendan@cygnus.com).    */

#include "pmachine.h"
#include "getopt.h"
#include "pfs.h"
#include "rdgram.h"
#include "archie.h"

/* Whether we should produce single-line listings suitable for frobbing by   */
/*    other programs, or produce nice clean human output (default).          */
int listflag = 0;

/* How to sort the data; 1 means by date, 0 is by inverse hostname.          */
int sortflag = 0;

/* Used by CUTCP to see if they specified the host with `-h' or if           */
/*    the config.tel file should be consulted.                               */
int hostset = 0;

/* When doing searches, should we make some comments to pacify the user?     */
int verbose = 0;

/* Maximum number of hits for this query; pushing this high is very          */
/*    anti-social.                                                           */
int max_hits = MAX_HITS;

/* The offset for the Prospero query.                                        */
int offset = 0;

/* Display the Alex filename?                                                */
int alex = 0;

/* The default host to query for searches.                                   */
char *host = ARCHIE_HOST;

FILE *archie_out;

/* The name this program was run with.                                       */
char *program_name;

extern int pfs_debug;
extern int rdgram_priority;

void usage ();
extern char *getenv ();

int
main (argc, argv)
     int argc;
     char **argv;
{
  Query query = EXACT;
  int optc, tmp;
  /* If true, display the release.                                           */
  int exitflag = 0;
  /* The file to print the results to.  Defaults to stdout.                  */
  char *outfile = (char *)NULL;
  char *p;
  static char *archies[] = { ARCHIES };

#ifdef SOCKS
  LIBPREFIX2(init)(argv[0]);
#endif

  program_name = argv[0];

  /* Default debugging level.                                                */
  pfs_debug = 0;

  if ((p = getenv ("ARCHIE_HOST")) != (char *) NULL)
    host = p;

  while ((optc = getopt (argc, argv, "D:LN::O:ceh:alm:o:rstvV")) != EOF)
    {
      switch (optc)
	{
	case 'D':
	  pfs_debug = atoi (optarg);
	  break;

	case 'L':
	  printf ("Known archie servers:\n");
	  for (tmp = 0; tmp < NARCHIES; tmp++)
	    printf ("\t%s\n", archies[tmp]);
	  printf (" * %s is the default Archie server.\n", ARCHIE_HOST);
	  printf (" * For the most up-to-date list, write to an Archie server and give it\n   the command `servers'.\n");
	  exitflag = 1;
	  break;
	case 'N':
	  if (optarg)
	    {
	      rdgram_priority = atoi (optarg);
	      if (rdgram_priority > RDGRAM_MAX_SPRI)
		rdgram_priority = RDGRAM_MAX_PRI;
	      else if (rdgram_priority < RDGRAM_MIN_PRI)
		rdgram_priority = RDGRAM_MIN_PRI;
	    }
	  else
	    rdgram_priority = RDGRAM_MAX_PRI;
	  break;

	case 'c': /* Substring (case-sensitive).  */
	  query = SUBSTRING_CASE;
	  break;

	case 'e': /* Exact match.  */
	  query = EXACT;
	  break;

	case 'h': /* Archie host.  */
	  host = optarg;
	  break;

	case 'a': /* List matches as Alex filenames.  */
	  alex = 1;
	  break;

	case 'l': /* List one match per line.  */
	  listflag = 1;
	  break;

	case 'm': /* Maximum number of hits for the query.  */
	  max_hits = atoi (optarg);
	  if (max_hits < 1)
	    {
	      fprintf (stderr,
		       "%s: option `-m' requires a max hits value >= 1\n",
		       program_name);
	      exit (ERROR_EXIT);
	    }
	  break;

	case 'o': /* output file */
	  if (outfile)
	    {
	      fprintf (stderr, "%s: multiple output files specified\n",
		       program_name);
	      exit (ERROR_EXIT);
	    }
	  outfile = optarg;
	  break;

	case 'O': /* Specify the offset.  */
	  offset = atoi (optarg);
	  break;

	case 'r': /* Regexp search.  */
	  query = REGEXP;
	  break;

	case 's': /* Substring (case insensitive).  */
	  query = SUBSTRING;
	  break;

	case 't': /* Sort inverted by date.  */
	  sortflag = 1;
	  break;

	case 'v': /* Display version.  */
	  fprintf (stderr,
		   "Client version %s based upon Prospero version %s%s\n",
		   CLIENT_VERSION,
#ifdef DEBUG
		   PFS_RELEASE, " with debugging.");
#else
		   PFS_RELEASE, ".");
#endif
	  exitflag = 1;
	  break;

	case 'V': /* Verbose when search is happening.  */
	  verbose = 1;
	  break;

	default:
	  usage ();
	}
    }

  if (exitflag)
    exit (0);
  else if (optind == argc)
    usage ();
  else if (alex && listflag)
    {
      fprintf (stderr, "%s: only one of `-a' or `-l' may be used\n",
	       program_name);
      exit (ERROR_EXIT);
    }

  if (outfile)
    {
      archie_out = fopen (outfile, "w+");
      if (archie_out == (FILE *) NULL)
	{
	  fprintf (stderr, "%s: cannot open %s\n", program_name, outfile);
	  exit (ERROR_EXIT);
	}
    }
  else
    archie_out = stdout;

  for (; optind < argc; ++optind)
    procquery (host, argv[optind], max_hits, offset, query);

  if (outfile)
    fclose (archie_out);

  return (0);
}

#define HFLAG	"]"

void
usage ()
{
  fprintf (stderr, "Usage: %s [-acelorstvLV] [-m hits%s [-N level] string\n", program_name, HFLAG);
  fprintf (stderr, "          -a : list matches as Alex filenames\n");
  fprintf (stderr, "          -c : case sensitive substring search\n");
  fprintf (stderr, "          -e : exact string match (default)\n");
  fprintf (stderr, "          -r : regular expression search\n");
  fprintf (stderr, "          -s : case insensitive substring search\n");
  fprintf (stderr, "          -l : list one match per line\n");
  fprintf (stderr, "          -t : sort inverted by date\n");
  fprintf (stderr, "     -m hits : specifies maximum number of hits to return (default %d)\n", max_hits);
  fprintf (stderr, " -o filename : specifies file to store results in\n");
  fprintf (stderr, "     -h host : specifies server host\n");
  fprintf (stderr, "          -L : list known servers and current default\n");
  fprintf (stderr, "    -N level : specifies query niceness level (0-35765)\n");

  exit (ERROR_EXIT);
}

