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

unix.superglobalmegacorp.com

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