|
|
1.1 ! root 1: # ! 2: ! 3: #include "rcv.h" ! 4: ! 5: /* ! 6: * Mail -- a mail program ! 7: * ! 8: * Mail to others. ! 9: */ ! 10: ! 11: /* ! 12: * Send message described by the passed pointer to the ! 13: * passed output buffer. Return -1 on error, but normally ! 14: * the number of lines written. ! 15: */ ! 16: ! 17: send(mailp, obuf) ! 18: struct message *mailp; ! 19: FILE *obuf; ! 20: { ! 21: register struct message *mp; ! 22: register int t; ! 23: unsigned int c; ! 24: FILE *ibuf; ! 25: int lc; ! 26: ! 27: mp = mailp; ! 28: ibuf = setinput(mp); ! 29: c = msize(mp); ! 30: lc = 0; ! 31: while (c-- > 0) { ! 32: putc(t = getc(ibuf), obuf); ! 33: if (t == '\n') ! 34: lc++; ! 35: if (ferror(obuf)) ! 36: return(-1); ! 37: } ! 38: return(lc); ! 39: } ! 40: ! 41: /* ! 42: * Interface between the argument list and the mail1 routine ! 43: * which does all the dirty work. ! 44: */ ! 45: ! 46: mail(people) ! 47: char **people; ! 48: { ! 49: register char *cp2; ! 50: register int s; ! 51: char *buf, **ap; ! 52: struct header head; ! 53: ! 54: for (s = 0, ap = people; *ap != (char *) -1; ap++) ! 55: s += strlen(*ap) + 1; ! 56: buf = salloc(s+1); ! 57: cp2 = buf; ! 58: for (ap = people; *ap != (char *) -1; ap++) { ! 59: cp2 = copy(*ap, cp2); ! 60: *cp2++ = ' '; ! 61: } ! 62: if (cp2 != buf) ! 63: cp2--; ! 64: *cp2 = '\0'; ! 65: head.h_to = buf; ! 66: head.h_subject = NOSTR; ! 67: head.h_cc = NOSTR; ! 68: head.h_bcc = NOSTR; ! 69: head.h_seq = 0; ! 70: mail1(&head); ! 71: return(0); ! 72: } ! 73: ! 74: ! 75: /* ! 76: * Send mail to a bunch of user names. The interface is through ! 77: * the mail routine below. ! 78: */ ! 79: ! 80: sendmail(str) ! 81: char *str; ! 82: { ! 83: register char **ap; ! 84: char *bufp; ! 85: register int t; ! 86: struct header head; ! 87: ! 88: if (blankline(str)) ! 89: head.h_to = NOSTR; ! 90: else ! 91: head.h_to = str; ! 92: head.h_subject = NOSTR; ! 93: head.h_cc = NOSTR; ! 94: head.h_bcc = NOSTR; ! 95: head.h_seq = 0; ! 96: mail1(&head); ! 97: return(0); ! 98: } ! 99: ! 100: /* ! 101: * Mail a message on standard input to the people indicated ! 102: * in the passed header. (Internal interface). ! 103: */ ! 104: ! 105: mail1(hp) ! 106: struct header *hp; ! 107: { ! 108: register char *cp; ! 109: int pid, i, s; ! 110: char **namelist; ! 111: struct name *to; ! 112: FILE *mtf; ! 113: ! 114: /* ! 115: * Collect user's mail from standard input. ! 116: * Get the result as mtf. ! 117: */ ! 118: ! 119: pid = -1; ! 120: if (hp->h_subject == NOSTR) ! 121: hp->h_seq = 0; ! 122: else ! 123: hp->h_seq = 1; ! 124: if ((mtf = collect(hp)) == NULL) ! 125: return(-1); ! 126: if (fsize(mtf) == 0 && hp->h_subject == NOSTR) { ! 127: printf("No message !?!\n"); ! 128: goto out; ! 129: } ! 130: if (intty && value("askcc") != NOSTR) ! 131: grabh(hp, GCC); ! 132: else if (intty) { ! 133: printf("EOT\n"); ! 134: flush(); ! 135: } ! 136: ! 137: /* ! 138: * Now, take the user names from the combined ! 139: * to and cc lists and do all the alias ! 140: * processing. ! 141: */ ! 142: ! 143: senderr = 0; ! 144: to = usermap(cat(extract(hp->h_bcc), ! 145: cat(extract(hp->h_to), extract(hp->h_cc)))); ! 146: if (to == NIL) { ! 147: printf("No recipients specified\n"); ! 148: goto topdog; ! 149: } ! 150: ! 151: /* ! 152: * Look through the recipient list for names with /'s ! 153: * in them which we write to as files directly. ! 154: */ ! 155: ! 156: to = outof(to, mtf, hp); ! 157: rewind(mtf); ! 158: to = verify(to); ! 159: if (senderr) { ! 160: topdog: ! 161: remove(deadletter); ! 162: exwrite(deadletter, mtf, 1); ! 163: rewind(mtf); ! 164: } ! 165: if (to == NIL) ! 166: goto out; ! 167: to = elide(to); ! 168: mechk(to); ! 169: if (count(to) > 1) ! 170: hp->h_seq++; ! 171: if (hp->h_seq > 0) ! 172: if ((mtf = infix(hp, mtf)) == NULL) { ! 173: fprintf(stderr, ". . . message lost, sorry.\n"); ! 174: return(-1); ! 175: } ! 176: namelist = unpack(to); ! 177: if (value("record") != NOSTR) ! 178: savemail(value("record"), hp, mtf, namelist); ! 179: ! 180: /* ! 181: * Wait, to absorb a potential zombie, then ! 182: * fork, set up the temporary mail file as standard ! 183: * input for "mail" and exec with the user list we generated ! 184: * far above. Return the process id to caller in case he ! 185: * wants to await the completion of mail. ! 186: */ ! 187: ! 188: wait(&s); ! 189: rewind(mtf); ! 190: pid = fork(); ! 191: if (pid == -1) { ! 192: perror("fork"); ! 193: remove(deadletter); ! 194: exwrite(deadletter, mtf, 1); ! 195: goto out; ! 196: } ! 197: if (pid == 0) { ! 198: for (i = SIGHUP; i <= SIGQUIT; i++) ! 199: signal(i, SIG_IGN); ! 200: s = fileno(mtf); ! 201: for (i = 3; i < 15; i++) ! 202: if (i != s) ! 203: close(i); ! 204: close(0); ! 205: dup(s); ! 206: close(s); ! 207: #ifdef CC ! 208: submit(getpid()); ! 209: #endif ! 210: execv(MAIL, namelist); ! 211: perror(MAIL); ! 212: exit(1); ! 213: } ! 214: ! 215: out: ! 216: fclose(mtf); ! 217: return(pid); ! 218: } ! 219: ! 220: /* ! 221: * Prepend a header in front of the collected stuff ! 222: * and return the new file. ! 223: */ ! 224: ! 225: FILE * ! 226: infix(hp, fi) ! 227: struct header *hp; ! 228: FILE *fi; ! 229: { ! 230: extern char tempMail[]; ! 231: register FILE *nfo, *nfi; ! 232: register int c; ! 233: ! 234: if ((nfo = fopen(tempMail, "w")) == NULL) { ! 235: perror(tempMail); ! 236: return(fi); ! 237: } ! 238: if ((nfi = fopen(tempMail, "r")) == NULL) { ! 239: perror(tempMail); ! 240: fclose(nfo); ! 241: return(fi); ! 242: } ! 243: remove(tempMail); ! 244: puthead(hp, nfo, GTO|GSUBJECT|GCC); ! 245: c = getc(fi); ! 246: while (c != EOF) { ! 247: putc(c, nfo); ! 248: c = getc(fi); ! 249: } ! 250: fflush(nfo); ! 251: if (ferror(nfo)) { ! 252: perror(tempMail); ! 253: fclose(nfo); ! 254: fclose(nfi); ! 255: return(fi); ! 256: } ! 257: fclose(nfo); ! 258: fclose(fi); ! 259: rewind(nfi); ! 260: return(nfi); ! 261: } ! 262: ! 263: /* ! 264: * Dump the to, subject, cc header on the ! 265: * passed file buffer. ! 266: */ ! 267: ! 268: puthead(hp, fo, w) ! 269: struct header *hp; ! 270: FILE *fo; ! 271: { ! 272: register int gotcha; ! 273: ! 274: gotcha = 0; ! 275: if (hp->h_to != NOSTR && w & GTO) ! 276: fprintf(fo, "To: %s\n", hp->h_to), gotcha++; ! 277: if (hp->h_subject != NOSTR && w & GSUBJECT) ! 278: fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++; ! 279: if (hp->h_cc != NOSTR && w & GCC) ! 280: fprintf(fo, "Cc: %s\n", hp->h_cc), gotcha++; ! 281: if (hp->h_bcc != NOSTR && w & GBCC) ! 282: fprintf(fo, "Bcc: %s\n", hp->h_bcc), gotcha++; ! 283: if (gotcha) ! 284: putc('\n', fo); ! 285: return(0); ! 286: } ! 287: ! 288: /* ! 289: * Save the outgoing mail on the passed file. ! 290: */ ! 291: ! 292: savemail(name, hp, fi, tolist) ! 293: char name[], **tolist; ! 294: struct header *hp; ! 295: FILE *fi; ! 296: { ! 297: register FILE *fo; ! 298: register int c; ! 299: long now; ! 300: ! 301: if ((fo = fopen(name, "a")) == NULL) { ! 302: perror(name); ! 303: return(-1); ! 304: } ! 305: time(&now); ! 306: fprintf(fo, "From %s %s", *(tolist+1), ctime(&now)); ! 307: rewind(fi); ! 308: for (c = getc(fi); c != EOF; c = getc(fi)) ! 309: putc(c, fo); ! 310: fprintf(fo, "\n"); ! 311: fflush(fo); ! 312: if (ferror(fo)) ! 313: perror(name); ! 314: fclose(fo); ! 315: return(0); ! 316: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.