/* Copyright 1993 - Matti Aarnio, Turku University, Turku, Finland
   This will be free software, but only when it is finished.

   The way the Zmailer uses DBM entries is by using strings with
   their terminating NULL as keys, and as data..  Thus the length
   is strlen(string)+1, not strlen(string) !
*/

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <fcntl.h>
#include <ndbm.h>

#define PROG "makendbm"

extern int errno;
extern char *sys_errlist[];
extern int sys_nerr;

extern void create_dbase();

void
usage(prog,err,errno)
char *prog, *err;
int errno;
{
  fprintf(stderr,"Usage: %s database.name [infilename|-]\n",prog);
  fprintf(stderr,"  If no infilename is defined, database.name is assumed.\n");
  fprintf(stderr,"  (ndbm appends  .pag, and .dir  into actual db file names..)\n");
  fprintf(stderr," Error now: %s",err);
  if (errno > 0 && errno < sys_nerr)
    fprintf(stderr,", errno=%d (%s)",errno,sys_errlist[errno]);
  fprintf(stderr,"\n");
  exit (1);
}

int
main(argc,argv)
int argc;
char *argv[];
{
  char *dbasename = NULL;
  FILE *infile = NULL;
  DBM *dbmfile;

  if (argc < 2) usage(argv[0],"too few arguments",0);
  if (argc > 3) usage(argv[0],"too many arguments",0);
  dbasename = argv[1];

  if (argc == 3) {
    if (strcmp(argv[2],"-")==0)
      infile = stdin;
    else
      infile = (FILE*)fopen(argv[2],"r");
  } else
    infile = (FILE*)fopen(argv[1],"r");

  if (infile == NULL) usage(argv[0],"bad infile",errno);

  dbmfile = dbm_open(dbasename, O_RDWR|O_CREAT|O_TRUNC, 0644);
  if (dbmfile == NULL)
    usage(argv[0],"Can't open dbase file",errno);


  create_dbase(infile,dbmfile);

  dbm_close(dbmfile);

  return 0;
}

void
create_dbase(infile,dbmfile)
FILE *infile;
DBM *dbmfile;
{
	char linebuf[2048];
	char *s, *t;
	datum dat;
	datum key;

	while (!feof(infile) && !ferror(infile) && !dbm_error(dbmfile)) {
	  *linebuf = 0;
	  fgets(linebuf,sizeof(linebuf)-1,infile);
	  if (*linebuf == 0) break; /* Last! */
	  s = (char *)strchr(linebuf,'\n');
	  if (s) *s = 0; /* Zap \n from the end -- if it exists.. */
	  if (*linebuf == '#') continue; /* Comment! */

	  /* Scan first white-space separated token, point its start with t! */
	  t = linebuf;
	  while (*t == '\t' || *t == ' ') ++t;

	  if (*t == 0) continue; /* Blank line! */

	  s = t;
	  while (*s && *s != '\t' && *s != ' ') ++s;
	  if (*s) {
	    *s = 0; /* Found end of input token, put 0 there, and look if
		       there is some data on this line! */
	    ++s;
	    while (*s && (*s == '\t' || *s == ' ')) ++s;
	    /* Point to begin of data after separating white space! */
	  }


	  key.dptr  = t;
	  key.dsize = strlen(t)+1;
	  dat.dptr  = s;
	  dat.dsize = strlen(s)+1;

	  if (dbm_store(dbmfile, key, dat, DBM_INSERT) != 0) {
	    fprintf(stderr,"Key: `%s' is duplicate!\n",t);
	  }
	}
}
