]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/rcvstore.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / rcvstore.c
1 /* rcvstore.c - incorporate new mail asynchronously
2 originally from Julian Onions */
3 #ifndef lint
4 static char ident[] = "@(#)$Id: rcvstore.c,v 1.9 1992/12/15 00:20:22 jromine Exp $";
5 #endif /* lint */
6
7 #include "../h/mh.h"
8 #include <errno.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #ifdef LOCALE
14 #include <locale.h>
15 #endif
16
17 /* \f */
18
19 static struct swit switches[] = {
20 #define CRETSW 0
21 "create", 0,
22 #define NCRETSW 1
23 "nocreate", 0,
24
25 #define PUBSW 2
26 "public", 0,
27 #define NPUBSW 3
28 "nopublic", 0,
29
30 #define SEQSW 4
31 "sequence name", 0,
32
33 #define ZEROSW 5
34 "zero", 0,
35 #define NZEROSW 6
36 "nozero", 0,
37
38 #define HELPSW 7
39 "help", 4,
40
41 NULL, 0
42 };
43
44 /* \f */
45
46 extern int errno;
47
48 static char *tmpfilenam = NULLCP;
49 /* \f */
50
51 /* ARGSUSED */
52
53 main (argc, argv)
54 int argc;
55 char *argv[];
56 {
57 int publicsw = -1,
58 zerosw = 0,
59 msgnum,
60 create = 1,
61 fd,
62 seqp = 0;
63 char *cp,
64 *maildir,
65 *folder = NULL,
66 buf[100],
67 **ap,
68 **argp,
69 *arguments[MAXARGS],
70 *seqs[NATTRS+1];
71 struct msgs *mp;
72 struct stat st;
73
74 #ifdef LOCALE
75 setlocale(LC_ALL, "");
76 #endif
77 invo_name = r1bindex (argv[0], '/');
78 mts_init (invo_name);
79 if ((cp = m_find (invo_name)) != NULL) {
80 ap = brkstring (cp = getcpy (cp), " ", "\n");
81 ap = copyip (ap, arguments);
82 }
83 else
84 ap = arguments;
85 (void) copyip (argv + 1, ap);
86 argp = arguments;
87
88 /* \f */
89
90 while (cp = *argp++) {
91 if (*cp == '-')
92 switch (smatch (++cp, switches)) {
93 case AMBIGSW:
94 ambigsw (cp, switches);
95 done (1);
96 case UNKWNSW:
97 adios (NULLCP, "-%s unknown", cp);
98 case HELPSW:
99 (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
100 help (buf, switches);
101 done (1);
102
103 case SEQSW:
104 if (!(cp = *argp++) || *cp == '-')
105 adios (NULLCP, "missing argument name to %s",
106 argp[-2]);
107 if (seqp < NATTRS)
108 seqs[seqp++] = cp;
109 else
110 adios (NULLCP, "only %d sequences allowed!", NATTRS);
111 continue;
112 case PUBSW:
113 publicsw = 1;
114 continue;
115 case NPUBSW:
116 publicsw = 0;
117 continue;
118 case ZEROSW:
119 zerosw++;
120 continue;
121 case NZEROSW:
122 zerosw = 0;
123 continue;
124
125 case CRETSW:
126 create++;
127 continue;
128 case NCRETSW:
129 create = 0;
130 continue;
131 }
132 if (*cp == '+' || *cp == '@') {
133 if (folder)
134 adios (NULLCP, "only one folder at a time!");
135 else
136 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
137 }
138 else
139 adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
140 }
141
142 /* \f */
143
144 if (!m_find ("path"))
145 free (path ("./", TFOLDER));
146 if (!folder && !(folder = m_find (inbox)))
147 folder = defalt;
148 maildir = m_maildir (folder);
149
150 if (stat (maildir, &st) == NOTOK) {
151 if (errno != ENOENT)
152 adios (maildir, "error on folder");
153 if (!create)
154 adios (NULLCP, "folder %s doesn't exist", maildir);
155 if (!makedir (maildir))
156 adios (NULLCP, "unable to create folder %s", maildir);
157 }
158
159 if (chdir (maildir) == NOTOK)
160 adios (maildir, "unable to change directory to");
161 if (!(mp = m_gmsg (folder)))
162 adios (NULLCP, "unable to read folder %s", folder);
163
164 (void) signal (SIGHUP, SIG_IGN);
165 (void) signal (SIGINT, SIG_IGN);
166 (void) signal (SIGQUIT, SIG_IGN);
167 (void) signal (SIGTERM, SIG_IGN);
168
169 /* \f */
170
171 if ((fd = creat (tmpfilenam = m_scratch ("", invo_name), m_gmprot ()))
172 == NOTOK)
173 adios (tmpfilenam, "unable to create");
174 (void) chmod (tmpfilenam, m_gmprot ());
175
176 cpydata (fileno (stdin), fd, "standard input", tmpfilenam);
177
178 if (fstat (fd, &st) == NOTOK) {
179 (void) unlink (tmpfilenam);
180 adios (tmpfilenam, "unable to fstat");
181 }
182 if (close (fd) == NOTOK)
183 adios (tmpfilenam, "error closing");
184 if (st.st_size == 0) {
185 (void) unlink (tmpfilenam);
186 advise (NULLCP, "empty file");
187 done (0);
188 }
189
190 msgnum = mp -> hghmsg;
191 do {
192 msgnum++, mp -> hghmsg++;
193 if (msgnum > mp -> hghoff)
194 if ((mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER)) == NULL)
195 adios (NULLCP, "unable to allocate folder storage");
196
197 mp -> msgstats[msgnum] |= EXISTS | UNSEEN;
198 errno = 0;
199 } while (link (tmpfilenam, m_name (msgnum)) == NOTOK && errno == EEXIST);
200
201 (void) unlink (tmpfilenam);
202 tmpfilenam = NULLCP;
203 if (errno != 0)
204 adios (NULLCP, "can't file message %d", msgnum);
205
206 if (mp -> lowmsg == 0)
207 mp -> lowmsg = msgnum;
208 mp -> msgflags |= SEQMOD;
209
210 seqs[seqp] = NULL;
211 for (seqp = 0; seqs[seqp]; seqp++) {
212 if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw))
213 done (1);
214 if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw))
215 done (1);
216 }
217
218 m_setvis (mp, 0);
219 m_sync (mp);
220 m_update ();
221
222 done (0);
223 }
224
225 void done (status)
226 register int status;
227 {
228 if (tmpfilenam && *tmpfilenam)
229 (void) unlink (tmpfilenam);
230 exit (status);
231 }