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