1: /* mhmail.c - simple mail program */ 2: 3: #include "../h/mh.h" 4: #include <stdio.h> 5: #include <signal.h> 6: 7: /* */ 8: 9: static struct swit switches[] = { 10: #define BODYSW 0 11: "body text", 0, 12: 13: #define CCSW 1 14: "cc addrs ...", 0, 15: 16: #define FROMSW 2 17: "from addr", 0, 18: 19: #define SUBJSW 3 20: "subject", 0, 21: 22: #define HELPSW 4 23: "help", 4, 24: 25: NULL, NULL 26: }; 27: 28: /* */ 29: 30: int intrser (); 31: 32: 33: static char tmpfil[BUFSIZ]; 34: 35: /* */ 36: 37: /* ARGSUSED */ 38: 39: main (argc, argv) 40: int argc; 41: char *argv[]; 42: { 43: int child_id, 44: status, 45: i, 46: iscc = 0, 47: somebody; 48: char *cp, 49: *tolist = NULL, 50: *cclist = NULL, 51: *subject = NULL, 52: *from = NULL, 53: *body = NULL, 54: **argp = argv + 1, 55: buf[100]; 56: FILE * out; 57: 58: invo_name = r1bindex (argv[0], '/'); 59: m_foil (NULLCP); 60: 61: if (argc == 1) { 62: execlp (incproc, r1bindex (incproc, '/'), NULLCP); 63: adios (incproc, "unable to exec"); 64: } 65: 66: /* */ 67: 68: while (cp = *argp++) { 69: if (*cp == '-') 70: switch (smatch (++cp, switches)) { 71: case AMBIGSW: 72: ambigsw (cp, switches); 73: done (1); 74: 75: case UNKWNSW: 76: adios (NULLCP, "-%s unknown", cp); 77: 78: case HELPSW: 79: (void) sprintf (buf, "%s [addrs ... [switches]]", 80: invo_name); 81: help (buf, switches); 82: done (1); 83: 84: case FROMSW: 85: if (!(from = *argp++) || *from == '-') 86: adios (NULLCP, "missing argument to %s", argp[-2]); 87: continue; 88: 89: case BODYSW: 90: if (!(body = *argp++) || *body == '-') 91: adios (NULLCP, "missing argument to %s", argp[-2]); 92: continue; 93: 94: case CCSW: 95: iscc++; 96: continue; 97: 98: case SUBJSW: 99: if (!(subject = *argp++) || *subject == '-') 100: adios (NULLCP, "missing argument to %s", argp[-2]); 101: continue; 102: } 103: if (iscc) 104: cclist = cclist ? add (cp, add (", ", cclist)) : getcpy (cp); 105: else 106: tolist = tolist ? add (cp, add (", ", tolist)) : getcpy (cp); 107: } 108: 109: /* */ 110: 111: (void) strcpy (tmpfil, m_tmpfil (invo_name)); 112: if ((out = fopen (tmpfil, "w")) == NULL) 113: adios (tmpfil, "unable to write"); 114: (void) chmod (tmpfil, 0600); 115: 116: setsig (SIGINT, intrser); 117: 118: fprintf (out, "To: %s\n", tolist); 119: if (cclist) 120: fprintf (out, "cc: %s\n", cclist); 121: if (subject) 122: fprintf (out, "Subject: %s\n", subject); 123: if (from) 124: fprintf (out, "From: %s\n", from); 125: fprintf (out, "\n"); 126: 127: if (body) 128: fprintf (out, "%s\n", body); 129: else { 130: for (somebody = 0; 131: (i = read (fileno (stdin), buf, sizeof buf)) > 0; 132: somebody++) 133: if (fwrite (buf, sizeof *buf, i, out) != i) 134: adios (tmpfil, "error writing"); 135: if (!somebody) { 136: (void) unlink (tmpfil); 137: done (1); 138: } 139: } 140: (void) fclose (out); 141: 142: /* */ 143: 144: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) 145: sleep (5); 146: switch (child_id) { 147: case NOTOK: /* report failure and then send it */ 148: admonish (NULLCP, "unable to fork"); 149: 150: case OK: 151: execlp (postproc, r1bindex (postproc, '/'), tmpfil, NULLCP); 152: fprintf (stderr, "unable to exec "); 153: perror (postproc); 154: _exit (-1); 155: 156: default: 157: if (status = pidXwait (child_id, postproc)) { 158: fprintf (stderr, "Letter saved in dead.letter\n"); 159: execl ("/bin/mv", "mv", tmpfil, "dead.letter", NULLCP); 160: execl ("/usr/bin/mv", "mv", tmpfil, "dead.letter", NULLCP); 161: perror ("mv"); 162: _exit (-1); 163: } 164: 165: (void) unlink (tmpfil); 166: done (status ? 1 : 0); 167: } 168: } 169: 170: /* */ 171: 172: /* ARGSUSED */ 173: 174: static int intrser (i) 175: int i; 176: { 177: #ifndef BSD42 178: if (i) 179: (void) signal (i, SIG_IGN); 180: #endif BSD42 181: 182: (void) unlink (tmpfil); 183: done (i != 0 ? 1 : 0); 184: }