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

Revision 12455, 5.2 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 * rcvstore.c -- asynchronously add mail to a folder
4 *
5 * $Id: rcvstore.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 <h/signals.h>
11#include <errno.h>
12#include <signal.h>
13
14static struct swit switches[] = {
15#define CRETSW         0
16    { "create", 0 },
17#define NCRETSW        1
18    { "nocreate", 0 },
19#define UNSEENSW       2
20    { "unseen", 0 },
21#define NUNSEENSW      3
22    { "nounseen", 0 },
23#define PUBSW          4
24    { "public", 0 },
25#define NPUBSW         5
26    { "nopublic",  0 },
27#define ZEROSW         6
28    { "zero",   0 },
29#define NZEROSW        7
30    { "nozero", 0 },
31#define SEQSW          8
32    { "sequence name", 0 },
33#define VERSIONSW      9
34    { "version", 0 },
35#define HELPSW        10
36    { "help", 4 },
37    { NULL, 0 }
38};
39
40extern int errno;
41
42/*
43 * name of temporary file to store incoming message
44 */
45static char *tmpfilenam = NULL;
46
47
48int
49main (int argc, char **argv)
50{
51    int publicsw = -1, zerosw = 0;
52    int create = 1, unseensw = 1;
53    int fd, msgnum, seqp = 0;
54    char *cp, *maildir, *folder = NULL, buf[BUFSIZ];
55    char **argp, **arguments, *seqs[NUMATTRS+1];
56    struct msgs *mp;
57    struct stat st;
58
59#ifdef LOCALE
60    setlocale(LC_ALL, "");
61#endif
62    invo_name = r1bindex (argv[0], '/');
63
64    /* read user profile/context */
65    context_read();
66
67    mts_init (invo_name);
68    arguments = getarguments (invo_name, argc, argv, 1);
69    argp = arguments;
70
71    /* parse arguments */
72    while ((cp = *argp++)) {
73        if (*cp == '-') {
74            switch (smatch (++cp, switches)) {
75            case AMBIGSW:
76                ambigsw (cp, switches);
77                done (1);
78            case UNKWNSW:
79                adios (NULL, "-%s unknown", cp);
80
81            case HELPSW:
82                snprintf (buf, sizeof(buf), "%s [+folder] [switches]",
83                          invo_name);
84                print_help (buf, switches, 1);
85                done (1);
86            case VERSIONSW:
87                print_version(invo_name);
88                done (1);
89
90            case SEQSW:
91                if (!(cp = *argp++) || *cp == '-')
92                    adios (NULL, "missing argument name to %s", argp[-2]);
93
94                /* check if too many sequences specified */
95                if (seqp >= NUMATTRS)
96                    adios (NULL, "too many sequences (more than %d) specified", NUMATTRS);
97                seqs[seqp++] = cp;
98                continue;
99
100            case UNSEENSW:
101                unseensw = 1;
102                continue;
103            case NUNSEENSW:
104                unseensw = 0;
105                continue;
106
107            case PUBSW:
108                publicsw = 1;
109                continue;
110            case NPUBSW:
111                publicsw = 0;
112                continue;
113
114            case ZEROSW:
115                zerosw++;
116                continue;
117            case NZEROSW:
118                zerosw = 0;
119                continue;
120
121            case CRETSW:
122                create++;
123                continue;
124            case NCRETSW:
125                create = 0;
126                continue;
127            }
128        }
129        if (*cp == '+' || *cp == '@') {
130            if (folder)
131                adios (NULL, "only one folder at a time!");
132            else
133                folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
134        } else {
135            adios (NULL, "usage: %s [+folder] [switches]", invo_name);
136        }
137    }
138
139    seqs[seqp] = NULL;  /* NULL terminate list of sequences */
140
141    if (!context_find ("path"))
142        free (path ("./", TFOLDER));
143
144    /* if no folder is given, use default folder */
145    if (!folder)
146        folder = getfolder (0);
147    maildir = m_maildir (folder);
148
149    /* check if folder exists */
150    if (stat (maildir, &st) == NOTOK) {
151        if (errno != ENOENT)
152            adios (maildir, "error on folder");
153        if (!create)
154            adios (NULL, "folder %s doesn't exist", maildir);
155        if (!makedir (maildir))
156            adios (NULL, "unable to create folder %s", maildir);
157    }
158
159    if (chdir (maildir) == NOTOK)
160        adios (maildir, "unable to change directory to");
161
162    /* ignore a few signals */
163    SIGNAL (SIGHUP, SIG_IGN);
164    SIGNAL (SIGINT, SIG_IGN);
165    SIGNAL (SIGQUIT, SIG_IGN);
166    SIGNAL (SIGTERM, SIG_IGN);
167
168    /* create a temporary file */
169    tmpfilenam = m_scratch ("", invo_name);
170    if ((fd = creat (tmpfilenam, m_gmprot ())) == NOTOK)
171        adios (tmpfilenam, "unable to create");
172    chmod (tmpfilenam, m_gmprot());
173
174    /* copy the message from stdin into temp file */
175    cpydata (fileno (stdin), fd, "standard input", tmpfilenam);
176
177    if (fstat (fd, &st) == NOTOK) {
178        unlink (tmpfilenam);
179        adios (tmpfilenam, "unable to fstat");
180    }
181    if (close (fd) == NOTOK)
182        adios (tmpfilenam, "error closing");
183
184    /* don't add file if it is empty */
185    if (st.st_size == 0) {
186        unlink (tmpfilenam);
187        advise (NULL, "empty file");
188        done (0);
189    }
190
191    /*
192     * read folder and create message structure
193     */
194    if (!(mp = folder_read (folder)))
195        adios (NULL, "unable to read folder %s", folder);
196
197    /*
198     * Link message into folder, and possibly add
199     * to the Unseen-Sequence's.
200     */
201    if ((msgnum = folder_addmsg (&mp, tmpfilenam, 0, unseensw, 0)) == -1)
202        done (1);
203
204    /*
205     * Add the message to any extra sequences
206     * that have been specified.
207     */
208    for (seqp = 0; seqs[seqp]; seqp++) {
209        if (!seq_addmsg (mp, seqs[seqp], msgnum, publicsw, zerosw))
210            done (1);
211    }
212
213    seq_setunseen (mp, 0);      /* synchronize any Unseen-Sequence's      */
214    seq_save (mp);              /* synchronize and save message sequences */
215    folder_free (mp);           /* free folder/message structure          */
216
217    context_save ();            /* save the global context file           */
218    unlink (tmpfilenam);        /* remove temporary file                  */
219    tmpfilenam = NULL;
220
221    done (0);
222}
223
224/*
225 * Clean up and exit
226 */
227void
228done(int status)
229{
230    if (tmpfilenam && *tmpfilenam)
231        unlink (tmpfilenam);
232    exit (status);
233}
Note: See TracBrowser for help on using the repository browser.