#line 1026 "../../src/builtin/snarf.m4"
/* -*- buffer-read-only: t -*- vi: set ro:
   THIS FILE IS GENERATED AUTOMATICALLY.  PLEASE DO NOT EDIT.
*/
#line 1026
#ifdef HAVE_CONFIG_H
#line 1026
# include <config.h>
#line 1026
#endif
#line 1026
#include <sys/types.h>
#line 1026

#line 1026
#include "mailfromd.h"
#line 1026
#include "prog.h"
#line 1026
#include "builtin.h"
#line 1026

#line 1026

#line 1066 "../../src/builtin/snarf.m4"

/* End of snarf.m4 */
#line 1 "burst.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2011-2025 Sergey Poznyakoff

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

/* Functions for converting RFC-934 digests into MIME messages.
   Largely inspired by MU's mh/burst.c */


#include <mflib/status.h>
#include "msg.h"
#include "global.h"

#define DEFAULT_EB_LEN 2

/* Minimal length of encapsulation boundary */
static size_t burst_eb_min_length_loc
#line 28 "burst.bi"
;

/* Digest messages */

/* Bursting FSA states according to RFC 934:
   
      S1 ::   "-" S3
            | CRLF {CRLF} S1
            | c {c} S2

      S2 ::   CRLF {CRLF} S1
            | c {c} S2

      S3 ::   " " S2
            | c S4     ;; the bursting agent should consider the current
	               ;; message ended.  

      S4 ::   CRLF S5
            | c S4

      S5 ::   CRLF S5
            | c {c} S2 ;; The bursting agent should consider a new
	               ;; message started
*/

#define S1 1
#define S2 2
#define S3 3
#define S4 4
#define S5 5

/* Negative state means no write */
static int transtab[5][256] = {
/* S1 */ {  S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S1,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2, -S3,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2 },
/* S2 */ {  S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S1,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2 },
/* S3 */ { -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S2, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4 },
/* S4 */ { -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S5, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4, 
           -S4, -S4, -S4, -S4, -S4, -S4, -S4, -S4 },
/* S5 */ {  S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2, -S5,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2, 
            S2,  S2,  S2,  S2,  S2,  S2,  S2,  S2 }
};

#define F_FIRST  0x01  /* First part of the message (no EB seen so far) */
#define F_ENCAPS 0x02  /* Within encapsulated part */

struct burst_stream {
	mu_mime_t mime;
	mu_stream_t stream;  /* Output stream */
	int flags;           /* See F_ flags above */
	size_t partno;       /* Number of the part within the message */
	int burst_ctl;
};

static void
_cleanup_message(void *ptr)
{
	mu_message_t msg = ptr;
	mu_message_destroy(&msg, mu_message_get_owner(msg));
}

static void
_cleanup_header(void *ptr)
{
	mu_header_t hdr = ptr;
	mu_header_destroy(&hdr);
}

static void
_cleanup_body(void *ptr)
{
	mu_body_t body = ptr;
	mu_body_destroy(&body, mu_body_get_owner(body));
}

