#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 "msg.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2008-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/>. */



#include "msg.h"
#include "global.h"

static size_t nmsgs = MAX_MSGS;

static struct mu_cfg_param msg_cfg_param[] = {
	{ "max-open-messages", mu_c_size, &nmsgs, 0, NULL,
	  N_("Maximum number of messages to open simultaneously.") },
	{ NULL }
};

static void *
alloc_msgs()
{
	return mu_calloc(nmsgs, sizeof(struct mf_message));
}

static void
destroy_msgs(void *data)
{
	struct mf_message *mtab = data;
	struct mf_message *p;
	for (p = mtab; p < mtab + nmsgs; p++) {
		bi_close_message(p);
	}
	free(mtab);
}

void
drop_current_message(void *data)
{
	int i;
	struct mf_message *tab = data;
	for (i = 0; i < nmsgs; i++)
		if (tab[i].msg && tab[i].type == MF_MSG_CURRENT) {
			bi_close_message(&tab[i]);
			break;
		}
}


#line 59

#line 59
static int MSGTAB_id;
#line 59 "msg.bi"


static int
find_slot(struct mf_message *tab)
{
	int i;
	for (i = 0; i < nmsgs; i++)
		if (tab[i].msg == NULL)
			return i;
	return -1;
}

static int
do_msg_close(void *item, void *data)
{
	bi_close_message(item);
	return 0;
}

void
bi_close_message(struct mf_message *mp)
{
	if (mp->msg) {
		mu_stream_destroy(&mp->mstr);
		mu_stream_destroy(&mp->bstr);
		if (mp->type == MF_MSG_STANDALONE)
			mu_message_destroy(&mp->msg,
					   mu_message_get_owner(mp->msg));
		mu_list_foreach(mp->msglist, do_msg_close, NULL);
		mu_list_destroy(&mp->msglist);
		free(mp->buf);
		memset(mp, 0, sizeof *mp);
	}
}

int
bi_message_register(eval_environ_t env,
		    mu_list_t msglist, mu_message_t msg, int type)
{
	struct mf_message *msgtab = env_get_builtin_priv(env,MSGTAB_id);
	int idx = find_slot(msgtab);
	if (idx >= 0) {
		struct mf_message *mp = msgtab + idx;
		mp->msg = msg;
		mp->type = type;
		mu_list_create(&mp->msglist);
		if (msglist)
			mu_list_append(msglist, mp);
	}
	return idx;
}

int
bi_get_current_message(eval_environ_t env, mu_message_t *ret_msg)
{
	int i;
	struct mf_message *tab = env_get_builtin_priv(env,MSGTAB_id);
	mu_stream_t mstr;
	mu_message_t msg;
	int rc;

	for (i = 0; i < nmsgs; i++)
		if (tab[i].msg && tab[i].type == MF_MSG_CURRENT) 
			break;
 	if (i == nmsgs) {
		rc = env_get_stream(env,&mstr);
			if (!(rc >= 0))
#line 125
		(
#line 125
	env_throw_bi(env, mfe_failure, NULL, _("cannot obtain capture stream reference: %s"),mu_strerror(rc))
#line 125
)
#line 128
;
		msg = _builtin_mu_stream_to_message(mstr, env, NULL);
		i = bi_message_register(env, NULL, msg, MF_MSG_CURRENT);
			if (!(i >= 0))
#line 131
		(
#line 131
	env_throw_bi(env, mfe_failure, NULL, _("no more message slots available"))
#line 131
)
#line 133
;
	}
	if (ret_msg)
		*ret_msg = tab[i].msg;
	return i;
}


#line 152


#line 163


#line 174


#line 192


mu_message_t
bi_message_from_descr(eval_environ_t env, int nmsg)
{
	
#line 197
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 197
	struct mf_message *mp;
#line 197
			
#line 197
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 197
		(
#line 197
	env_throw_bi(env, mfe_range, NULL, _("invalid message descriptor"))
#line 197
)
#line 197
;
#line 197
	mp = mtab + nmsg;
#line 197
		if (!(mp->msg))
#line 197
		(
#line 197
	env_throw_bi(env, mfe_failure, NULL, _("message not open"))
#line 197
)
#line 197

#line 197
;
	return mp->msg;
}

/* void message_close(number msg) */
void
#line 202
bi_message_close(eval_environ_t env)
#line 202

#line 202

#line 202 "msg.bi"
{
#line 202
	
#line 202

#line 202
        long  nmsg;
#line 202
        
#line 202

#line 202
        get_numeric_arg(env, 0, &nmsg);
#line 202
        
#line 202
        adjust_stack(env, 1);
#line 202

#line 202

#line 202
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 202
		prog_trace(env, "message_close %lu",nmsg);;
#line 202

{
	
#line 204
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 204
	struct mf_message *mp;
#line 204
			
#line 204
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 204
		(
#line 204
	env_throw_bi(env, mfe_range, "message_close", _("invalid message descriptor"))
#line 204
)
#line 204
;
#line 204
	mp = mtab + nmsg;
#line 204
		if (!(mp->msg))
#line 204
		(
#line 204
	env_throw_bi(env, mfe_failure, "message_close", _("message not open"))
#line 204
)
#line 204

#line 204
;
	bi_close_message(mp);
}

#line 207
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 207
	return;
#line 207
}

/* number message_size(number nmsg) */
void
#line 210
bi_message_size(eval_environ_t env)
#line 210

#line 210

#line 210 "msg.bi"
{
#line 210
	
#line 210

#line 210
        long  nmsg;
#line 210
        
#line 210

#line 210
        get_numeric_arg(env, 0, &nmsg);
#line 210
        
#line 210
        adjust_stack(env, 1);
#line 210

#line 210

#line 210
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 210
		prog_trace(env, "message_size %lu",nmsg);;
#line 210

{
	int rc;
	size_t size;
	
#line 214
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 214
	struct mf_message *mp;
#line 214
			
#line 214
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 214
		(
#line 214
	env_throw_bi(env, mfe_range, "message_size", _("invalid message descriptor"))
#line 214
)
#line 214
;
#line 214
	mp = mtab + nmsg;
#line 214
		if (!(mp->msg))
#line 214
		(
#line 214
	env_throw_bi(env, mfe_failure, "message_size", _("message not open"))
#line 214
)
#line 214

#line 214
;
	
	rc = mu_message_size(mp->msg, &size);
		if (!(rc == 0))
#line 217
		(
#line 217
	env_throw_bi(env, mfe_failure, "message_size", "%s",mu_strerror(rc))
#line 217
)
#line 219
;
		if (!(size < LONG_MAX))
#line 220
		(
#line 220
	env_throw_bi(env, mfe_range, "message_size", _("message size out of representable range"))
#line 220
)
#line 222
;
	
#line 223
do {
#line 223
  push(env, (STKVAL)(mft_number)((long)size));
#line 223
  goto endlab;
#line 223
} while (0);
}	
endlab:
#line 225
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 225
	return;
#line 225
}

/* number message_lines(number nmsg) */
void
#line 228
bi_message_lines(eval_environ_t env)
#line 228

#line 228

#line 228 "msg.bi"
{
#line 228
	
#line 228

#line 228
        long  nmsg;
#line 228
        
#line 228

#line 228
        get_numeric_arg(env, 0, &nmsg);
#line 228
        
#line 228
        adjust_stack(env, 1);
#line 228

#line 228

#line 228
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 228
		prog_trace(env, "message_lines %lu",nmsg);;
#line 228

{
	int rc;
	size_t lines;
	
#line 232
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 232
	struct mf_message *mp;
#line 232
			
#line 232
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 232
		(
#line 232
	env_throw_bi(env, mfe_range, "message_lines", _("invalid message descriptor"))
#line 232
)
#line 232
;
#line 232
	mp = mtab + nmsg;
#line 232
		if (!(mp->msg))
#line 232
		(
#line 232
	env_throw_bi(env, mfe_failure, "message_lines", _("message not open"))
#line 232
)
#line 232

#line 232
;

	rc = mu_message_lines(mp->msg, &lines);
		if (!(rc == 0))
#line 235
		(
#line 235
	env_throw_bi(env, mfe_failure, "message_lines", "%s",mu_strerror(rc))
#line 235
)
#line 238
;
	
#line 239
do {
#line 239
  push(env, (STKVAL)(mft_number)(lines));
#line 239
  goto endlab;
#line 239
} while (0);
}
endlab:
#line 241
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 241
	return;
#line 241
}

/* number message_body_size(number nmsg) */
void
#line 244
bi_message_body_size(eval_environ_t env)
#line 244

#line 244

