/*
* This part deals with the history database and had
* been originally written by
*
* Kai Uwe Rommel <rommel@ars.muc.de>
*
* Bug reports related to THIS heavily modified version
* should be sent to
*
* harald@os2point.ping.de
* harald@haport.sesam.com
* Fido: 2:2448/434
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <dbgheap.h>
#include <lprintf.h>
#include <dbm.h>
#include <datetime.h>
#include <active.h>
#include <history.h>
/************************************************************************/
/* */
/* gethistart */
/* */
/* Finds an article entry in the history file by it's id and */
/* returns the path name of this article if found. */
/* */
/* Parameter Description */
/* ------------ ------------------------------------------------------- */
/* historyfile Points to a string that specifies the name of the */
/* history data base. Usually this will be "history". */
/* */
/* msg_id Points to a string that specifies the id of the */
/* message to search for. */
/* */
/* artpath Points to a buffer that receives the path to the */
/* message if found. This buffer must be preinitialized */
/* with the name of the newsgroup's home directory. */
/* If the caller doesn't need the path then this pointer */
/* may be NULL. */
/* ------------ ------------------------------------------------------- */
/* Return value True if found, false otherwise. */
/* */
/************************************************************************/
int gethistart(const char *historyfile, char *msg_id, char *artpath)
{
register char *cp;
register char *cp1;
char *line;
DBM *db;
datum key, val;
char *histpag;
int isvirgin;
/*
* If no history file exists we assume that we were
* started in a virgin environment. We check this first
* to avoid an error message while opening the database.
*/
histpag = malloc(strlen(historyfile) + 5);
strcat(strcpy(histpag, historyfile), ".pag");
isvirgin = access(histpag, 0);
free(histpag);
if(isvirgin)
return(0);
/*
* Fetch the entry with the given message id
*/
if((db = dbm_open(historyfile, O_RDONLY, 0)) != NULL) {
key.dptr = msg_id;
key.dsize = strlen(msg_id) + 1;
val = dbm_fetch(db, key);
if (val.dptr == NULL) {
dbm_close(db);
return(0); /* article not found */
}
if(artpath == NULL) {
dbm_close(db);
return(1); /* article found, caller doesn't need path */
}
/*
* We need to copy the history line because dbm_close
* will free the read buffer of the database.
*/
line = strdup(val.dptr);
dbm_close(db);
}
else {
lprintf("Failed to open %s", historyfile);
return(0);
}
/*
* We assume this structure of our history line
* <msg_id> <time> <size> <grp:num>[,<grp:num>]
* Field separators may be space or tab. The last
* field <grp:num> may be repeated and separated
* by commas.
*/
cp = line;
while(*cp && *cp != ' ' && *cp != '\t')
cp++;
while(*cp == ' ' || *cp == '\t')
cp++;
while(*cp && *cp != ' ' && *cp != '\t')
cp++;
while(*cp == ' ' || *cp == '\t')
cp++;
if(*cp) {
/*
* Now cp points to the first <grp:num> item.
* Append the path of this message to artpath.
*/
cp1 = strchr(artpath, '\0');
*cp1++ = '\\';
while(*cp && *cp != ' ' && *cp != '\t' && *cp != ',') {
if(*cp == '.' || *cp == ':')
*cp1++ = '\\';
else
*cp1++ = *cp;
cp++;
}
*cp1 = '\0';
free(line);
return(1); /* article found, path supplied */
}
free(line);
return (0); /* article found, but could not supply path */
}
/************************************************************************/
/* */
/* addhistart */
/* */
/* */
/************************************************************************/
int addhistart(const char *historyfile, char *messageID,
char **ngarray, long art_size)
{
int groups_found = 0;
char *hist_record = malloc(HISTRECSIZE);
char snum[12];
long himsg;
datum key, val;
void *hfp;
int i;
/*
* Create history record
*/
sprintf(hist_record, "%ld %ld ", local_to_gmt(time(NULL)), art_size);
for(i = 0; ngarray[i] != NULL; i++) {
if(find_active(NULL, ngarray[i], NULL, &himsg)) {
if (groups_found)
strcat(hist_record, ",");
strcat(hist_record, ngarray[i]);
strcat(hist_record, ":");
strcat(hist_record, ltoa(himsg, snum, 10));
groups_found++;
}
}
if(groups_found) {
/*
* Add history record to database
*/
if((hfp = dbm_open(historyfile, O_RDWR | O_CREAT, 0666)) != NULL) {
key.dptr = messageID;
key.dsize = strlen(key.dptr) + 1;
val.dptr = hist_record;
val.dsize = strlen(val.dptr) + 1;
if (dbm_store(hfp, key, val, DBM_REPLACE))
lprintf("Failed to store history record");
dbm_close(hfp);
}
else
lprintf("Failed to open %s", historyfile);
}
free(hist_record);
return(groups_found != 0);
}
/************************************************************************/
/* */
/* delhistart */
/* */
/* Finds an article entry in the history file by it's id and deletes */
/* this entry if found. */
/* */
/* Parameter Description */
/* ------------ ------------------------------------------------------- */
/* historyfile Points to a string that specifies the name of the */
/* history data base. Usually this will be "history". */
/* */
/* msg_id Points to a string that specifies the id of the */
/* message to search for. */
/* */
/* artlist Points to a buffer that receives a list of messages */
/* in the format <grp:num>[,<grp:num>]. If no entry was */
/* found in historyfile, then this string will be empty. */
/* ------------ ------------------------------------------------------- */
/* Return value Pointer to artlist. */
/* */
/************************************************************************/
char *delhistart(const char *historyfile, char *msg_id, char *artlist)
{
datum key, val;
void *hfp;
char *line;
char *cp;
*artlist = '\0';
/*
* Search history file
*/
if((hfp = dbm_open(historyfile, O_RDWR | O_CREAT, 0666)) == NULL) {
lprintf("Failed to open %s", historyfile);
return(artlist);
}
key.dptr = msg_id;
key.dsize = strlen(key.dptr) + 1;
val = dbm_fetch(hfp, key);
if(val.dptr == NULL) {
dbm_close(hfp);
lprintf("Can't find %s to cancel", msg_id);
return(artlist);
}
line = strdup(val.dptr);
/*
* Delete entry
*/
key.dptr = msg_id; /* To check: Is this really needed? */
key.dsize = strlen(key.dptr) + 1;
if(dbm_cancel(hfp, key))
lprintf("Failed to remove article(s) from history");
dbm_close(hfp);
/*
* Copy result into buffer
*/
cp = line;
while(*cp && *cp != ' ' && *cp != '\t')
cp++;
while(*cp == ' ' || *cp == '\t')
cp++;
while(*cp && *cp != ' ' && *cp != '\t')
cp++;
while(*cp == ' ' || *cp == '\t')
cp++;
if(cp)
strcpy(artlist, cp);
free(line);
return(artlist);
}