Annotation of 42BSD/ucb/Mail/head.c, revision 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.