Annotation of 3BSD/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 (strlen(hl.l_from) >= 17) {
                     33:                fail(linebuf, "From field too long");
                     34:                return(0);
                     35:        }
                     36:        if (!isdate(hl.l_date)) {
                     37:                fail(linebuf, "Date field not legal date");
                     38:                return(0);
                     39:        }
                     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:        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 (isname(dp, "tty", 3)) {
                     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:  * See if the two passed strings agree in the first n characters.
                    122:  * Return true if they do, gnu.
                    123:  */
                    124: 
                    125: isname(as1, as2, acount)
                    126:        char *as1, *as2;
                    127: {
                    128:        register char *s1, *s2;
                    129:        register count;
                    130: 
                    131:        s1 = as1;
                    132:        s2 = as2;
                    133:        count = acount;
                    134:        if (count > 0)
                    135:                do
                    136:                        if (*s1++ != *s2++)
                    137:                                return(0);
                    138:                while (--count);
                    139:        return(1);
                    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:  */
                    147: 
                    148: #define        L       1               /* An alpha 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: 
                    155: char ctypes[] = {L,L,L,S,L,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0};
                    156: 
                    157: isdate(date)
                    158:        char date[];
                    159: {
                    160:        register char *cp, *tp;
                    161:        register int c;
                    162: 
                    163:        cp = date;
                    164:        tp = ctypes;
                    165:        while (*cp != '\0' && *tp != 0) {
                    166:                c = *cp++;
                    167:                switch (*tp++) {
                    168:                case L:
                    169:                        if (!isalpha(c))
                    170:                                return(0);
                    171:                        break;
                    172: 
                    173:                case S:
                    174:                        if (c != ' ')
                    175:                                return(0);
                    176:                        break;
                    177: 
                    178:                case D:
                    179:                        if (!isdigit(c))
                    180:                                return(0);
                    181:                        break;
                    182: 
                    183:                case O:
                    184:                        if (c != ' ' && !isdigit(c))
                    185:                                return(0);
                    186:                        break;
                    187: 
                    188:                case C:
                    189:                        if (c != ':')
                    190:                                return(0);
                    191:                        break;
                    192: 
                    193:                case N:
                    194:                        if (c != '\n')
                    195:                                return(0);
                    196:                        break;
                    197:                }
                    198:        }
                    199:        if (*cp != '\0' || *tp != 0)
                    200:                return(0);
                    201:        return(1);
                    202: }
                    203: 
                    204: /*
                    205:  * Collect a liberal (space, tab delimited) word into the word buffer
                    206:  * passed.  Also, return a pointer to the next word following that,
                    207:  * or NOSTR if none follow.
                    208:  */
                    209: 
                    210: char *
                    211: nextword(wp, wbuf)
                    212:        char wp[], wbuf[];
                    213: {
                    214:        register char *cp, *cp2;
                    215: 
                    216:        if ((cp = wp) == NOSTR) {
                    217:                copy("", wbuf);
                    218:                return(NOSTR);
                    219:        }
                    220:        cp2 = wbuf;
                    221:        while (!any(*cp, " \t") && *cp != '\0')
                    222:                *cp2++ = *cp++;
                    223:        *cp2 = '\0';
                    224:        while (any(*cp, " \t"))
                    225:                cp++;
                    226:        if (*cp == '\0')
                    227:                return(NOSTR);
                    228:        return(cp);
                    229: }
                    230: 
                    231: /*
                    232:  * Test to see if the character is an ascii alphabetic.
                    233:  */
                    234: 
                    235: isalpha(c)
                    236: {
                    237:        register int ch;
                    238: 
                    239:        ch = raise(c);
                    240:        return(ch >= 'A' && ch <= 'Z');
                    241: }
                    242: 
                    243: /*
                    244:  * Test to see if the character is an ascii digit.
                    245:  */
                    246: 
                    247: isdigit(c)
                    248: {
                    249:        return(c >= '0' && c <= '9');
                    250: }
                    251: 
                    252: /*
                    253:  * Copy str1 to str2, return pointer to null in str2.
                    254:  */
                    255: 
                    256: char *
                    257: copy(str1, str2)
                    258:        char *str1, *str2;
                    259: {
                    260:        register char *s1, *s2;
                    261: 
                    262:        s1 = str1;
                    263:        s2 = str2;
                    264:        while (*s1)
                    265:                *s2++ = *s1++;
                    266:        *s2 = 0;
                    267:        return(s2);
                    268: }
                    269: 
                    270: /*
                    271:  * Is ch any of the characters in str?
                    272:  */
                    273: 
                    274: any(ch, str)
                    275:        char *str;
                    276: {
                    277:        register char *f;
                    278:        register c;
                    279: 
                    280:        f = str;
                    281:        c = ch;
                    282:        while (*f)
                    283:                if (c == *f++)
                    284:                        return(1);
                    285:        return(0);
                    286: }
                    287: 
                    288: /*
                    289:  * Convert lower case letters to upper case.
                    290:  */
                    291: 
                    292: raise(c)
                    293:        register int c;
                    294: {
                    295:        if (c >= 'a' && c <= 'z')
                    296:                c += 'A' - 'a';
                    297:        return(c);
                    298: }

unix.superglobalmegacorp.com

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