.B burst
.RI [ +folder ]
.RI [ msgs ]
-.RB [ \-inplace " | " \-noinplace ]
-.RB [ \-quiet " | " \-noquiet ]
.RB [ \-verbose " | " \-noverbose ]
.RB [ \-version ]
.RB [ \-help ]
considers the specified messages in the named folder to be
Internet digests, and explodes them in that folder.
.PP
-If
-.B \-inplace
-is given, each digest is replaced by the \*(lqtable
-of contents\*(rq for the digest (the original digest is removed).
-.B Burst
-then renumbers all of the messages following the digest in the
-folder to make room for each of the messages contained within the digest.
-These messages are placed immediately after the digest.
-.PP
-If
-.B \-noinplace
-is given, each digest is preserved, no table of contents
-is produced, and the messages contained within the digest are placed at
-the end of the folder. Other messages are not tampered with in any way.
-.PP
-The
-.B \-quiet
-switch directs
-.B burst
-to be silent about reporting
-messages that are not in digest format.
+The messages contained within the digest are placed at the end of the folder.
+The digest is preserved.
+No other messages are tampered with in any way.
.PP
The
.B \-verbose
It turns out that
.B burst
works equally well on forwarded messages
-and blind\-carbon\-copies as on Internet digests, provided that the
-former two were generated by
-.B forw
-or
-.BR send .
+and blind\-carbon\-copies as on Internet digests, provided that they
+use RFC 934 message encapsulation.
+.PP
+To extract messages encapsulated with MIME, use
+.BR mhstore (1).
.SH FILES
.fc ^ ~
.fi
.SH "SEE ALSO"
-inc(1), pack(1),
+mhstore(1),
.I "Proposed Standard for Message Encapsulation"
(RFC\-934)
.nf
.RB ` +folder "' defaults to the current folder"
.RB ` msgs "' defaults to cur"
-.RB ` \-noinplace '
-.RB ` \-noquiet '
.RB ` \-noverbose '
.fi
.SH CONTEXT
-If a folder is given, it will become the current folder. If
-.B \-inplace
-is given, then the first message burst becomes the current message.
-This leaves the context ready for a
-.B show
-of the table of contents
-of the digest, and a
-.B next
-to see the first message of the digest. If
-.B \-noinplace
-is given, then the first message extracted from the
-first digest burst becomes the current message. This leaves the context
-in a similar, but not identical, state to the context achieved when using
-.BR \-inplace .
+If a folder is given, it will become the current folder.
+The first message extracted from the
+first digest burst becomes the current message.
.SH BUGS
The
prematurely and splitting a single encapsulated message into two or
more messages. These erroneous digestifying programs should be fixed.
.PP
-Furthermore, any text which appears after the last encapsulated message
+Any text which appears after the last encapsulated message
is not placed in a separate message by
.BR burst .
In the case of
digestified messages, this text is usually an \*(lqEnd of digest\*(rq
-string. As a result of this possibly un\-friendly behavior on the
-part of
-.BR burst ,
-note that when the
-.B \-inplace
-option is used,
-this trailing information is lost. In practice, this is not a problem
-since correspondents usually place remarks in text prior to the first
-encapsulated message, and this information is not lost.
+string.
#include <h/mh.h>
static struct swit switches[] = {
-#define INPLSW 0
- { "inplace", 0 },
-#define NINPLSW 1
- { "noinplace", 0 },
-#define QIETSW 2
- { "quiet", 0 },
-#define NQIETSW 3
- { "noquiet", 0 },
-#define VERBSW 4
+#define VERBSW 0
{ "verbose", 0 },
-#define NVERBSW 5
+#define NVERBSW 1
{ "noverbose", 0 },
-#define VERSIONSW 6
+#define VERSIONSW 2
{ "version", 0 },
-#define HELPSW 7
+#define HELPSW 3
{ "help", 0 },
{ NULL, 0 }
};
** static prototypes
*/
static int find_delim(int, struct smsg *);
-static void burst(struct msgs **, int, struct smsg *, int, int, int, char *);
+static void burst(struct msgs **, int, struct smsg *, int, int, char *);
static void cpybrst(FILE *, FILE *, char *, char *, int);
int
main(int argc, char **argv)
{
- int inplace = 0, quietsw = 0, verbosw = 0;
+ int verbosw = 0;
int msgp = 0, hi, msgnum, numburst;
char *cp, *maildir, *folder = NULL, buf[BUFSIZ];
char **argp, **arguments, *msgs[MAXARGS];
print_version(invo_name);
done(1);
- case INPLSW:
- inplace++;
- continue;
- case NINPLSW:
- inplace = 0;
- continue;
-
- case QIETSW:
- quietsw++;
- continue;
- case NQIETSW:
- quietsw = 0;
- continue;
-
case VERBSW:
verbosw++;
continue;
/* burst all the SELECTED messages */
for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
if (is_selected(mp, msgnum)) {
- if ((numburst = find_delim(msgnum, smsgs)) >= 1) {
+ if ((numburst = find_delim(msgnum, smsgs)) > 0) {
if (verbosw)
printf("%d message%s exploded from digest %d\n", numburst, numburst > 1 ? "s" : "", msgnum);
- burst(&mp, msgnum, smsgs, numburst, inplace, verbosw, maildir);
+ burst(&mp, msgnum, smsgs, numburst, verbosw, maildir);
+ } else if (numburst == 0) {
+ admonish(NULL, "message %d not in digest format", msgnum);
} else {
- if (numburst == 0) {
- if (!quietsw)
- admonish(NULL, "message %d not in digest format", msgnum);
- } /* this pair of braces was missing before 1999-07-15 */
- else
- adios(NULL, "burst() botch -- you lose big");
+ adios(NULL, "burst() botch -- you lose big");
}
}
}
- free((char *) smsgs);
- context_replace(curfolder, folder); /* update current folder */
+ free(smsgs);
+ context_replace(curfolder, folder);
/*
- ** If -inplace is given, then the first message burst becomes
- ** the current message (which will now show a table of contents).
- ** Otherwise, the first message extracted from the first digest
+ ** The first message extracted from the first digest
** becomes the current message.
*/
- if (inplace) {
- if (mp->lowsel != mp->curmsg)
- seq_setcur(mp, mp->lowsel);
- } else {
- if (hi <= mp->hghmsg)
- seq_setcur(mp, hi);
+ if (hi <= mp->hghmsg) {
+ seq_setcur(mp, hi);
}
- seq_save(mp); /* synchronize message sequences */
- context_save(); /* save the context file */
- folder_free(mp); /* free folder/message structure */
+ seq_save(mp);
+ context_save();
+ folder_free(mp);
done(0);
return 1;
}
** Scan the message and find the beginning and
** end of all the messages in the digest.
*/
-
static int
find_delim(int msgnum, struct smsg *smsgs)
{
if ((in = fopen(msgnam = m_name(msgnum), "r")) == NULL)
adios(msgnam, "unable to read message");
- for (msgp = 0, pos = 0L; msgp <= MAXFOLDER;) {
+ for (msgp = 0, pos = 0L; msgp <= MAXFOLDER; msgp++) {
while (fgets(buffer, sizeof(buffer), in) && buffer[0] == '\n')
pos += (long) strlen(buffer);
- if (feof(in))
+ if (feof(in)) {
break;
+ }
fseek(in, pos, SEEK_SET);
smsgs[msgp].s_start = pos;
wasdlm = strncmp(buffer, delim3, ld3) == 0;
if (smsgs[msgp].s_start != pos)
- smsgs[msgp++].s_stop = (c == '\n' && wasdlm) ?
+ smsgs[msgp].s_stop = (c == '\n' && wasdlm) ?
pos - 1 : pos;
if (feof(in)) {
break;
}
fclose(in);
- return (msgp - 1); /* toss "End of XXX Digest" */
+ return (msgp > 0) ? msgp-1 : 0; /* toss "End of XXX Digest" */
}
/*
** Burst out the messages in the digest into the folder
*/
-
static void
burst(struct msgs **mpp, int msgnum, struct smsg *smsgs, int numburst,
- int inplace, int verbosw, char *maildir)
+ int verbosw, char *maildir)
{
int i, j, mode;
char *msgnam;
- char f1[BUFSIZ], f2[BUFSIZ], f3[BUFSIZ];
+ char destfil[BUFSIZ];
FILE *in, *out;
struct stat st;
struct msgs *mp;
mp = *mpp;
/*
- ** See if we have enough space in the folder
+ ** Ensure we have enough space in the folder
** structure for all the new messages.
*/
- if ((mp->hghmsg + numburst > mp->hghoff) &&
- !(mp = folder_realloc(mp, mp->lowoff, mp->hghmsg + numburst)))
+ if ((mp->hghmsg + numburst > mp->hghoff) && !(mp = folder_realloc(mp,
+ mp->lowoff, mp->hghmsg + numburst)))
adios(NULL, "unable to allocate folder storage");
*mpp = mp;
- j = mp->hghmsg; /* old value */
- mp->hghmsg += numburst;
- mp->nummsg += numburst;
-
/*
- ** If this is not the highest SELECTED message, then
- ** increment mp->hghsel by numburst, since the highest
- ** SELECTED is about to be slid down by that amount.
- */
- if (msgnum < mp->hghsel)
- mp->hghsel += numburst;
-
- /*
- ** If -inplace is given, renumber the messages after the
- ** source message, to make room for each of the messages
- ** contained within the digest.
- **
- ** This is equivalent to refiling a message from the point
- ** of view of the external hooks.
- */
- if (inplace) {
- for (i = mp->hghmsg; j > msgnum; i--, j--) {
- strncpy(f1, m_name(i), sizeof(f1));
- strncpy(f2, m_name(j), sizeof(f2));
- if (does_exist(mp, j)) {
- if (verbosw)
- printf("message %d becomes message %d\n", j, i);
-
- if (rename(f2, f1) == NOTOK)
- admonish(f1, "unable to rename %s to", f2);
-
- snprintf(f1, sizeof (f1), "%s/%d", maildir, i);
- snprintf(f2, sizeof (f2), "%s/%d", maildir, j);
- ext_hook("ref-hook", f1, f2);
-
- copy_msg_flags(mp, i, j);
- clear_msg_flags(mp, j);
- mp->msgflags |= SEQMOD;
- }
- }
- }
-
- unset_selected(mp, msgnum);
-
- /* new hghmsg is hghmsg + numburst
- **
** At this point, there is an array of numburst smsgs, each
** element of which contains the starting and stopping offsets
- ** (seeks) of the message in the digest. The inplace flag is set
- ** if the original digest is replaced by a message containing
- ** the table of contents. smsgs[0] is that table of contents.
- ** Go through the message numbers in reverse order (high to low).
- **
- ** Set f1 to the name of the destination message, f2 to the name
- ** of a scratch file. Extract a message from the digest to the
- ** scratch file. Move the original message to a backup file if
- ** the destination message number is the same as the number of
- ** the original message, which only happens if the inplace flag
- ** is set. Then move the scratch file to the destination message.
- **
- ** Moving the original message to the backup file is equivalent
- ** to deleting the message from the point of view of the external
- ** hooks. And bursting each message is equivalent to adding a
- ** new message.
+ ** (seeks) of the message in the digest. Go through the message
+ ** numbers. Ignore smsgs[0], which is the table of contents.
*/
-
- i = inplace ? msgnum + numburst : mp->hghmsg;
- for (j = numburst; j >= (inplace ? 0 : 1); i--, j--) {
- strncpy(f1, m_name(i), sizeof(f1));
- strncpy(f2, m_mktemp(invo_name, NULL, &out), sizeof(f2));
-
- if (verbosw && i != msgnum)
+ for (j=1, i=mp->hghmsg+1; j<=numburst; j++, i++) {
+ snprintf(destfil, sizeof destfil, "%s/%d", maildir, i);
+ if (!(out = fopen(destfil, "w"))) {
+ adios(destfil, "unable to open");
+ }
+ if (verbosw) {
printf("message %d of digest %d becomes message %d\n",
j, msgnum, i);
-
- chmod(f2, mode);
+ }
+ chmod(destfil, mode);
fseek(in, smsgs[j].s_start, SEEK_SET);
- cpybrst(in, out, msgnam, f2,
+ cpybrst(in, out, msgnam, destfil,
(int) (smsgs[j].s_stop - smsgs[j].s_start));
fclose(out);
-
- if (i == msgnum) {
- strncpy(f3, m_backup(f1), sizeof(f3));
- if (rename(f1, f3) == NOTOK)
- admonish(f3, "unable to rename %s to", f1);
-
- snprintf(f3, sizeof (f3), "%s/%d", maildir, i);
- ext_hook("del-hook", f3, NULL);
- }
- if (rename(f2, f1) == NOTOK)
- admonish(f1, "unable to rename %s to", f2);
-
- snprintf(f3, sizeof (f3), "%s/%d", maildir, i);
- ext_hook("add-hook", f3, NULL);
-
+ mp->hghmsg++;
+ mp->nummsg++;
+ /*
+ ** Bursting each message is equivalent to adding a
+ ** new message from the point of view of the external hooks.
+ */
+ ext_hook("add-hook", destfil, NULL);
copy_msg_flags(mp, i, msgnum);
mp->msgflags |= SEQMOD;
}
-
fclose(in);
}
-#define S1 0
-#define S2 1
-#define S3 2
-
/*
-** Copy a mesage which is being burst out of a digest.
+** Copy a message which is being burst out of a digest.
** It will remove any "dashstuffing" in the message.
*/
-
static void
cpybrst(FILE *in, FILE *out, char *ifile, char *ofile, int len)
{
- register int c, state;
+ int c;
+ enum { S1, S2, S3 } state;
for (state = S1; (c = fgetc(in)) != EOF && len > 0; len--) {
if (c == 0)