Annotation of researchv10no/cmd/nupas/print/message.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <regexp.h>
                      3: #include <signal.h>
                      4: #include "mail.h"
                      5: #include "string.h"
                      6: #include "message.h"
                      7: #include "aux.h"
                      8: #include <sys/stat.h>
                      9: 
                     10: /* imported */
                     11: extern char *malloc();
                     12: extern long time();
                     13: FILE *lockopen();
                     14: FILE *lockreopen();
                     15: 
                     16: /* definition of UNIX message headers */
                     17: 
                     18: #define MSGALLOC 32
                     19: 
                     20: typedef struct {
                     21:        message m[MSGALLOC];
                     22:        int o;
                     23: } msgalloc;
                     24: static msgalloc *freep=NULL;
                     25: 
                     26: /* read in a message, interpret the 'From' header */
                     27: extern message *
                     28: m_get(sp)
                     29:        string *sp;
                     30: {
                     31:        message *mp;
                     32:        register char *cp;
                     33: 
                     34:        if (freep==NULL || freep->o >= MSGALLOC) {
                     35:                freep = (msgalloc *)malloc(sizeof(msgalloc));
                     36:                if (freep==NULL) {
                     37:                        perror("allocating message");
                     38:                        exit(1);
                     39:                }
                     40:                freep->o = 0;
                     41:        }
                     42:        mp = &(freep->m[freep->o++]);
                     43:        mp->body = NULL;
                     44:        mp->sender = s_new();
                     45:        mp->date = s_new();
                     46:        mp->extent = mp->prev = mp->next = NULL;
                     47:        mp->status = 0;
                     48:        mp->pos = 0;
                     49: 
                     50:        if (sp->ptr >= sp->end) {
                     51:                mzero = mp;
                     52:                return NULL;
                     53:        }
                     54: 
                     55:        /* parse From lines */
                     56:        for(cp=sp->ptr; *cp=='\n'||*cp==' '||*cp=='\t'; cp++);
                     57:        for(sp->ptr=cp; *cp != '\n' && *cp; cp++);
                     58:        *cp = '\0';
                     59:        if (parse_header(sp->ptr, mp->sender, mp->date)<0) {
                     60:                fprintf(stderr, "!mailbox format incorrect\n");
                     61:                mzero = mp;
                     62:                return NULL;
                     63:        }
                     64:        *cp++ = '\n';
                     65:        sp->ptr = cp;
                     66: 
                     67:        /* get body */
                     68:        while (cp < sp->end && !IS_HEADER(cp)) {
                     69:                while (*cp++ != '\n')
                     70:                        ;
                     71:        }
                     72:        cp[-1] = '\0';
                     73: 
                     74:        mp->size = cp - sp->ptr;
                     75:        mp->body = s_array(sp->ptr, mp->size);
                     76:        sp->ptr = cp;
                     77:        return mp;
                     78: }
                     79: 
                     80: /* output a message, return 0 if ok -1 otherwise */
                     81: extern int
                     82: m_print(mp, fp, nl, header)
                     83:        message *mp;    /* the message */
                     84:        FILE *fp;       /* where to print it */
                     85: {
                     86:        SIG_TYP pstat;
                     87:        int rv = 0;
                     88: 
                     89:        pstat = signal(SIGPIPE, SIG_IGN);
                     90:        if (header)
                     91:                print_header(fp, s_to_c(mp->sender), s_to_c(mp->date));
                     92:        fflush(fp);
                     93: 
                     94:        /*
                     95:         *  the following are writes instead of an fwrites because,
                     96:         *  in the case of a broken pipe, fwrite will continuously
                     97:         *  generate SIGPIPE's.  Enough SIGPIPE's will terminate the
                     98:         *  process despite the SIG_IGN (at least on v9).
                     99:         */
                    100:        if (mp->size > 0)
                    101:                if(write(fileno(fp), s_to_c(mp->body), mp->size-1) != mp->size-1)
                    102:                        rv = -1;
                    103:        if (rv==0 && nl)
                    104:                if(write(fileno(fp), "\n", 1) != 1)
                    105:                        rv = -1;
                    106: 
                    107:        signal(SIGPIPE, pstat);
                    108:        return ferror(fp) ? -1 : rv;
                    109: }
                    110: 
                    111: /* lists of mail messages */
                    112: message *mzero;                /* zeroth message */
                    113: message *mlist;                /* first mail message */
                    114: message *mlast;                /* last mail message */
                    115: 
                    116: long mbsize;           /* last size of mail box */
                    117: 
                    118: 
                    119: /* 
                    120:  *  read in the mail file.  mbsize is the spot to start reading from.
                    121:  *  if fpp is non-zero then don't close the locked fmailbox, just
                    122:  *  return the file pointer to it.
                    123:  */
                    124: static FILE *
                    125: rd_mbox(file, reverse, newmail, fp)
                    126:        char *file;
                    127:        int reverse;
                    128:        FILE *fp;
                    129: {
                    130:        message *mp;
                    131:        int pos = 0;
                    132:        struct stat sbuf;
                    133:        string *line;
                    134:        char *corefile;
                    135:        int len;
                    136: 
                    137:        if(fp==NULL)
                    138:                fp = lockopen(file, "r", 0, -1, -1);
                    139:        if(fp==NULL)
                    140:                return NULL;
                    141:        if (stat(file, &sbuf) < 0){
                    142:                lockclose(fp);
                    143:                return NULL;
                    144:        }
                    145:        if (sbuf.st_size <= mbsize)
                    146:                return fp;
                    147:        fseek(fp, mbsize, 0);
                    148:        len = sbuf.st_size-mbsize;
                    149:        corefile = malloc(len+1);
                    150:        if (corefile == NULL || fread(corefile, len, 1, fp)!=1) {
                    151:                perror("reading mbox");
                    152:                exit(1);
                    153:        }
                    154:        corefile[len-1] = '\n';         /* ensure last mbox char is \n */
                    155:        corefile[len] = '\0';           /* ensure null termination */
                    156:        line = s_array(corefile, len);
                    157:        if (mbsize==0) {
                    158:                switch(delivery_status(s_restart(line))) {
                    159:                case MF_PIPE:
                    160:                        printf("mail: mail is being piped to %s\n", line->ptr);
                    161:                        lockclose(fp);
                    162:                        return NULL;
                    163:                case MF_FORWARD:
                    164:                        printf("mail: mail is being forwarded to %s\n", line->ptr);
                    165:                        lockclose(fp);
                    166:                        return NULL;
                    167:                }
                    168:        }
                    169:        s_restart(line);
                    170:        while((mp = m_get(line)) != NULL) {
                    171:                if (mlist == NULL)
                    172:                        mlist = mlast = mp;
                    173:                else if (reverse) {
                    174:                        mlast->next = mp;
                    175:                        mp->prev = mlast;
                    176:                        mlast = mp;
                    177:                } else {
                    178:                        mp->next = mlist;
                    179:                        mlist->prev = mp;
                    180:                        mlist = mp;
                    181:                }
                    182:        }
                    183:        if (mlist==NULL)
                    184:                return fp;
                    185:        mzero->next = mlist;
                    186:        mzero->prev = mlast;
                    187:        for (mp=mzero; mp!=NULL; mp=mp->next)
                    188:                mp->pos=pos++;
                    189:        mbsize = sbuf.st_size;
                    190:        if (newmail)
                    191:                printf("mail: new message arrived\n");
                    192:        return fp;
                    193: }
                    194: 
                    195: /* read the mailbox */
                    196: extern int
                    197: read_mbox(file, reverse)
                    198:        char *file;
                    199:        int reverse;
                    200: {
                    201:        FILE *fp;
                    202:        SIG_TYP fhup, fint, fquit;
                    203: 
                    204:        fhup = signal(SIGHUP, SIG_IGN);
                    205:        fint = signal(SIGINT, SIG_IGN);
                    206:        fquit = signal(SIGQUIT, SIG_IGN);
                    207:        fp = rd_mbox(file, reverse, 0, NULL);
                    208:        if(fp!=NULL)
                    209:                lockclose(fp);
                    210:        signal(SIGHUP, fhup);
                    211:        signal(SIGINT, fint);
                    212:        signal(SIGQUIT, fquit);
                    213:        return fp==NULL ? -1 : 0;
                    214: }
                    215: 
                    216: /* read the mailbox looking for new messages */
                    217: extern int
                    218: reread_mbox(file, reverse)
                    219:        char *file;
                    220:        int reverse;
                    221: {
                    222:        FILE *fp;
                    223:        SIG_TYP fhup, fint, fquit;
                    224: 
                    225:        fhup = signal(SIGHUP, SIG_IGN);
                    226:        fint = signal(SIGINT, SIG_IGN);
                    227:        fquit = signal(SIGQUIT, SIG_IGN);
                    228:        fp = rd_mbox(file, reverse, 1, NULL);
                    229:        if(fp!=NULL)
                    230:                lockclose(fp);
                    231:        signal(SIGHUP, fhup);
                    232:        signal(SIGINT, fint);
                    233:        signal(SIGQUIT, fquit);
                    234:        return fp==NULL ? -1 : 0;
                    235: }
                    236: 
                    237: /* read any changes from the mailbox and write out the result */
                    238: rdwr_mbox(file, reverse)
                    239:        char *file;
                    240: {
                    241:        int rv, err;
                    242:        FILE *fp;
                    243:        message *mp;
                    244: 
                    245:        /*
                    246:         *  if nothing has changed, just return
                    247:         */
                    248:        for (mp=mlist; mp!=NULL; mp=mp->next)
                    249:                if (mp->status&DELETED)
                    250:                        break;
                    251:        if (mp==NULL)
                    252:                return 0;
                    253: 
                    254:        /*
                    255:         *  read mailbox to pick up any changes
                    256:         */
                    257:        fp = NULL;
                    258:        if((fp=rd_mbox(file, reverse, 1, NULL)) == NULL){
                    259:                fprintf(stderr, "mail: can't write mail file %s\n", file);
                    260:                return 1;
                    261:        }
                    262: 
                    263:        /*
                    264:         *  now rewrite it.  use the fp passed back from read_mbox to
                    265:         *  maintain the lock across both operations.
                    266:         */
                    267:        if(fp==NULL)
                    268:                fp = lockopen(file, "w", 0, -1, -1);
                    269:        else
                    270:                fp = lockreopen(file, "w", fp);
                    271:        if (fp == NULL) {
                    272:                fprintf(stderr, "mail: can't write mail file %s\n", file);
                    273:                return 1;
                    274:        } else {
                    275:                rv = 0;
                    276:                mlist->prev = NULL;     /* ignore mzero */
                    277:                err = 0;
                    278:                for(mp=reverse?mlist:mlast; mp!=NULL; mp=reverse?mp->next:mp->prev)
                    279:                        if ((mp->status&DELETED)==0)
                    280:                                err += m_print(mp, fp, 1, 1);
                    281:                if (err < 0) {
                    282:                        fprintf(stderr,"mail: error writing mail file %s\n", file);
                    283:                        rv = 1;
                    284:                }
                    285:                lockclose(fp);
                    286:        }
                    287:        return rv;
                    288: }
                    289: 
                    290: /* write out the mail file */
                    291: extern int
                    292: write_mbox(file, reverse)
                    293:        char *file;
                    294:        int reverse;
                    295: {
                    296:        SIG_TYP fhup, fint, fquit;
                    297:        int rv;
                    298: 
                    299:        fhup = signal(SIGHUP, SIG_IGN);
                    300:        fint = signal(SIGINT, SIG_IGN);
                    301:        fquit = signal(SIGQUIT, SIG_IGN);
                    302:        rv = rdwr_mbox(file, reverse);
                    303:        signal(SIGHUP, fhup);
                    304:        signal(SIGINT, fint);
                    305:        signal(SIGQUIT, fquit);
                    306:        return rv;
                    307: }
                    308: 
                    309: /* imported */
                    310: extern char *getenv();
                    311: extern int getpid();
                    312: 
                    313: /* global to semaphores */
                    314: static char semaphore[128];
                    315: 
                    316: extern void
                    317: V()
                    318: {
                    319:        unlink(semaphore);
                    320: }
                    321: 
                    322: /* return name of tty if file is already being read, NULL otherwise */
                    323: extern int
                    324: P()
                    325: {
                    326:        char file[128];
                    327:        struct stat sbuf;
                    328:        FILE *fp;
                    329:        int pid;
                    330:        char *home = getenv("HOME");
                    331: 
                    332:        if (home == NULL)
                    333:                return 0;
                    334:        (void)strcpy(file, home);
                    335:        (void)strcat(file, "/.Maillock");
                    336:        if (stat(file, &sbuf) >= 0) {
                    337: 
                    338:                /* lock file exists */
                    339:                fp = fopen(file, "r");
                    340:                if (fp != NULL) {
                    341:                        fscanf(fp, "%d", &pid);
                    342:                        fclose(fp);
                    343:                }
                    344:                if (fp == NULL || kill(pid, 0)==0) {
                    345:                        fprintf(stderr,"WARNING: You are already reading mail.\n");
                    346:                        fprintf(stderr, "\tThis instance of mail is read only.\n");
                    347:                        return -1;
                    348:                }
                    349:        }
                    350: 
                    351:        /* create a semaphore file */
                    352:        strcpy(semaphore, file);
                    353:        V();
                    354:        fp = fopen(semaphore, "w");
                    355:        if (fp == NULL)
                    356:                return 0;               /* nothing else we can do */
                    357:        fprintf(fp, "%d somewhere", getpid());
                    358:        fclose(fp);
                    359:        return 0;
                    360: }

unix.superglobalmegacorp.com

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