#line 244 "msg.bi"
{
#line 244
	
#line 244

#line 244
        long  nmsg;
#line 244
        
#line 244

#line 244
        get_numeric_arg(env, 0, &nmsg);
#line 244
        
#line 244
        adjust_stack(env, 1);
#line 244

#line 244

#line 244
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 244
		prog_trace(env, "message_body_size %lu",nmsg);;
#line 244

{
	int rc;
	size_t size;
	
#line 248
	
#line 248
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 248
	struct mf_message *mp;
#line 248
			
#line 248
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 248
		(
#line 248
	env_throw_bi(env, mfe_range, "message_body_size", _("invalid message descriptor"))
#line 248
)
#line 248
;
#line 248
	mp = mtab + nmsg;
#line 248
		if (!(mp->msg))
#line 248
		(
#line 248
	env_throw_bi(env, mfe_failure, "message_body_size", _("message not open"))
#line 248
)
#line 248

#line 248
;
#line 248
	if (!mp->body) {
#line 248
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 248
			if (!(rc == 0))
#line 248
		(
#line 248
	env_throw_bi(env, mfe_failure, "message_body_size", "mu_message_get_body: %s",mu_strerror(rc))
#line 248
)
#line 248
;
#line 248
	}	  
#line 248
;
	
	rc = mu_body_size(mp->body, &size);
		if (!(rc == 0))
#line 251
		(
#line 251
	env_throw_bi(env, mfe_failure, "message_body_size", "%s",mu_strerror(rc))
#line 251
)
#line 253
;
		if (!(size < LONG_MAX))
#line 254
		(
#line 254
	env_throw_bi(env, mfe_range, "message_body_size", _("body size out of representable range"))
#line 254
)
#line 256
;
	
#line 257
do {
#line 257
  push(env, (STKVAL)(mft_number)((long)size));
#line 257
  goto endlab;
#line 257
} while (0);
}
endlab:
#line 259
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 259
	return;
#line 259
}

/* boolean message_body_is_empty(number nmsg) */
void
#line 262
bi_message_body_is_empty(eval_environ_t env)
#line 262

#line 262

#line 262 "msg.bi"
{
#line 262
	
#line 262

#line 262
        long  nmsg;
#line 262
        
#line 262

#line 262
        get_numeric_arg(env, 0, &nmsg);
#line 262
        
#line 262
        adjust_stack(env, 1);
#line 262

#line 262

#line 262
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 262
		prog_trace(env, "message_body_is_empty %lu",nmsg);;
#line 262

{
        int rc, res;
	char c;
	size_t n;
	mu_stream_t input, fstr;
	char *encoding = NULL;

	
#line 270
	
#line 270
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 270
	struct mf_message *mp;
#line 270
			
#line 270
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 270
		(
#line 270
	env_throw_bi(env, mfe_range, "message_body_is_empty", _("invalid message descriptor"))
#line 270
)
#line 270
;
#line 270
	mp = mtab + nmsg;
#line 270
		if (!(mp->msg))
#line 270
		(
#line 270
	env_throw_bi(env, mfe_failure, "message_body_is_empty", _("message not open"))
#line 270
)
#line 270

#line 270
;
#line 270
	if (!mp->body) {
#line 270
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 270
			if (!(rc == 0))
#line 270
		(
#line 270
	env_throw_bi(env, mfe_failure, "message_body_is_empty", "mu_message_get_body: %s",mu_strerror(rc))
#line 270
)
#line 270
;
#line 270
	}	  
#line 270
	if (!mp->hdr) {
#line 270
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 270
			if (!(rc == 0))
#line 270
		(
#line 270
	env_throw_bi(env, mfe_failure, "message_body_is_empty", "mu_message_get_header: %s",mu_strerror(rc))
#line 270
)
#line 270
;
#line 270
	}	  
#line 270
;
	rc = mu_body_size(mp->body, &n);
		if (!(rc == 0))
#line 272
		(
#line 272
	env_throw_bi(env, mfe_failure, "message_body_is_empty", "mu_body_size: %s",mu_strerror(rc))
#line 272
)
#line 274
;
	if (n == 0)
		
#line 276
do {
#line 276
  push(env, (STKVAL)(mft_number)(1));
#line 276
  goto endlab;
#line 276
} while (0);

	rc = mu_body_get_streamref(mp->body, &input);
		if (!(rc == 0))
#line 279
		(
#line 279
	env_throw_bi(env, mfe_failure, "message_body_is_empty", "mu_body_get_streamref: %s",mu_strerror(rc))
#line 279
)
#line 281
;

	mu_header_aget_value_unfold(mp->hdr,
				    MU_HEADER_CONTENT_TRANSFER_ENCODING,
				    &encoding);
	if (encoding) {
		rc = mu_filter_create(&fstr, input, encoding,
				      MU_FILTER_DECODE,
				      MU_STREAM_READ);
		if (rc) {
			mu_error(_("can't create filter for encoding %s: %s"),
				 encoding, mu_strerror(rc));
			fstr = input;
		} else 
			mu_stream_unref(input);
		free(encoding);
	} else
		fstr = input;
	
	res = 1;
	while (mu_stream_read(fstr, &c, 1, &n) == 0 && n > 0) {
		if (!mu_isspace(c)) {
			res = 0;
			break;
		}
	}
	mu_stream_unref(fstr);
	
#line 308
do {
#line 308
  push(env, (STKVAL)(mft_number)(res));
#line 308
  goto endlab;
#line 308
} while (0);
}
endlab:
#line 310
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 310
	return;
#line 310
}
	 
/* number message_body_lines(number nmsg) */
void
#line 313
bi_message_body_lines(eval_environ_t env)
#line 313

#line 313

#line 313 "msg.bi"
{
#line 313
	
#line 313

#line 313
        long  nmsg;
#line 313
        
#line 313

#line 313
        get_numeric_arg(env, 0, &nmsg);
#line 313
        
#line 313
        adjust_stack(env, 1);
#line 313

#line 313

#line 313
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 313
		prog_trace(env, "message_body_lines %lu",nmsg);;
#line 313

{
	int rc;
	size_t lines;
	
#line 317
	
#line 317
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 317
	struct mf_message *mp;
#line 317
			
#line 317
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 317
		(
#line 317
	env_throw_bi(env, mfe_range, "message_body_lines", _("invalid message descriptor"))
#line 317
)
#line 317
;
#line 317
	mp = mtab + nmsg;
#line 317
		if (!(mp->msg))
#line 317
		(
#line 317
	env_throw_bi(env, mfe_failure, "message_body_lines", _("message not open"))
#line 317
)
#line 317

#line 317
;
#line 317
	if (!mp->body) {
#line 317
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 317
			if (!(rc == 0))
#line 317
		(
#line 317
	env_throw_bi(env, mfe_failure, "message_body_lines", "mu_message_get_body: %s",mu_strerror(rc))
#line 317
)
#line 317
;
#line 317
	}	  
#line 317
;

	rc = mu_body_lines(mp->body, &lines);
		if (!(rc == 0))
#line 320
		(
#line 320
	env_throw_bi(env, mfe_failure, "message_body_lines", "%s",mu_strerror(rc))
#line 320
)
#line 323
;
	
#line 324
do {
#line 324
  push(env, (STKVAL)(mft_number)(lines));
#line 324
  goto endlab;
#line 324
} while (0);
}
endlab:
#line 326
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 326
	return;
#line 326
}


/* Headers */

/* number message_header_size(number nmsg) */
void
#line 332
bi_message_header_size(eval_environ_t env)
#line 332

#line 332

#line 332 "msg.bi"
{
#line 332
	
#line 332

#line 332
        long  nmsg;
#line 332
        
#line 332

#line 332
        get_numeric_arg(env, 0, &nmsg);
#line 332
        
#line 332
        adjust_stack(env, 1);
#line 332

#line 332

#line 332
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 332
		prog_trace(env, "message_header_size %lu",nmsg);;
#line 332

{
	int rc;
	size_t size;
	
#line 336
	
#line 336
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 336
	struct mf_message *mp;
#line 336
			
#line 336
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 336
		(
#line 336
	env_throw_bi(env, mfe_range, "message_header_size", _("invalid message descriptor"))
#line 336
)
#line 336
;
#line 336
	mp = mtab + nmsg;
#line 336
		if (!(mp->msg))
#line 336
		(
#line 336
	env_throw_bi(env, mfe_failure, "message_header_size", _("message not open"))
#line 336
)
#line 336

#line 336
;
#line 336
	if (!mp->hdr) {
#line 336
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 336
			if (!(rc == 0))
#line 336
		(
#line 336
	env_throw_bi(env, mfe_failure, "message_header_size", "mu_message_get_header: %s",mu_strerror(rc))
#line 336
)
#line 336
;
#line 336
	}	  
#line 336
;
	
	rc = mu_header_size(mp->hdr, &size);
		if (!(rc == 0))
#line 339
		(
#line 339
	env_throw_bi(env, mfe_failure, "message_header_size", "%s",mu_strerror(rc))
#line 339
)
#line 341
;
		if (!(size < LONG_MAX))
#line 342
		(
#line 342
	env_throw_bi(env, mfe_range, "message_header_size", _("header size out of representable range"))
#line 342
)
#line 344
;
	
#line 345
do {
#line 345
  push(env, (STKVAL)(mft_number)((long)size));
#line 345
  goto endlab;
#line 345
} while (0);
}
endlab:
#line 347
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 347
	return;
#line 347
}

