untermud/DOC/
untermud/DOC/U/
untermud/DOC/U/U-examples/
untermud/DOC/internals/
untermud/DOC/wizard/
untermud/MISC/
untermud/MISC/dbchk/
untermud/RWHO/
untermud/RWHO/rwhod/
/*
    Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/

/* configure all options BEFORE including system stuff. */
#include    "config.h"
#include    "mud.h"
#ifdef WIN32
#include    "getopt.h"
#endif

extern char *optarg;
extern int optind;
extern int opterr;

#ifdef  DB_DIRHASH
extern int dhdb_init ();
extern int dhdb_travstart ();
extern int dhdb_traverse ();
extern int dhdb_travend ();
extern int dhdb_put ();
extern int dhdb_close ();
#endif

#ifdef  DB_DBMFILE
extern int dddb_init ();
extern int dddb_travstart ();
extern int dddb_traverse ();
extern int dddb_travend ();
extern int dddb_put ();
extern int dddb_close ();
#endif

#ifdef  DB_GDBMFILE
extern int dgdb_init ();
extern int dgdb_travstart ();
extern int dgdb_traverse ();
extern int dgdb_travend ();
extern int dgdb_put ();
extern int dgdb_close ();
#endif

int usage ();
int setexpr (char *s);
int checkexpr (char *nam, Obj * op);

int main (int ac, char **av)
{
  int (*initin) () = 0;
  int (*objput) () = 0;
  int (*closer) () = 0;
  char obuf[MAXOID];
  Obj *op;

  FILE *in = stdin;
  FILE *out = stdout;
  char typ = '\0';
  char *fdir = (char *) 0;
  char *cexp = (char *) 0;
  int vflg = 0;
  int lflg = 0;
  int xflg = 0;
  int cnt = 0;
  int bflg = 0;
  int avsiz = 0;
  int losiz = 1000000;
  int hisiz = 0;
  int sflg = 0;
#ifdef COMPRESS_OIF
  int cin = 0;                  /* input compressed */
  int cout = 0;                 /* output compressed */
#endif
  int x;

#ifdef COMPRESS_OIF
  comp_init ();
#endif

  while ((x = getopt (ac, av, "C:b:c:i:f:hsdgvlo:x")) != EOF) {
    switch (x) {
#ifdef COMPRESS_OIF
    case 'C':
      if (*optarg == 'i')
        cin = 1;
      if (*optarg == 'o')
        cout = 1;
      break;
#endif

    case 'i':
      in = fopen (optarg, "rb");
      if (in == (FILE *) 0) {
        perror (optarg);
        exit (1);
      }
      break;


    case 'o':
      out = fopen (optarg, "wb");
      if (out == (FILE *) 0) {
        perror (optarg);
        exit (1);
      }
      break;


    case 'b':
      bflg = atoi (optarg);
      if (bflg <= 0) {
        fprintf (stderr, "illegal size %s\n", optarg);
        exit (1);
      }
      break;


#ifdef  DB_DIRHASH
    case 'h':
      initin = dhdb_init;
      objput = dhdb_put;
      closer = dhdb_close;
      typ = 'h';
      break;
#endif


#ifdef  DB_DBMFILE
    case 'd':
      initin = dddb_init;
      objput = dddb_put;
      closer = dddb_close;
      typ = 'd';
      break;
#endif


#ifdef  DB_GDBMFILE
    case 'g':
      initin = dgdb_init;
      objput = dgdb_put;
      closer = dgdb_close;
      typ = 'g';
      break;
#endif


    case 'c':
      cexp = optarg;
      break;


    case 'f':
      fdir = optarg;
      break;


    case 'v':
      vflg++;
      break;


    case 's':
      sflg++;
      break;


    case 'x':
      xflg++;
      break;


    case 'l':
      lflg++;
      break;


    case '?':
    default:
      exit (usage ());
    }
  }

  if (!xflg && initin == 0) {
    fprintf (stderr, "what kind of database is this?\n");
    exit (1);
  }

  if (fdir) {
#ifdef  DB_DIRHASH
    if (typ == 'h') {
      dhdb_sethpath (fdir);
      if (bflg)
        dhdb_sethsiz (bflg);
    }
#endif
#ifdef  DB_DBMFILE
    if (typ == 'd') {
      dddb_setfile (fdir);
      if (bflg)
        dddb_setbsiz (bflg);
    }
#endif
#ifdef  DB_GDBMFILE
    if (typ == 'g')
      dgdb_setfile (fdir);
#endif
  }


  if (cexp != (char *) 0 && setexpr (cexp))
    exit (1);


  if (!xflg && (*initin) ()) {
    fprintf (stderr, "cannot initialize db layer\n");
    exit (1);
  }

  obuf[0] = '\0';
  while (1) {
    tmp_sync ();

#ifdef COMPRESS_OIF
    if (cin)
      comp_on (1);
    else
      comp_on (0);
#endif
    op = oiffromFILE (in, obuf);
    if (op == (Obj *) 0)
      break;

    if (obuf[0] == '\0') {
      fprintf (stderr, "unnamed object in input\n");
      objfree (op);
      obuf[0] = '\0';
      continue;
    }


    if (cexp != (char *) 0 && checkexpr (obuf, op) == 0) {
      if (vflg)
        fprintf (stderr, "<- %s\n", obuf);
      objfree (op);
      obuf[0] = '\0';
      continue;
    }


    if (sflg) {
      int nsiz;

      nsiz = oif_objsiz (op, obuf);
      avsiz = ((avsiz * cnt) + nsiz) / (cnt + 1);
      if (nsiz > hisiz)
        hisiz = nsiz;
      else if (nsiz < losiz)
        losiz = nsiz;
    }

    /* list only */
    if (lflg) {
      printf ("%s\n", obuf);
      objfree (op);
      obuf[0] = '\0';
      cnt++;
      continue;
    }
#ifdef COMPRESS_OIF
    if (cout)
      comp_on (1);
    else
      comp_on (0);
#endif

    /* copy to stdout */
    if (xflg) {
      oiftoFILE (op, out, obuf);
      objfree (op);
      obuf[0] = '\0';
      cnt++;
      continue;
    }

    if ((*objput) (op, obuf)) {
      fprintf (stderr, "cannot store object %s\n", obuf);
      objfree (op);
      obuf[0] = '\0';
      continue;
    } else {
      cnt++;
      if (vflg)
        fprintf (stderr, "<+ %s\n", obuf);
      objfree (op);
      obuf[0] = '\0';
    }
  }


  if (!xflg && (*closer) ()) {
    fprintf (stderr, "cannot close db layer\n");
    exit (1);
  }

  if (xflg)
    fprintf (stderr, "selected %d objects\n", cnt);
  else
    fprintf (stderr, "stored %d objects\n", cnt);
  if (sflg)
    fprintf (stderr, "object size: %d min, %d average, %d max\n",
      losiz, avsiz, hisiz);
  exit (0);
}



int usage ()
{
  fprintf (stderr, "usage: loaddb -d|h|g|x [-f datapath] [-i infile]\n");
  fprintf (stderr, "[-v (verbose)] [-l (list only)] [-o outfile]\n");
  fprintf (stderr, "[-s (object size statistics)]\n");
  fprintf (stderr, "[-c selection_expression]\n");

#ifdef  COMPRESS_OIF
  fprintf (stderr, "[-C i (input is compressed)] [-C o (compress output)]\n");
#endif
  return (1);
}