|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)head.c 5.7 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include "rcv.h" ! 25: ! 26: /* ! 27: * Mail -- a mail program ! 28: * ! 29: * Routines for processing and detecting headlines. ! 30: */ ! 31: ! 32: /* ! 33: * See if the passed line buffer is a mail header. ! 34: * Return true if yes. Note the extreme pains to ! 35: * accomodate all funny formats. ! 36: */ ! 37: ishead(linebuf) ! 38: char linebuf[]; ! 39: { ! 40: register char *cp; ! 41: struct headline hl; ! 42: char parbuf[BUFSIZ]; ! 43: ! 44: cp = linebuf; ! 45: if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' || ! 46: *cp++ != ' ') ! 47: return (0); ! 48: parse(linebuf, &hl, parbuf); ! 49: if (hl.l_from == NOSTR || hl.l_date == NOSTR) { ! 50: fail(linebuf, "No from or date field"); ! 51: return (0); ! 52: } ! 53: if (!isdate(hl.l_date)) { ! 54: fail(linebuf, "Date field not legal date"); ! 55: return (0); ! 56: } ! 57: /* ! 58: * I guess we got it! ! 59: */ ! 60: return (1); ! 61: } ! 62: ! 63: /*ARGSUSED*/ ! 64: fail(linebuf, reason) ! 65: char linebuf[], reason[]; ! 66: { ! 67: ! 68: /* ! 69: if (value("debug") == NOSTR) ! 70: return; ! 71: fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason); ! 72: */ ! 73: } ! 74: ! 75: /* ! 76: * Split a headline into its useful components. ! 77: * Copy the line into dynamic string space, then set ! 78: * pointers into the copied line in the passed headline ! 79: * structure. Actually, it scans. ! 80: */ ! 81: parse(line, hl, pbuf) ! 82: char line[], pbuf[]; ! 83: register struct headline *hl; ! 84: { ! 85: register char *cp; ! 86: char *sp; ! 87: char word[LINESIZE]; ! 88: ! 89: hl->l_from = NOSTR; ! 90: hl->l_tty = NOSTR; ! 91: hl->l_date = NOSTR; ! 92: cp = line; ! 93: sp = pbuf; ! 94: /* ! 95: * Skip over "From" first. ! 96: */ ! 97: cp = nextword(cp, word); ! 98: cp = nextword(cp, word); ! 99: if (*word) ! 100: hl->l_from = copyin(word, &sp); ! 101: if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') { ! 102: cp = nextword(cp, word); ! 103: hl->l_tty = copyin(word, &sp); ! 104: } ! 105: if (cp != NOSTR) ! 106: hl->l_date = copyin(cp, &sp); ! 107: } ! 108: ! 109: /* ! 110: * Copy the string on the left into the string on the right ! 111: * and bump the right (reference) string pointer by the length. ! 112: * Thus, dynamically allocate space in the right string, copying ! 113: * the left string into it. ! 114: */ ! 115: char * ! 116: copyin(src, space) ! 117: register char *src; ! 118: char **space; ! 119: { ! 120: register char *cp; ! 121: char *top; ! 122: ! 123: top = cp = *space; ! 124: while (*cp++ = *src++) ! 125: ; ! 126: *space = cp; ! 127: return (top); ! 128: } ! 129: ! 130: /* ! 131: * Test to see if the passed string is a ctime(3) generated ! 132: * date string as documented in the manual. The template ! 133: * below is used as the criterion of correctness. ! 134: * Also, we check for a possible trailing time zone using ! 135: * the tmztype template. ! 136: */ ! 137: ! 138: /* ! 139: * 'A' An upper case char ! 140: * 'a' A lower case char ! 141: * ' ' A space ! 142: * '0' A digit ! 143: * 'O' An optional digit or space ! 144: * ':' A colon ! 145: * 'N' A new line ! 146: */ ! 147: char ctype[] = "Aaa Aaa O0 00:00:00 0000"; ! 148: char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000"; ! 149: ! 150: isdate(date) ! 151: char date[]; ! 152: { ! 153: ! 154: return cmatch(date, ctype) || cmatch(date, tmztype); ! 155: } ! 156: ! 157: /* ! 158: * Match the given string (cp) against the given template (tp). ! 159: * Return 1 if they match, 0 if they don't ! 160: */ ! 161: cmatch(cp, tp) ! 162: register char *cp, *tp; ! 163: { ! 164: ! 165: while (*cp && *tp) ! 166: switch (*tp++) { ! 167: case 'a': ! 168: if (!islower(*cp++)) ! 169: return 0; ! 170: break; ! 171: case 'A': ! 172: if (!isupper(*cp++)) ! 173: return 0; ! 174: break; ! 175: case ' ': ! 176: if (*cp++ != ' ') ! 177: return 0; ! 178: break; ! 179: case '0': ! 180: if (!isdigit(*cp++)) ! 181: return 0; ! 182: break; ! 183: case 'O': ! 184: if (*cp != ' ' && !isdigit(*cp)) ! 185: return 0; ! 186: cp++; ! 187: break; ! 188: case ':': ! 189: if (*cp++ != ':') ! 190: return 0; ! 191: break; ! 192: case 'N': ! 193: if (*cp++ != '\n') ! 194: return 0; ! 195: break; ! 196: } ! 197: if (*cp || *tp) ! 198: return 0; ! 199: return (1); ! 200: } ! 201: ! 202: /* ! 203: * Collect a liberal (space, tab delimited) word into the word buffer ! 204: * passed. Also, return a pointer to the next word following that, ! 205: * or NOSTR if none follow. ! 206: */ ! 207: char * ! 208: nextword(wp, wbuf) ! 209: register char *wp, *wbuf; ! 210: { ! 211: register c; ! 212: ! 213: if (wp == NOSTR) { ! 214: *wbuf = 0; ! 215: return (NOSTR); ! 216: } ! 217: while ((c = *wp++) && c != ' ' && c != '\t') { ! 218: *wbuf++ = c; ! 219: if (c == '"') { ! 220: while ((c = *wp++) && c != '"') ! 221: *wbuf++ = c; ! 222: if (c == '"') ! 223: *wbuf++ = c; ! 224: else ! 225: wp--; ! 226: } ! 227: } ! 228: *wbuf = '\0'; ! 229: for (; c == ' ' || c == '\t'; c = *wp++) ! 230: ; ! 231: if (c == 0) ! 232: return (NOSTR); ! 233: return (wp - 1); ! 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.