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