static mu_message_t
create_temp_message(eval_environ_t env, mu_stream_t stream)
{
	int rc;
	mu_header_t hdr;
	mu_body_t body;
	mu_message_t msg;
	
		if (!((rc = mu_message_create(&msg, NULL)) == 0))
#line 263
		(
#line 263
	env_throw_bi(env, mfe_failure, NULL, "mu_message_create: %s",mu_strerror(rc))
#line 263
)
#line 266
;
	env_function_cleanup_add(env, CLEANUP_THROW, msg, _cleanup_message);

		if (!((rc = mu_header_create(&hdr, "\n", 1)) == 0))
#line 269
		(
#line 269
	env_throw_bi(env, mfe_failure, NULL, "mu_header_create: %s",mu_strerror(rc))
#line 269
)
#line 272
;
	env_function_cleanup_add(env, CLEANUP_THROW, hdr, _cleanup_header);

		if (!((rc = mu_body_create(&body, msg)) == 0))
#line 275
		(
#line 275
	env_throw_bi(env, mfe_failure, NULL, "mu_body_create: %s",mu_strerror(rc))
#line 275
)
#line 278
;
	env_function_cleanup_add(env, CLEANUP_THROW, body, _cleanup_body);

	/* FIXME: MU: mu_body_set_stream does not change stream's refcount */
		if (!((rc = mu_body_set_stream(body, stream, msg)) == 0))
#line 282
		(
#line 282
	env_throw_bi(env, mfe_failure, NULL, "mu_body_set_stream: %s",mu_strerror(rc))
#line 282
)
#line 285
;
	
	mu_message_set_header(msg, hdr, NULL);
	mu_message_set_body(msg, body, NULL);
	
        env_function_cleanup_del(env, CLEANUP_THROW,msg);
	env_function_cleanup_del(env, CLEANUP_THROW,hdr);
	env_function_cleanup_del(env, CLEANUP_THROW,body);
	return msg;
}

static inline void
finish_stream(eval_environ_t env, struct burst_stream *bs)
{
	if (bs->stream) {
		int rc;
		mu_message_t msg;
      
		bs->flags &= ~F_FIRST;
		mu_stream_seek(bs->stream, 0, SEEK_SET, NULL);
		rc = mu_stream_to_message(bs->stream, &msg);
		if (rc == MU_ERR_INVALID_EMAIL) {
			switch (bs->burst_ctl & _MFL_BURST_ERR_MASK) {
			case _MFL_BURST_ERR_FAIL:
				(
#line 309
	env_throw_bi(env, mfe_failure, NULL, "mu_stream_to_message: %s",mu_strerror (rc))
#line 309
);
#line 312
				
			case _MFL_BURST_ERR_IGNORE:
				mu_stream_unref(bs->stream);
				bs->stream = 0;
				return;

			case _MFL_BURST_ERR_BODY:
				msg = create_temp_message(env, bs->stream);
			}				
		} else
				if (!(rc == 0))
#line 322
		(
#line 322
	env_throw_bi(env, mfe_failure, NULL, "mu_stream_to_message: %s",mu_strerror(rc))
#line 322
)
#line 325
;
		mu_mime_add_part(bs->mime, msg);
		mu_message_unref(msg);
		bs->stream = 0;
		bs->partno++;
	}
}  

static inline void
flush_stream(eval_environ_t env, struct burst_stream *bs,
	     char *buf, size_t size)
{
	int rc;

	if (size == 0)
		return;
	if (!bs->stream) {
		rc = mu_temp_file_stream_create(&bs->stream, NULL, 0);
			if (!(rc == 0))
#line 343
		(
#line 343
	env_throw_bi(env, mfe_failure, NULL, _("Cannot open temporary file: %s"),mu_strerror(rc))
#line 343
)
#line 346
;
		/*
		mu_stream_printf(bs->stream, "X-Burst-Part: 0 %lu %02x\n",
				 (unsigned long) bs->partno, bs->flags);
		if (!bs->flags)
			mu_stream_write(bs->stream, "\n", 1, NULL);
		*/
	}

	rc = mu_stream_write(bs->stream, buf, size, NULL);
		if (!(rc == 0))
#line 356
		(
#line 356
	env_throw_bi(env, mfe_failure, NULL, _("error writing temporary stream: %s"),mu_strerror(rc))
#line 356
)
#line 359
;
}

static void
burst_stream_cleanup(void *data)
{
	struct burst_stream *bs = data;
	mu_stream_unref(bs->stream);
	mu_mime_destroy(&bs->mime);
	free(bs);
}

/* Burst an RFC 934 digest.  Return 0 if OK, 1 if the message is not
   a valid digest. */
