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

📄 misc.c

📁 早期freebsd实现
💻 C
字号:
/*  $Revision: 1.14 $****  Miscellaneous support routines.*/#include "nnrpd.h"#include "dbz.h"#if	defined(DO_NEED_TIME)#include <time.h>#endif	/* defined(DO_NEED_TIME) */#include <sys/time.h>#define ASCtoNUM(c)		((c) - '0')#define CHARStoINT(c1, c2)	(ASCtoNUM((c1)) * 10 + ASCtoNUM((c2)))#define DaysInYear(y)		((y % 4 ? 365 : 366))/***  Parse a string into a NULL-terminated array of words; return number**  of words.  If argvp isn't NULL, it and what it points to will be**  DISPOSE'd.*/intArgify(line, argvp)    char		*line;    char		***argvp;{    register char	**argv;    register char	*p;    register int	i;    if (*argvp != NULL) {	DISPOSE(*argvp[0]);	DISPOSE(*argvp);    }    /*  Copy the line, which we will split up. */    while (ISWHITE(*line))	line++;    i = strlen(line);    p = NEW(char, i + 1);    (void)strcpy(p, line);    /* Allocate worst-case amount of space. */    for (*argvp = argv = NEW(char*, i + 2); *p; ) {	/* Mark start of this word, find its end. */	for (*argv++ = p; *p && !ISWHITE(*p); )	    p++;	if (*p == '\0')	    break;	/* Nip off word, skip whitespace. */	for (*p++ = '\0'; ISWHITE(*p); )	    p++;    }    *argv = NULL;    return argv - *argvp;}/***  Take a vector which Argify made and glue it back together with**  spaces between each element.  Returns a pointer to dynamic space.*/char *Glom(av)    char		**av;{    register char	**v;    register char	*p;    register int	i;    char		*save;    /* Get space. */    for (i = 0, v = av; *v; v++)	i += strlen(*v) + 1;    for (save = p = NEW(char, i + 1), v = av; *v; v++) {	if (p > save)	    *p++ = ' ';	p += strlen(strcpy(p, *v));    }    return save;}/***  Match a list of newsgroup specifiers against a list of newsgroups.**  func is called to see if there is a match.*/BOOLPERMmatch(match, Pats, list)    register BOOL	match;    char		**Pats;    char		**list;{    register int	i;    register char	*p;    if (Pats[0] == NULL)	return TRUE;    for ( ; *list; list++)	for (i = 0; (p = Pats[i]) != NULL; i++) {	    if (p[0] == '!') {		if (wildmat(*list, ++p))		    match = FALSE;	    }	    else if (wildmat(*list, p))		match = TRUE;	}    return match;}/***  Check to see if user is allowed to see this article by matching**  Newsgroups line.*/BOOLPERMartok(qp)    register QIOSTATE	*qp;{    static char		**grplist;    register char	*p;    register char	*q;    BOOL		found;    if (!PERMspecified)	return PERMdefault;    for (found = FALSE; ; ) {	p = QIOread(qp);	if (p == NULL) {	    if (QIOtoolong(qp))		continue;	    break;	}	if (*p == '\n')	    /* End of header */	    break;	if (*p != 'N' && *p != 'n')	    continue;	if ((q = strchr(p, ':')) == NULL)	    continue;	*q = '\0';	if (caseEQ(p, "newsgroups")) {	    found = NGgetlist(&grplist, q + 2);	    break;	}    }    (void)QIOrewind(qp);    if (!found)	/* No newgroups or null entry. */	return 1;    return PERMmatch(PERMdefault, PERMlist, grplist);}/***  Parse a date like yymmddhhmmss into a long.  Return -1 on error.*/longNNTPtoGMT(av1, av2)    char		*av1;    char		*av2;{    /* Note that this is origin-one! */    static int		DaysInMonth[12] = {	0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30    };    register char	*p;    int			year;    int			month;    int			day;    int			hour;    int			mins;    int			secs;    register int	i;    long		seconds;    char		buff[6 + 6 + 1];    if (strlen(av1) != 6 || strlen(av2) != 6)	return -1;    (void)sprintf(buff, "%s%s", av1, av2);    for (p = buff; *p; p++)	if (!CTYPE(isdigit, *p))	    return -1;    year  = CHARStoINT(buff[ 0], buff[ 1]);    month = CHARStoINT(buff[ 2], buff[ 3]);    day   = CHARStoINT(buff[ 4], buff[ 5]);    hour  = CHARStoINT(buff[ 6], buff[ 7]);    mins  = CHARStoINT(buff[ 8], buff[ 9]);    secs  = CHARStoINT(buff[10], buff[11]);    if (month < 1 || month > 12     || day < 1 || day > 31     || mins < 0 || mins > 59     || secs < 0 || secs > 59)	return -1;    if (hour == 24) {	hour = 0;	day++;    }    else if (hour < 0 || hour > 23)	return -1;    for (seconds = 0, year += 1900, i = 1970; i < year; i++)	seconds += DaysInYear(i);    if (DaysInYear(year) == 366 && month > 2)	seconds++;    while (--month > 0)	seconds += DaysInMonth[month];    seconds += day - 1;    seconds = 24 * seconds + hour;    seconds = 60 * seconds + mins;    seconds = 60 * seconds + secs;    return seconds;}/***  Convert local time (seconds since epoch) to GMT.*/longLOCALtoGMT(t)    long	t;{    TIMEINFO	Now;    (void)GetTimeInfo(&Now);    t += Now.tzone * 60;    return t;}/***  Return the path name of an article if it is in the history file.**  Return a pointer to static data.*/char *HISgetent(msg_id, fulldata)    char		*msg_id;    BOOL		fulldata;{    static BOOL		setup;#if	NNRP_DBZINCORE_DELAY > 0    static int		count = NNRP_DBZINCORE_DELAY;#endif	/* NNRP_DBZINCORE_DELAY > 0 */    static FILE		*hfp;    static char		path[BIG_BUFFER];    register char	*p;    register char	*q;    register int	i;    char		*save;    char		buff[BIG_BUFFER];    OFFSET_T		l;    datum		key;    datum		value;    struct stat		Sb;#if	NNRP_DBZINCORE_DELAY > 0    if (count && --count == 0) {	if (setup) {	    (void)dbmclose();	    setup = FALSE;	}	(void)dbzincore(1);    }#endif	/* NNRP_DBZINCORE_DELAY > 0 */    if (!setup) {	if (dbminit(HISTORY) < 0) {	    syslog(L_ERROR, "%s cant dbminit %s %m", ClientHost, HISTORY);	    return NULL;	}	setup = TRUE;    }    /* Set the key value, fetch the entry. */    for (p = key.dptr = msg_id; *p; p++)	if (*p == HIS_FIELDSEP || *p == '\n')	    *p = HIS_BADCHAR;    key.dsize = p - key.dptr + 1;    value = dbzfetch(key);    if (value.dptr == NULL)	return NULL;    for (q = (char *)&l, p = value.dptr, i = sizeof l; --i >= 0; )	*q++ = *p++;    /* Open history file if we need to. */    if (hfp == NULL) {	if ((hfp = fopen(HISTORY, "r")) == NULL) {	    syslog(L_ERROR, "%s cant fopen %s %m", ClientHost, HISTORY);	    return NULL;	}	CloseOnExec((int)fileno(hfp), TRUE);    }    /* Seek and read. */    if (fseek(hfp, l, SEEK_SET) == -1) {	syslog(L_ERROR, "%s cant fseek to %ld %m", ClientHost, l);	return NULL;    }    if (fgets(buff, sizeof buff, hfp) == NULL) {	syslog(L_ERROR, "%s cant fgets from %ld %m", ClientHost, l);	return NULL;    }    if ((p = strchr(buff, '\n')) != NULL)	*p = '\0';    /* Skip first two fields. */    if ((p = strchr(buff, '\t')) == NULL) {	syslog(L_ERROR, "%s bad_history at %ld for %s", ClientHost, l, msg_id);	return NULL;    }    if ((p = strchr(p + 1, '\t')) == NULL)	/* Article has expired. */	return NULL;    save = p + 1;    /* Want the full data? */    if (fulldata) {	(void)strcpy(path, save);	for (p = path; *p; p++)	    if (*p == '.')		*p = '/';	return path;    }    /* Want something we can open; loop over all entries. */    for ( ; ; save = q + 1) {	if ((q = strchr(save, ' ')) != NULL)	    *q = '\0';	for (p = save; *p; p++)	    if (*p == '.')		*p = '/';	(void)sprintf(path, "%s/%s", _PATH_SPOOL, save);	if (stat(path, &Sb) >= 0)	    return path;	if (q == NULL)	    break;    }    return NULL;}/***  Parse a newsgroups line, return TRUE if there were any.*/BOOLNGgetlist(argvp, list)    char		***argvp;    char		*list;{    register char	*p;    for (p = list; *p; p++)	if (*p == ',')	    *p = ' ';    return Argify(list, argvp) != 0;}/***  Take an NNTP distribution list <d1,d2,...> and turn it into an array.*/BOOLParseDistlist(argvp, list)    char		***argvp;    char		*list;{    static char		**argv;    register char	*p;    if (list[0] != '<' || (p = strchr(&list[1], '>')) == NULL)	return FALSE;    *p = '\0';    for (p = list + 1; *p; p++)	if (*p == ',')	    *p = ' ';    (void)Argify(list + 1, &argv);    *argvp = argv;    return TRUE;}/***  Read a line of input, with timeout.*/READTYPEREADline(start, size, timeout)    char		*start;    int			size;    int			timeout;{    static int		count;    static char		buffer[BUFSIZ];    static char		*bp;    register char	*p;    register char	*end;    struct timeval	t;    FDSET		rmask;    int			i;    char		c;    for (p = start, end = &start[size - 1]; ; ) {	if (count == 0) {	    /* Fill the buffer. */    Again:	    FD_ZERO(&rmask);	    FD_SET(STDIN, &rmask);	    t.tv_sec = timeout;	    t.tv_usec = 0;	    i = select(STDIN + 1, &rmask, (FDSET *)NULL, (FDSET *)NULL, &t);	    if (i < 0) {		if (errno == EINTR)		    goto Again;		syslog(L_ERROR, "%s cant select %m", ClientHost);		return RTtimeout;	    }	    if (i == 0 || !FD_ISSET(STDIN, &rmask))		return RTtimeout;	    count = read(STDIN, buffer, sizeof buffer);	    if (count < 0) {		syslog(L_ERROR, "%s cant read %m", ClientHost);		return RTtimeout;	    }	    if (count == 0)		return RTeof;	    bp = buffer;	}	/* Process next character. */	count--;	c = *bp++;	if (c == '\n')	    break;	if (p < end)	    *p++ = c;    }    /* If last two characters are \r\n, kill the \r as well as the \n. */    if (p > start && p < end && p[-1] == '\r')	p--;    *p = '\0';    return p == end ? RTlong : RTok;}

⌨️ 快捷键说明

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