⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 his.c

📁 早期freebsd实现
💻 C
字号:
/*  $Revision: 1.21 $****  History file routines.*/#include "innd.h"#include "dbz.h"STATIC char	HIShistpath[] = _PATH_HISTORY;STATIC FILE	*HISwritefp;STATIC int	HISreadfd;STATIC int	HISdirty;STATIC int	HISincore = INND_DBZINCORE;/***  Set up the history files.*/voidHISsetup(){    if (HISwritefp == NULL) {	/* Open the history file for appending formatted I/O. */	if ((HISwritefp = fopen(HIShistpath, "a")) == NULL) {	    syslog(L_FATAL, "%s cant fopen %s %m", LogName, HIShistpath);	    exit(1);	}	CloseOnExec((int)fileno(HISwritefp), TRUE);	/* Open the history file for reading. */	if ((HISreadfd = open(HIShistpath, O_RDONLY)) < 0) {	    syslog(L_FATAL, "%s cant open %s %m", LogName, HIShistpath);	    exit(1);	}	CloseOnExec(HISreadfd, TRUE);	/* Open the DBZ file. */	(void)dbzincore(HISincore);	(void)dbzwritethrough(1);	if (dbminit(HIShistpath) < 0) {	    syslog(L_FATAL, "%s cant dbminit %s %m", HIShistpath, LogName);	    exit(1);	}    }}/***  Synchronize the in-core history file (flush it).*/voidHISsync(){    if (HISdirty) {	if (dbzsync()) {	    syslog(L_FATAL, "%s cant dbzsync %m", LogName);	    exit(1);	}	HISdirty = 0;    }}/***  Close the history files.*/voidHISclose(){    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(L_ERROR, "%s cant dbmclose %m", LogName);	if (fclose(HISwritefp) == EOF)	    syslog(L_ERROR, "%s cant fclose history %m", LogName);	HISwritefp = NULL;	if (close(HISreadfd) < 0)	    syslog(L_ERROR, "%s cant close history %m", LogName);	HISreadfd = -1;    }}/***  File in the DBZ datum for a Message-ID, making sure not to copy any**  illegal characters.*/STATIC voidHISsetkey(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 = '\0';    keyp->dsize = dest - MessageID.Data + 1;}/***  Get the list of files under which a Message-ID is stored.*/char *HISfilesfor(MessageID)    char		*MessageID;{    static BUFFER	Files;    char		*dest;    datum		key;    datum		val;    long		offset;    register char	*p;    register int	i;    /* Get the seek value into the history file. */    HISsetkey(MessageID, &key);    val = dbzfetch(key);    if (val.dptr == NULL || val.dsize != sizeof offset)	return NULL;    /* Get space. */    if (Files.Data == NULL) {	Files.Size = BUFSIZ;	Files.Data = NEW(char, Files.Size);    }    /* 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)	return NULL;    /* Read the text until \n or EOF. */    for (Files.Used = 0; ; ) {	i = read(HISreadfd,		&Files.Data[Files.Used], Files.Size - Files.Used - 1);	if (i <= 0)	    return NULL;	Files.Used += i;	Files.Data[Files.Used] = '\0';	if ((p = strchr(Files.Data, '\n')) != NULL) {	    *p = '\0';	    break;	}	/* If we have half our buffer left, get more space. */	if (Files.Size - Files.Used < Files.Size / 2) {	    Files.Size += BUFSIZ;	    RENEW(Files.Data, char, Files.Size);	}    }    /* Move past the first two fields -- Message-ID and date info. */    if ((p = strchr(Files.Data, HIS_FIELDSEP)) == NULL)	return NULL;    if ((p = strchr(p + 1, HIS_FIELDSEP)) == NULL)	return NULL;    /* Translate newsgroup separators to slashes, return the fieldstart. */    for (dest = ++p; *p; p++)	if (*p == '.')	    *p = '/';    return dest;}/***  Have we already seen an article?*/BOOLHIShavearticle(MessageID)    char	*MessageID;{    datum	key;    datum	val;    HISsetkey(MessageID, &key);    val = dbzfetch(key);    return val.dptr != NULL;}/***  Turn a history filename entry from slashes to dots.  It's a pity**  we have to do this.*/STATIC voidHISslashify(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 = '/';}/***  Write a history entry.*/BOOLHISwrite(Data, paths)    ARTDATA		*Data;    char		*paths;{    static char		NOPATHS[] = "";    long		offset;    datum		key;    datum		val;    int			i;    HISsetkey(Data->MessageID, &key);    if (paths != NULL && paths[0] != '\0')	HISslashify(paths);    else	paths = NOPATHS;    offset = ftell(HISwritefp);    if (Data->Expires > 0)	i = fprintf(HISwritefp, "%s%c%ld%c%ld%c%ld%c%s\n",		key.dptr, HIS_FIELDSEP,		(long)Data->Arrived, HIS_SUBFIELDSEP, (long)Data->Expires,		    HIS_SUBFIELDSEP, (long)Data->Posted, HIS_FIELDSEP,		paths);    else	i = fprintf(HISwritefp, "%s%c%ld%c%s%c%ld%c%s\n",		key.dptr, HIS_FIELDSEP,		(long)Data->Arrived, HIS_SUBFIELDSEP, HIS_NOEXP,		    HIS_SUBFIELDSEP, (long)Data->Posted, HIS_FIELDSEP,		paths);    if (i == EOF || fflush(HISwritefp) == EOF) {	/* The history line is now an orphan... */	IOError("history");	syslog(L_ERROR, "%s cant write history %m", LogName);	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(L_ERROR, "%s cant dbzstore %m", LogName);	return FALSE;    }    if (++HISdirty >= ICD_SYNC_COUNT)	HISsync();    return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -