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

Defined functions

cmatch defined in line 161; used 2 times
copyin defined in line 109; used 5 times
fail defined in line 52; used 2 times
isalpha defined in line 251; never used
isdate defined in line 145; used 1 times
  • in line 40
isdigit defined in line 263; used 2 times
ishead defined in line 25; used 2 times
nextword defined in line 219; used 4 times
parse defined in line 68; used 2 times
raise defined in line 308; used 7 times

Defined variables

ctypes defined in line 142; used 1 times
sccsid defined in line 8; never used
tmztypes defined in line 143; used 1 times

Defined macros

C defined in line 138; used 4 times
D defined in line 136; used 22 times
L defined in line 134; used 8 times
N defined in line 139; never used
O defined in line 137; used 2 times
S defined in line 135; used 9 times
U defined in line 140; used 7 times
Last modified: 1985-06-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 856
Valid CSS Valid XHTML 1.0 Strict