Annotation of 3BSD/cmd/ucbmail/head.c, revision 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.