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

📄 article.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    register char	*q;    struct stat		Sb;    for ( ; ; ) {	if ((p = QIOread(qp)) == NULL) {	    if (QIOtoolong(qp))		continue;	    break;	}	if (*p == '\0')	    /* End of headers. */	    break;	if (ISWHITE(*p) || (q = strchr(p, ':')) == NULL)	    /* Continuation or bogus (shouldn't happen) line; ignore. */	    continue;	*q = '\0';	if (caseEQ(header, p))	    return *++q ? q + 1 : NULL;    }    if (IsLines && fstat(QIOfileno(qp), &Sb) >= 0) {	/* Lines estimation taken from Tor Lillqvist <tml@tik.vtt.fi>'s	 * posting <TML.92Jul10031233@hemuli.tik.vtt.fi> in	 * news.sysadmin. */	(void)sprintf(buff, "%d",	    (int)(6.4e-8 * Sb.st_size * Sb.st_size + 0.023 * Sb.st_size - 12));	return buff;    }    return NULL;}STATIC BOOLCMDgetrange(ac, av, rp)    int			ac;    char		*av[];    register ARTRANGE	*rp;{    register char	*p;    if (GRPcount == 0) {	Reply("%s\r\n", ARTnotingroup);	return FALSE;    }    if (ac == 1) {	/* No argument, do only current article. */	if (ARTindex < 0 || ARTindex >= ARTsize) {	    Reply("%s\r\n", ARTnocurrart);	    return FALSE;	}	rp->High = rp->Low = ARTnumbers[ARTindex];	return TRUE;    }    /* Got just a single number? */    if ((p = strchr(av[1], '-')) == NULL) {	rp->Low = rp->High = atol(av[1]);	return TRUE;    }    /* Parse range. */    *p++ = '\0';    rp->Low = atol(av[1]);    if (ARTsize) {	if (*p == '\0' || (rp->High = atol(p)) < rp->Low)	    /* "XHDR 234-0 header" gives everything to the end. */	    rp->High = ARTnumbers[ARTsize - 1];	else if (rp->High > ARTnumbers[ARTsize - 1])	    rp->High = ARTnumbers[ARTsize - 1];	if (rp->Low < ARTnumbers[0])	    rp->Low = ARTnumbers[0];    }    else	/* No articles; make sure loops don't run. */	rp->High = rp->Low ? rp->Low - 1 : 0;    return TRUE;}/***  Return a field from the overview line or NULL on error.  Return a copy**  since we might be re-using the line later.*/STATIC char *OVERGetHeader(p, field)    register char	*p;    int			field;{    static char		*buff;    static int		buffsize;    register int	i;    ARTOVERFIELD	*fp;    char		*next;    /* Skip leading headers. */    for (fp = &ARTfields[field - 1]; --field >= 0 && *p; p++)	if ((p = strchr(p, '\t')) == NULL)	    return NULL;    if (*p == '\0')	return NULL;    if (fp->HasHeader)	p += fp->Length + 2;    /* Figure out length; get space. */    if ((next = strchr(p, '\t')) != NULL)	i = next - p;    else	i = strlen(p);    if (buffsize == 0) {	buffsize = i;	buff = NEW(char, buffsize + 1);    }    else if (buffsize < i) {	buffsize = i;	RENEW(buff, char, buffsize + 1);    }    (void)strncpy(buff, p, i);    buff[i] = '\0';    return buff;}/***  Open an OVERVIEW file.*/STATIC BOOLOVERopen(){    char	name[SPOOLNAMEBUFF];    /* Already open? */    if (OVERqp != NULL)	/* Don't rewind -- we are probably going forward via repeated	 * NNTP commands. */	return TRUE;    /* Failed here before? */    if (OVERopens++)	return FALSE;    OVERline = NULL;    OVERarticle = 0;    (void)sprintf(name, "%s/%s/%s", _PATH_OVERVIEWDIR, GRPlast, _PATH_OVERVIEW);    OVERqp = QIOopen(name, QIO_BUFFER);    return OVERqp != NULL;}/***  Close the OVERVIEW file.*/voidOVERclose(){    if (OVERqp != NULL) {	QIOclose(OVERqp);	OVERqp = NULL;	OVERopens = 0;    }}/***  Return the overview data for an article or NULL on failure.**  Assumes that what we return is never modified.*/STATIC char *OVERfind(artnum)    ARTNUM	artnum;{    if (OVERqp == NULL)	return NULL;    if (OVERarticle > artnum) {	(void)QIOrewind(OVERqp);	OVERarticle = 0;	OVERline = NULL;    }    for ( ; OVERarticle < artnum; OVERarticle = atol(OVERline))	if ((OVERline = QIOread(OVERqp)) == NULL) {	    if (QIOtoolong(OVERqp))		continue;	    /* Don't close file; we may rewind. */	    return NULL;	}    return OVERarticle == artnum ? OVERline : NULL;}/***  Read an article and create an overview line without the trailing**  newline.  Returns pointer to static space or NULL on error.*/STATIC char *OVERgen(name)    char			*name;{    static ARTOVERFIELD		*Headers;    static char			*buff;    static int			buffsize;    register ARTOVERFIELD	*fp;    register ARTOVERFIELD	*hp;    register QIOSTATE		*qp;    register char		*colon;    register char		*line;    register char		*p;    register int		i;    register int		size;    register int		ov_size;    register long		lines;    struct stat			Sb;    long			t;    char			value[10];    /* Open article. */    if ((qp = QIOopen(name, QIO_BUFFER)) == NULL)	return NULL;    if ((p = strrchr(name, '/')) != NULL)	name = p + 1;    /* Set up place to store headers. */    if (Headers == NULL) {	Headers = NEW(ARTOVERFIELD, ARTfieldsize);	for (hp = Headers, i = ARTfieldsize; --i >= 0; hp++)	    hp->Length = 0;    }    for (hp = Headers, i = ARTfieldsize; --i >= 0; hp++)	hp->HasHeader = FALSE;    for ( ; ; ) {	/* Read next line. */	if ((line = QIOread(qp)) == NULL) {	    if (QIOtoolong(qp))		continue;	    /* Error or EOF (in headers!?); shouldn't happen. */	    QIOclose(qp);	    return NULL;	}	/* End of headers? */	if (*line == '\0')	    break;	/* See if we want this header. */	fp = ARTfields;	for (hp = Headers, i = ARTfieldsize; --i >= 0; hp++, fp++) {	    colon = &line[fp->Length];	    if (*colon != ':')		continue;	    *colon = '\0';	    if (!caseEQ(line, fp->Header)) {		*colon = ':';		continue;	    }	    *colon = ':';	    if (fp->HasHeader)		p = line;	    else		/* Skip colon and whitespace, store value. */		for (p = colon; *++p && ISWHITE(*p); )		    continue;	    size = strlen(p);	    if (hp->Length == 0) {		hp->Length = size;		hp->Header = NEW(char, hp->Length + 1);	    }	    else if (hp->Length < size) {		hp->Length = size;		RENEW(hp->Header, char, hp->Length + 1);	    }	    (void)strcpy(hp->Header, p);	    for (p = hp->Header; *p; p++)		if (*p == '\t' || *p == '\n')		    *p = ' ';	    hp->HasHeader = TRUE;	}    }    /* Read body of article, just to get lines. */    for (lines = 0; ; lines++)	if ((p = QIOread(qp)) == NULL) {	    if (QIOtoolong(qp))		continue;	    if (QIOerror(qp)) {		QIOclose(qp);		return NULL;	    }	    break;	}    /* Calculate total size, fix hardwired headers. */    ov_size = strlen(name) + ARTfieldsize + 2;    for (hp = Headers, fp = ARTfields, i = ARTfieldsize; --i >= 0; hp++, fp++) {	if (caseEQ(fp->Header, "Bytes") || caseEQ(fp->Header, "Lines")) {	    if (fp->Header[0] == 'B' || fp->Header[0] == 'b')		t = fstat(QIOfileno(qp), &Sb) >= 0 ? (long)Sb.st_size : 0L;	    else		t = lines;	    (void)sprintf(value, "%ld", t);	    size = strlen(value);	    if (hp->Length == 0) {		 hp->Length = size;		hp->Header = NEW(char, hp->Length + 1);	    }	    else if (hp->Length < size) {		hp->Length = size;		RENEW(hp->Header, char, hp->Length + 1);	    }	    (void)strcpy(hp->Header, value);	    hp->HasHeader = TRUE;	}	if (hp->HasHeader)	    ov_size += strlen(hp->Header);    }    /* Get space. */    if (buffsize == 0) {	buffsize = ov_size;	buff = NEW(char, buffsize + 1);    }    else if (buffsize < ov_size) {	buffsize = ov_size;	RENEW(buff, char, buffsize + 1);    }    /* Glue all the fields together. */    p = buff + strlen(strcpy(buff, name));    for (hp = Headers, i = ARTfieldsize; --i >= 0; hp++) {	*p++ = '\t';	if (hp->HasHeader)	    p += strlen(strcpy(p, hp->Header));    }    *p = '\0';    QIOclose(qp);    return buff;}/***  XHDR, a common extension.  Retrieve specified header from a**  Message-ID or article range.*/FUNCTYPECMDxhdr(ac, av)    int			ac;    char		*av[];{    register QIOSTATE	*qp;    register ARTNUM	i;    register char	*p;    int			Overview;    BOOL		IsLines;    ARTRANGE		range;    char		buff[SPOOLNAMEBUFF];    ARTNUM		art;    if (!PERMcanread) {	Reply("%s\r\n", NOACCESS);	return;    }    IsLines = caseEQ(av[1], "lines");    /* Message-ID specified? */    if (ac == 3 && av[2][0] == '<') {	if ((qp = ARTopenbyid(av[2], &art)) == NULL) {	    Reply("%d No such article\r\n", NNTP_DONTHAVEIT_VAL);	    return;	}	Reply("%d %ld %s header of article %s.\r\n",	   NNTP_HEAD_FOLLOWS_VAL, art, av[1], av[2]);	p = GetHeader(qp, av[1], IsLines);	Printf("%s %s\r\n", av[2], p ? p : "(none)");	QIOclose(qp);	Printf(".\r\n");	return;    }    /* Range specified. */    if (!CMDgetrange(ac - 1, av + 1, &range))	return;    /* Is this a header in our overview? */    for (Overview = 0, i = 0; i < ARTfieldsize; i++)	if (caseEQ(ARTfields[i].Header, av[1])) {	    if (OVERopen())		Overview = i + 1;	    break;	}    Reply("%d %s fields follow\r\n", NNTP_HEAD_FOLLOWS_VAL, av[1]);    for (i = range.Low; i <= range.High; i++) {	if (ARTfind(i) < 0)	    continue;	/* Get it from the overview? */	if (Overview && (p = OVERfind(i)) != NULL) {	    p = OVERGetHeader(p, Overview);	    Printf("%d %s\r\n", i, p && *p ? p : "(none)");	    continue;	}	(void)sprintf(buff, "%ld", i);	if ((qp = QIOopen(buff, QIO_BUFFER)) == NULL)	    continue;	p = GetHeader(qp, av[1], IsLines);	Printf("%d %s\r\n", i, p ? p : "(none)");	QIOclose(qp);    }    Printf(".\r\n");}/***  XOVER another extension.  Dump parts of the overview database.*/FUNCTYPECMDxover(ac, av)    int			ac;    char		*av[];{    register char	*p;    register ARTNUM	i;    register BOOL	Opened;    ARTRANGE		range;    char		buff[SPOOLNAMEBUFF];    if (!PERMcanread) {	Printf("%s\r\n", NOACCESS);	return;    }    /* Trying to read. */    if (GRPcount == 0) {	Reply("%s\r\n", ARTnotingroup);	return;    }    /* Parse range. */    if (!CMDgetrange(ac, av, &range))	return;    Reply("%d data follows\r\n", NNTP_OVERVIEW_FOLLOWS_VAL);    for (Opened = OVERopen(), i = range.Low; i <= range.High; i++) {	if (ARTfind(i) < 0)	    continue;	if (Opened && (p = OVERfind(i)) != NULL) {	    Printf("%s\r\n", p);	    continue;	}	(void)sprintf(buff, "%ld", i);	if ((p = OVERgen(buff)) != NULL)	    Printf("%s\r\n", p);    }    Printf(".\r\n");}/***  XPAT, an uncommon extension.  Print only headers that match the pattern.*//* ARGSUSED */FUNCTYPECMDxpat(ac, av)    int			ac;    char		*av[];{    register char	*p;    register QIOSTATE	*qp;    register ARTNUM	i;    ARTRANGE		range;    char		*header;    char		*pattern;    char		*text;    int			Overview;    char		buff[SPOOLNAMEBUFF];    ARTNUM		art;    if (!PERMcanread) {	Printf("%s\r\n", NOACCESS);	return;    }    header = av[1];    /* Message-ID specified? */    if (av[2][0] == '<') {	p = av[2];	qp = ARTopenbyid(p, &art);	if (qp == NULL) {	    Printf("%d No such article.\r\n", NNTP_DONTHAVEIT_VAL);	    return;	}	Printf("%d %s matches follow.\r\n", NNTP_HEAD_FOLLOWS_VAL, header);	pattern = Glom(&av[3]);	if ((text = GetHeader(qp, header, FALSE)) != NULL	 && wildmat(text, pattern))	    Printf("%s %s\r\n", p, text);	QIOclose(qp);	Printf(".\r\n");	DISPOSE(pattern);	return;    }    /* Range specified. */    if (!CMDgetrange(ac - 1, av + 1, &range))	return;    /* In overview? */    for (Overview = 0, i = 0; i < ARTfieldsize; i++)	if (caseEQ(ARTfields[i].Header, av[1])) {	    if (OVERopen())		Overview = i + 1;	    break;	}    Printf("%d %s matches follow.\r\n", NNTP_HEAD_FOLLOWS_VAL, header);    for (pattern = Glom(&av[3]), i = range.Low; i < range.High; i++) {	if (ARTfind(i) < 0)	    continue;	/* Get it from the Overview? */	if (Overview	 && (p = OVERfind(i)) != NULL	 && (p = OVERGetHeader(p, Overview)) != NULL) {	    if (wildmat(p, pattern))		Printf("%ld %s\r\n", i, p);	    continue;	}	(void)sprintf(buff, "%ld", i);	if ((qp = QIOopen(buff, QIO_BUFFER)) == NULL)	    continue;	if ((p = GetHeader(qp, av[1], FALSE)) == NULL)	    p = "(none)";	if (wildmat(p, pattern))	    Printf("%ld %s\r\n", i, p);	QIOclose(qp);    }    Printf(".\r\n");    DISPOSE(pattern);}

⌨️ 快捷键说明

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