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

unix.superglobalmegacorp.com

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