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

unix.superglobalmegacorp.com

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