/*
 * W-NEWS       A simple NEWS processing package.
 *              wntrim trims your history file to keep size low.
 *              Default removes articles of two weeks old (same as expire).
 *
 * Version:     @(#)wntrim.c	4.40	11/24/93
 *
 * Author:      Edvard Tuinder, <etuinder@delirium.NL.MugNet.ORG>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              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 <sys/stat.h>
#include "wnews.h"
#if HAVE_SDBM
#   include <sdbm.h>
#else
#   include <ndbm.h>
#endif


char debug = 0;
char *program;


void main (argc, argv)
int argc;
char *argv[];
{
  DBM *old_db, *new_db;
  FILE *hist, *nhist;
  char buf[256];
  char first[256];		/* for normal history file truncation */
  char temp[256];		/* mktemp() */
  time_t tijd, db_tijd;
  datum data, key;
  int deleted = 0;
  char found = 0;

  program = *argv;
  if ((chdir (LIBDIR)) == ERROR) {
	perror("chdir");
	exit(ERROR);
  }
  (void) time(&tijd);

  if (argc == 1) tijd -= (14 * 60 * 60 * 24);
    else {
	if (!isdigit(*argv[1])) {
		fprintf(stderr, "Invalid argument `%s'\n", argv[1]);
		fprintf(stderr, "Usage: %s [days]\n", program);
		fputs("       where days is a numeric argument\n", stderr);
		exit(ERROR);
	}
	tijd -= atoi(argv[1]) * 60 * 60 * 24;
  }

  old_db = dbm_open (HISTFILE, O_RDONLY, 0);
  if (old_db == (DBM *) NULL) {
	fprintf(stderr, "Can't open %s\n", HISTFILE);
	perror("dbm_open");
	exit(ERROR);
  }

  strcpy (temp, "history.XXXXXX");
  mktemp (temp);

  if ((new_db = dbm_open(temp, (O_CREAT|O_RDWR|O_NDELAY|O_TRUNC),
					(S_IRUSR|S_IWUSR))) == (DBM *) NULL) {
	fprintf(stderr, "Can't open temporary file %s\n", temp);
	perror("dbm_open");
	dbm_close(old_db);
	exit(-1);
  }

  for (key = dbm_firstkey(old_db);
		key.dptr != (char *) NULL; key = dbm_nextkey (old_db)) {
	bzero(buf, 250);
	data = dbm_fetch(old_db, key);
	bcopy(data.dptr, buf, 9);
	db_tijd = atol(buf);
	if (db_tijd > tijd) {
		if (dbm_store(new_db, key, data, DBM_INSERT)) {
			perror("dbm_store");
			dbm_close(old_db);
			dbm_close(new_db);
			exit(ERROR);
		}
	} else deleted++;
  }

  (void) dbm_close(old_db);
  (void) dbm_close(new_db);

  if (deleted) {
	logmsg(LOGINFO | LOGSYS, "removed %d entries from history dbase\n",
	      							deleted);

	strncpy(first, data.dptr, data.dsize);

	/*
	 * I should do all kinds of sprintf's for MS-LOSS.
	 * NO-WAY, they don't have DBM !! .... ET
	 */
	unlink("history.dir");
	unlink("history.pag");
	sprintf(buf, "%s.dir", temp);
	rename(buf, "history.dir");
	sprintf(buf, "%s.pag", temp);
	rename(buf, "history.pag");

	/*
	 * Now we need to adjust the `normal' history file. This
	 * takes some reading !  (and writing).
	 */
	if ((hist = fopen(HISTFILE, "r")) == (FILE *)NULL) {
		fputs("Couldn't open history file !\n", stderr);
		perror("fopen");
		exit(ERROR);
	}

	if ((nhist = fopen(temp, "w")) == (FILE *)NULL) {
		fputs("Couldn't open temporary history file !\n", stderr);
		perror("fopen");
		exit(ERROR);
	}

	bzero(buf, 256);

	while((fgets(buf, 256, hist)) != (char *) NULL && !found) {
		if (! strncmp(buf, first, strlen(first))) found = 1;
	}

	fputs(buf, nhist);	/* This one is valid too */
	while((fgets(buf, 256, hist)) != (char *) NULL)
		fputs(buf, nhist);

	fclose(hist);
	fclose(nhist);
	unlink(HISTFILE);
	rename(temp, HISTFILE);
  } else {
	/* No entries were deleted ! Cleanup temporary files */
	sprintf(buf, "%s.dir", temp);
	rename(buf, "history.dir");
	sprintf(buf, "%s.pag", temp);
	rename(buf, "history.pag");
  }
}
