/*
 * W-NEWS       A simple NEWS processing package for MINIX.
 *		This program converts the history file from dbm
 *		format to ascii and vice versa.
 *
 * Usage:       mkhist {-a|-d} [fname]
 *
 * Version:     @(#)mkhist.c	4.50	28-Feb-1995
 *
 * Authors:     Miquel van Smoorenburg, <miquels@drinkel.ow.org>
 *
 *		Copyright 1988-1993 MicroWalt Corporation
 *		Copyright 1994,1995 Cistron Software C.V.
 *		This program 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 of the License, or (at your option) any later version.
 */
#include "wnews.h"

char *Version = "@(#) mkhist 4.43 (28-Feb-1994) MvS";
char *program = "mkhist";

#if HAVE_DBM

#if HAVE_SDBM
#  include <sdbm.h>
#else
#  include <ndbm.h>
#endif

char histfile[128];

/* Read ascii file and create dbm file. */
void make_dbm(fname)
char *fname;
{
  FILE *fp;
  char line[256];
  char *date, *name;
  struct tm tm;
  time_t t;
  int artno;
  char *p;
  int gotit = 0;

  /* See which file name to use. */
  if (strcmp(fname, "-") == 0) {
	fname = histfile;
	fp = stdin;
  } else if ((fp = fopen(fname, "r")) == NULL) {
	fprintf(stderr, "mkhist: ");
	perror(fname);
	exit(1);
  }

  hist_init(fname);

  /* Read history file line by line. */
  while(fgets(line, 256, fp)) {
	gotit = 1;
	/* Strip '\n' */
	if ((p = strchr(line, '\n')) != NULL) *p = 0;

	/* Separate msgid, date and name. */
	if ((date = strchr(line, '\t')) == NULL) continue;
	*date++ = 0;
	if ((name = strchr(date, '\t')) == NULL) continue;
	*name++ = 0;

	/* Separate newsgroup and article. */
	if ((p = strchr(name, '/')) == NULL) continue;
	*p++ = 0;
	artno = atoi(p);

	/* Now turn date into time_t */
	tm.tm_sec = 0;
	tm.tm_isdst = 0; /* Don't know. */
	if (sscanf(date, "%d/%d/%d %d:%d", &tm.tm_mon, &tm.tm_mday,
		&tm.tm_year, &tm.tm_hour, &tm.tm_min) != 5) continue;
	if (tm.tm_year > 1900) tm.tm_year -= 1900;
	if (tm.tm_year < 70) tm.tm_year += 100;
	tm.tm_mon--;
	t = wmktime(&tm);

	/* And add the article to the database. */
	hist_add(line, name, artno, t, 1);
  }

  /* History file could be empty. */
  if (gotit == 0) {
	(void) time(&t);
	hist_add("<dummy@not.there>", "junk", 1, t, 1);
  }

  /* Done. */
  if (fp != stdin) fclose(fp);
  hist_close();
}

/* Read dbm file and create ascii file. */
void make_ascii(fname)
char *fname;
{
  datum key, data;
  DBM *db;
  FILE *fp;

  if (strcmp(fname, "-") == 0) {
	fname = histfile;
	fp = stdout;
  } else if ((fp = fopen(fname, "w")) == NULL) {
	fprintf(stderr, "mkhist: ");
	perror(fname);
	exit(1);
  }

  if ((db = dbm_open(fname, O_RDONLY, 0)) == NULL) {
	fprintf(stderr, "mkhist: dbm file ");
	perror(fname);
	exit(1);
  }

  for(key = dbm_firstkey(db); key.dptr != NULL; key = dbm_nextkey(db)) {
	data = dbm_fetch(db, key);
	if (data.dptr == NULL) {
		fprintf(stderr, "mkhist: dbm file %s inconsistent\n", fname);
		continue;
	}
	hist_print(key.dptr, data.dptr, data.dsize, fp);
  }

  /* Done. */
  if (fp != stdout) fclose(fp);
  dbm_close(db);
}

void usage()
{
  fprintf(stderr, "Usage: mkhist {-d|-a} [filename]\n");
  exit(1);
}

int main(argc, argv)
int argc;
char **argv;
{
  int c;
  char *fname;
  int do_ascii = 0, do_dbm = 0;

  while((c = getopt(argc, argv, "ad")) != EOF)
	switch(c) {
		case 'a':
			do_ascii++;
			do_dbm = 0;
			break;
		case 'd':
			do_dbm++;
			do_ascii = 0;
			break;
		default:
			exit(1);
	}

  sprintf(histfile, "%s/%s", VARDIR, HISTFILE);

  if (optind == argc)
	fname = histfile;
  else
	fname = argv[optind];

  if (!do_ascii & !do_dbm) usage();

  if (do_ascii) make_ascii(fname);
  if (do_dbm) make_dbm(fname);

  return(0);
}

#else /* !HAVE_DBM */

int main()
{
  fprintf(stderr, "mkhist: this version of wnews does not use dbm files\n");
  return(1);
}
#endif /* HAVE_DBM */
