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