Annotation of 40BSD/cmd/ucbmail/head.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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