|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)head.c 2.4 (Berkeley) 8/28/83"; ! 3: #endif ! 4: ! 5: #include "rcv.h" ! 6: ! 7: /* ! 8: * Mail -- a mail program ! 9: * ! 10: * Routines for processing and detecting headlines. ! 11: */ ! 12: ! 13: /* ! 14: * See if the passed line buffer is a mail header. ! 15: * Return true if yes. Note the extreme pains to ! 16: * accomodate all funny formats. ! 17: */ ! 18: ! 19: ishead(linebuf) ! 20: char linebuf[]; ! 21: { ! 22: register char *cp; ! 23: struct headline hl; ! 24: char parbuf[BUFSIZ]; ! 25: ! 26: cp = linebuf; ! 27: if (strncmp("From ", cp, 5) != 0) ! 28: return(0); ! 29: parse(cp, &hl, parbuf); ! 30: if (hl.l_from == NOSTR || hl.l_date == NOSTR) { ! 31: fail(linebuf, "No from or date field"); ! 32: return(0); ! 33: } ! 34: if (!isdate(hl.l_date)) { ! 35: fail(linebuf, "Date field not legal date"); ! 36: return(0); ! 37: } ! 38: ! 39: /* ! 40: * I guess we got it! ! 41: */ ! 42: ! 43: return(1); ! 44: } ! 45: ! 46: fail(linebuf, reason) ! 47: char linebuf[], reason[]; ! 48: { ! 49: ! 50: if (1 /*value("debug") == NOSTR*/) ! 51: return; ! 52: fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason); ! 53: } ! 54: ! 55: /* ! 56: * Split a headline into its useful components. ! 57: * Copy the line into dynamic string space, then set ! 58: * pointers into the copied line in the passed headline ! 59: * structure. Actually, it scans. ! 60: */ ! 61: ! 62: parse(line, hl, pbuf) ! 63: char line[], pbuf[]; ! 64: struct headline *hl; ! 65: { ! 66: register char *cp, *dp; ! 67: char *sp; ! 68: char word[LINESIZE]; ! 69: ! 70: hl->l_from = NOSTR; ! 71: hl->l_tty = NOSTR; ! 72: hl->l_date = NOSTR; ! 73: cp = line; ! 74: sp = pbuf; ! 75: ! 76: /* ! 77: * Skip the first "word" of the line, which should be "From" ! 78: * anyway. ! 79: */ ! 80: ! 81: cp = nextword(cp, word); ! 82: dp = nextword(cp, word); ! 83: if (!equal(word, "")) ! 84: hl->l_from = copyin(word, &sp); ! 85: if (strncmp(dp, "tty", 3) == 0) { ! 86: cp = nextword(dp, word); ! 87: hl->l_tty = copyin(word, &sp); ! 88: if (cp != NOSTR) ! 89: hl->l_date = copyin(cp, &sp); ! 90: } ! 91: else ! 92: if (dp != NOSTR) ! 93: hl->l_date = copyin(dp, &sp); ! 94: } ! 95: ! 96: /* ! 97: * Copy the string on the left into the string on the right ! 98: * and bump the right (reference) string pointer by the length. ! 99: * Thus, dynamically allocate space in the right string, copying ! 100: * the left string into it. ! 101: */ ! 102: ! 103: char * ! 104: copyin(src, space) ! 105: char src[]; ! 106: char **space; ! 107: { ! 108: register char *cp, *top; ! 109: register int s; ! 110: ! 111: s = strlen(src); ! 112: cp = *space; ! 113: top = cp; ! 114: strcpy(cp, src); ! 115: cp += s + 1; ! 116: *space = cp; ! 117: return(top); ! 118: } ! 119: ! 120: /* ! 121: * Test to see if the passed string is a ctime(3) generated ! 122: * date string as documented in the manual. The template ! 123: * below is used as the criterion of correctness. ! 124: * Also, we check for a possible trailing time zone using ! 125: * the auxtype template. ! 126: */ ! 127: ! 128: #define L 1 /* A lower case char */ ! 129: #define S 2 /* A space */ ! 130: #define D 3 /* A digit */ ! 131: #define O 4 /* An optional digit or space */ ! 132: #define C 5 /* A colon */ ! 133: #define N 6 /* A new line */ ! 134: #define U 7 /* An upper case char */ ! 135: ! 136: 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}; ! 137: 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}; ! 138: ! 139: isdate(date) ! 140: char date[]; ! 141: { ! 142: register char *cp; ! 143: ! 144: cp = date; ! 145: if (cmatch(cp, ctypes)) ! 146: return(1); ! 147: return(cmatch(cp, tmztypes)); ! 148: } ! 149: ! 150: /* ! 151: * Match the given string against the given template. ! 152: * Return 1 if they match, 0 if they don't ! 153: */ ! 154: ! 155: cmatch(str, temp) ! 156: char str[], temp[]; ! 157: { ! 158: register char *cp, *tp; ! 159: register int c; ! 160: ! 161: cp = str; ! 162: tp = temp; ! 163: while (*cp != '\0' && *tp != 0) { ! 164: c = *cp++; ! 165: switch (*tp++) { ! 166: case L: ! 167: if (c < 'a' || c > 'z') ! 168: return(0); ! 169: break; ! 170: ! 171: case U: ! 172: if (c < 'A' || c > 'Z') ! 173: return(0); ! 174: break; ! 175: ! 176: case S: ! 177: if (c != ' ') ! 178: return(0); ! 179: break; ! 180: ! 181: case D: ! 182: if (!isdigit(c)) ! 183: return(0); ! 184: break; ! 185: ! 186: case O: ! 187: if (c != ' ' && !isdigit(c)) ! 188: return(0); ! 189: break; ! 190: ! 191: case C: ! 192: if (c != ':') ! 193: return(0); ! 194: break; ! 195: ! 196: case N: ! 197: if (c != '\n') ! 198: return(0); ! 199: break; ! 200: } ! 201: } ! 202: if (*cp != '\0' || *tp != 0) ! 203: return(0); ! 204: return(1); ! 205: } ! 206: ! 207: /* ! 208: * Collect a liberal (space, tab delimited) word into the word buffer ! 209: * passed. Also, return a pointer to the next word following that, ! 210: * or NOSTR if none follow. ! 211: */ ! 212: ! 213: char * ! 214: nextword(wp, wbuf) ! 215: char wp[], wbuf[]; ! 216: { ! 217: register char *cp, *cp2; ! 218: ! 219: if ((cp = wp) == NOSTR) { ! 220: copy("", wbuf); ! 221: return(NOSTR); ! 222: } ! 223: cp2 = wbuf; ! 224: while (!any(*cp, " \t") && *cp != '\0') ! 225: if (*cp == '"') { ! 226: *cp2++ = *cp++; ! 227: while (*cp != '\0' && *cp != '"') ! 228: *cp2++ = *cp++; ! 229: if (*cp == '"') ! 230: *cp2++ = *cp++; ! 231: } else ! 232: *cp2++ = *cp++; ! 233: *cp2 = '\0'; ! 234: while (any(*cp, " \t")) ! 235: cp++; ! 236: if (*cp == '\0') ! 237: return(NOSTR); ! 238: return(cp); ! 239: } ! 240: ! 241: /* ! 242: * Test to see if the character is an ascii alphabetic. ! 243: */ ! 244: ! 245: isalpha(c) ! 246: { ! 247: register int ch; ! 248: ! 249: ch = raise(c); ! 250: return(ch >= 'A' && ch <= 'Z'); ! 251: } ! 252: ! 253: /* ! 254: * Test to see if the character is an ascii digit. ! 255: */ ! 256: ! 257: isdigit(c) ! 258: { ! 259: return(c >= '0' && c <= '9'); ! 260: } ! 261: ! 262: /* ! 263: * Copy str1 to str2, return pointer to null in str2. ! 264: */ ! 265: ! 266: char * ! 267: copy(str1, str2) ! 268: char *str1, *str2; ! 269: { ! 270: register char *s1, *s2; ! 271: ! 272: s1 = str1; ! 273: s2 = str2; ! 274: while (*s1) ! 275: *s2++ = *s1++; ! 276: *s2 = 0; ! 277: return(s2); ! 278: } ! 279: ! 280: /* ! 281: * Is ch any of the characters in str? ! 282: */ ! 283: ! 284: any(ch, str) ! 285: char *str; ! 286: { ! 287: register char *f; ! 288: register c; ! 289: ! 290: f = str; ! 291: c = ch; ! 292: while (*f) ! 293: if (c == *f++) ! 294: return(1); ! 295: return(0); ! 296: } ! 297: ! 298: /* ! 299: * Convert lower case letters to upper case. ! 300: */ ! 301: ! 302: raise(c) ! 303: register int c; ! 304: { ! 305: if (c >= 'a' && c <= 'z') ! 306: c += 'A' - 'a'; ! 307: return(c); ! 308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.