burst - undigestifier program

By James T Perkins ·

TML message #1740From bundle 143

This program splits a TML digest (or a TML bundle, or any forward- or
digest-format message) on its input stream and seperates it into its
component messages, and mails them back to the invoker.  this may sound
preverse but it's way cool! I know, I didn't think much of it until I
tried it.

>From a mail program that lets you pipe to a program with a "|" command,
you can do: "| burst", for example.  If you can get at a message from a
shell command line, you can do "burst <digest-file".  Have fun folks.

Make sure you read the comment header so you know exactly what it does,
prior to running it.  If you are not on a unix system, with any decent
editor you should be able to extract the source code (all source lines
begin with X).

James
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Traveller Mailing List Administrator	     James T Perkins @ Tektronix, Inc
[email removed]                      	     Beaverton, Oregon, USA
[email removed]                              "Load Auto/Evade, Beowulf!"

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  burst.c
# Wrapped by [email removed] on Fri Nov  9 13:53:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f burst.c -a "${1}" != "-c" ; then
  echo shar: Will not over-write existing file \"burst.c\"
else
echo shar: Extracting \"burst.c\" \(5352 characters\)
sed "s/^X//" >burst.c <<'END_OF_burst.c'
X/*
X * NAME
X *	burst - burst a mail digest file and resend the messages to user
X *
X * SYNOPSIS
X *	cat digest-mail | burst
X *
X * DESCRIPTION
X *	Burst takes a MH-style digest or forwarded mail message on
X *	stdin, and seperates it into the individual internal messages.
X *	It then mails all the mail files back to the user running burst.
X *	It knows to ignore the leading digest summary and trailing
X *	digest end marker, as well as empty messages.  It also knows how
X *	to remove "- " from the beginning of "escaped" lines that start
X *	with "- -".
X *
X *	By defining the BURSTUSER environment variable, mail may be sent
X *	to a different user than the person running the burst program.
X *
X * ENVIRONMENT
X *	BURSTUSER, USER, LOGNAME - these hold the user's login name for
X *	the purposes of resending the mail.  If BURSTUSER is not defined,
X *	USER is used.  If USER isn't defined, LOGNAME is used.
X *
X * COMPILATION NOTE
X *	Define -DHAS_MKSTEMP when compiling on systems which have
X *	mkstemp() and no mktemp().
X *
X * AUTHOR
X *	James Perkins, [email removed], 9 Nov 1990
X *	This is shareware; file is freely distributable and modifiable.
X *	I assume no responsibility for use or misuse of this program,
X *	nor do I declare it fit for any particular application.
X *
X * HISTORY
X *	Inspired by a program by Ted Kim, [email removed].
X *	Burst was written for members of the Traveller Electronic Mailing
X *	List; contact [email removed] for details.
X *
X * BUGS
X *	Burst assumes a Unix-like mail and execution environment.
X */
X
X#include <stdio.h>
X#include <string.h>
X#ifndef HAS_MKSTEMP
X#include <sys/file.h>
X#endif
X
Xextern char *getenv();
Xextern char *sprintf();
X#ifndef HAS_MKSTEMP
Xextern char *mktemp();
X#endif
X
Xtypedef int bool;
X
X#define TRUE		1	/* for bool types */
X#define FALSE		0	/* for bool types */
X
X#define TMPNAMELEN	60	/* max temporary file name length */
X#define BUFLEN		256	/* max line length handleable */
X#define CMDLEN		256	/* max length for mail system() call cmd */
X
X#define TMPNAME		"/tmp/burstXXXXXXX"	/* tmp file to use */
X#define END_STRING	"End of "	/* first line of end of digest msg */
X#define MAIL		"/bin/mail"	/* mail program to use */
X
X/* macro to see if the beginning of a string matches another string */
X#define STRMATCH(s, t)	(strncmp((s), (t), strlen(t)) == 0)
X
X/* forward declarations */
Xchar *tmp_file_name();
Xbool extract_message();
Xvoid mail_file();
X
Xmain()
X{
X    char *tmp;
X    FILE *fp;
X    int mailable;
X    char *user;
X
X    if ((user = getenv("BURSTUSER")) == NULL)
X    {
X	if ((user = getenv("USER")) == NULL)
X	{
X	    if ((user = getenv("LOGNAME")) == NULL)
X	    {
X		(void)fprintf(stderr,
X		    "burst: can't find USER or LOGNAME envariable\n");
X		exit(1);
X	    }
X	}
X    }
X
X    while (!feof(stdin))
X    {
X	tmp = tmp_file_name(&fp);
X	if (fp == NULL)
X	{
X	    perror(tmp);
X	    exit(1);
X	}
X	mailable = extract_message(stdin, fp);
X	(void)fclose(fp);
X
X	if (mailable)
X	{
X	    mail_file(tmp, user);
X	}
X
X	(void)unlink(tmp);
X    }
X}
X
Xchar *
Xtmp_file_name(fpp)
XFILE **fpp;
X{
X    static char tmpname[TMPNAMELEN];
X    int fd;
X
X    (void)strcpy(tmpname, TMPNAME);
X
X#ifndef HAS_MKSTEMP
X    (void)mktemp(tmpname);
X    fd = open(tmpname, O_CREAT | O_RDWR | O_EXCL, 0644);
X#else
X    fd = mkstemp(tmpname);
X#endif
X    if (fd == NULL)
X    {
X	*fpp = NULL;
X    }
X    else
X    {
X	/* wrap stdio info around filedes */
X	*fpp = fdopen(fd, "w");
X    }
X
X    return tmpname;
X}
X
X/*
X * Read to the next line commencing with a pair of dashes. Store all
X * this in the output file. Delete any leading blank lines. Any line
X * beginning with "- -" should have the leading "- " deleted. the
X * terminating line, beginning with a pair of dashes, is not to be
X * echoed.
X *
X * If this is the first message extracted or the first nonblank line
X * matches END_STRING, or there is no text to the message, return code
X * mailable FALSE. Otherwise, return mailable TRUE.
X */
X
Xbool
Xextract_message(fin, fout)
XFILE *fin, *fout;
X{
X    static bool first_time = TRUE;
X    bool leading = TRUE;
X    char buf[BUFLEN];
X    bool mailable = TRUE;
X
X    if (first_time)
X    {
X	/* don't mail header */
X	first_time = FALSE;
X	mailable = FALSE;
X    }
X
X    while (!feof(fin))
X    {
X	if (fgets(buf, sizeof(buf), fin) == NULL)
X	{
X	    /* no dash line seperator - this definitely isn't mailable */
X	    mailable = FALSE;
X	    break;
X	}
X
X	if (STRMATCH(buf, "--"))
X	{
X	    /* two dashes - end of message */
X	    break;
X	}
X
X	if (leading && STRMATCH(buf, "\n"))
X	{
X	    /* blank leading line - eat it */
X	    continue;
X	}
X
X	if (leading && STRMATCH(buf, END_STRING))
X	{
X	    /* tail of digest - don't mail this */
X	    mailable = FALSE;
X	}
X
X	/* first line of message text */
X	leading = FALSE;
X
X	if (STRMATCH(buf, "- -"))
X	{
X	    /* escaped dash line - echo, deleting leading "- " */
X	    fputs(buf + 2, fout);
X	}
X	else
X	{
X	    /* normal line - echo */
X	    fputs(buf, fout);
X	}
X    }
X
X    if (leading == TRUE)
X    {
X	/* No text in the mail message */
X	return FALSE;
X    }
X
X    return mailable;
X}
X
X/*
X * Mail the tmp file to the user
X */
X
Xvoid
Xmail_file(tmpfile, user)
Xchar *tmpfile;
Xchar *user;
X{
X    char cmd[CMDLEN];
X    int code;
X
X    (void)sprintf(cmd, "%s %s <%s", MAIL, user, tmpfile);
X    if ((code = system(cmd)) != 0)
X    {
X	(void)fprintf(stderr, "burst: command \"%s\" returned exit code %d\n",
X	    cmd, code);
X	exit(code);
X    }
X}
END_OF_burst.c
if test 5352 -ne `wc -c <burst.c`; then
    echo shar: \"burst.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0