/* number message_header_lines(number nmsg) */
void
#line 350
bi_message_header_lines(eval_environ_t env)
#line 350

#line 350

#line 350 "msg.bi"
{
#line 350
	
#line 350

#line 350
        long  nmsg;
#line 350
        
#line 350

#line 350
        get_numeric_arg(env, 0, &nmsg);
#line 350
        
#line 350
        adjust_stack(env, 1);
#line 350

#line 350

#line 350
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 350
		prog_trace(env, "message_header_lines %lu",nmsg);;
#line 350

{
	int rc;
	size_t lines;
	
#line 354
	
#line 354
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 354
	struct mf_message *mp;
#line 354
			
#line 354
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 354
		(
#line 354
	env_throw_bi(env, mfe_range, "message_header_lines", _("invalid message descriptor"))
#line 354
)
#line 354
;
#line 354
	mp = mtab + nmsg;
#line 354
		if (!(mp->msg))
#line 354
		(
#line 354
	env_throw_bi(env, mfe_failure, "message_header_lines", _("message not open"))
#line 354
)
#line 354

#line 354
;
#line 354
	if (!mp->hdr) {
#line 354
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 354
			if (!(rc == 0))
#line 354
		(
#line 354
	env_throw_bi(env, mfe_failure, "message_header_lines", "mu_message_get_header: %s",mu_strerror(rc))
#line 354
)
#line 354
;
#line 354
	}	  
#line 354
;

	rc = mu_header_lines(mp->hdr, &lines);
		if (!(rc == 0))
#line 357
		(
#line 357
	env_throw_bi(env, mfe_failure, "message_header_lines", "%s",mu_strerror(rc))
#line 357
)
#line 360
;
	
#line 361
do {
#line 361
  push(env, (STKVAL)(mft_number)(lines));
#line 361
  goto endlab;
#line 361
} while (0);
}
endlab:
#line 363
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 363
	return;
#line 363
}

/* number message_header_count(number nmsg[; string name]) */
void
#line 366
bi_message_header_count(eval_environ_t env)
#line 366

#line 366

#line 366 "msg.bi"
{
#line 366
	
#line 366

#line 366
        long  nmsg;
#line 366
        char *  name;
#line 366
        
#line 366
        long __bi_argcnt;
#line 366
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 366
        get_numeric_arg(env, 1, &nmsg);
#line 366
        if (__bi_argcnt > 1)
#line 366
                get_string_arg(env, 2, &name);
#line 366
        
#line 366
        adjust_stack(env, __bi_argcnt + 1);
#line 366

#line 366

#line 366
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 366
		prog_trace(env, "message_header_count %lu %s",nmsg, ((__bi_argcnt > 1) ? name : ""));;

{
	int rc;
	size_t count;
	
#line 371
	
#line 371
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 371
	struct mf_message *mp;
#line 371
			
#line 371
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 371
		(
#line 371
	env_throw_bi(env, mfe_range, "message_header_count", _("invalid message descriptor"))
#line 371
)
#line 371
;
#line 371
	mp = mtab + nmsg;
#line 371
		if (!(mp->msg))
#line 371
		(
#line 371
	env_throw_bi(env, mfe_failure, "message_header_count", _("message not open"))
#line 371
)
#line 371

#line 371
;
#line 371
	if (!mp->hdr) {
#line 371
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 371
			if (!(rc == 0))
#line 371
		(
#line 371
	env_throw_bi(env, mfe_failure, "message_header_count", "mu_message_get_header: %s",mu_strerror(rc))
#line 371
)
#line 371
;
#line 371
	}	  
#line 371
;

	rc = mu_header_get_field_count(mp->hdr, &count);
		if (!(rc == 0))
#line 374
		(
#line 374
	env_throw_bi(env, mfe_failure, "message_header_count", "%s",mu_strerror(rc))
#line 374
)
#line 377
;
	
	if ((__bi_argcnt > 1)) {
		size_t n;

		for (n = 1; n <= count; n++) {
			const char *val;
			rc = mu_header_sget_value_n(mp->hdr, name, n, &val);
			if (rc == MU_ERR_NOENT)
				break;
			else if (rc)
				(
#line 388
	env_throw_bi(env, mfe_failure, "message_header_count", "%s",mu_strerror(rc))
#line 388
);
		}
		count = n - 1;
	}
	
#line 392
do {
#line 392
  push(env, (STKVAL)(mft_number)(count));
#line 392
  goto endlab;
#line 392
} while (0);
}
endlab:
#line 394
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 394
	return;
#line 394
}

/* bool message_has_header(number msg, string header[, number idx]) */
void
#line 397
bi_message_has_header(eval_environ_t env)
#line 397

#line 397

#line 397 "msg.bi"
{
#line 397
	
#line 397

#line 397
        long  nmsg;
#line 397
        char *  header;
#line 397
        long  idx;
#line 397
        
#line 397
        long __bi_argcnt;
#line 397
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 397
        get_numeric_arg(env, 1, &nmsg);
#line 397
        get_string_arg(env, 2, &header);
#line 397
        if (__bi_argcnt > 2)
#line 397
                get_numeric_arg(env, 3, &idx);
#line 397
        
#line 397
        adjust_stack(env, __bi_argcnt + 1);
#line 397

#line 397

#line 397
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 397
		prog_trace(env, "message_has_header %lu %s %lu",nmsg, header, ((__bi_argcnt > 2) ? idx : 0));;

{
	int rc;
	const char *val;
	
#line 402
	
#line 402
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 402
	struct mf_message *mp;
#line 402
			
#line 402
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 402
		(
#line 402
	env_throw_bi(env, mfe_range, "message_has_header", _("invalid message descriptor"))
#line 402
)
#line 402
;
#line 402
	mp = mtab + nmsg;
#line 402
		if (!(mp->msg))
#line 402
		(
#line 402
	env_throw_bi(env, mfe_failure, "message_has_header", _("message not open"))
#line 402
)
#line 402

#line 402
;
#line 402
	if (!mp->hdr) {
#line 402
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 402
			if (!(rc == 0))
#line 402
		(
#line 402
	env_throw_bi(env, mfe_failure, "message_has_header", "mu_message_get_header: %s",mu_strerror(rc))
#line 402
)
#line 402
;
#line 402
	}	  
#line 402
;

	rc = mu_header_sget_value_n(mp->hdr, header, ((__bi_argcnt > 2) ? idx : 1), &val);
 	
#line 405
do {
#line 405
  push(env, (STKVAL)(mft_number)(rc == 0));
#line 405
  goto endlab;
#line 405
} while (0);
}
endlab:
#line 407
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 407
	return;
#line 407
}

/* string message_find_header(number msg, string header[, number idx]) */
void
#line 410
bi_message_find_header(eval_environ_t env)
#line 410

#line 410

#line 410 "msg.bi"
{
#line 410
	
#line 410

#line 410
        long  nmsg;
#line 410
        char * MFL_DATASEG header;
#line 410
        long  idx;
#line 410
        
#line 410
        long __bi_argcnt;
#line 410
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 410
        get_numeric_arg(env, 1, &nmsg);
#line 410
        get_string_arg(env, 2, &header);
#line 410
        if (__bi_argcnt > 2)
#line 410
                get_numeric_arg(env, 3, &idx);
#line 410
        
#line 410
        adjust_stack(env, __bi_argcnt + 1);
#line 410

#line 410

#line 410
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 410
		prog_trace(env, "message_find_header %lu %s %lu",nmsg, header, ((__bi_argcnt > 2) ? idx : 0));;

{
	int rc;
	const char *val;
	
#line 415
	
#line 415
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 415
	struct mf_message *mp;
#line 415
			
#line 415
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 415
		(
#line 415
	env_throw_bi(env, mfe_range, "message_find_header", _("invalid message descriptor"))
#line 415
)
#line 415
;
#line 415
	mp = mtab + nmsg;
#line 415
		if (!(mp->msg))
#line 415
		(
#line 415
	env_throw_bi(env, mfe_failure, "message_find_header", _("message not open"))
#line 415
)
#line 415

#line 415
;
#line 415
	if (!mp->hdr) {
#line 415
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 415
			if (!(rc == 0))
#line 415
		(
#line 415
	env_throw_bi(env, mfe_failure, "message_find_header", "mu_message_get_header: %s",mu_strerror(rc))
#line 415
)
#line 415
;
#line 415
	}	  
#line 415
;

	rc = mu_header_sget_value_n(mp->hdr, header, ((__bi_argcnt > 2) ? idx : 1), &val);
	if (rc == MU_ERR_NOENT)
		(
#line 419
	env_throw_bi(env, mfe_not_found, "message_find_header", _("header not found"))
#line 419
);
	else if (rc)
		(
#line 421
	env_throw_bi(env, mfe_failure, "message_find_header", "%s",mu_strerror(rc))
#line 421
);
	
#line 422
do {
#line 422
  pushs(env, val);
#line 422
  goto endlab;
#line 422
} while (0);
}
endlab:
#line 424
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 424
	return;
#line 424
}

