view f-demime/b2q_out.c @ 2:1857d0d5a7bd

f-demime: fix parsing of Content-* headers
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 06 May 2023 06:33:26 +0000
parents 7e0d08176f32
children
line wrap: on
line source

/*
 * This module implements the output side of base64-to-QP conversion.
 */

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

extern FILE *tempfile;

static char linebuf[QP_MAX_LINE];
static unsigned line_len, trailing_newline;

static void
add_plain_char(ch)
{
	linebuf[line_len++] = ch;
	linebuf[line_len] = '\0';
	if (!strcmp(linebuf, "From ")) {
		strcpy(linebuf, "=46rom ");
		line_len = 7;
	} else if (!strcmp(linebuf, "--")) {
		strcpy(linebuf, "=2D-");
		line_len = 4;
	} else if (!strcmp(linebuf, ".")) {
		strcpy(linebuf, "=2E");
		line_len = 3;
	}
}

static void
add_octet_char(ch)
{
	sprintf(linebuf + line_len, "=%02X", ch);
	line_len += 3;
}

static void
process_newline()
{
	if (line_len) {
		if (linebuf[line_len-1] == ' ')
			strcpy(linebuf + line_len - 1, "=20");
		fputs(linebuf, stdout);
		line_len = 0;
	}
	putchar('\n');
}

static void
process_char(ch)
{
	if (ch == '\n') {
		process_newline();
		trailing_newline++;
		if (trailing_newline > 2)
			trailing_newline = 2;
		return;
	}
	if (line_len >= QP_MAX_LINE - 2) {
		printf("%s=\n", linebuf);
		line_len = 0;
	}
	if (ch == '=')
		add_octet_char(ch);
	else if (ch >= ' ' && ch <= '~')
		add_plain_char(ch);
	else
		add_octet_char(ch);
	trailing_newline = 0;
}

void
b2q_emit_output()
{
	int c;

	rewind(tempfile);
	line_len = 0;
	trailing_newline = 1;
	while ((c = getc(tempfile)) != EOF)
		process_char(c);
	fclose(tempfile);
	while (trailing_newline < 2) {
		process_newline();
		trailing_newline++;
	}
}