Annotation of researchv10no/cmd/upas/smtp/header.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <ctype.h>
        !             3: #include "mail.h"
        !             4: #include "string.h"
        !             5: #include "header.h"
        !             6: #include "aux.h"
        !             7: #include <regexp.h>
        !             8: 
        !             9: /* imported */
        !            10: extern char *malloc();
        !            11: extern char *strcpy();
        !            12: extern char *strchr();
        !            13: extern int strncmp();
        !            14: extern void exit();
        !            15: 
        !            16: /* predeclared */
        !            17: extern void addheader();
        !            18: extern void addbody();
        !            19: 
        !            20: /* global to this file */
        !            21: static regexp *rfprog;
        !            22: static regexp *fprog;
        !            23: 
        !            24: /* imported */
        !            25: extern int extrafrom;
        !            26: 
        !            27: /*
        !            28:  *     Input header from standard input.  Actually two extra lines are also
        !            29:  *     read, but this is a problem.  Save some header lines in the header
        !            30:  *     array.
        !            31:  */
        !            32: extern
        !            33: getheader(fgetsp, fp)
        !            34:        char *(*fgetsp)();
        !            35:        FILE *fp;
        !            36: {
        !            37:        char buf[4096];
        !            38:        string *line;
        !            39:        string *from=NULL;
        !            40:        string *date=NULL;
        !            41:        char *cp;
        !            42:        header *hp;
        !            43:        int n;
        !            44:  
        !            45:        /*
        !            46:         *  forget any old headers
        !            47:         */
        !            48:        for (hp = hdrs; *(hp->name) != '\0'; hp++)
        !            49:                hp->line = (string *)0;
        !            50: 
        !            51:        /*
        !            52:         *  preload the first line for the parsing below
        !            53:         */
        !            54:        if((*fgetsp)(buf, sizeof buf, fp) == 0)
        !            55:                return ferror(fp) ? -1 : 0;
        !            56: 
        !            57:        /*  If the first line of an rfc822 message
        !            58:         *  is a unix from line, use that to `seed' the From: and
        !            59:         *  Date: fields.
        !            60:         */
        !            61:        if(strncmp(buf, "From ", 5)==0) {
        !            62:                if (getunixfrom(buf, &from, &date)==0) {
        !            63:                        for (hp = hdrs; *(hp->name) != '\0'; hp++) {
        !            64:                                if (STRCMP("UnixFrom:", hp) == 0) {
        !            65:                                        hp->line = from;
        !            66:                                        from = (string *)0;
        !            67:                                        continue;
        !            68:                                };
        !            69:                                if (STRCMP("UnixDate:", hp) == 0) {
        !            70:                                        hp->line = date;
        !            71:                                        date = (string *)0;
        !            72:                                        continue;
        !            73:                                };
        !            74:                        }
        !            75:                        return 0;
        !            76:                }
        !            77:        }
        !            78: 
        !            79:        /* Now get real 822 headers */
        !            80:        while (buf[0] != '\n' && buf[0] != '\0') {
        !            81:                /* gather a multiple line header field */
        !            82:                line = s_new();
        !            83:                do {
        !            84:                        s_append(line, buf);
        !            85:                        if((*fgetsp)(buf, sizeof buf, fp) == 0) {
        !            86:                                if(ferror(fp))
        !            87:                                        return -1;
        !            88:                                *buf = 0;
        !            89:                                break;
        !            90:                        }
        !            91:                } while (*buf==' ' || *buf=='\t');
        !            92: 
        !            93:                /* header lines must contain `:' with no preceding white */
        !            94:                for(cp=s_to_c(line); *cp; cp++)
        !            95:                        if(isspace(*cp) || *cp==':')
        !            96:                                break;
        !            97:                if (*cp != ':') {
        !            98:                        addbody(line);
        !            99:                        break;
        !           100:                }
        !           101: 
        !           102:                /* look for `important' headers */
        !           103:                for (hp = hdrs; *(hp->name) != '\0'; hp++) {
        !           104:                        if (cistrncmp(s_to_c(line), hp->name, hp->size) == 0) {
        !           105:                                hp->line = line;
        !           106:                                break;
        !           107:                        };
        !           108:                }
        !           109:                addheader(line);
        !           110:        }
        !           111:        /* at this point, buf contains a line of the body */
        !           112:        if(buf[0])
        !           113:                addbody(s_copy(buf));
        !           114:        return 0;
        !           115: }
        !           116: 
        !           117: /*
        !           118:  *     Keep a (circular) list of header lines to output.
        !           119:  */
        !           120: typedef struct quux{
        !           121:        struct quux *next;
        !           122:        string *line;
        !           123: } hlist;
        !           124: static hlist dummy = { &dummy, '\0' };
        !           125: static hlist *list = &dummy;
        !           126: 
        !           127: /*
        !           128:  *     Add to list of header lines.
        !           129:  */
        !           130: extern void
        !           131: addheader(line)
        !           132:        string *line;
        !           133: {
        !           134:        hlist *thing;
        !           135: 
        !           136:        thing = (hlist *)malloc(sizeof(hlist));
        !           137:        if (thing == NULL) {
        !           138:                perror("reading header");
        !           139:                exit(1);
        !           140:        }
        !           141:        thing->line = line;
        !           142:        thing->next = list->next;
        !           143:        list->next = thing;
        !           144:        list = thing;
        !           145: }
        !           146: 
        !           147: /*
        !           148:  *     Print list of headers.
        !           149:  */
        !           150: extern int
        !           151: printheaders(fputsp, fp, originalfrom)
        !           152:        FILE *fp;
        !           153:        int (*fputsp)();
        !           154: {
        !           155:        hlist *thing, *othing;
        !           156:        int printed = 0;
        !           157: 
        !           158:        for(thing = list->next->next; thing != &dummy; ){
        !           159:                printed++;
        !           160:                if(originalfrom && strncmp(s_to_c(thing->line), "From:", 5)==0)
        !           161:                        (*fputsp)("Original-", fp);
        !           162:                (*fputsp)(s_to_c(thing->line), fp);
        !           163:                s_free(thing->line);
        !           164:                othing = thing;
        !           165:                thing = thing->next;
        !           166:                free(othing);
        !           167:        }
        !           168:        list = dummy.next = &dummy;     /* reinitialize for future calls */
        !           169:        return(printed);
        !           170: }
        !           171: 
        !           172: /*
        !           173:  *     Keep a (circular) list of body lines to output.
        !           174:  */
        !           175: static hlist bdummy = { &bdummy, '\0' };
        !           176: static hlist *blist = &bdummy;
        !           177: 
        !           178: /*
        !           179:  *     Add to list of body lines.
        !           180:  */
        !           181: extern void
        !           182: addbody(line)
        !           183:        string *line;
        !           184: {
        !           185:        hlist *thing;
        !           186: 
        !           187:        thing = (hlist *)malloc(sizeof(hlist));
        !           188:        if (thing == NULL) {
        !           189:                perror("reading header");
        !           190:                exit(1);
        !           191:        }
        !           192:        thing->line = line;
        !           193:        thing->next = blist->next;
        !           194:        blist->next = thing;
        !           195:        blist = thing;
        !           196: }
        !           197: 
        !           198: /*
        !           199:  *     Print list of body lines
        !           200:  */
        !           201: extern void
        !           202: printbodies(fputsp, fp)
        !           203:        FILE *fp;
        !           204:        int (*fputsp)();
        !           205: {
        !           206:        hlist *thing, *othing;
        !           207:        int line = 0;
        !           208: 
        !           209:        for(thing = blist->next->next; thing != &bdummy; ){
        !           210:                /* dump extraneous new line */
        !           211:                if(line++!=0 || *s_to_c(thing->line)!='\n')
        !           212:                        (*fputsp)(s_to_c(thing->line), fp);
        !           213:                s_free(thing->line);
        !           214:                othing = thing;
        !           215:                thing = thing->next;
        !           216:                free(othing);
        !           217:        }
        !           218:        blist = bdummy.next = &bdummy;
        !           219: }
        !           220: 
        !           221: /*
        !           222:  *  extract sender and date from a unix remote from line.  return -1
        !           223:  *  if its the wrong format, 0 otherwise.
        !           224:  */
        !           225: getunixfrom(line, fpp, dpp)
        !           226:        char *line;
        !           227:        string **fpp;
        !           228:        string **dpp;
        !           229: {              
        !           230:        regsubexp subexp[10];
        !           231: 
        !           232:        if (rfprog == NULL)
        !           233:                rfprog = regcomp(REMFROMRE);
        !           234:        if (regexec(rfprog, line, subexp, 10)) {
        !           235:                *fpp = s_new();
        !           236:                append_match(subexp, *fpp, REMSYSMATCH);
        !           237:                s_append(*fpp, "!");
        !           238:                append_match(subexp, *fpp, REMSENDERMATCH);
        !           239:                *dpp = s_new();
        !           240:                append_match(subexp, *dpp, REMDATEMATCH);
        !           241:                return 0;
        !           242:        }
        !           243:        if (fprog == NULL)
        !           244:                fprog = regcomp(FROMRE);
        !           245:        if (regexec(fprog, line, subexp, 10)) {
        !           246:                *fpp = s_new();
        !           247:                append_match(subexp, *fpp, SENDERMATCH);
        !           248:                *dpp = s_new();
        !           249:                append_match(subexp, *dpp, DATEMATCH);
        !           250:                return 0;
        !           251:        }
        !           252:        return -1;
        !           253: }
        !           254: 
        !           255: /*
        !           256:  *  The addr is either the first whitespace delimited token or
        !           257:  *  the first thing enclosed in "<" ">".
        !           258:  *  Sets extrafrom > 0 if a from line with other cruft in it.
        !           259:  */
        !           260: extern string *
        !           261: getaddr(line)
        !           262:        char *line;
        !           263: {
        !           264:        register char *lp;
        !           265:        register int comment = 0;
        !           266:        register int anticomment = 0;
        !           267:        register int inquote = 0;
        !           268:        static string *sender=0;
        !           269: 
        !           270:        if (!sender)
        !           271:                sender = s_new();
        !           272:        s_restart(sender);
        !           273:        lp = line;
        !           274:        for (; *lp; lp++) {
        !           275:                if (comment) {
        !           276:                        if (*lp=='(')
        !           277:                                comment++;
        !           278:                        if (*lp==')')
        !           279:                                comment--;
        !           280:                        continue;
        !           281:                }
        !           282:                if (anticomment) {
        !           283:                        if (*lp=='>') {
        !           284:                                if (*(lp+1)!='\n')
        !           285:                                        extrafrom++;
        !           286:                                break;
        !           287:                        }
        !           288:                }
        !           289:                if (inquote) {
        !           290:                        if (*lp=='"')
        !           291:                                inquote = 0;
        !           292:                        s_putc(sender, *lp);
        !           293:                        continue;
        !           294:                }
        !           295:                switch (*lp) {
        !           296:                case '\t':
        !           297:                case '\n':
        !           298:                        break;
        !           299:                case ' ':
        !           300:                        if (cistrncmp(lp, " at ", sizeof(" at ")-1)==0) {
        !           301:                                s_putc(sender, '@');
        !           302:                                lp += sizeof(" at ")-2;
        !           303:                        }
        !           304:                        break;
        !           305:                case '<':
        !           306:                        anticomment = 1;
        !           307:                        if(*s_to_c(sender)!='\0')
        !           308:                                extrafrom++;
        !           309:                        s_restart(sender);
        !           310:                        break;
        !           311:                case '(':
        !           312:                        extrafrom++;
        !           313:                        comment++;
        !           314:                        break;
        !           315:                case '"':
        !           316:                        inquote = 1;
        !           317:                        /* fall through */
        !           318:                default:
        !           319:                        s_putc(sender, *lp);
        !           320:                        break;
        !           321:                }
        !           322:        }
        !           323:        s_terminate(sender);
        !           324:        s_restart(sender);
        !           325:        return(sender);
        !           326: }
        !           327: 
        !           328: /*
        !           329:  *  case independent string compare
        !           330:  */
        !           331: extern int
        !           332: cistrncmp(s1, s2, n)
        !           333:        char *s1;
        !           334:        char *s2;
        !           335: {
        !           336:        int c1, c2;
        !           337: 
        !           338:        for(; *s1 && n>0; n--, s1++, s2++){
        !           339:                c1 = isupper(*s1) ? tolower(*s1) : *s1;
        !           340:                c2 = isupper(*s2) ? tolower(*s2) : *s2;
        !           341:                if (c1 != c2)
        !           342:                        return -1;
        !           343:        }
        !           344:        return(0);
        !           345: }

unix.superglobalmegacorp.com

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