/* string message_nth_header_name(number msg, number n) */
void
#line 427
bi_message_nth_header_name(eval_environ_t env)
#line 427

#line 427

#line 427 "msg.bi"
{
#line 427
	
#line 427

#line 427
        long  nmsg;
#line 427
        long  idx;
#line 427
        
#line 427

#line 427
        get_numeric_arg(env, 0, &nmsg);
#line 427
        get_numeric_arg(env, 1, &idx);
#line 427
        
#line 427
        adjust_stack(env, 2);
#line 427

#line 427

#line 427
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 427
		prog_trace(env, "message_nth_header_name %lu %lu",nmsg, idx);;
#line 427

{
	int rc;
	const char *val;
	
#line 431
	
#line 431
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 431
	struct mf_message *mp;
#line 431
			
#line 431
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 431
		(
#line 431
	env_throw_bi(env, mfe_range, "message_nth_header_name", _("invalid message descriptor"))
#line 431
)
#line 431
;
#line 431
	mp = mtab + nmsg;
#line 431
		if (!(mp->msg))
#line 431
		(
#line 431
	env_throw_bi(env, mfe_failure, "message_nth_header_name", _("message not open"))
#line 431
)
#line 431

#line 431
;
#line 431
	if (!mp->hdr) {
#line 431
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 431
			if (!(rc == 0))
#line 431
		(
#line 431
	env_throw_bi(env, mfe_failure, "message_nth_header_name", "mu_message_get_header: %s",mu_strerror(rc))
#line 431
)
#line 431
;
#line 431
	}	  
#line 431
;
	
	rc = mu_header_sget_field_name(mp->hdr, idx, &val);
	if (rc == MU_ERR_NOENT)
		(
#line 435
	env_throw_bi(env, mfe_range, "message_nth_header_name", "header index out of range")
#line 435
);
	else if (rc)
		(
#line 437
	env_throw_bi(env, mfe_failure, "message_nth_header_name", "%s",mu_strerror(rc))
#line 437
);
	
#line 438
do {
#line 438
  pushs(env, val);
#line 438
  goto endlab;
#line 438
} while (0);
}
endlab:
#line 440
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 440
	return;
#line 440
}

/* string message_nth_header_value(number msg, number n) */
void
#line 443
bi_message_nth_header_value(eval_environ_t env)
#line 443

#line 443

#line 443 "msg.bi"
{
#line 443
	
#line 443

#line 443
        long  nmsg;
#line 443
        long  idx;
#line 443
        
#line 443

#line 443
        get_numeric_arg(env, 0, &nmsg);
#line 443
        get_numeric_arg(env, 1, &idx);
#line 443
        
#line 443
        adjust_stack(env, 2);
#line 443

#line 443

#line 443
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 443
		prog_trace(env, "message_nth_header_value %lu %lu",nmsg, idx);;
#line 443

{
	int rc;
	const char *val;
	
#line 447
	
#line 447
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 447
	struct mf_message *mp;
#line 447
			
#line 447
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 447
		(
#line 447
	env_throw_bi(env, mfe_range, "message_nth_header_value", _("invalid message descriptor"))
#line 447
)
#line 447
;
#line 447
	mp = mtab + nmsg;
#line 447
		if (!(mp->msg))
#line 447
		(
#line 447
	env_throw_bi(env, mfe_failure, "message_nth_header_value", _("message not open"))
#line 447
)
#line 447

#line 447
;
#line 447
	if (!mp->hdr) {
#line 447
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 447
			if (!(rc == 0))
#line 447
		(
#line 447
	env_throw_bi(env, mfe_failure, "message_nth_header_value", "mu_message_get_header: %s",mu_strerror(rc))
#line 447
)
#line 447
;
#line 447
	}	  
#line 447
;
	
	rc = mu_header_sget_field_value(mp->hdr, idx, &val);
	if (rc == MU_ERR_NOENT)
		(
#line 451
	env_throw_bi(env, mfe_range, "message_nth_header_value", "header index out of range")
#line 451
);
	else if (rc)
		(
#line 453
	env_throw_bi(env, mfe_failure, "message_nth_header_value", "%s",mu_strerror(rc))
#line 453
);
	
#line 454
do {
#line 454
  pushs(env, val);
#line 454
  goto endlab;
#line 454
} while (0);
}
endlab:
#line 456
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 456
	return;
#line 456
}


/* Multipart messages */

/* bool message_is_multipart(number msg) */
void
#line 462
bi_message_is_multipart(eval_environ_t env)
#line 462

#line 462

#line 462 "msg.bi"
{
#line 462
	
#line 462

#line 462
        long  nmsg;
#line 462
        
#line 462

#line 462
        get_numeric_arg(env, 0, &nmsg);
#line 462
        
#line 462
        adjust_stack(env, 1);
#line 462

#line 462

#line 462
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 462
		prog_trace(env, "message_is_multipart %lu",nmsg);;
#line 462

{
	int rc, res;
	
#line 465
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 465
	struct mf_message *mp;
#line 465
			
#line 465
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 465
		(
#line 465
	env_throw_bi(env, mfe_range, "message_is_multipart", _("invalid message descriptor"))
#line 465
)
#line 465
;
#line 465
	mp = mtab + nmsg;
#line 465
		if (!(mp->msg))
#line 465
		(
#line 465
	env_throw_bi(env, mfe_failure, "message_is_multipart", _("message not open"))
#line 465
)
#line 465

#line 465
;

	rc = mu_message_is_multipart(mp->msg, &res);
		if (!(rc == 0))
#line 468
		(
#line 468
	env_throw_bi(env, mfe_failure, "message_is_multipart", "%s",mu_strerror(rc))
#line 468
)
#line 471
;
	
#line 472
do {
#line 472
  push(env, (STKVAL)(mft_number)(res));
#line 472
  goto endlab;
#line 472
} while (0);
}
endlab:
#line 474
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 474
	return;
#line 474
}

/* number message_count_parts(number msg) */
void
#line 477
bi_message_count_parts(eval_environ_t env)
#line 477

#line 477

#line 477 "msg.bi"
{
#line 477
	
#line 477

#line 477
        long  nmsg;
#line 477
        
#line 477

#line 477
        get_numeric_arg(env, 0, &nmsg);
#line 477
        
#line 477
        adjust_stack(env, 1);
#line 477

#line 477

#line 477
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 477
		prog_trace(env, "message_count_parts %lu",nmsg);;
#line 477

{
	int rc;
	size_t count;
	
#line 481
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 481
	struct mf_message *mp;
#line 481
			
#line 481
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 481
		(
#line 481
	env_throw_bi(env, mfe_range, "message_count_parts", _("invalid message descriptor"))
#line 481
)
#line 481
;
#line 481
	mp = mtab + nmsg;
#line 481
		if (!(mp->msg))
#line 481
		(
#line 481
	env_throw_bi(env, mfe_failure, "message_count_parts", _("message not open"))
#line 481
)
#line 481

#line 481
;
	rc = mu_message_get_num_parts(mp->msg, &count);
		if (!(rc == 0))
#line 483
		(
#line 483
	env_throw_bi(env, mfe_failure, "message_count_parts", "%s",mu_strerror(rc))
#line 483
)
#line 486
;
	
#line 487
do {
#line 487
  push(env, (STKVAL)(mft_number)(count));
#line 487
  goto endlab;
#line 487
} while (0);
}
endlab:
#line 489
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 489
	return;
#line 489
}

/* number message_get_part(number msg, number idx) */
void
#line 492
bi_message_get_part(eval_environ_t env)
#line 492

#line 492

