Annotation of 42BSD/ucb/Mail/head.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)head.c     2.4 (Berkeley) 8/28/83";
                      3: #endif
                      4: 
                      5: #include "rcv.h"
                      6: 
                      7: /*
                      8:  * Mail -- a mail program
                      9:  *
                     10:  * Routines for processing and detecting headlines.
                     11:  */
                     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: }

unix.superglobalmegacorp.com

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