his.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:10k
- /* $Revision: 1.1 $
- **
- ** History file routines.
- */
- #include "innbbsconf.h"
- #include "bbslib.h"
- #include "his.h"
- #define STATIC static
- /*STATIC char HIShistpath[] = _PATH_HISTORY;*/
- STATIC FILE *HISwritefp;
- STATIC int HISreadfd;
- STATIC int HISdirty;
- STATIC int HISincore = XINDEX_DBZINCORE;
- STATIC char *LogName = "xindexchan";
- #ifndef EXPIREDAYS
- #define EXPIREDAYS 4
- #endif
- #ifndef DEFAULT_HIST_SIZE
- #define DEFAULT_HIST_SIZE 100000
- #endif
- hisincore(flag)
- int flag;
- {
- HISincore = flag;
- }
- makedbz(histpath, entry)
- char *histpath;
- long entry;
- {
- long size;
- size = dbzsize(entry);
- dbzfresh(histpath, size, 't', 0, 1);
- dbmclose();
- }
- void HISsetup();
- void HISclose();
- void
- mkhistory(srchist)
- char *srchist;
- {
- FILE *hismaint;
- time_t lasthist, now;
- char maintbuff[256];
- char *ptr;
- hismaint = fopen(srchist, "r");
- if (hismaint == NULL) {
- return;
- } {
- char newhistpath[1024];
- char newhistdirpath[1024];
- char newhistpagpath[1024];
- sprintf(newhistpath, "%s.n", srchist);
- sprintf(newhistdirpath, "%s.n.dir", srchist);
- sprintf(newhistpagpath, "%s.n.pag", srchist);
- if (!isfile(newhistdirpath) || !isfile(newhistpagpath)) {
- makedbz(newhistpath, DEFAULT_HIST_SIZE);
- }
- myHISsetup(newhistpath);
- while (fgets(maintbuff, sizeof(maintbuff), hismaint) != NULL) {
- datum key;
- ptr = (char *) strchr(maintbuff, 't');
- if (ptr != NULL) {
- *ptr = ' ';
- ptr++;
- }
- key.dptr = maintbuff;
- key.dsize = strlen(maintbuff);
- myHISwrite(&key, ptr);
- }
- (void) HISclose();
- /*
- * rename(newhistpath, srchist);
- * rename(newhistdirpath, fileglue("%s.dir", srchist));
- * rename(newhistpagpath, fileglue("%s.pag", srchist));
- */
- }
- fclose(hismaint);
- }
- time_t
- gethisinfo()
- {
- FILE *hismaint;
- time_t lasthist, now;
- char maintbuff[4096];
- char *ptr;
- hismaint = fopen(HISTORY, "r");
- if (hismaint == NULL) {
- return 0;
- }
- fgets(maintbuff, sizeof(maintbuff), hismaint);
- fclose(hismaint);
- ptr = (char *) strchr(maintbuff, 't');
- if (ptr != NULL) {
- ptr++;
- lasthist = atol(ptr);
- return lasthist;
- }
- return 0;
- }
- void
- HISmaint()
- {
- FILE *hismaint;
- time_t lasthist, now;
- char maintbuff[4096];
- char *ptr;
- if (!isfile(HISTORY)) {
- makedbz(HISTORY, DEFAULT_HIST_SIZE);
- }
- hismaint = fopen(HISTORY, "r");
- if (hismaint == NULL) {
- return;
- }
- fgets(maintbuff, sizeof(maintbuff), hismaint);
- ptr = (char *) strchr(maintbuff, 't');
- if (ptr != NULL) {
- ptr++;
- lasthist = atol(ptr);
- time(&now);
- if (lasthist + 86400 * Expiredays * 2 < now) {
- char newhistpath[1024];
- char newhistdirpath[1024];
- char newhistpagpath[1024];
- (void) HISclose();
- sprintf(newhistpath, "%s.n", HISTORY);
- sprintf(newhistdirpath, "%s.n.dir", HISTORY);
- sprintf(newhistpagpath, "%s.n.pag", HISTORY);
- if (!isfile(newhistdirpath)) {
- makedbz(newhistpath, DEFAULT_HIST_SIZE);
- }
- myHISsetup(newhistpath);
- while (fgets(maintbuff, sizeof(maintbuff), hismaint) != NULL) {
- datum key;
- ptr = (char *) strchr(maintbuff, 't');
- if (ptr != NULL) {
- *ptr = ' ';
- ptr++;
- lasthist = atol(ptr);
- } else {
- continue;
- }
- if (lasthist + 99600 * Expiredays < now)
- continue;
- key.dptr = maintbuff;
- key.dsize = strlen(maintbuff);
- myHISwrite(&key, ptr);
- }
- (void) HISclose();
- rename(HISTORY, (char *) fileglue("%s.o", HISTORY));
- rename(newhistpath, HISTORY);
- rename(newhistdirpath, (char *) fileglue("%s.dir", HISTORY));
- rename(newhistpagpath, (char *) fileglue("%s.pag", HISTORY));
- (void) HISsetup();
- }
- }
- fclose(hismaint);
- }
- /*
- ** Set up the history files.
- */
- void
- HISsetup()
- {
- myHISsetup(HISTORY);
- }
- int
- myHISsetup(histpath)
- char *histpath;
- {
- if (HISwritefp == NULL) {
- /* Open the history file for appending formatted I/O. */
- if ((HISwritefp = fopen(histpath, "a")) == NULL) {
- syslog(LOG_CRIT, "%s cant fopen %s %m", LogName, histpath);
- exit(1);
- }
- CloseOnExec((int) fileno(HISwritefp), TRUE);
- /* Open the history file for reading. */
- if ((HISreadfd = open(histpath, O_RDONLY)) < 0) {
- syslog(LOG_CRIT, "%s cant open %s %m", LogName, histpath);
- exit(1);
- }
- CloseOnExec(HISreadfd, TRUE);
- /* Open the DBZ file. */
- /* (void)dbzincore(HISincore); */
- (void) dbzincore(HISincore);
- (void) dbzwritethrough(1);
- if (dbminit(histpath) < 0) {
- syslog(LOG_CRIT, "%s cant dbminit %s %m", histpath, LogName);
- exit(1);
- }
- }
- }
- /*
- ** Synchronize the in-core history file (flush it).
- */
- void
- HISsync()
- {
- if (HISdirty) {
- if (dbzsync()) {
- syslog(LOG_CRIT, "%s cant dbzsync %m", LogName);
- exit(1);
- }
- HISdirty = 0;
- }
- }
- /*
- ** Close the history files.
- */
- void
- HISclose()
- {
- if (HISwritefp != NULL) {
- /*
- * Since dbmclose calls dbzsync we could replace this line
- * with "HISdirty = 0;". Oh well, it keeps the abstraction
- * clean.
- */
- HISsync();
- if (dbmclose() < 0)
- syslog(LOG_ERR, "%s cant dbmclose %m", LogName);
- if (fclose(HISwritefp) == EOF)
- syslog(LOG_ERR, "%s cant fclose history %m", LogName);
- HISwritefp = NULL;
- if (close(HISreadfd) < 0)
- syslog(LOG_ERR, "%s cant close history %m", LogName);
- HISreadfd = -1;
- }
- }
- #ifdef HISset
- /*
- ** File in the DBZ datum for a Message-ID, making sure not to copy any
- ** illegal characters.
- */
- STATIC void
- HISsetkey(p, keyp)
- register char *p;
- datum *keyp;
- {
- static BUFFER MessageID;
- register char *dest;
- register int i;
- /* Get space to hold the ID. */
- i = strlen(p);
- if (MessageID.Data == NULL) {
- MessageID.Data = NEW(char, i + 1);
- MessageID.Size = i;
- } else if (MessageID.Size < i) {
- RENEW(MessageID.Data, char, i + 1);
- MessageID.Size = i;
- }
- for (keyp->dptr = dest = MessageID.Data; *p; p++)
- if (*p == HIS_FIELDSEP || *p == 'n')
- *dest++ = HIS_BADCHAR;
- else
- *dest++ = *p;
- *dest = ' ';
- keyp->dsize = dest - MessageID.Data + 1;
- }
- #endif
- /*
- ** Get the list of files under which a Message-ID is stored.
- */
- char *
- HISfilesfor(key, output)
- datum *key;
- datum *output;
- {
- char *dest;
- datum val;
- off_t offset;
- register char *p;
- register int i;
- int Used;
- /* Get the seek value into the history file. */
- val = dbzfetch(*key);
- if (val.dptr == NULL || val.dsize != sizeof offset) {
- /* printf("fail here val.dptr %dn",val.dptr); */
- return NULL;
- }
- /* Get space. */
- if (output->dptr == NULL) {
- printf("fail here output->dptr nulln");
- return NULL;
- }
- /* Copy the value to an aligned spot. */
- for (p = val.dptr, dest = (char *) &offset, i = sizeof offset; --i >= 0;)
- *dest++ = *p++;
- if (lseek(HISreadfd, offset, SEEK_SET) == -1) {
- printf("fail here lseek %dn", offset);
- return NULL;
- }
- /* Read the text until n or EOF. */
- for (output->dsize = 0, Used = 0;;) {
- i = read(HISreadfd,
- &output->dptr[output->dsize], LEN - 1);
- if (i <= 0) {
- printf("fail here i %dn", i);
- return NULL;
- }
- Used += i;
- output->dptr[Used] = ' ';
- if ((p = (char *) strchr(output->dptr, 'n')) != NULL) {
- *p = ' ';
- break;
- }
- }
- /* Move past the first two fields -- Message-ID and date info. */
- if ((p = (char *) strchr(output->dptr, HIS_FIELDSEP)) == NULL) {
- printf("fail here no HIS_FILEn");
- return NULL;
- }
- return p + 1;
- /*
- * if ((p = (char*)strchr(p + 1, HIS_FIELDSEP)) == NULL) return NULL;
- */
- /* Translate newsgroup separators to slashes, return the fieldstart. */
- }
- /*
- ** Have we already seen an article?
- */
- #ifdef HISh
- BOOL
- HIShavearticle(MessageID)
- char *MessageID;
- {
- datum key;
- datum val;
- HISsetkey(MessageID, &key);
- val = dbzfetch(key);
- return val.dptr != NULL;
- }
- #endif
- /*
- ** Turn a history filename entry from slashes to dots. It's a pity
- ** we have to do this.
- */
- STATIC void
- HISslashify(p)
- register char *p;
- {
- register char *last;
- for (last = NULL; *p; p++) {
- if (*p == '/') {
- *p = '.';
- last = p;
- } else if (*p == ' ' && last != NULL)
- *last = '/';
- }
- if (last)
- *last = '/';
- }
- IOError(error)
- char *error;
- {
- fprintf(stderr, "%sn", error);
- }
- /*BOOL*/
- myHISwrite(key, remain)
- datum *key;
- char *remain;
- {
- static char NOPATHS[] = "";
- long offset;
- datum val;
- int i;
- val = dbzfetch(*key);
- if (val.dptr != NULL) {
- return FALSE;
- }
- flock(fileno(HISwritefp), LOCK_EX);
- offset = ftell(HISwritefp);
- i = fprintf(HISwritefp, "%s%c%s",
- key->dptr, HIS_FIELDSEP, remain);
- if (i == EOF || fflush(HISwritefp) == EOF) {
- /* The history line is now an orphan... */
- IOError("history");
- syslog(LOG_ERR, "%s cant write history %m", LogName);
- flock(fileno(HISwritefp), LOCK_UN);
- return FALSE;
- }
- /* Set up the database values and write them. */
- val.dptr = (char *) &offset;
- val.dsize = sizeof offset;
- if (dbzstore(*key, val) < 0) {
- IOError("my history database");
- syslog(LOG_ERR, "%s cant dbzstore %m", LogName);
- flock(fileno(HISwritefp), LOCK_UN);
- return FALSE;
- }
- if (++HISdirty >= ICD_SYNC_COUNT)
- HISsync();
- flock(fileno(HISwritefp), LOCK_UN);
- return TRUE;
- }
- /*
- ** Write a history entry.
- */
- BOOL
- HISwrite(key, date, paths)
- datum *key;
- char *paths;
- long date;
- {
- static char NOPATHS[] = "";
- long offset;
- datum val;
- int i;
- flock(fileno(HISwritefp), LOCK_EX);
- offset = ftell(HISwritefp);
- i = fprintf(HISwritefp, "%s%c%ld%c%sn",
- key->dptr, HIS_FIELDSEP, (long) date, HIS_FIELDSEP,
- paths);
- if (i == EOF || fflush(HISwritefp) == EOF) {
- /* The history line is now an orphan... */
- IOError("history");
- syslog(LOG_ERR, "%s cant write history %m", LogName);
- flock(fileno(HISwritefp), LOCK_UN);
- return FALSE;
- }
- /* Set up the database values and write them. */
- val.dptr = (char *) &offset;
- val.dsize = sizeof offset;
- if (dbzstore(*key, val) < 0) {
- IOError("history database");
- syslog(LOG_ERR, "%s cant dbzstore %m", LogName);
- flock(fileno(HISwritefp), LOCK_UN);
- return FALSE;
- }
- if (++HISdirty >= ICD_SYNC_COUNT)
- HISsync();
- flock(fileno(HISwritefp), LOCK_UN);
- return TRUE;
- }