|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.