int
burst_digest(eval_environ_t env, mu_mime_t mime, mu_message_t msg,
	     int ctl)
{
	int rc;
	mu_body_t body;
	mu_header_t hdr;
	mu_stream_t is;
	const char *encoding;
	unsigned char c;
	size_t n;
	int state = S1;
	int eb_length = 0;
	struct burst_stream *bs;
	int result = 0;

	int eb_min_length = mf_c_val(*env_data_ref(env, burst_eb_min_length_loc),int) ;
	if (eb_min_length <= 0)
		eb_min_length = DEFAULT_EB_LEN;

	bs = mu_alloc(sizeof(*bs));
	bs->mime = mime;
	bs->stream = NULL;
	bs->flags = F_FIRST;
	bs->partno = 1;
	bs->burst_ctl = ctl;
	env_function_cleanup_add(env, CLEANUP_ALWAYS, bs, burst_stream_cleanup);
		
	rc = mu_message_get_body(msg, &body);
		if (!(rc == 0))
#line 402
		(
#line 402
	env_throw_bi(env, mfe_failure, NULL, "mu_message_get_body: %s",mu_strerror(rc))
#line 402
)
#line 405
;
	
	rc = mu_body_get_streamref(body, &is);
		if (!(rc == 0))
#line 408
		(
#line 408
	env_throw_bi(env, mfe_failure, NULL, "mu_body_get_streamref: %s",mu_strerror(rc))
#line 408
)
#line 411
;
	env_function_cleanup_add(env, CLEANUP_ALWAYS, is, _builtin_stream_cleanup);

	if (ctl & _MFL_BURST_DECODE) {
		rc = mu_message_get_header(msg, &hdr);
			if (!(rc == 0))
#line 416
		(
#line 416
	env_throw_bi(env, mfe_failure, NULL, "mu_message_get_header: %s",mu_strerror(rc))
#line 416
)
#line 419
;

		if (mu_header_sget_value(hdr,
					 MU_HEADER_CONTENT_TRANSFER_ENCODING,
					 &encoding) == 0) {
			char *args[3];
			mu_stream_t flt;
			
			args[0] = (char*)encoding;
			args[1] = "+";
			args[2] = "CRLF";
		
			rc = mu_filter_chain_create(&flt, is,
						    MU_FILTER_DECODE,
						    MU_STREAM_READ,
						    3, args);
			if (rc == 0) {
				is = flt;
			} else if (rc == MU_ERR_NOENT)
				/* FIXME: nothing to do? */;
			else
				(
#line 440
	env_throw_bi(env, mfe_failure, NULL, "mu_filter_create(%s): %s",encoding,mu_strerror(rc))
#line 440
);
#line 444
		}
	}
	
	while (mu_stream_read(is, &c, 1, &n) == 0 && n == 1) {
		int newstate = transtab[state - 1][c];
		int silent = 0;
      
		if (newstate < 0) {
			newstate = -newstate;
			silent = 1;
		}

		if (state == S1) {
			if (newstate == S1) {
				if (bs->flags == F_FIRST)
					silent = 1;
			} else if (newstate == S3) {
				/* GNU extension: check if we have seen enough
				   dashes to constitute a valid encapsulation
				   boundary. */
				
				eb_length++;
				if (eb_length < eb_min_length)
					continue; /* Ignore state change */
				if (eb_min_length > 1) {
					newstate = S4;
					finish_stream(env, bs);
					bs->flags ^= F_ENCAPS;
				}
			} else
				for (; eb_length; eb_length--)
					flush_stream(env, bs, "-", 1);
			eb_length = 0;
		} else if (state == S5 && newstate == S2) {
			/* As the automaton traverses from state S5 to S2, the
			   bursting agent should consider a new message started
			   and output the first character. */
			finish_stream(env, bs);
		} else if (state == S3 && newstate == S4) {
			/* As the automaton traverses from state S3 to S4, the
			   bursting agent should consider the current message
			   ended. */
			finish_stream(env, bs);
			bs->flags ^= F_ENCAPS;
		}
		state = newstate;
		if (!silent)
			flush_stream(env, bs, (char*)&c, 1);
	}

	if (bs->flags == F_FIRST) {
		mu_stream_destroy(&bs->stream);
		result = 1;
	} else {
		if (bs->stream) {
			mu_off_t size = 0;
			mu_stream_size(bs->stream, &size);
			if (size)
				finish_stream(env, bs);
			else
				mu_stream_destroy(&bs->stream);
		}
		bs->mime = NULL;
	}
//FIXME	MF_CLEANUP(bs);
	return result;
}

