source: trunk/third/nmh/uip/mhmail.c @ 12455

Revision 12455, 4.5 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * mhmail.c -- simple mail program
4 *
5 * $Id: mhmail.c,v 1.1.1.1 1999-02-07 18:14:14 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <h/signals.h>
10#include <signal.h>
11
12static struct swit switches[] = {
13#define BODYSW             0
14    { "body text", 0 },
15#define CCSW               1
16    { "cc addrs ...", 0 },
17#define FROMSW             2
18    { "from addr", 0 },
19#define SUBJSW             3
20    { "subject text", 0 },
21#define VERSIONSW          4
22    { "version", 0 },
23#define HELPSW             5
24    { "help", 4 },
25#define RESNDSW            6
26    { "resent", -6 },
27#define QUEUESW            7
28    { "queued", -6 },
29    { NULL, 0 }
30};
31
32static char tmpfil[BUFSIZ];
33
34/*
35 * static prototypes
36 */
37static RETSIGTYPE intrser (int);
38
39
40int
41main (int argc, char **argv)
42{
43    pid_t child_id;
44    int status, i, iscc = 0, nvec;
45    int queued = 0, resent = 0, somebody;
46    char *cp, *tolist = NULL, *cclist = NULL, *subject = NULL;
47    char *from = NULL, *body = NULL, **argp, **arguments;
48    char *vec[5], buf[BUFSIZ];
49    FILE *out;
50
51#ifdef LOCALE
52    setlocale(LC_ALL, "");
53#endif
54    invo_name = r1bindex (argv[0], '/');
55
56    /* foil search of user profile/context */
57    if (context_foil (NULL) == -1)
58        done (1);
59
60    /* If no arguments, just incorporate new mail */
61    if (argc == 1) {
62        execlp (incproc, r1bindex (incproc, '/'), NULL);
63        adios (incproc, "unable to exec");
64    }
65
66    arguments = getarguments (invo_name, argc, argv, 0);
67    argp = arguments;
68
69    while ((cp = *argp++)) {
70        if (*cp == '-') {
71            switch (smatch (++cp, switches)) {
72                case AMBIGSW:
73                    ambigsw (cp, switches);
74                    done (1);
75                case UNKWNSW:
76                    adios (NULL, "-%s unknown", cp);
77
78                case HELPSW:
79                    snprintf (buf, sizeof(buf), "%s [addrs ... [switches]]",
80                        invo_name);
81                    print_help (buf, switches, 0);
82                    done (1);
83                case VERSIONSW:
84                    print_version(invo_name);
85                    done (1);
86
87                case FROMSW:
88                    if (!(from = *argp++) || *from == '-')
89                        adios (NULL, "missing argument to %s", argp[-2]);
90                    continue;
91
92                case BODYSW:
93                    if (!(body = *argp++) || *body == '-')
94                        adios (NULL, "missing argument to %s", argp[-2]);
95                    continue;
96
97                case CCSW:
98                    iscc++;
99                    continue;
100
101                case SUBJSW:
102                    if (!(subject = *argp++) || *subject == '-')
103                        adios (NULL, "missing argument to %s", argp[-2]);
104                    continue;
105
106                case RESNDSW:
107                    resent++;
108                    continue;
109
110                case QUEUESW:
111                    queued++;
112                    continue;
113            }
114        }
115        if (iscc)
116            cclist = cclist ? add (cp, add (", ", cclist)) : getcpy (cp);
117        else
118            tolist = tolist ? add (cp, add (", ", tolist)) : getcpy (cp);
119    }
120
121    if (tolist == NULL)
122        adios (NULL, "usage: %s addrs ... [switches]", invo_name);
123    strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
124    if ((out = fopen (tmpfil, "w")) == NULL)
125        adios (tmpfil, "unable to write");
126    chmod (tmpfil, 0600);
127
128    SIGNAL2 (SIGINT, intrser);
129
130    fprintf (out, "%sTo: %s\n", resent ? "Resent-" : "", tolist);
131    if (cclist)
132        fprintf (out, "%scc: %s\n", resent ? "Resent-" : "", cclist);
133    if (subject)
134        fprintf (out, "%sSubject: %s\n", resent ? "Resent-" : "", subject);
135    if (from)
136        fprintf (out, "%sFrom: %s\n", resent ? "Resent-" : "", from);
137    if (!resent)
138        fputs ("\n", out);
139
140    if (body) {
141        fprintf (out, "%s", body);
142        if (*body && *(body + strlen (body) - 1) != '\n')
143            fputs ("\n", out);
144    } else {
145        for (somebody = 0;
146                (i = fread (buf, sizeof(*buf), sizeof(buf), stdin)) > 0;
147                somebody++)
148            if (fwrite (buf, sizeof(*buf), i, out) != i)
149                adios (tmpfil, "error writing");
150        if (!somebody) {
151            unlink (tmpfil);
152            done (1);
153        }
154    }
155    fclose (out);
156
157    nvec = 0;
158    vec[nvec++] = r1bindex (postproc, '/');
159    vec[nvec++] = tmpfil;
160    if (resent)
161        vec[nvec++] = "-dist";
162    if (queued)
163        vec[nvec++] = "-queued";
164    vec[nvec] = NULL;
165
166    for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
167        sleep (5);
168
169    if (child_id == NOTOK) {
170        /* report failure and then send it */
171        admonish (NULL, "unable to fork");
172    } else if (child_id) {
173        /* parent process */
174        if ((status = pidXwait(child_id, postproc))) {
175            fprintf (stderr, "Letter saved in dead.letter\n");
176            execl ("/bin/mv", "mv", tmpfil, "dead.letter", NULL);
177            execl ("/usr/bin/mv", "mv", tmpfil, "dead.letter", NULL);
178            perror ("mv");
179            _exit (-1);
180        }
181        unlink (tmpfil);
182        done (status ? 1 : 0);
183    } else {
184        /* child process */
185        execvp (postproc, vec);
186        fprintf (stderr, "unable to exec ");
187        perror (postproc);
188        _exit (-1);
189    }
190}
191
192
193static RETSIGTYPE
194intrser (int i)
195{
196#ifndef RELIABLE_SIGNALS
197    if (i)
198        SIGNAL (i, SIG_IGN);
199#endif
200
201    unlink (tmpfil);
202    done (i != 0 ? 1 : 0);
203}
204
Note: See TracBrowser for help on using the repository browser.