view f-demime/msgstate.c @ 0:7e0d08176f32

f-demime starting code
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 06 May 2023 06:14:03 +0000
parents
children 612c4d0df768
line wrap: on
line source

/*
 * This module implements the message state machine, receiving input lines
 * and message start/end markers from the input processing main loop.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "defs.h"

enum msg_state msg_state;
enum msg_hdr_state hdr_state;
unsigned mp_nest_level;
char mp_boundaries[MAX_MP_NESTING][MAX_MP_BOUNDARY+1];
int mp_is_digest[MAX_MP_NESTING];
char cont_type_buf[HDR_BUF_SIZE], cont_te_buf[HDR_BUF_SIZE];
int got_cont_type, got_cont_te;

void
start_entity_hdr()
{
	msg_state = MSG_STATE_HEADER;
	hdr_state = HDR_STATE_BEGIN;
	got_cont_type = 0;
	got_cont_te = 0;
}

void
begin_new_message()
{
	mp_nest_level = 0;
	start_entity_hdr();
}

static void
emit_prefrom_warning()
{
	static int done;

	if (done)
		return;
	fprintf(stderr,
		"f-demime warning: data present before the first From\n");
	done = 1;
}

static int
check_mp_terminator(line)
	char *line;
{
	unsigned lev, bndlen;
	char *bnd, *cp;

	if (line[0] != '-' || line[1] != '-')
		return(0);
	for (lev = 0; lev < mp_nest_level; lev++) {
		bnd = mp_boundaries[lev];
		bndlen = strlen(bnd);
		if (strncmp(line+2, bnd, bndlen))
			continue;
		finish_msg_body();
		puts(line);
		cp = line + 2 + bndlen;
		if (!*cp || isspace(*cp)) {
			mp_nest_level = lev + 1;
			start_entity_hdr();
			return(1);
		}
		if (cp[0] != '-' || cp[1] != '-')
			puts("X-Fdemime-Error: invalid delimiter line");
		mp_nest_level = lev;
		msg_state = MSG_STATE_BODY_PASS;
		return(1);
	}
	return(0);
}

void
message_input_line(line)
	char *line;
{
	if (check_mp_terminator(line))
		return;
	switch (msg_state) {
	case MSG_STATE_UNDEF:
		emit_prefrom_warning();
		puts(line);
		return;
	case MSG_STATE_HEADER:
		header_input_line(line);
		return;
	case MSG_STATE_BODY_PASS:
		puts(line);
		return;
	case MSG_STATE_PTEXT_B64:
	case MSG_STATE_BLOB_B64:
	case MSG_STATE_B64_TO_QP:
		base64_input_line(line);
		return;
	case MSG_STATE_PTEXT_QP:
		qpdec_input_line(line);
		return;
	default:
		fprintf(stderr,
		"f-demime internal error: bad state in message_input_line()\n");
		abort();
	}
}