1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
#ifdef HAS_NDBM_H
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <gdbm-ndbm.h>
#include <fcntl.h>
#include "lutil.h"
#include "xutil.h"
#include "config.h"
#include "ftn.h"
#include "rfcaddr.h"
#ifndef IF_DBM_SUFFIX
#ifdef HAS_BSD_DB
#define IF_DBM_SUFFIX ".db"
#else
#define IF_DBM_SUFFIX ".dir"
#endif
#endif
static DBM *id_db = NULL;
static int opened = 0;
static int fillidb(void);
static int init(void)
{
int needbuild;
struct stat stbuf1;
char buf[128];
struct stat stbuf2;
#ifndef HAS_BSD_DB
FILE *fp;
#endif
if ((msgidbm == NULL) || (newslog == NULL)) return -1;
if (opened == -1) return -1;
if (stat(newslog,&stbuf1) != 0) return -1;
if (opened) return 0;
needbuild=0;
sprintf(buf,"%s" IF_DBM_SUFFIX,msgidbm);
if ((stat(buf,&stbuf2) != 0) ||
(stbuf1.st_mtime > stbuf2.st_mtime))
{
loginf("SEEN-BY database rebuild requested");
needbuild=1;
sprintf(buf,"%s" IF_DBM_SUFFIX,msgidbm);
#ifdef HAS_BSD_DB
unlink(buf);
#else
if ((fp=fopen(buf,"w"))) fclose(fp);
sprintf(buf,"%s.pag",msgidbm);
if ((fp=fopen(buf,"w"))) fclose(fp);
#endif
}
if ((id_db=dbm_open(msgidbm,O_RDWR | O_CREAT,0600)) == NULL)
{
opened = -1;
return -1;
}
opened = 1;
if (needbuild) return fillidb();
return 0;
}
static int fillidb(void)
{
datum key,val;
char buf[128],*line=NULL,se[16],*seen=NULL,*p,*q,*pe,*id;
faddr *fa = NULL;
FILE *fp;
int n=0;
if ((fp=fopen(newslog,"r")) == NULL) return -1;
while (!feof(fp))
{
while (((line == NULL) || (line[strlen(line)-1] != '\n')) &&
(fgets(buf,sizeof(buf)-1,fp)))
line=xstrcat(line,buf);
if (line == NULL) goto nextline;
pe=line+strlen(line);
strtok(line," \t\n"); /* Month */
strtok(NULL," \t\n"); /* Date */
strtok(NULL," \t\n"); /* Time */
if ((p=strtok(NULL," \t\n")) != NULL)
{
if (*p == '+') /* INN style log */
{
p=strtok(NULL," \t\n"); /* skip source host */
}
else /* maybe cnews style log? */
{
if (((p=strtok(NULL," \t\n")) == NULL) ||
(*p != '+')) goto nextline;
}
}
debug(8,"good log entry for %s",p);
if ((id=strtok(NULL," \t\n")) == NULL) goto nextline;
/* some witchkraft with char *q,*pe is needed because */
/* otherwise strtok called from within parsefaddr will */
/* interfere with strtok in the while cycle */
q=NULL;
while ((p=strtok(q," \t\n")))
{
if ((q=p+strlen(p)+1) >= pe) q=NULL;
debug(8,"try parse %s",p);
if ((fa=parsefaddr(p)))
{
sprintf(se,"%s ",
ascfnode(fa,0x06));
seen=xstrcat(seen,se);
debug(8,"new seen: \"%s\"",seen);
tidy_faddr(fa);
}
else debug(8,"unparsable: %s",addrerrstr(addrerror));
}
if (seen)
{
key.dptr=id;
key.dsize=strlen(id);
val.dptr=seen;
val.dsize=strlen(seen);
*(seen+strlen(seen)-1) = '\0';
if (dbm_store(id_db,key,val,0) < 0)
logerr("$cannot store: \"%s\" \"%s\"",id,seen);
else debug(8,"seen-by for \"%s\" is \"%s\"",id,seen);
n++;
}
nextline:
if (seen) free(seen);
seen=NULL;
if (line) free(line);
line=NULL;
}
loginf("SEEN-BY database now contains %d records",n);
return 0;
}
char *idlookup(msgid)
char *msgid;
{
datum key,val;
if (init()) return "";
debug(8,"idlookup \"%s\"",S(msgid));
key.dptr=msgid;
key.dsize=strlen(msgid);
val=dbm_fetch(id_db,key);
if (val.dptr) return val.dptr;
else return "";
}
#endif
void close_id_db(void)
{
if (opened != 1) return;
#ifndef DONT_HAVE_CLOSEDBM
#ifdef HAS_NDBM_H
dbm_close(id_db);
#endif
#endif
opened=0;
}
|