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

Revision 12455, 9.7 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 * send.c -- send a composed message
4 *
5 * $Id: send.c,v 1.1.1.1 1999-02-07 18:14:16 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <fcntl.h>
10#include <errno.h>
11#include <signal.h>
12
13
14static struct swit switches[] = {
15#define ALIASW                 0
16    { "alias aliasfile", 0 },
17#define DEBUGSW                1
18    { "debug", -5 },
19#define DRAFTSW                2
20    { "draft", 0 },
21#define DFOLDSW                3
22    { "draftfolder +folder", 6 },
23#define DMSGSW                 4
24    { "draftmessage msg", 6 },
25#define NDFLDSW                5
26    { "nodraftfolder", 0 },
27#define FILTSW                 6
28    { "filter filterfile", 0 },
29#define NFILTSW                7
30    { "nofilter", 0 },
31#define FRMTSW                 8
32    { "format", 0 },
33#define NFRMTSW                9
34    { "noformat", 0 },
35#define FORWSW                10
36    { "forward", 0 },
37#define NFORWSW               11
38    { "noforward", 0 },
39#define MIMESW                12
40    { "mime", 0 },
41#define NMIMESW               13
42    { "nomime", 0 },
43#define MSGDSW                14
44    { "msgid", 0 },
45#define NMSGDSW               15
46    { "nomsgid", 0 },
47#define PUSHSW                16
48    { "push", 0 },
49#define NPUSHSW               17
50    { "nopush", 0 },
51#define SPLITSW               18
52    { "split seconds", 0 },
53#define UNIQSW                19
54    { "unique", -6 },
55#define NUNIQSW               20
56    { "nounique", -8 },
57#define VERBSW                21
58    { "verbose", 0 },
59#define NVERBSW               22
60    { "noverbose", 0 },
61#define WATCSW                23
62    { "watch", 0 },
63#define NWATCSW               24
64    { "nowatch", 0 },
65#define WIDTHSW               25
66    { "width columns", 0 },
67#define VERSIONSW             26
68    { "version", 0 },
69#define HELPSW                27
70    { "help", 4 },
71#define BITSTUFFSW            28
72    { "dashstuffing", -12 },
73#define NBITSTUFFSW           29
74    { "nodashstuffing", -14 },
75#define MAILSW                30
76    { "mail", -4 },
77#define SAMLSW                31
78    { "saml", -4 },
79#define SENDSW                32
80    { "send", -4 },
81#define SOMLSW                33
82    { "soml", -4 },
83#define CLIESW                34
84    { "client host", -6 },
85#define SERVSW                35
86    { "server host", -6 },
87#define SNOOPSW               36
88    { "snoop", -5 },
89    { NULL, 0 }
90};
91
92static struct swit anyl[] = {
93#define NOSW     0
94    { "no", 0 },
95#define YESW     1
96    { "yes", 0 },
97#define LISTDSW  2
98    { "list", 0 },
99    { NULL, 0 }
100};
101
102extern int debugsw;             /* from sendsbr.c */
103extern int forwsw;
104extern int inplace;
105extern int pushsw;
106extern int splitsw;
107extern int unique;
108extern int verbsw;
109
110extern char *altmsg;            /*  .. */
111extern char *annotext;
112extern char *distfile;
113
114extern int   errno;
115
116int
117main (int argc, char **argv)
118{
119    int msgp = 0, distsw = 0, vecp = 1;
120    int isdf = 0, mime = 0;
121    int msgnum, status;
122    char *cp, *dfolder = NULL, *maildir = NULL;
123    char buf[BUFSIZ], **ap, **argp, **arguments;
124    char *msgs[MAXARGS], *vec[MAXARGS];
125    struct msgs *mp;
126    struct stat st;
127#ifdef UCI
128    FILE *fp;
129#endif /* UCI */
130
131#ifdef LOCALE
132    setlocale(LC_ALL, "");
133#endif
134    invo_name = r1bindex (argv[0], '/');
135
136    /* read user profile/context */
137    context_read();
138
139    arguments = getarguments (invo_name, argc, argv, 1);
140    argp = arguments;
141
142    vec[vecp++] = "-library";
143    vec[vecp++] = getcpy (m_maildir (""));
144
145    while ((cp = *argp++)) {
146        if (*cp == '-') {
147            switch (smatch (++cp, switches)) {
148                case AMBIGSW:
149                    ambigsw (cp, switches);
150                    done (1);
151                case UNKWNSW:
152                    adios (NULL, "-%s unknown\n", cp);
153
154                case HELPSW:
155                    snprintf (buf, sizeof(buf), "%s [file] [switches]", invo_name);
156                    print_help (buf, switches, 1);
157                    done (1);
158                case VERSIONSW:
159                    print_version(invo_name);
160                    done (1);
161
162                case DRAFTSW:
163                    msgs[msgp++] = draft;
164                    continue;
165
166                case DFOLDSW:
167                    if (dfolder)
168                        adios (NULL, "only one draft folder at a time!");
169                    if (!(cp = *argp++) || *cp == '-')
170                        adios (NULL, "missing argument to %s", argp[-2]);
171                    dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
172                            *cp != '@' ? TFOLDER : TSUBCWF);
173                    continue;
174                case DMSGSW:
175                    if (!(cp = *argp++) || *cp == '-')
176                        adios (NULL, "missing argument to %s", argp[-2]);
177                    msgs[msgp++] = cp;
178                    continue;
179                case NDFLDSW:
180                    dfolder = NULL;
181                    isdf = NOTOK;
182                    continue;
183
184                case PUSHSW:
185                    pushsw++;
186                    continue;
187                case NPUSHSW:
188                    pushsw = 0;
189                    continue;
190
191                case SPLITSW:
192                    if (!(cp = *argp++) || sscanf (cp, "%d", &splitsw) != 1)
193                        adios (NULL, "missing argument to %s", argp[-2]);
194                    continue;
195
196                case UNIQSW:
197                    unique++;
198                    continue;
199                case NUNIQSW:
200                    unique = 0;
201                    continue;
202
203                case FORWSW:
204                    forwsw++;
205                    continue;
206                case NFORWSW:
207                    forwsw = 0;
208                    continue;
209
210                case VERBSW:
211                    verbsw++;
212                    vec[vecp++] = --cp;
213                    continue;
214                case NVERBSW:
215                    verbsw = 0;
216                    vec[vecp++] = --cp;
217                    continue;
218
219                case MIMESW:
220                    mime++;
221                    vec[vecp++] = --cp;
222                    continue;
223                case NMIMESW:
224                    mime = 0;
225                    vec[vecp++] = --cp;
226                    continue;
227
228                case DEBUGSW:
229                    debugsw++;  /* fall */
230                case NFILTSW:
231                case FRMTSW:
232                case NFRMTSW:
233                case BITSTUFFSW:
234                case NBITSTUFFSW:
235                case MSGDSW:
236                case NMSGDSW:
237                case WATCSW:
238                case NWATCSW:
239                case MAILSW:
240                case SAMLSW:
241                case SENDSW:
242                case SOMLSW:
243                case SNOOPSW:
244                    vec[vecp++] = --cp;
245                    continue;
246
247                case ALIASW:
248                case FILTSW:
249                case WIDTHSW:
250                case CLIESW:
251                case SERVSW:
252                    vec[vecp++] = --cp;
253                    if (!(cp = *argp++) || *cp == '-')
254                        adios (NULL, "missing argument to %s", argp[-2]);
255                    vec[vecp++] = cp;
256                    continue;
257            }
258        } else {
259            msgs[msgp++] = cp;
260        }
261    }
262
263    /*
264     * check for "Aliasfile:" profile entry
265     */
266    if ((cp = context_find ("Aliasfile"))) {
267        char *dp = NULL;
268
269        for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++) {
270            vec[vecp++] = "-alias";
271            vec[vecp++] = *ap;
272        }
273    }
274
275    if (dfolder == NULL) {
276        if (msgp == 0) {
277#ifdef WHATNOW
278            if ((cp = getenv ("mhdraft")) && *cp) {
279                msgs[msgp++] = cp;
280                goto go_to_it;
281            }
282#endif /* WHATNOW */
283            msgs[msgp++] = getcpy (m_draft (NULL, NULL, 1, &isdf));
284            if (stat (msgs[0], &st) == NOTOK)
285                adios (msgs[0], "unable to stat draft file");
286            cp = concat ("Use \"", msgs[0], "\"? ", NULL);
287            for (status = LISTDSW; status != YESW;) {
288                if (!(argp = getans (cp, anyl)))
289                    done (1);
290                switch (status = smatch (*argp, anyl)) {
291                    case NOSW:
292                        done (0);
293                    case YESW:
294                        break;
295                    case LISTDSW:
296                        showfile (++argp, msgs[0]);
297                        break;
298                    default:
299                        advise (NULL, "say what?");
300                        break;
301                }
302            }
303        } else {
304            for (msgnum = 0; msgnum < msgp; msgnum++)
305                msgs[msgnum] = getcpy (m_maildir (msgs[msgnum]));
306        }
307    } else {
308        if (!context_find ("path"))
309            free (path ("./", TFOLDER));
310
311        if (!msgp)
312            msgs[msgp++] = "cur";
313        maildir = m_maildir (dfolder);
314
315        if (chdir (maildir) == NOTOK)
316            adios (maildir, "unable to change directory to");
317
318        /* read folder and create message structure */
319        if (!(mp = folder_read (dfolder)))
320            adios (NULL, "unable to read folder %s", dfolder);
321
322        /* check for empty folder */
323        if (mp->nummsg == 0)
324            adios (NULL, "no messages in %s", dfolder);
325
326        /* parse all the message ranges/sequences and set SELECTED */
327        for (msgnum = 0; msgnum < msgp; msgnum++)
328            if (!m_convert (mp, msgs[msgnum]))
329                done (1);
330        seq_setprev (mp);       /* set the previous-sequence */
331
332        for (msgp = 0, msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
333            if (is_selected (mp, msgnum)) {
334                msgs[msgp++] = getcpy (m_name (msgnum));
335                unset_exists (mp, msgnum);
336            }
337        }
338
339        mp->msgflags |= SEQMOD;
340        seq_save (mp);
341    }
342
343#ifdef WHATNOW
344go_to_it:
345#endif /* WHATNOW */
346
347    if ((cp = getenv ("SIGNATURE")) == NULL || *cp == 0)
348        if ((cp = context_find ("signature")) && *cp)
349            m_putenv ("SIGNATURE", cp);
350#ifdef UCI
351        else {
352            snprintf (buf, sizeof(buf), "%s/.signature", mypath);
353            if ((fp = fopen (buf, "r")) != NULL
354                && fgets (buf, sizeof buf, fp) != NULL) {
355                    fclose (fp);
356                    if (cp = strchr (buf, '\n'))
357                        *cp = 0;
358                    m_putenv ("SIGNATURE", buf);
359            }
360        }
361#endif /* UCI */
362
363    for (msgnum = 0; msgnum < msgp; msgnum++)
364        if (stat (msgs[msgnum], &st) == NOTOK)
365            adios (msgs[msgnum], "unable to stat draft file");
366
367    if ((annotext = getenv ("mhannotate")) == NULL || *annotext == 0)
368        annotext = NULL;
369    if (annotext && ((cp = getenv ("mhinplace")) != NULL && *cp != 0))
370        inplace = atoi (cp);
371    if ((altmsg = getenv ("mhaltmsg")) == NULL || *altmsg == 0)
372        altmsg = NULL;  /* used by dist interface - see below */
373
374    if ((cp = getenv ("mhdist"))
375            && *cp
376            && (distsw = atoi (cp))
377            && altmsg) {
378        vec[vecp++] = "-dist";
379        distfile = getcpy (m_scratch (altmsg, invo_name));
380        if (link (altmsg, distfile) == NOTOK) {
381            if (errno != EXDEV
382#ifdef EISREMOTE
383                    && errno != EISREMOTE
384#endif /* EISREMOTE */
385                )
386                adios (distfile, "unable to link %s to", altmsg);
387            free (distfile);
388            distfile = getcpy (m_tmpfil (invo_name));
389            {
390                int in, out;
391                struct stat st;
392
393                if ((in = open (altmsg, O_RDONLY)) == NOTOK)
394                    adios (altmsg, "unable to open");
395                fstat(in, &st);
396                if ((out = creat (distfile, (int) st.st_mode & 0777)) == NOTOK)
397                    adios (distfile, "unable to write");
398                cpydata (in, out, altmsg, distfile);
399                close (in);
400                close (out);
401            }   
402        }
403    } else {
404        distfile = NULL;
405    }
406
407    if (altmsg == NULL || stat (altmsg, &st) == NOTOK) {
408        st.st_mtime = 0;
409        st.st_dev = 0;
410        st.st_ino = 0;
411    }
412    if (pushsw)
413        push ();
414
415    status = 0;
416    vec[0] = r1bindex (postproc, '/');
417    closefds (3);
418
419    for (msgnum = 0; msgnum < msgp; msgnum++) {
420        switch (sendsbr (vec, vecp, msgs[msgnum], &st, 1)) {
421            case DONE:
422                done (++status);
423            case NOTOK:
424                status++;       /* fall */
425            case OK:
426                break;
427        }
428    }
429
430    context_save ();    /* save the context file */
431    done (status);
432}
Note: See TracBrowser for help on using the repository browser.