1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms, with or without
   6:  * modification, are permitted provided that the following conditions
   7:  * are met:
   8:  * 1. Redistributions of source code must retain the above copyright
   9:  *    notice, this list of conditions and the following disclaimer.
  10:  * 2. Redistributions in binary form must reproduce the above copyright
  11:  *    notice, this list of conditions and the following disclaimer in the
  12:  *    documentation and/or other materials provided with the distribution.
  13:  * 3. All advertising materials mentioning features or use of this software
  14:  *    must display the following acknowledgement:
  15:  *	This product includes software developed by the University of
  16:  *	California, Berkeley and its contributors.
  17:  * 4. Neither the name of the University nor the names of its contributors
  18:  *    may be used to endorse or promote products derived from this software
  19:  *    without specific prior written permission.
  20:  *
  21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31:  * SUCH DAMAGE.
  32:  */
  33: 
  34: #if !defined(lint) && defined(DOSCCS)
  35: static char sccsid[] = "@(#)head.c	5.7 (Berkeley) 6/1/90";
  36: #endif
  37: 
  38: #include "rcv.h"
  39: 
  40: /*
  41:  * Mail -- a mail program
  42:  *
  43:  * Routines for processing and detecting headlines.
  44:  */
  45: 
  46: /*
  47:  * See if the passed line buffer is a mail header.
  48:  * Return true if yes.  Note the extreme pains to
  49:  * accomodate all funny formats.
  50:  */
  51: ishead(linebuf)
  52:     char linebuf[];
  53: {
  54:     register char *cp;
  55:     struct headline hl;
  56:     char parbuf[BUFSIZ];
  57: 
  58:     cp = linebuf;
  59:     if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
  60:         *cp++ != ' ')
  61:         return (0);
  62:     parse(linebuf, &hl, parbuf);
  63:     if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
  64:         fail(linebuf, "No from or date field");
  65:         return (0);
  66:     }
  67:     if (!isdate(hl.l_date)) {
  68:         fail(linebuf, "Date field not legal date");
  69:         return (0);
  70:     }
  71:     /*
  72: 	 * I guess we got it!
  73: 	 */
  74:     return (1);
  75: }
  76: 
  77: /*ARGSUSED*/
  78: fail(linebuf, reason)
  79:     char linebuf[], reason[];
  80: {
  81: 
  82:     if (value("debug") == NOSTR)
  83:         return;
  84:     fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);
  85: }
  86: 
  87: /*
  88:  * Split a headline into its useful components.
  89:  * Copy the line into dynamic string space, then set
  90:  * pointers into the copied line in the passed headline
  91:  * structure.  Actually, it scans.
  92:  */
  93: parse(line, hl, pbuf)
  94:     char line[], pbuf[];
  95:     register struct headline *hl;
  96: {
  97:     register char *cp;
  98:     char *sp;
  99:     char word[LINESIZE];
 100: 
 101:     hl->l_from = NOSTR;
 102:     hl->l_tty = NOSTR;
 103:     hl->l_date = NOSTR;
 104:     cp = line;
 105:     sp = pbuf;
 106:     /*
 107: 	 * Skip over "From" first.
 108: 	 */
 109:     cp = nextword(cp, word);
 110:     cp = nextword(cp, word);
 111:     if (*word)
 112:         hl->l_from = copyin(word, &sp);
 113:     if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
 114:         cp = nextword(cp, word);
 115:         hl->l_tty = copyin(word, &sp);
 116:     }
 117:     if (cp != NOSTR)
 118:         hl->l_date = copyin(cp, &sp);
 119: }
 120: 
 121: /*
 122:  * Copy the string on the left into the string on the right
 123:  * and bump the right (reference) string pointer by the length.
 124:  * Thus, dynamically allocate space in the right string, copying
 125:  * the left string into it.
 126:  */
 127: char *
 128: copyin(src, space)
 129:     register char *src;
 130:     char **space;
 131: {
 132:     register char *cp;
 133:     char *top;
 134: 
 135:     top = cp = *space;
 136:     while (*cp++ = *src++)
 137:         ;
 138:     *space = cp;
 139:     return (top);
 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:  * Also, we check for a possible trailing time zone using
 147:  * the tmztype template.
 148:  */
 149: 
 150: /*
 151:  * 'A'	An upper case char
 152:  * 'a'	A lower case char
 153:  * ' '	A space
 154:  * '0'	A digit
 155:  * 'O'	An optional digit or space
 156:  * ':'	A colon
 157:  * 'N'	A new line
 158:  */
 159: char *ctype = "Aaa Aaa O0 00:00:00 0000";
 160: char *tmztype = "Aaa Aaa O0 00:00:00 AAA 0000";
 161: 
 162: isdate(date)
 163:     char date[];
 164: {
 165: 
 166:     return cmatch(date, ctype) || cmatch(date, tmztype);
 167: }
 168: 
 169: /*
 170:  * Match the given string (cp) against the given template (tp).
 171:  * Return 1 if they match, 0 if they don't
 172:  */
 173: cmatch(cp, tp)
 174:     register char *cp, *tp;
 175: {
 176: 
 177:     while (*cp && *tp)
 178:         switch (*tp++) {
 179:         case 'a':
 180:             if (!islower(*cp++))
 181:                 return 0;
 182:             break;
 183:         case 'A':
 184:             if (!isupper(*cp++))
 185:                 return 0;
 186:             break;
 187:         case ' ':
 188:             if (*cp++ != ' ')
 189:                 return 0;
 190:             break;
 191:         case '0':
 192:             if (!isdigit(*cp++))
 193:                 return 0;
 194:             break;
 195:         case 'O':
 196:             if (*cp != ' ' && !isdigit(*cp))
 197:                 return 0;
 198:             cp++;
 199:             break;
 200:         case ':':
 201:             if (*cp++ != ':')
 202:                 return 0;
 203:             break;
 204:         case 'N':
 205:             if (*cp++ != '\n')
 206:                 return 0;
 207:             break;
 208:         }
 209:     if (*cp || *tp)
 210:         return 0;
 211:     return (1);
 212: }
 213: 
 214: /*
 215:  * Collect a liberal (space, tab delimited) word into the word buffer
 216:  * passed.  Also, return a pointer to the next word following that,
 217:  * or NOSTR if none follow.
 218:  */
 219: char *
 220: nextword(wp, wbuf)
 221:     register char *wp, *wbuf;
 222: {
 223:     register c;
 224: 
 225:     if (wp == NOSTR) {
 226:         *wbuf = 0;
 227:         return (NOSTR);
 228:     }
 229:     while ((c = *wp++) && c != ' ' && c != '\t') {
 230:         *wbuf++ = c;
 231:         if (c == '"') {
 232:             while ((c = *wp++) && c != '"')
 233:                 *wbuf++ = c;
 234:             if (c == '"')
 235:                 *wbuf++ = c;
 236:             else
 237:                 wp--;
 238:         }
 239:     }
 240:     *wbuf = '\0';
 241:     for (; c == ' ' || c == '\t'; c = *wp++)
 242:         ;
 243:     if (c == 0)
 244:         return (NOSTR);
 245:     return (wp - 1);
 246: }

Defined functions

cmatch defined in line 173; used 2 times
  • in line 166(2)
copyin defined in line 127; used 4 times
fail defined in line 78; used 2 times
isdate defined in line 162; used 1 times
  • in line 67
ishead defined in line 51; used 2 times
nextword defined in line 219; used 4 times
parse defined in line 93; used 2 times

Defined variables

ctype defined in line 159; used 1 times
sccsid defined in line 35; never used
tmztype defined in line 160; used 1 times
Last modified: 1992-10-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2784
Valid CSS Valid XHTML 1.0 Strict