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