#line 492 "msg.bi"
{
#line 492
	
#line 492

#line 492
        long  nmsg;
#line 492
        long  idx;
#line 492
        
#line 492

#line 492
        get_numeric_arg(env, 0, &nmsg);
#line 492
        get_numeric_arg(env, 1, &idx);
#line 492
        
#line 492
        adjust_stack(env, 2);
#line 492

#line 492

#line 492
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 492
		prog_trace(env, "message_get_part %lu %lu",nmsg, idx);;
#line 492

{
	int rc;
	mu_message_t msg;
	
#line 496
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 496
	struct mf_message *mp;
#line 496
			
#line 496
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 496
		(
#line 496
	env_throw_bi(env, mfe_range, "message_get_part", _("invalid message descriptor"))
#line 496
)
#line 496
;
#line 496
	mp = mtab + nmsg;
#line 496
		if (!(mp->msg))
#line 496
		(
#line 496
	env_throw_bi(env, mfe_failure, "message_get_part", _("message not open"))
#line 496
)
#line 496

#line 496
;

	rc = mu_message_get_part(mp->msg, idx, &msg);
		if (!(rc == 0))
#line 499
		(
#line 499
	env_throw_bi(env, mfe_failure, "message_get_part", "%s",mu_strerror(rc))
#line 499
)
#line 502
;
	rc = bi_message_register(env, mp->msglist, msg, MF_MSG_MAILBOX);
		if (!(rc >= 0))
#line 504
		(
#line 504
	env_throw_bi(env, mfe_failure, "message_get_part", _("no more message slots available"))
#line 504
)
#line 506
;
	
#line 507
do {
#line 507
  push(env, (STKVAL)(mft_number)(rc));
#line 507
  goto endlab;
#line 507
} while (0);
}
endlab:
#line 509
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 509
	return;
#line 509
}


/* Reading */

/* string message_rewind(number nmsg) */
void
#line 515
bi_message_rewind(eval_environ_t env)
#line 515

#line 515

#line 515 "msg.bi"
{
#line 515
	
#line 515

#line 515
        long  nmsg;
#line 515
        
#line 515

#line 515
        get_numeric_arg(env, 0, &nmsg);
#line 515
        
#line 515
        adjust_stack(env, 1);
#line 515

#line 515

#line 515
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 515
		prog_trace(env, "message_rewind %lu",nmsg);;
#line 515

{
	
#line 517
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 517
	struct mf_message *mp;
#line 517
			
#line 517
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 517
		(
#line 517
	env_throw_bi(env, mfe_range, "message_rewind", _("invalid message descriptor"))
#line 517
)
#line 517
;
#line 517
	mp = mtab + nmsg;
#line 517
		if (!(mp->msg))
#line 517
		(
#line 517
	env_throw_bi(env, mfe_failure, "message_rewind", _("message not open"))
#line 517
)
#line 517

#line 517
;
	mu_stream_destroy(&mp->mstr);
}

#line 520
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 520
	return;
#line 520
}

/* string message_read_line(number nmsg) */
void
#line 523
bi_message_read_line(eval_environ_t env)
#line 523

#line 523

#line 523 "msg.bi"
{
#line 523
	
#line 523

#line 523
        long  nmsg;
#line 523
        
#line 523

#line 523
        get_numeric_arg(env, 0, &nmsg);
#line 523
        
#line 523
        adjust_stack(env, 1);
#line 523

#line 523

#line 523
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 523
		prog_trace(env, "message_read_line %lu",nmsg);;
#line 523

{
	int rc;
	size_t size;
	
#line 527
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 527
	struct mf_message *mp;
#line 527
			
#line 527
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 527
		(
#line 527
	env_throw_bi(env, mfe_range, "message_read_line", _("invalid message descriptor"))
#line 527
)
#line 527
;
#line 527
	mp = mtab + nmsg;
#line 527
		if (!(mp->msg))
#line 527
		(
#line 527
	env_throw_bi(env, mfe_failure, "message_read_line", _("message not open"))
#line 527
)
#line 527

#line 527
;

	if (!mp->mstr) {
		rc = mu_message_get_streamref(mp->msg, &mp->mstr);
			if (!(rc == 0))
#line 531
		(
#line 531
	env_throw_bi(env, mfe_failure, "message_read_line", "mu_message_get_stream: %s",mu_strerror(rc))
#line 531
)
#line 534
;
	}
	rc = mu_stream_getline(mp->mstr, &mp->buf, &mp->bufsize, &size);
		if (!(rc == 0))
#line 537
		(
#line 537
	env_throw_bi(env, mfe_io, "message_read_line", "mu_stream_getline: %s",mu_strerror(rc))
#line 537
)
#line 540
;
		if (!(size > 0))
#line 541
		(
#line 541
	env_throw_bi(env, mfe_eof, "message_read_line", "mu_stream_getline: %s",_("end of input"))
#line 541
)
#line 544
;
	
#line 545
do {
#line 545
  pushs(env, mp->buf);
#line 545
  goto endlab;
#line 545
} while (0);
}
endlab:
#line 547
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 547
	return;
#line 547
}

/* string message_body_rewind(number nmsg) */
void
#line 550
bi_message_body_rewind(eval_environ_t env)
#line 550

#line 550

#line 550 "msg.bi"
{
#line 550
	
#line 550

#line 550
        long  nmsg;
#line 550
        
#line 550

#line 550
        get_numeric_arg(env, 0, &nmsg);
#line 550
        
#line 550
        adjust_stack(env, 1);
#line 550

#line 550

#line 550
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 550
		prog_trace(env, "message_body_rewind %lu",nmsg);;
#line 550

{
	
#line 552
	
#line 552
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 552
	struct mf_message *mp;
#line 552
			
#line 552
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 552
		(
#line 552
	env_throw_bi(env, mfe_range, "message_body_rewind", _("invalid message descriptor"))
#line 552
)
#line 552
;
#line 552
	mp = mtab + nmsg;
#line 552
		if (!(mp->msg))
#line 552
		(
#line 552
	env_throw_bi(env, mfe_failure, "message_body_rewind", _("message not open"))
#line 552
)
#line 552

#line 552
;
#line 552
	if (!mp->body) {
#line 552
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 552
			if (!(rc == 0))
#line 552
		(
#line 552
	env_throw_bi(env, mfe_failure, "message_body_rewind", "mu_message_get_body: %s",mu_strerror(rc))
#line 552
)
#line 552
;
#line 552
	}	  
#line 552
;
	mu_stream_destroy(&mp->bstr);
}

#line 555
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 555
	return;
#line 555
}

/* string message_read_body_line(number msg)  */
void
#line 558
bi_message_read_body_line(eval_environ_t env)
#line 558

#line 558

#line 558 "msg.bi"
{
#line 558
	
#line 558

#line 558
        long  nmsg;
#line 558
        
#line 558

#line 558
        get_numeric_arg(env, 0, &nmsg);
#line 558
        
#line 558
        adjust_stack(env, 1);
#line 558

#line 558

#line 558
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 558
		prog_trace(env, "message_read_body_line %lu",nmsg);;
#line 558

{
	int rc;
	size_t size;
	
#line 562
	
#line 562
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 562
	struct mf_message *mp;
#line 562
			
#line 562
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 562
		(
#line 562
	env_throw_bi(env, mfe_range, "message_read_body_line", _("invalid message descriptor"))
#line 562
)
#line 562
;
#line 562
	mp = mtab + nmsg;
#line 562
		if (!(mp->msg))
#line 562
		(
#line 562
	env_throw_bi(env, mfe_failure, "message_read_body_line", _("message not open"))
#line 562
)
#line 562

#line 562
;
#line 562
	if (!mp->body) {
#line 562
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 562
			if (!(rc == 0))
#line 562
		(
#line 562
	env_throw_bi(env, mfe_failure, "message_read_body_line", "mu_message_get_body: %s",mu_strerror(rc))
#line 562
)
#line 562
;
#line 562
	}	  
#line 562
;
	
	if (!mp->bstr) {
		rc = mu_body_get_streamref(mp->body, &mp->bstr);
			if (!(rc == 0))
#line 566
		(
#line 566
	env_throw_bi(env, mfe_failure, "message_read_body_line", "mu_body_get_stream: %s",mu_strerror(rc))
#line 566
)
#line 569
;
	}
	rc = mu_stream_getline(mp->bstr, &mp->buf, &mp->bufsize, &size);
		if (!(rc == 0))
#line 572
		(
#line 572
	env_throw_bi(env, mfe_io, "message_read_body_line", "mu_stream_getline: %s",mu_strerror(rc))
#line 572
)
#line 575
;
		if (!(size > 0))
#line 576
		(
#line 576
	env_throw_bi(env, mfe_eof, "message_read_body_line", "mu_stream_getline: %s",_("end of input"))
#line 576
)
#line 579
;
	
#line 580
do {
#line 580
  pushs(env, mp->buf);
#line 580
  goto endlab;
#line 580
} while (0);
}
endlab:
#line 582
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 582
	return;
#line 582
}

