1: #
   2: 
   3: #include "rcv.h"
   4: 
   5: /*
   6:  * Mail -- a mail program
   7:  *
   8:  * Routines for processing and detecting headlines.
   9:  */
  10: 
  11: static char *SccsId = "@(#)head.c	2.2 3/3/83";
  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: }

Defined functions

cmatch defined in line 155; used 2 times
copyin defined in line 103; used 5 times
fail defined in line 46; used 2 times
isalpha defined in line 245; used 1 times
isdate defined in line 139; used 1 times
  • in line 34
isdigit defined in line 257; used 2 times
ishead defined in line 19; used 2 times
nextword defined in line 213; used 4 times
parse defined in line 62; used 2 times
raise defined in line 302; used 5 times

Defined variables

SccsId defined in line 11; never used
ctypes defined in line 136; used 1 times
tmztypes defined in line 137; used 1 times

Defined macros

C defined in line 132; used 4 times
D defined in line 130; used 22 times
L defined in line 128; used 8 times
N defined in line 133; never used
O defined in line 131; used 2 times
S defined in line 129; used 9 times
U defined in line 134; used 7 times
Last modified: 1983-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 976
Valid CSS Valid XHTML 1.0 Strict