|
|
1.1 ! root 1: # ! 2: ! 3: #include "rcv.h" ! 4: ! 5: /* ! 6: * Mail -- a mail program ! 7: * ! 8: * Routines for processing and detecting headlines. ! 9: */ ! 10: ! 11: /* ! 12: * See if the passed line buffer is a mail header. ! 13: * Return true if yes. Note the extreme pains to ! 14: * accomodate all funny formats. ! 15: */ ! 16: ! 17: ishead(linebuf) ! 18: char linebuf[]; ! 19: { ! 20: register char *cp; ! 21: struct headline hl; ! 22: char parbuf[BUFSIZ]; ! 23: ! 24: cp = linebuf; ! 25: if (!isname("From ", cp, 5)) ! 26: return(0); ! 27: parse(cp, &hl, parbuf); ! 28: if (hl.l_from == NOSTR || hl.l_date == NOSTR) { ! 29: fail(linebuf, "No from or date field"); ! 30: return(0); ! 31: } ! 32: if (strlen(hl.l_from) >= 17) { ! 33: fail(linebuf, "From field too long"); ! 34: return(0); ! 35: } ! 36: if (!isdate(hl.l_date)) { ! 37: fail(linebuf, "Date field not legal date"); ! 38: return(0); ! 39: } ! 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: 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 (isname(dp, "tty", 3)) { ! 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: * See if the two passed strings agree in the first n characters. ! 122: * Return true if they do, gnu. ! 123: */ ! 124: ! 125: isname(as1, as2, acount) ! 126: char *as1, *as2; ! 127: { ! 128: register char *s1, *s2; ! 129: register count; ! 130: ! 131: s1 = as1; ! 132: s2 = as2; ! 133: count = acount; ! 134: if (count > 0) ! 135: do ! 136: if (*s1++ != *s2++) ! 137: return(0); ! 138: while (--count); ! 139: return(1); ! 140: } ! 141: ! 142: /* ! 143: * Test to see if the passed string is a ctime(3) generated ! 144: * date string as documented in the manual. The template ! 145: * below is used as the criterion of correctness. ! 146: */ ! 147: ! 148: #define L 1 /* An alpha char */ ! 149: #define S 2 /* A space */ ! 150: #define D 3 /* A digit */ ! 151: #define O 4 /* An optional digit or space */ ! 152: #define C 5 /* A colon */ ! 153: #define N 6 /* A new line */ ! 154: ! 155: char ctypes[] = {L,L,L,S,L,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0}; ! 156: ! 157: isdate(date) ! 158: char date[]; ! 159: { ! 160: register char *cp, *tp; ! 161: register int c; ! 162: ! 163: cp = date; ! 164: tp = ctypes; ! 165: while (*cp != '\0' && *tp != 0) { ! 166: c = *cp++; ! 167: switch (*tp++) { ! 168: case L: ! 169: if (!isalpha(c)) ! 170: return(0); ! 171: break; ! 172: ! 173: case S: ! 174: if (c != ' ') ! 175: return(0); ! 176: break; ! 177: ! 178: case D: ! 179: if (!isdigit(c)) ! 180: return(0); ! 181: break; ! 182: ! 183: case O: ! 184: if (c != ' ' && !isdigit(c)) ! 185: return(0); ! 186: break; ! 187: ! 188: case C: ! 189: if (c != ':') ! 190: return(0); ! 191: break; ! 192: ! 193: case N: ! 194: if (c != '\n') ! 195: return(0); ! 196: break; ! 197: } ! 198: } ! 199: if (*cp != '\0' || *tp != 0) ! 200: return(0); ! 201: return(1); ! 202: } ! 203: ! 204: /* ! 205: * Collect a liberal (space, tab delimited) word into the word buffer ! 206: * passed. Also, return a pointer to the next word following that, ! 207: * or NOSTR if none follow. ! 208: */ ! 209: ! 210: char * ! 211: nextword(wp, wbuf) ! 212: char wp[], wbuf[]; ! 213: { ! 214: register char *cp, *cp2; ! 215: ! 216: if ((cp = wp) == NOSTR) { ! 217: copy("", wbuf); ! 218: return(NOSTR); ! 219: } ! 220: cp2 = wbuf; ! 221: while (!any(*cp, " \t") && *cp != '\0') ! 222: *cp2++ = *cp++; ! 223: *cp2 = '\0'; ! 224: while (any(*cp, " \t")) ! 225: cp++; ! 226: if (*cp == '\0') ! 227: return(NOSTR); ! 228: return(cp); ! 229: } ! 230: ! 231: /* ! 232: * Test to see if the character is an ascii alphabetic. ! 233: */ ! 234: ! 235: isalpha(c) ! 236: { ! 237: register int ch; ! 238: ! 239: ch = raise(c); ! 240: return(ch >= 'A' && ch <= 'Z'); ! 241: } ! 242: ! 243: /* ! 244: * Test to see if the character is an ascii digit. ! 245: */ ! 246: ! 247: isdigit(c) ! 248: { ! 249: return(c >= '0' && c <= '9'); ! 250: } ! 251: ! 252: /* ! 253: * Copy str1 to str2, return pointer to null in str2. ! 254: */ ! 255: ! 256: char * ! 257: copy(str1, str2) ! 258: char *str1, *str2; ! 259: { ! 260: register char *s1, *s2; ! 261: ! 262: s1 = str1; ! 263: s2 = str2; ! 264: while (*s1) ! 265: *s2++ = *s1++; ! 266: *s2 = 0; ! 267: return(s2); ! 268: } ! 269: ! 270: /* ! 271: * Is ch any of the characters in str? ! 272: */ ! 273: ! 274: any(ch, str) ! 275: char *str; ! 276: { ! 277: register char *f; ! 278: register c; ! 279: ! 280: f = str; ! 281: c = ch; ! 282: while (*f) ! 283: if (c == *f++) ! 284: return(1); ! 285: return(0); ! 286: } ! 287: ! 288: /* ! 289: * Convert lower case letters to upper case. ! 290: */ ! 291: ! 292: raise(c) ! 293: register int c; ! 294: { ! 295: if (c >= 'a' && c <= 'z') ! 296: c += 'A' - 'a'; ! 297: return(c); ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.