/* string message_to_stream(number fd, number msg; string mu_filter_chain) */
void
#line 585
bi_message_to_stream(eval_environ_t env)
#line 585

#line 585

#line 585 "msg.bi"
{
#line 585
	
#line 585

#line 585
        long  fd;
#line 585
        long  nmsg;
#line 585
        char *  fltchain;
#line 585
        
#line 585
        long __bi_argcnt;
#line 585
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 585
        get_numeric_arg(env, 1, &fd);
#line 585
        get_numeric_arg(env, 2, &nmsg);
#line 585
        if (__bi_argcnt > 2)
#line 585
                get_string_arg(env, 3, &fltchain);
#line 585
        
#line 585
        adjust_stack(env, __bi_argcnt + 1);
#line 585

#line 585

#line 585
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 585
		prog_trace(env, "message_to_stream %lu %lu %s",fd, nmsg, ((__bi_argcnt > 2) ? fltchain : ""));;

{
	int rc;
	int yes = 1;
	mu_stream_t dst;
	char *flts = ((__bi_argcnt > 2) ? fltchain : 0);
	
	
#line 593
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 593
	struct mf_message *mp;
#line 593
			
#line 593
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 593
		(
#line 593
	env_throw_bi(env, mfe_range, "message_to_stream", _("invalid message descriptor"))
#line 593
)
#line 593
;
#line 593
	mp = mtab + nmsg;
#line 593
		if (!(mp->msg))
#line 593
		(
#line 593
	env_throw_bi(env, mfe_failure, "message_to_stream", _("message not open"))
#line 593
)
#line 593

#line 593
;
	
	rc = mu_fd_stream_create(&dst, NULL, _bi_io_fd(env, fd, 1),
				 MU_STREAM_WRITE);
		if (!(rc == 0))
#line 597
		(
#line 597
	env_throw_bi(env, mfe_failure, "message_to_stream", "mu_fd_stream_create: %s",mu_strerror(rc))
#line 597
)
#line 600
;
	mu_stream_ioctl(dst, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
	if (flts) {
		struct mu_wordsplit ws;
		mu_stream_t flt;
		
		rc = mu_wordsplit(flts, &ws, MU_WRDSF_DEFFLAGS);
			if (!(rc == 0))
#line 607
		(
#line 607
	env_throw_bi(env, mfe_failure, "message_to_stream", "mu_wordsplit: %s",mu_wordsplit_strerror(&ws))
#line 607
)
#line 610
;
		rc = mu_filter_chain_create(&flt, dst, MU_FILTER_ENCODE,
					    MU_STREAM_WRITE,
					    ws.ws_wordc, ws.ws_wordv);
		mu_wordsplit_free(&ws);
			if (!(rc == 0))
#line 615
		(
#line 615
	env_throw_bi(env, mfe_failure, "message_to_stream", "mu_filter_chain_create(\"%s\"): %s",flts,mu_strerror(rc))
#line 615
)
#line 619
;
		mu_stream_unref(dst);
		dst = flt;
	}

	if (!mp->mstr) {
		rc = mu_message_get_streamref(mp->msg, &mp->mstr);
			if (!(rc == 0))
#line 626
		(
#line 626
	env_throw_bi(env, mfe_failure, "message_to_stream", "mu_message_get_stream: %s",mu_strerror(rc))
#line 626
)
#line 629
;
	}
	rc = mu_stream_copy(dst, mp->mstr, 0, NULL);
		if (!(rc == 0))
#line 632
		(
#line 632
	env_throw_bi(env, mfe_failure, "message_to_stream", "mu_stream_copy: %s",mu_strerror(rc))
#line 632
)
#line 635
;
	mu_stream_close(dst);
	mu_stream_unref(dst);
}

#line 639
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 639
	return;
#line 639
}

/* number message_from_stream(number fd; string mu_filter_chain) */
void
#line 642
bi_message_from_stream(eval_environ_t env)
#line 642

#line 642

#line 642 "msg.bi"
{
#line 642
	
#line 642

#line 642
        long  fd;
#line 642
        char *  fltchain;
#line 642
        
#line 642
        long __bi_argcnt;
#line 642
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 642
        get_numeric_arg(env, 1, &fd);
#line 642
        if (__bi_argcnt > 1)
#line 642
                get_string_arg(env, 2, &fltchain);
#line 642
        
#line 642
        adjust_stack(env, __bi_argcnt + 1);
#line 642

#line 642

#line 642
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 642
		prog_trace(env, "message_from_stream %lu %s",fd, ((__bi_argcnt > 1) ? fltchain : ""));;

{
	int rc;
	int yes = 1;
	mu_stream_t src;
	char *flts = ((__bi_argcnt > 1) ? fltchain : 0);
	mu_message_t msg;
	
	rc = mu_fd_stream_create(&src, NULL, _bi_io_fd(env, fd, 0),
				 MU_STREAM_READ|MU_STREAM_SEEK);
				    
		if (!(rc == 0))
#line 654
		(
#line 654
	env_throw_bi(env, mfe_failure, "message_from_stream", "mu_fd_stream_create: %s",mu_strerror(rc))
#line 654
)
#line 657
;
	mu_stream_ioctl(src, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
	if (flts) {
		struct mu_wordsplit ws;
		mu_stream_t flt;
		
		rc = mu_wordsplit(flts, &ws, MU_WRDSF_DEFFLAGS);
			if (!(rc == 0))
#line 664
		(
#line 664
	env_throw_bi(env, mfe_failure, "message_from_stream", "mu_wordsplit: %s",mu_wordsplit_strerror(&ws))
#line 664
)
#line 667
;
		rc = mu_filter_chain_create(&flt, src, MU_FILTER_ENCODE,
					    MU_STREAM_READ,
					    ws.ws_wordc, ws.ws_wordv);
		mu_wordsplit_free(&ws);
			if (!(rc == 0))
#line 672
		(
#line 672
	env_throw_bi(env, mfe_failure, "message_from_stream", "mu_filter_chain_create(\"%s\"): %s",flts,mu_strerror(rc))
#line 672
)
#line 676
;
		mu_stream_unref(src);
		src = flt;
	}

	msg = _builtin_mu_stream_to_message(src, env, "message_from_stream");

	rc = bi_message_register(env, NULL, msg, MF_MSG_STANDALONE);
	if (rc < 0) {
		mu_message_destroy(&msg, mu_message_get_owner(msg));
		(
#line 686
	env_throw_bi(env, mfe_failure, "message_from_stream", _("no more message slots available"))
#line 686
);
#line 688
	}
	
#line 689
do {
#line 689
  push(env, (STKVAL)(mft_number)(rc));
#line 689
  goto endlab;
#line 689
} while (0);
}
endlab:
#line 691
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 691
	return;
#line 691
}

#if MAILUTILS_VERSION_MAJOR == 3 && MAILUTILS_VERSION_MINOR < 13

/*
 * Before mailutils commit 62a81295d771a9ca90e617b13992279932211b78,
 * mu_filter_chain_create would (1) decrement the reference counter of
 * its transport argument in case of errors, except (2) if the error
 * was caused by failure of the filter initialization function.
 * This exception is due to another bug, which happened to compensate
 * for the first one and which was fixed by mailutils commit
 * 231194ebb67b2c2865b8d4e82bd5379761742ec1, 
 *
 * See the following link for detailed description of both bugs:
 * http://git.savannah.gnu.org/cgit/mailutils.git/plain/libmailutils/tests/fltcnt.c?id=231194ebb67b2c2865b8d4e82bd5379761742ec1.
 *
 * To illustrate this on the example of ICONV filter, invoked by
 * charset_setup:
 *
 *   - If all arguments are OK, the function creates the filter, and
 *     increments transport reference counter by 1.
 *   - If unsupported encoding was given, transport reference counter
 *     is decremented by one.
 *   - If unsupported fallback method is given, reference counter
 *     is not changed.
 * 
 * The following workaround ensures the proper behavior:
 *
 *   - On success, reference counter increases by one.
 *   - One error, it remains unchanged.
 */

# include <mailutils/sys/stream.h>

static int
mfl_filter_chain_create(mu_stream_t *pret, mu_stream_t transport,
			int defmode, int flags,
			size_t argc, char **argv)
{
	int rc;
	int ref_count = transport->ref_count;	

	/*
	 * Increase reference counter to prevent transport from being
	 * freed as a result of bug [1].
	 */
	mu_stream_ref(transport);
	rc = mu_filter_chain_create(pret, transport, defmode, flags,
				    argc, argv);
	if (rc == 0)
		/* On success, decrement the counter. */
		mu_stream_unref(transport);
	else    /* We've hit bug [2].  Decrement the counter. */
		if (transport->ref_count > ref_count)
			mu_stream_unref(transport);
	return rc;
}
#else
static int
mfl_filter_chain_create(mu_stream_t *pret, mu_stream_t transport,
			int defmode, int flags,
			size_t argc, char **argv)
{
	return mu_filter_chain_create(pret, transport, defmode, flags,
				      argc, argv);
}
#endif

static int
mime_decode_filter(mu_stream_t *retflt, mu_stream_t stream, mu_message_t msg)
{
	int rc;
	mu_header_t hdr;
	char *encoding = NULL;
	
	/* Get the headers. */
	rc = mu_message_get_header(msg, &hdr);
	if (rc) {
		mu_diag_funcall(MU_DIAG_ERROR, "mu_message_get_header", NULL, rc);
		return rc;
	}

	/* Filter the stream through the appropriate decoder. */
	rc = mu_header_aget_value_unfold(hdr,
					 MU_HEADER_CONTENT_TRANSFER_ENCODING,
					 &encoding);
	switch (rc) {
	case 0:
		mu_rtrim_class(encoding, MU_CTYPE_SPACE);
		break;
		
	case MU_ERR_NOENT:
		encoding = NULL;
		break;
		
	default:
		mu_diag_funcall(MU_DIAG_ERROR, "mu_header_aget_value_unfold",
				NULL, rc);
		return rc;
	}

	if (encoding == NULL || *encoding == '\0') {
		/* No need to filter */;
		mu_stream_ref(stream);
		*retflt = stream;
		rc = 0;
	} else if ((rc = mu_filter_create(retflt, stream, encoding,
					  MU_FILTER_DECODE,
					  MU_STREAM_READ)) == 0) {
		/* success */;
	} else if (rc == MU_ERR_NOENT) {
		mu_error("unknown encoding: %s", encoding);
	} else {
		mu_diag_funcall(MU_DIAG_ERROR,
				"mu_filter_create", encoding, rc);
	}

	free(encoding);
	return rc;
}

static int
mime_charset_filter(mu_stream_t *retflt, mu_stream_t stream,
		    mu_message_t msg, char const *charset,
		    char const *charset_fallback)
{
	int rc;
	mu_header_t hdr;
	mu_content_type_t ct;
	char *buf = NULL;
	
	rc = mu_message_get_header(msg, &hdr);
	if (rc) {
		mu_diag_funcall(MU_DIAG_ERROR, "mu_message_get_header", NULL, rc);
		return rc;
	}

	/* Read and parse the Content-Type header. */
	rc = mu_header_aget_value_unfold(hdr, MU_HEADER_CONTENT_TYPE, &buf);
	if (rc == MU_ERR_NOENT) {
		buf = strdup("text/plain");
		if (!buf)
			return errno;
	} else if (rc) {
		mu_diag_funcall(MU_DIAG_ERROR,
				"mu_header_aget_value_unfold", NULL, rc);
		return rc;
	}

#if MAILUTILS_VERSION_MAJOR > 3 || MAILUTILS_VERSION_MINOR >= 10
	rc = mu_content_type_parse_ext(buf, NULL,
				       MU_CONTENT_TYPE_RELAXED |
				       MU_CONTENT_TYPE_PARAM, &ct);
#else
	rc = mu_content_type_parse(buf, NULL, &ct);
#endif
	if (rc) {
		mu_diag_funcall(MU_DIAG_ERROR,
				"mu_content_type_parse_ext", buf, rc);
		free(buf);
		return rc;
	}
	free(buf);
	buf = NULL;

	/* Convert the content to the requested charset. */
	struct mu_mime_param *param;
	if (charset && charset[0]
	    && mu_assoc_lookup(ct->param, "charset", &param) == 0
	    && mu_c_strcasecmp(param->value, charset)) {
		char const *argv[] = { "iconv", NULL, NULL, NULL, NULL };
		int argc = 1;
		int rc;
      
		argv[argc++] = param->value;
		if (charset) {
			argv[argc++] = charset;
			if (charset_fallback)
				argv[argc++] = charset_fallback;
		}
		rc = mfl_filter_chain_create(retflt, stream,
					     MU_FILTER_ENCODE,
					     MU_STREAM_READ,
					     argc, (char**) argv);
		if (rc)	{
			//FIXME
			mu_error(_("can't convert from charset %s to %s: %s"),
				 param->value, charset, mu_strerror (rc));
			return rc;
		}
	} else {
		mu_stream_ref(stream);
		*retflt = stream;
	}
	mu_content_type_destroy(&ct);
	return rc;
}

struct filter_closure {
	mu_message_t msg;
	char *errmsg;
};

static int
fltfunc(mu_stream_t *dst,
	mu_stream_t src,
	int mode,
	int flags,
	size_t argc,
	char **argv,
	void *closure)
{
	struct filter_closure *cls = closure;
	int rc = ENOSYS;
	
	if (strcmp(argv[0], "mimedecode") == 0) {
		rc = mime_decode_filter(dst, src, cls->msg);
	} else if (strcmp(argv[0], "charset") == 0) {
		char *charset = NULL;
		char *charset_fallback = NULL;
		
		switch (argc) {
		case 3:
			charset_fallback = argv[2];
		case 2:
			charset = argv[1];
		case 1:
			break;
		default:
			return MU_ERR_FAILURE; //FIXME: error code
		}
		rc = mime_charset_filter(dst, src,
					 cls->msg,
					 charset,
					 charset_fallback);
	}
	return rc;
}

static void
errfunc(int ec, char const *errmsg, char const *input, int start, int end,
	void *closure)
{
	struct filter_closure *cls = closure;
	size_t n = 0;
	cls->errmsg = NULL;
	mu_asnprintf(&cls->errmsg, &n, "%s, near %.*s",
		     errmsg, end - start, input + start);
}

static void
free_errmsg_ptr(void *ptr)
{
	free(*(void**)ptr);
}

/* string message_body_to_stream(number fd, number msg; string mu_filter_chain) */
void
#line 948
bi_message_body_to_stream(eval_environ_t env)
#line 948

#line 948

#line 948 "msg.bi"
{
#line 948
	
#line 948

#line 948
        long  fd;
#line 948
        long  nmsg;
#line 948
        char *  fltchain;
#line 948
        
#line 948
        long __bi_argcnt;
#line 948
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 948
        get_numeric_arg(env, 1, &fd);
#line 948
        get_numeric_arg(env, 2, &nmsg);
#line 948
        if (__bi_argcnt > 2)
#line 948
                get_string_arg(env, 3, &fltchain);
#line 948
        
#line 948
        adjust_stack(env, __bi_argcnt + 1);
#line 948

#line 948

#line 948
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 948
		prog_trace(env, "message_body_to_stream %lu %lu %s",fd, nmsg, ((__bi_argcnt > 2) ? fltchain : ""));;

{
	int rc;
	int yes = 1;
	mu_stream_t dst;
	mu_stream_t src = NULL;
	char *flts = ((__bi_argcnt > 2) ? fltchain : 0);
	
	
#line 957
	
#line 957
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 957
	struct mf_message *mp;
#line 957
			
#line 957
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 957
		(
#line 957
	env_throw_bi(env, mfe_range, "message_body_to_stream", _("invalid message descriptor"))
#line 957
)
#line 957
;
#line 957
	mp = mtab + nmsg;
#line 957
		if (!(mp->msg))
#line 957
		(
#line 957
	env_throw_bi(env, mfe_failure, "message_body_to_stream", _("message not open"))
#line 957
)
#line 957

#line 957
;
#line 957
	if (!mp->body) {
#line 957
		int rc = mu_message_get_body(mp->msg, &mp->body);
#line 957
			if (!(rc == 0))
#line 957
		(
#line 957
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_message_get_body: %s",mu_strerror(rc))
#line 957
)
#line 957
;
#line 957
	}	  
#line 957
	if (!mp->hdr) {
#line 957
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 957
			if (!(rc == 0))
#line 957
		(
#line 957
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_message_get_header: %s",mu_strerror(rc))
#line 957
)
#line 957
;
#line 957
	}	  
#line 957
;
	
	rc = mu_fd_stream_create(&dst, NULL, _bi_io_fd(env, fd, 1),
				 MU_STREAM_WRITE);
		if (!(rc == 0))
#line 961
		(
#line 961
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_fd_stream_create: %s",mu_strerror(rc))
#line 961
)
#line 964
;
	mu_stream_ioctl(dst, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
	env_function_cleanup_add(env, CLEANUP_ALWAYS, dst, _builtin_stream_cleanup);

	rc = mu_body_get_streamref(mp->body, &src);
		if (!(rc == 0))
#line 969
		(
#line 969
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_body_get_streamref: %s",mu_strerror(rc))
#line 969
)
#line 972
;

	if (flts) {
		mu_stream_t flt;
		struct filter_closure cls;
		cls.msg = mp->msg;
		cls.errmsg = NULL;

		env_function_cleanup_add(env, CLEANUP_ALWAYS, &cls.errmsg, free_errmsg_ptr);

		rc = mfl_filter_pipe_create(&flt, src,
					    MU_FILTER_ENCODE,
					    MU_STREAM_READ,
					    flts,
					    fltfunc,
					    errfunc,
					    &cls);
		mu_stream_unref(src);
		if (rc == 0) {
			src = flt;
		} else {
			(
#line 993
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "%s",cls.errmsg)
#line 993
);
		}
	}

	rc = mu_stream_copy(dst, src, 0, NULL);

	mu_stream_unref(src);

	switch (rc) {
	case 0:
		break;

	case EILSEQ:
		(
#line 1006
	env_throw_bi(env, mfe_ilseq, "message_body_to_stream", "illegal byte sequence")
#line 1006
);
#line 1008
		break;

	default:
		(
#line 1011
	env_throw_bi(env, mfe_failure, "message_body_to_stream", "mu_stream_copy: %s",mu_strerror(rc))
#line 1011
);
#line 1014
	}
}

#line 1016
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 1016
	return;
#line 1016
}

void
#line 1018
bi_message_content_type(eval_environ_t env)
#line 1018

#line 1018

#line 1018 "msg.bi"
{
#line 1018
	
#line 1018

#line 1018
        long  nmsg;
#line 1018
        
#line 1018

#line 1018
        get_numeric_arg(env, 0, &nmsg);
#line 1018
        
#line 1018
        adjust_stack(env, 1);
#line 1018

#line 1018

#line 1018
	if (builtin_module_trace(BUILTIN_IDX_msg))
#line 1018
		prog_trace(env, "message_content_type %lu",nmsg);;
#line 1018

{
	int rc;
	char *buf;
	mu_content_type_t ct;
	
#line 1023
	
#line 1023
	struct mf_message *mtab = env_get_builtin_priv(env,MSGTAB_id);
#line 1023
	struct mf_message *mp;
#line 1023
			
#line 1023
		if (!(nmsg >= 0 && nmsg < nmsgs))
#line 1023
		(
#line 1023
	env_throw_bi(env, mfe_range, "message_content_type", _("invalid message descriptor"))
#line 1023
)
#line 1023
;
#line 1023
	mp = mtab + nmsg;
#line 1023
		if (!(mp->msg))
#line 1023
		(
#line 1023
	env_throw_bi(env, mfe_failure, "message_content_type", _("message not open"))
#line 1023
)
#line 1023

#line 1023
;
#line 1023
	if (!mp->hdr) {
#line 1023
		int rc = mu_message_get_header(mp->msg, &mp->hdr);
#line 1023
			if (!(rc == 0))
#line 1023
		(
#line 1023
	env_throw_bi(env, mfe_failure, "message_content_type", "mu_message_get_header: %s",mu_strerror(rc))
#line 1023
)
#line 1023
;
#line 1023
	}	  
#line 1023
;

	rc = mu_header_aget_value_unfold(mp->hdr, MU_HEADER_CONTENT_TYPE, &buf);
	switch (rc) {
	case 0:
		break;

	case MU_ERR_NOENT:
		
#line 1031
do {
#line 1031
  pushs(env, "text/plain");
#line 1031
  goto endlab;
#line 1031
} while (0);
		
	default:
		(
#line 1034
	env_throw_bi(env, mfe_failure, "message_content_type", "mu_header_aget_value_unfold: %s",mu_strerror(rc))
#line 1034
);
#line 1037
	}
	
#if MAILUTILS_VERSION_MAJOR > 3 || MAILUTILS_VERSION_MINOR >= 10
	rc = mu_content_type_parse_ext(buf, NULL,
				       MU_CONTENT_TYPE_RELAXED |
				       MU_CONTENT_TYPE_PARAM, &ct);
#else
	rc = mu_content_type_parse(buf, NULL, &ct);
#endif
	free(buf);
		if (!(rc == 0))
#line 1047
		(
#line 1047
	env_throw_bi(env, mfe_failure, "message_content_type", "mu_content_type_parse_ext: %s",mu_strerror(rc))
#line 1047
)
#line 1049
;
	
	heap_obstack_begin(env);
	
#line 1052
do {
#line 1052
  char *__s = ct->type;
#line 1052
  heap_obstack_grow(env, __s, strlen(__s));
#line 1052
} while (0);
	do { char __c = '/'; heap_obstack_grow(env, &__c, 1); } while(0);
	
#line 1054
do {
#line 1054
  char *__s = ct->subtype;
#line 1054
  heap_obstack_grow(env, __s, strlen(__s));
#line 1054
} while (0);
	mu_content_type_destroy(&ct);
	do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
	
#line 1057
do {
#line 1057
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 1057
  goto endlab;
#line 1057
} while (0);	
}
endlab:
#line 1059
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 1059
	return;
#line 1059
}

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

#line 1026

#line 1026

#line 1026
void
#line 1026
msg_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 59 "msg.bi"
MSGTAB_id = builtin_priv_register(alloc_msgs, destroy_msgs,
#line 59
drop_current_message);
#line 202 "msg.bi"
va_builtin_install_ex("message_close", bi_message_close, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
#line 210 "msg.bi"
va_builtin_install_ex("message_size", bi_message_size, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 228 "msg.bi"
va_builtin_install_ex("message_lines", bi_message_lines, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 244 "msg.bi"
va_builtin_install_ex("message_body_size", bi_message_body_size, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 262 "msg.bi"
va_builtin_install_ex("message_body_is_empty", bi_message_body_is_empty, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 313 "msg.bi"
va_builtin_install_ex("message_body_lines", bi_message_body_lines, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 332 "msg.bi"
va_builtin_install_ex("message_header_size", bi_message_header_size, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 350 "msg.bi"
va_builtin_install_ex("message_header_lines", bi_message_header_lines, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 366 "msg.bi"
va_builtin_install_ex("message_header_count", bi_message_header_count, 0, dtype_number, 2, 1, 0|0, dtype_number, dtype_string);
#line 397 "msg.bi"
va_builtin_install_ex("message_has_header", bi_message_has_header, 0, dtype_number, 3, 1, 0|0, dtype_number, dtype_string, dtype_number);
#line 410 "msg.bi"
va_builtin_install_ex("message_find_header", bi_message_find_header, 0, dtype_string, 3, 1, 0|0, dtype_number, dtype_string, dtype_number);
#line 427 "msg.bi"
va_builtin_install_ex("message_nth_header_name", bi_message_nth_header_name, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
#line 443 "msg.bi"
va_builtin_install_ex("message_nth_header_value", bi_message_nth_header_value, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
#line 462 "msg.bi"
va_builtin_install_ex("message_is_multipart", bi_message_is_multipart, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 477 "msg.bi"
va_builtin_install_ex("message_count_parts", bi_message_count_parts, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 492 "msg.bi"
va_builtin_install_ex("message_get_part", bi_message_get_part, 0, dtype_number, 2, 0, 0|0, dtype_number, dtype_number);
#line 515 "msg.bi"
va_builtin_install_ex("message_rewind", bi_message_rewind, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
#line 523 "msg.bi"
va_builtin_install_ex("message_read_line", bi_message_read_line, 0, dtype_string, 1, 0, 0|0, dtype_number);
#line 550 "msg.bi"
va_builtin_install_ex("message_body_rewind", bi_message_body_rewind, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
#line 558 "msg.bi"
va_builtin_install_ex("message_read_body_line", bi_message_read_body_line, 0, dtype_string, 1, 0, 0|0, dtype_number);
#line 585 "msg.bi"
va_builtin_install_ex("message_to_stream", bi_message_to_stream, 0, dtype_unspecified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string);
#line 642 "msg.bi"
va_builtin_install_ex("message_from_stream", bi_message_from_stream, 0, dtype_number, 2, 1, 0|0, dtype_number, dtype_string);
#line 948 "msg.bi"
va_builtin_install_ex("message_body_to_stream", bi_message_body_to_stream, 0, dtype_unspecified, 3, 1, 0|0, dtype_number, dtype_number, dtype_string);
#line 1018 "msg.bi"
va_builtin_install_ex("message_content_type", bi_message_content_type, 0, dtype_string, 1, 0, 0|0, dtype_number);

#line 1026 "../../src/builtin/snarf.m4"
	
#line 1026
	 mf_add_runtime_params(msg_cfg_param);
#line 1026
	 
#line 1026
}
#line 1026 "../../src/builtin/snarf.m4"

