📄 m_getfld.c
字号:
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 + -