Annotation of researchv10no/cmd/upas/send/message.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <regexp.h>
        !             3: #include <signal.h>
        !             4: #include <pwd.h>
        !             5: #include "mail.h"
        !             6: #include "string.h"
        !             7: #include "message.h"
        !             8: #include "aux.h"
        !             9: 
        !            10: /* imported */
        !            11: extern char *malloc();
        !            12: extern long time();
        !            13: extern char *ctime();
        !            14: extern char *getlog();
        !            15: extern void exit();
        !            16: extern char *thedate();
        !            17: 
        !            18: /* global to this file */
        !            19: static regexp *rfprog;
        !            20: static regexp *fprog;
        !            21: static pipe_err=0;
        !            22: 
        !            23: #define VMLIMIT (64*1024)
        !            24: #define MSGLIMIT (5*1024*1024)
        !            25: 
        !            26: extern void
        !            27: default_from(mp)
        !            28:        message *mp;
        !            29: {
        !            30:        char *logname;
        !            31:        struct passwd *pw;
        !            32:        extern struct passwd *getpwuid();
        !            33:        extern char *getenv();
        !            34: 
        !            35:        /* add in date and sender */
        !            36:        if ((logname=getenv("upasname")) == NULL) {
        !            37:                if ((logname=getlog()) == NULL)
        !            38:                        logname = "Liz.Bimmler";
        !            39:        }
        !            40:        s_append(mp->sender, logname);
        !            41:        s_append(mp->date, thedate());
        !            42: }
        !            43: 
        !            44: extern message *
        !            45: m_new()
        !            46: {
        !            47:        message *mp;
        !            48: 
        !            49:        mp = (message *)malloc(sizeof(message));
        !            50:        if (mp == NULL) {
        !            51:                perror("message:");
        !            52:                exit(1);
        !            53:        }
        !            54:        mp->sender = s_new();
        !            55:        mp->replyaddr = s_new();
        !            56:        mp->date = s_new();
        !            57:        mp->body = s_new();
        !            58:        mp->size = 0;
        !            59:        mp->fd = -1;
        !            60:        return mp;
        !            61: }
        !            62: 
        !            63: extern int
        !            64: m_free(mp)
        !            65:        message *mp;
        !            66: {
        !            67:        if(mp->fd >= 0)
        !            68:                close(mp->fd);
        !            69:        s_free(mp->sender);
        !            70:        s_free(mp->date);
        !            71:        s_free(mp->body);
        !            72:        free((char *)mp);
        !            73: }
        !            74: 
        !            75: /* read a message into a temp file , return an open fd to it */
        !            76: static int
        !            77: m_read_to_file(fp, mp)
        !            78:        FILE *fp;
        !            79:        message *mp;
        !            80: {
        !            81:        int cfd, fd;
        !            82:        int n;
        !            83:        char buf[4*1024];
        !            84: 
        !            85:        /*
        !            86:         *  create and unlink temp file
        !            87:         */
        !            88:        strcpy(buf, MAILROOT);
        !            89:        strcat(buf, "mtXXXXXX");
        !            90:        mktemp(buf);
        !            91:        if((cfd = creat(buf, 0600))<0)
        !            92:                return -1;
        !            93:        if((fd = open(buf, 2))<0){
        !            94:                unlink(buf);
        !            95:                close(cfd);
        !            96:                return -1;
        !            97:        }
        !            98:        close(cfd);
        !            99:        unlink(buf);
        !           100: 
        !           101:        /*
        !           102:         *  read the rest into the temp file
        !           103:         */
        !           104:        while((n = fread(buf, 1, sizeof buf, fp)) > 0){
        !           105:                if(write(fd, buf, n) != n){
        !           106:                        close(fd);
        !           107:                        return -1;
        !           108:                }
        !           109:                mp->size += n;
        !           110:                if(mp->size > MSGLIMIT){
        !           111:                        mp->size = -1;
        !           112:                        break;
        !           113:                }
        !           114:        }
        !           115: 
        !           116:        mp->fd = fd;
        !           117:        return 0;
        !           118: }
        !           119: 
        !           120: /* read in a message, interpret the 'From' header */
        !           121: extern message *
        !           122: m_read(fp, rmail, onatty)
        !           123:        FILE *fp;
        !           124:        int rmail;      /* true if invoked as /bin/rmail */
        !           125:        int onatty;     /* true if input from a terminal */
        !           126: {
        !           127:        message *mp;
        !           128:        regsubexp subexp[10];
        !           129:        int first;
        !           130: 
        !           131:        mp = m_new();
        !           132: 
        !           133:        /* parse From lines */
        !           134:        if (rmail) {
        !           135:                /* get remote address */
        !           136:                string *sender=s_new();
        !           137: 
        !           138:                if (rfprog == NULL)
        !           139:                        rfprog = regcomp(REMFROMRE);
        !           140:                first = 1;
        !           141:                while(s_read_line(fp, s_restart(mp->body)) != NULL) {
        !           142:                        if (regexec(rfprog, s_to_c(mp->body), subexp, 10) == 0){
        !           143:                                if(first == 0)
        !           144:                                        break;
        !           145:                                if (fprog == NULL)
        !           146:                                        fprog = regcomp(FROMRE);
        !           147:                                if(regexec(fprog, s_to_c(mp->body), subexp,10) == 0)
        !           148:                                        break;
        !           149:                                s_restart(mp->body);
        !           150:                                append_match(subexp, s_restart(sender), SENDERMATCH);
        !           151:                                append_match(subexp, s_restart(mp->date), DATEMATCH);
        !           152:                                break;
        !           153:                        }
        !           154:                        append_match(subexp, s_restart(sender), REMSENDERMATCH);
        !           155:                        append_match(subexp, s_restart(mp->date), REMDATEMATCH);
        !           156:                        if(subexp[REMSYSMATCH].sp!=subexp[REMSYSMATCH].ep){
        !           157:                                append_match(subexp, mp->sender, REMSYSMATCH);
        !           158:                                s_append(mp->sender, "!");
        !           159:                        }
        !           160:                        first = 0;
        !           161:                }
        !           162:                s_append(mp->sender, s_to_c(sender));
        !           163:                s_free(sender);
        !           164:        }
        !           165:        if (*s_to_c(mp->sender)=='\0')
        !           166:                default_from(mp);
        !           167: 
        !           168:        /* get body */
        !           169:        if(onatty){
        !           170:                /* user typing on terminal: terminator == '.' or EOF */
        !           171:                for(;;) {
        !           172:                        char *line;
        !           173: 
        !           174:                        if ((line=s_read_line(fp, mp->body))==NULL)
        !           175:                                break;
        !           176:                        if (strcmp(".\n", line)==0) {
        !           177:                                *line = '\0';
        !           178:                                mp->body->ptr = line;
        !           179:                                break;
        !           180:                        }
        !           181:                }
        !           182:                mp->size = mp->body->ptr - mp->body->base;
        !           183:        } else {
        !           184:                /*
        !           185:                 *  read up to VMLIMIT bytes (more or less).
        !           186:                 *  if message is longer use temp file
        !           187:                 */
        !           188:                mp->size = s_read_to_lim(fp, mp->body, VMLIMIT);
        !           189:                if(mp->size < 0){
        !           190:                        mp->size = -mp->size;
        !           191:                        if(m_read_to_file(fp, mp) < 0){
        !           192:                                perror("m_read");
        !           193:                                exit(1);
        !           194:                        }
        !           195:                }
        !           196:        }
        !           197: 
        !           198:        /*
        !           199:         *  ignore 0 length messages from a terminal
        !           200:         */
        !           201:        if (!rmail && *s_to_c(mp->body) == '\0')
        !           202:                return NULL;
        !           203: 
        !           204:        return mp;
        !           205: }
        !           206: 
        !           207: SIGRETURN
        !           208: sigpipe(s)
        !           209:        int s;
        !           210: {
        !           211:        signal(SIGPIPE, sigpipe);
        !           212:        pipe_err = -1;
        !           213: }
        !           214: 
        !           215: /* return a piece of message starting at `offset' */
        !           216: extern int
        !           217: m_get(mp, offset, pp)
        !           218:        message *mp;
        !           219:        long offset;
        !           220:        char **pp;
        !           221: {
        !           222:        static char buf[4*1024];
        !           223: 
        !           224:        /*
        !           225:         *  are we past eof?
        !           226:         */
        !           227:        if(offset >= mp->size)
        !           228:                return 0;
        !           229: 
        !           230:        /*
        !           231:         *  are we in the virtual memory portion?
        !           232:         */
        !           233:        if(offset < mp->body->ptr - mp->body->base){
        !           234:                *pp = mp->body->base + offset;
        !           235:                return mp->body->ptr - mp->body->base - offset;
        !           236:        }
        !           237: 
        !           238:        /*
        !           239:         *  read it from the temp file
        !           240:         */
        !           241:        offset -= mp->body->ptr - mp->body->base;
        !           242:        if(mp->fd < 0)
        !           243:                return -1;
        !           244:        if(lseek(mp->fd, offset, 0)<0)
        !           245:                return -1;
        !           246:        *pp = buf;
        !           247:        return read(mp->fd, buf, sizeof buf);
        !           248: }
        !           249: 
        !           250: /* output the message body without ^From escapes */
        !           251: static int
        !           252: m_noescape(mp, fp)
        !           253:        message *mp;    /* the message */
        !           254:        FILE *fp;       /* where to print it */
        !           255: {
        !           256:        long offset;
        !           257:        int n;
        !           258:        char *p;
        !           259: 
        !           260:        for(offset = 0; offset < mp->size; offset += n){
        !           261:                n = m_get(mp, offset, &p);
        !           262:                if(n < 0){
        !           263:                        fflush(fp);
        !           264:                        return -1;
        !           265:                }
        !           266:                fwrite(p, n, 1, fp);
        !           267:        }
        !           268:        fflush(fp);
        !           269:        return 0;
        !           270: }
        !           271: 
        !           272: /*
        !           273:  *  output the message body with ^From escapes.  The state machine
        !           274:  *  ensures that any line starting with a 'From ' gets a '>' stuck
        !           275:  *  in front of it.
        !           276:  */
        !           277: static int
        !           278: m_escape(mp, fp)
        !           279:        message *mp;    /* the message */
        !           280:        FILE *fp;       /* where to print it */
        !           281: {
        !           282:        register char *p;
        !           283:        register char *end;
        !           284:        register int state;
        !           285:        long offset;
        !           286:        int n;
        !           287:        char *start;
        !           288: 
        !           289:        state = 1;
        !           290:        for(offset = 0; offset < mp->size; offset += n){
        !           291:                n = m_get(mp, offset, &start);
        !           292:                if(n < 0){
        !           293:                        fflush(fp);
        !           294:                        return -1;
        !           295:                }
        !           296: 
        !           297:                p = start;
        !           298:                for(end = p+n; p < end; p++){
        !           299:                        switch(state){
        !           300:                        case 1:
        !           301:                                if(*p == 'F'){
        !           302:                                        state = 2;
        !           303:                                        continue;
        !           304:                                }
        !           305:                                state = 0;
        !           306:                                break;
        !           307:                        case 2:
        !           308:                                if(*p == 'r'){
        !           309:                                        state = 3;
        !           310:                                        continue;
        !           311:                                }
        !           312:                                state = 0;
        !           313:                                fputc('F', fp);
        !           314:                                break;
        !           315:                        case 3:
        !           316:                                if(*p == 'o'){
        !           317:                                        state = 4;
        !           318:                                        continue;
        !           319:                                }
        !           320:                                state = 0;
        !           321:                                fputc('F', fp);
        !           322:                                fputc('r', fp);
        !           323:                                break;
        !           324:                        case 4:
        !           325:                                if(*p == 'm'){
        !           326:                                        state = 5;
        !           327:                                        continue;
        !           328:                                }
        !           329:                                state = 0;
        !           330:                                fputc('F', fp);
        !           331:                                fputc('r', fp);
        !           332:                                fputc('o', fp);
        !           333:                                break;
        !           334:                        case 5:
        !           335:                                if(*p == ' ')
        !           336:                                        fputc('>', fp);
        !           337:                                state = 0;
        !           338:                                fputc('F', fp);
        !           339:                                fputc('r', fp);
        !           340:                                fputc('o', fp);
        !           341:                                fputc('m', fp);
        !           342:                                break;
        !           343:                        }
        !           344:                        fputc(*p, fp);
        !           345:                        if(*p == '\n')
        !           346:                                state = 1;
        !           347:                }
        !           348:        }
        !           349:        fflush(fp);
        !           350:        return 0;
        !           351: }
        !           352: 
        !           353: /* output a message */
        !           354: extern int
        !           355: m_print(mp, fp, remote, mbox)
        !           356:        message *mp;    /* the message */
        !           357:        FILE *fp;       /* where to print it */
        !           358:        char *remote;   /* 'remote from' string */
        !           359: {
        !           360:        SIG_TYP oldsig;
        !           361:        int err;
        !           362: 
        !           363:        pipe_err = 0;
        !           364:        oldsig = signal(SIGPIPE, sigpipe);
        !           365:        if (remote != NULL)
        !           366:                print_remote_header(fp,s_to_c(mp->sender),s_to_c(mp->date),remote);
        !           367:        else
        !           368:                print_header(fp, s_to_c(mp->sender), s_to_c(mp->date));
        !           369: 
        !           370:        if (!mbox)
        !           371:                err = m_noescape(mp, fp);
        !           372:        else
        !           373:                err = m_escape(mp, fp);
        !           374:        signal(SIGPIPE, oldsig);
        !           375:        if(ferror(fp))
        !           376:                err = -1;
        !           377:        return pipe_err|err;
        !           378: }
        !           379: 
        !           380: /* print just the message body */
        !           381: extern int
        !           382: m_bprint(mp, fp)
        !           383:        message *mp;    /* the message */
        !           384:        FILE *fp;       /* where to print it */
        !           385: {
        !           386:        SIG_TYP oldsig;
        !           387:        int err;
        !           388: 
        !           389:        pipe_err = 0;
        !           390:        oldsig = signal(SIGPIPE, sigpipe);
        !           391:        err = m_noescape(mp, fp);
        !           392:        signal(SIGPIPE, oldsig);
        !           393:        if(ferror(fp))
        !           394:                err = -1;
        !           395:        return pipe_err|err;
        !           396: }

unix.superglobalmegacorp.com

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