void
#line 512
bi_message_burst(eval_environ_t env)
#line 512

#line 512

#line 512 "burst.bi"
{
#line 512
	
#line 512

#line 512
        long  nmsg;
#line 512
        long  flags;
#line 512
        
#line 512
        long __bi_argcnt;
#line 512
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 512
        get_numeric_arg(env, 1, &nmsg);
#line 512
        if (__bi_argcnt > 1)
#line 512
                get_numeric_arg(env, 2, &flags);
#line 512
        
#line 512
        adjust_stack(env, __bi_argcnt + 1);
#line 512

#line 512

#line 512
	if (builtin_module_trace(BUILTIN_IDX_burst))
#line 512
		prog_trace(env, "message_burst %lu %lu",nmsg, ((__bi_argcnt > 1) ? flags : 0));;
#line 512

{
	int rc;
	mu_message_t msg;
	mu_mime_t mime;
	
	msg = bi_message_from_descr(env, nmsg);
	rc = mu_mime_create(&mime, NULL, 0);
		if (!(rc == 0))
#line 520
		(
#line 520
	env_throw_bi(env, mfe_failure, "message_burst", "mu_mime_create: %s",mu_strerror(rc))
#line 520
)
#line 523
;
	
	rc = burst_digest(env, mime, msg,
			  ((__bi_argcnt > 1) ? flags : _MFL_BURST_ERR_FAIL));
		if (!(rc == 0))
#line 527
		(
#line 527
	env_throw_bi(env, mfe_format, "message_burst", _("message is not a RFC-934 digest"))
#line 527
)
#line 529
;
	rc = mu_mime_to_message(mime, &msg);
	mu_mime_unref(mime);
		if (!(rc == 0))
#line 532
		(
#line 532
	env_throw_bi(env, mfe_failure, "message_burst", "mu_mime_get_message: %s",mu_strerror(rc))
#line 532
)
#line 535
;
	rc = bi_message_register(env, NULL, msg, MF_MSG_STANDALONE);
	if (rc < 0) {
		mu_message_destroy(&msg, mu_message_get_owner(msg));
		(
#line 539
	env_throw_bi(env, mfe_failure, "message_burst", _("no more message slots available"))
#line 539
);
#line 541
	}
	
#line 542
do {
#line 542
  push(env, (STKVAL)(mft_number)(rc));
#line 542
  goto endlab;
#line 542
} while (0);
}
endlab:
#line 544
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 544
	return;
#line 544
}

 	 
#line 550
	 
#line 1026 "../../src/builtin/snarf.m4"

#line 1026

#line 1026

#line 1026
void
#line 1026
burst_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 28 "burst.bi"
	builtin_variable_install("burst_eb_min_length", dtype_number, SYM_VOLATILE|SYM_PRECIOUS, &burst_eb_min_length_loc);
#line 512 "burst.bi"
va_builtin_install_ex("message_burst", bi_message_burst, 0, dtype_number, 2, 1, 0|0, dtype_number, dtype_number);

#line 1026 "../../src/builtin/snarf.m4"
	
#line 1026
	 long n = DEFAULT_EB_LEN;
#line 1026
         ds_init_variable("burst_eb_min_length", &n);
#line 1026

#line 1026
}
#line 1026 "../../src/builtin/snarf.m4"

