Annotation of 43BSDReno/usr.bin/mail/head.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.