Annotation of 41BSD/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 (!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.