1 /* burst.c - explode digests into individual messages */
3 static char ident[] = "@(#)$Id: burst.c,v 1.7 1992/12/15 00:20:22 jromine Exp $";
14 static cpybrst(), burst();
17 static struct swit switches[] = {
41 static char delim3[] = "-------";
44 static struct msgs *mp;
76 setlocale(LC_ALL, "");
78 invo_name = r1bindex (argv[0], '/');
79 if ((cp = m_find (invo_name)) != NULL) {
80 ap = brkstring (cp = getcpy (cp), " ", "\n");
81 ap = copyip (ap, arguments);
85 (void) copyip (argv + 1, ap);
90 while (cp = *argp++) {
92 switch (smatch (++cp, switches)) {
94 ambigsw (cp, switches);
97 adios (NULLCP, "-%s unknown\n", cp);
99 (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
101 help (buf, switches);
125 if (*cp == '+' || *cp == '@') {
127 adios (NULLCP, "only one folder at a time!");
129 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
137 if (!m_find ("path"))
138 free (path ("./", TFOLDER));
140 msgs[msgp++] = "cur";
142 folder = m_getfolder ();
143 maildir = m_maildir (folder);
145 if (chdir (maildir) == NOTOK)
146 adios (maildir, "unable to change directory to");
147 if (!(mp = m_gmsg (folder)))
148 adios (NULLCP, "unable to read folder %s", folder);
149 if (mp -> hghmsg == 0)
150 adios (NULLCP, "no messages in %s", folder);
152 for (msgnum = 0; msgnum < msgp; msgnum++)
153 if (!m_convert (mp, msgs[msgnum]))
157 smsgs = (struct smsg *)
158 calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
160 adios (NULLCP, "unable to allocate burst storage");
162 hi = mp -> hghmsg + 1;
163 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
164 if (mp -> msgstats[msgnum] & SELECTED)
165 burst (smsgs, msgnum, inplace, quietsw, verbosw);
167 free ((char *) smsgs);
169 m_replace (pfolder, folder);
171 if (mp -> lowsel != mp -> curmsg)
172 m_setcur (mp, mp -> lowsel);
175 if (hi <= mp -> hghmsg)
185 static burst (smsgs, msgnum, inplace, quietsw, verbosw)
186 register struct smsg *smsgs;
210 ld3 = strlen (delim3);
212 if ((in = fopen (msgnam = m_name (msgnum), "r")) == NULL)
213 adios (msgnam, "unable to read message");
215 mode = fstat (fileno (in), &st) != NOTOK ? (st.st_mode & 0777)
217 for (msgp = 0, pos = 0L; msgp <= MAXFOLDER;) {
218 while (fgets (buffer, sizeof buffer, in) != NULL
219 && buffer[0] == '\n')
220 pos += (long) strlen (buffer);
223 (void) fseek (in, pos, 0);
224 smsgs[msgp].s_start = pos;
227 fgets (buffer, sizeof buffer, in) != NULL;
229 if (strncmp (buffer, delim3, ld3) == 0
230 && (msgp == 1 || c == '\n')
231 && ((cc = peekc (in)) == '\n' || cc == EOF))
234 pos += (long) strlen (buffer);
236 wasdlm = strncmp (buffer, delim3, ld3) == 0;
237 if (smsgs[msgp].s_start != pos)
238 smsgs[msgp++].s_stop = (c == '\n' && wasdlm) ? pos - 1 : pos;
242 smsgs[msgp - 1].s_stop -= ((long) strlen (buffer) + 1);
243 msgp++; /* fake "End of XXX Digest" */
248 pos += (long) strlen (buffer);
253 switch (msgp--) { /* toss "End of XXX Digest" */
255 adios (NULLCP, "burst() botch -- you lose big");
259 admonish (NULLCP, "message %d not in digest format", msgnum);
265 printf ("%d message%s exploded from digest %d\n",
266 msgp, msgp != 1 ? "s" : "", msgnum);
269 /* msgp now contains the number of new msgs to be created */
271 if ((mp = m_remsg (mp, 0, mp -> hghmsg + msgp)) == NULL)
272 adios (NULLCP, "unable to allocate folder storage");
276 j = mp -> hghmsg; /* old value */
277 mp -> hghmsg += msgp;
278 mp -> nummsg += msgp;
279 if (mp -> hghsel > msgnum)
280 mp -> hghsel += msgp;
283 for (i = mp -> hghmsg; j > msgnum; i--, j--) {
284 (void) strcpy (f1, m_name (i));
285 (void) strcpy (f2, m_name (j));
286 if (mp -> msgstats[j] & EXISTS) {
288 printf ("message %d becomes message %d\n", j, i);
290 if (rename (f2, f1) == NOTOK)
291 admonish (f1, "unable to rename %s to", f2);
292 mp -> msgstats[i] = mp -> msgstats[j];
293 mp -> msgstats[j] = 0;
294 mp -> msgflags |= SEQMOD;
298 mp -> msgstats[msgnum] &= ~SELECTED;
299 i = inplace ? msgnum + msgp : mp -> hghmsg; /* new hghmsg is hghmsg+msgp */
300 for (j = msgp; j >= (inplace ? 0 : 1); i--, j--) {
301 (void) strcpy (f1, m_name (i));
302 (void) strcpy (f2, m_scratch ("", invo_name));
303 if (verbosw && i != msgnum)
304 printf ("message %d of digest %d becomes message %d\n",
307 if ((out = fopen (f2, "w")) == NULL)
308 adios (f2, "unable to write message");
309 (void) chmod (f2, mode);
310 (void) fseek (in, pos = smsgs[j].s_start, 0);
311 cpybrst (in, out, msgnam, f2,
312 (int) (smsgs[j].s_stop - smsgs[j].s_start));
316 (void) strcpy (f3, m_backup (f1));
317 if (rename (f1, f3) == NOTOK)
318 admonish (f3, "unable to rename %s to", f1);
320 if (rename (f2, f1) == NOTOK)
321 admonish (f1, "unable to rename %s to", f2);
322 mp -> msgstats[i] = mp -> msgstats[msgnum];
323 mp -> msgflags |= SEQMOD;
336 static cpybrst (in, out, ifile, ofile, len)
339 register char *ifile,
346 for (state = S1; (c = fgetc (in)) != EOF && len > 0; len--) {
359 (void) fputc (c, out);
369 (void) fputc (c, out);
381 state = c == '\n' ? S1 : S2;
382 (void) fputc ('-', out);
383 (void) fputc (c, out);
390 if (ferror (in) && !feof (in))
391 adios (ifile, "error reading");
393 adios (ofile, "error writing");