Mercurial > hg > Applications > mh
comparison uip/rcvstore.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | a6481689f99c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 /* rcvstore.c - incorporate new mail asynchronously | |
2 originally from Julian Onions */ | |
3 #ifndef lint | |
4 static char ident[] = "@(#)$Id$"; | |
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 /* */ | |
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 /* */ | |
45 | |
46 extern int errno; | |
47 | |
48 static char *tmpfilenam = NULLCP; | |
49 /* */ | |
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 #ifdef JAPAN | |
78 ml_init(); | |
79 #endif /* JAPAN */ | |
80 invo_name = r1bindex (argv[0], '/'); | |
81 mts_init (invo_name); | |
82 if ((cp = m_find (invo_name)) != NULL) { | |
83 ap = brkstring (cp = getcpy (cp), " ", "\n"); | |
84 ap = copyip (ap, arguments); | |
85 } | |
86 else | |
87 ap = arguments; | |
88 (void) copyip (argv + 1, ap); | |
89 argp = arguments; | |
90 | |
91 /* */ | |
92 | |
93 while (cp = *argp++) { | |
94 if (*cp == '-') | |
95 switch (smatch (++cp, switches)) { | |
96 case AMBIGSW: | |
97 ambigsw (cp, switches); | |
98 done (1); | |
99 case UNKWNSW: | |
100 adios (NULLCP, "-%s unknown", cp); | |
101 case HELPSW: | |
102 (void) sprintf (buf, "%s [+folder] [switches]", invo_name); | |
103 help (buf, switches); | |
104 done (1); | |
105 | |
106 case SEQSW: | |
107 if (!(cp = *argp++) || *cp == '-') | |
108 adios (NULLCP, "missing argument name to %s", | |
109 argp[-2]); | |
110 if (seqp < NATTRS) | |
111 seqs[seqp++] = cp; | |
112 else | |
113 adios (NULLCP, "only %d sequences allowed!", NATTRS); | |
114 continue; | |
115 case PUBSW: | |
116 publicsw = 1; | |
117 continue; | |
118 case NPUBSW: | |
119 publicsw = 0; | |
120 continue; | |
121 case ZEROSW: | |
122 zerosw++; | |
123 continue; | |
124 case NZEROSW: | |
125 zerosw = 0; | |
126 continue; | |
127 | |
128 case CRETSW: | |
129 create++; | |
130 continue; | |
131 case NCRETSW: | |
132 create = 0; | |
133 continue; | |
134 } | |
135 if (*cp == '+' || *cp == '@') { | |
136 if (folder) | |
137 adios (NULLCP, "only one folder at a time!"); | |
138 else | |
139 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); | |
140 } | |
141 else | |
142 adios (NULLCP, "usage: %s [+folder] [switches]", invo_name); | |
143 } | |
144 | |
145 /* */ | |
146 | |
147 if (!m_find ("path")) | |
148 free (path ("./", TFOLDER)); | |
149 if (!folder && !(folder = m_find (inbox))) | |
150 folder = defalt; | |
151 maildir = m_maildir (folder); | |
152 | |
153 if (stat (maildir, &st) == NOTOK) { | |
154 if (errno != ENOENT) | |
155 adios (maildir, "error on folder"); | |
156 if (!create) | |
157 adios (NULLCP, "folder %s doesn't exist", maildir); | |
158 if (!makedir (maildir)) | |
159 adios (NULLCP, "unable to create folder %s", maildir); | |
160 } | |
161 | |
162 if (chdir (maildir) == NOTOK) | |
163 adios (maildir, "unable to change directory to"); | |
164 if (!(mp = m_gmsg (folder))) | |
165 adios (NULLCP, "unable to read folder %s", folder); | |
166 | |
167 (void) signal (SIGHUP, SIG_IGN); | |
168 (void) signal (SIGINT, SIG_IGN); | |
169 (void) signal (SIGQUIT, SIG_IGN); | |
170 (void) signal (SIGTERM, SIG_IGN); | |
171 | |
172 /* */ | |
173 | |
174 if ((fd = creat (tmpfilenam = m_scratch ("", invo_name), m_gmprot ())) | |
175 == NOTOK) | |
176 adios (tmpfilenam, "unable to create"); | |
177 (void) chmod (tmpfilenam, m_gmprot ()); | |
178 | |
179 cpydata (fileno (stdin), fd, "standard input", tmpfilenam); | |
180 | |
181 if (fstat (fd, &st) == NOTOK) { | |
182 (void) unlink (tmpfilenam); | |
183 adios (tmpfilenam, "unable to fstat"); | |
184 } | |
185 if (close (fd) == NOTOK) | |
186 adios (tmpfilenam, "error closing"); | |
187 if (st.st_size == 0) { | |
188 (void) unlink (tmpfilenam); | |
189 advise (NULLCP, "empty file"); | |
190 done (0); | |
191 } | |
192 | |
193 msgnum = mp -> hghmsg; | |
194 do { | |
195 msgnum++, mp -> hghmsg++; | |
196 if (msgnum > mp -> hghoff) | |
197 if ((mp = m_remsg (mp, 0, mp -> hghoff + MAXFOLDER)) == NULL) | |
198 adios (NULLCP, "unable to allocate folder storage"); | |
199 | |
200 mp -> msgstats[msgnum] |= EXISTS | UNSEEN; | |
201 errno = 0; | |
202 } while (link (tmpfilenam, m_name (msgnum)) == NOTOK && errno == EEXIST); | |
203 | |
204 (void) unlink (tmpfilenam); | |
205 tmpfilenam = NULLCP; | |
206 if (errno != 0) | |
207 adios (NULLCP, "can't file message %d", msgnum); | |
208 | |
209 if (mp -> lowmsg == 0) | |
210 mp -> lowmsg = msgnum; | |
211 mp -> msgflags |= SEQMOD; | |
212 | |
213 seqs[seqp] = NULL; | |
214 for (seqp = 0; seqs[seqp]; seqp++) { | |
215 if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw)) | |
216 done (1); | |
217 if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw)) | |
218 done (1); | |
219 } | |
220 | |
221 m_setvis (mp, 0); | |
222 m_sync (mp); | |
223 m_update (); | |
224 | |
225 done (0); | |
226 } | |
227 | |
228 void done (status) | |
229 register int status; | |
230 { | |
231 if (tmpfilenam && *tmpfilenam) | |
232 (void) unlink (tmpfilenam); | |
233 exit (status); | |
234 } |