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