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

📄 m_getfld.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	    c = (cnt < i ? cnt : i);	    if (msg_style != MS_DEFAULT && c > 1) {		/*		 * packed maildrop - only take up to the (possible)		 * start of the next message.  This "matchc" should		 * probably be a Boyer-Moore matcher for non-vaxen,		 * particularly since we have the alignment table		 * all built for the end-of-buffer test (next).		 * But our vax timings indicate that the "matchc"		 * instruction is 50% faster than a carefully coded		 * B.M. matcher for most strings.  (So much for elegant		 * algorithms vs. brute force.)  Since I (currently)		 * run MH on a vax, we use the matchc instruction. --vj		 */		if (ep = matchc( fdelimlen, fdelim, c, bp ) )		    c = ep - bp + 1;		else {		    /*		     * There's no delim in the buffer but there may be		     * a partial one at the end.  If so, we want to leave		     * it so the "eom" check on the next call picks it up.		     * Use a modified Boyer-Moore matcher to make this		     * check relatively cheap.  The first "if" figures		     * out what position in the pattern matches the last		     * character in the buffer.  The inner "while" matches		     * the pattern against the buffer, backwards starting		     * at that position.  Note that unless the buffer		     * ends with one of the characters in the pattern		     * (excluding the first and last), we do only one test.		     */		    ep = bp + c - 1;		    if (sp = pat_map[*ep]) {			do {			    cp = sp;			    while (*--ep == *--cp)			    ;			    if (cp < fdelim) {				if (ep >= bp)				    /*				     * ep < bp means that all the buffer				     * contains is a prefix of delim.				     * If this prefix is really a delim, the				     * m_eom call at entry should have found				     * it.  Thus it's not a delim and we can				     * take all of it.				     */				    c = (ep - bp) + 2;			    break;			}			    /* try matching one less char of delim string */			    ep = bp + c - 1;			} while (--sp > fdelim);		    }		}	    }	    (void) bcopy( bp, buf, c );	    iob->_cnt -= c;	    iob->_ptr += c;	    if (bufsz < 0) {		msg_count = c;		return (state);	    }	    cp = buf + c;	    break;	default: 	    adios (NULLCP, "m_getfld() called with bogus state of %d", state);    }finish:;    *cp = 0;    msg_count = cp - buf;    return (state);}/*  */#ifdef	RPATHSstatic char  unixbuf[BUFSIZ] = "";#endif /* RPATHS */voidm_unknown(iob)	register FILE *iob;{    register	int c;    register	long pos;    char	text[10];    register    char *cp;    register	char *delimstr;    msg_style = MS_UNKNOWN;    /* Figure out what the message delimitter string is for this     * maildrop.  (This used to be part of m_Eom but I didn't like     * the idea of an "if" statement that could only succeed on the     * first call to m_Eom getting executed on each call, i.e., at     * every newline in the message).     *     * If the first line of the maildrop is a Unix "from" line, we say the     * style is UUCP and eat the rest of the line.  Otherwise we say the style     * is MMDF & look for the delimiter string specified when MH was built     * (or from the mtstailor file).     */    pos = ftell (iob);    if (fread (text, sizeof *text, 5, iob) == 5	    && strncmp (text, "From ", 5) == 0) {	msg_style = MS_UUCP;	delimstr = "\nFrom ";#ifndef	RPATHS	while ((c = getc (iob)) != '\n' && c >= 0)	    ;#else /* RPATHS */	cp = unixbuf;	while ((c = getc (iob)) != '\n')	    *cp++ = c;	*cp = 0;#endif /* RPATHS */    } else {	/* not a Unix style maildrop */	(void) fseek (iob, pos, 0);	if (mmdlm2 == NULLCP || *mmdlm2 == 0)	    mmdlm2 = "\001\001\001\001\n";	delimstr = mmdlm2;	msg_style = MS_MMDF;    }    c = strlen (delimstr);    fdelim = (unsigned char *)malloc((unsigned)c + 3);    *fdelim++ = '\0';    *fdelim = '\n';    msg_delim = (char *)fdelim+1;    edelim = (unsigned char *)msg_delim+1;    fdelimlen = c + 1;    edelimlen = c - 1;    (void)strcpy(msg_delim, delimstr);    delimend = (unsigned char *)msg_delim + edelimlen;    if (edelimlen <= 1)	adios (NULLCP, "maildrop delimiter must be at least 2 bytes");    /*     * build a Boyer-Moore end-position map for the matcher in m_getfld.     * N.B. - we don't match just the first char (since it's the newline     * separator) or the last char (since the matchc would have found it     * if it was a real delim).     */    pat_map = (unsigned char **) calloc (256, sizeof (unsigned char *));    for (cp = (char *)fdelim + 1; cp < (char *)delimend; cp++ )	pat_map[*cp] = (unsigned char *)cp;    if (msg_style == MS_MMDF) {	/* flush extra msg hdrs */	while ((c = Getc(iob)) >= 0 && eom (c, iob))	    ;	if (c >= 0)	    (void) ungetc(c, iob);    }}void m_eomsbr (action)int     (*action) ();{    if (eom_action = action) {	msg_style = MS_MSH;	*msg_delim = 0;	fdelimlen = 1;	delimend = fdelim;    } else {	msg_style = MS_MMDF;	msg_delim = (char *)fdelim + 1;	fdelimlen = strlen((char *)fdelim);	delimend = (unsigned char *)(msg_delim + edelimlen);    }}/*  *//* test for msg delimiter string */int  m_Eom (c, iob)register int     c;register FILE   *iob;{    register long pos = 0L;    register int i;    char    text[10];#ifdef	RPATHS    register    char *cp;#endif /* RPATHS */    pos = ftell (iob);    if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen	    || strncmp (text, (char *)edelim, edelimlen)) {	if (i == 0 && msg_style == MS_UUCP)	    /* the final newline in the (brain damaged) unix-format	     * maildrop is part of the delimitter - delete it.	     */	    return 1;#ifdef	notdef	(void) fseek (iob, pos, 0);#else	(void) fseek (iob, (long)(pos-1), 0);	(void) getc (iob);		/* should be OK */#endif /* !notdef */	return 0;    }    if (msg_style == MS_UUCP) {#ifndef	RPATHS	while ((c = getc (iob)) != '\n')	    if (c < 0)		break;#else /* RPATHS */	cp = unixbuf;	while ((c = getc (iob)) != '\n' && c >= 0)	    *cp++ = c;	*cp = 0;#endif /* RPATHS */    }    return 1;}/*  */#ifdef	RPATHSchar   *unixline () {    register char  *cp,                   *dp,                   *pp;    static char unixfrom[BUFSIZ];    pp = unixfrom;    if (cp = dp = index (unixbuf, ' ')) {	while (cp = index (cp + 1, 'r'))	    if (strncmp (cp, "remote from ", 12) == 0) {		*cp = 0;		(void) sprintf (pp, "%s!", cp + 12);		pp += strlen (pp);		break;	    }	if (cp == NULL)	    cp = unixbuf + strlen (unixbuf);	if ((cp -= 25) >= dp)	    *cp = 0;    }    (void) sprintf (pp, "%s\n", unixbuf);    unixbuf[0] = 0;    return unixfrom;}#endif /* RPATHS *//*  */#if (vax && !lint)	asm(".align 1");	asm("_matchc: .word 0");	asm("	movq 4(ap),r0");	asm("	movq 12(ap),r2");	asm("	matchc  r0,(r1),r2,(r3)");	asm("	beql 1f");	asm("	movl 4(ap),r3");	asm("1:	subl3  4(ap),r3,r0");	asm("	ret");#elsestatic unsigned char *matchc( patln, pat, strln, str )	int patln;	char *pat;	int strln;	register char *str;{	register char *es = str + strln - patln;	register char *sp;	register char *pp;	register char *ep = pat + patln;	register char pc = *pat++;	for(;;) {		while (pc != *str++)			if (str > es)				return 0;		sp = str; pp = pat;		while (pp < ep && *sp++ == *pp)			pp++;		if (pp >= ep) 			return ((unsigned char *)--str);	}}#endif/*  *//* * Locate character "term" in the next "cnt" characters of "src". * If found, return its address, otherwise return 0. */#if (vax && !lint)	asm(".align 1");	asm("_locc: .word 0");	asm("	movq  4(ap),r0");	asm("	locc  12(ap),r0,(r1)");	asm("	beql  1f");	asm("	movl  r1,r0");	asm("1:	ret");#elsestatic unsigned char *locc( cnt, src, term )	register int  cnt;	register unsigned char *src;	register unsigned char term;{    while (*src++ != term && --cnt > 0);    return (cnt > 0 ? --src : (unsigned char *)0);}#endif/*  */#if	!defined (BSD42) && !defined (bcopy)int	bcmp (b1, b2, length)register char *b1,	      *b2;register int   length;{    while (length-- > 0)	if (*b1++ != *b2++)	    return 1;    return 0;}bcopy (b1, b2, length)register char *b1,	      *b2;register int   length;{    while (length-- > 0)	*b2++ = *b1++;}bzero (b, length)register char *b;register int   length;{    while (length-- > 0)	*b++ = 0;}#endif /* not BSD42 */

⌨️ 快捷键说明

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