diff f-demime/header.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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/f-demime/header.c	Sat May 06 06:14:03 2023 +0000
@@ -0,0 +1,145 @@
+/*
+ * This module implements initial processing (pass-through and collection)
+ * of message and body part headers.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "defs.h"
+
+extern enum msg_hdr_state hdr_state;
+extern char cont_type_buf[HDR_BUF_SIZE], cont_te_buf[HDR_BUF_SIZE];
+extern int got_cont_type, got_cont_te;
+
+static void
+error(line, msg)
+	char *line, *msg;
+{
+	if (got_cont_type) {
+		fputs(cont_type_buf, stdout);
+		got_cont_type = 0;
+	}
+	if (got_cont_te) {
+		fputs(cont_te_buf, stdout);
+		got_cont_te = 0;
+	}
+	printf("X-Fdemime-Error: %s\n", msg);
+	puts(line);
+	hdr_state = HDR_STATE_ERROR;
+}
+
+static void
+error_ct_cont(hdr_name)
+	char *hdr_name;
+{
+	printf("X-Fdemime-Error: %s header is too long\n", hdr_name);
+}
+
+static void
+cont_line(line)
+	char *line;
+{
+	unsigned prev_len;
+
+	switch (hdr_state) {
+	case HDR_STATE_BEGIN:
+		error(line, "continuation line at the beginning of header");
+		return;
+	case HDR_STATE_GOTSOME:
+		puts(line);
+		return;
+	case HDR_STATE_CONT_TYPE:
+		prev_len = strlen(cont_type_buf);
+		if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) {
+			error_ct_cont("Content-Type");
+			fputs(cont_type_buf, stdout);
+			puts(line);
+			hdr_state = HDR_STATE_ERROR;
+			got_cont_type = 0;
+			return;
+		}
+		sprintf(cont_type_buf + prev_len, "%s\n", line);
+		return;
+	case HDR_STATE_CONT_TE:
+		prev_len = strlen(cont_te_buf);
+		if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) {
+			error_ct_cont("Content-Transfer-Encoding");
+			fputs(cont_te_buf, stdout);
+			puts(line);
+			hdr_state = HDR_STATE_ERROR;
+			got_cont_te = 0;
+			return;
+		}
+		sprintf(cont_te_buf + prev_len, "%s\n", line);
+		return;
+	default:
+		fprintf(stderr,
+			"f-demime internal error: bad state in cont_line()\n");
+		abort();
+	}
+}
+
+void
+header_input_line(line)
+	char *line;
+{
+	char *cp, savech;
+	enum msg_hdr_state newhdr;
+
+	if (!line[0]) {
+		process_header_end();
+		return;
+	}
+	if (hdr_state == HDR_STATE_ERROR) {
+		puts(line);
+		return;
+	}
+	if (line[0] == ' ' || line[0] == '\t') {
+		cont_line(line);
+		return;
+	}
+	cp = index(line, ':');
+	if (!cp) {
+		error(line, "header line has no colon");
+		return;
+	}
+	if (cp == line) {
+		error(line, "null header field name");
+		return;
+	}
+	while (cp[-1] == ' ' || cp[-1] == '\t')
+		cp--;
+	savech = *cp;
+	*cp = '\0';
+	if (!strcasecmp(line, "Content-Type"))
+		newhdr = HDR_STATE_CONT_TYPE;
+	else if (!strcasecmp(line, "Content-Transfer-Encoding"))
+		newhdr = HDR_STATE_CONT_TE;
+	else
+		newhdr = HDR_STATE_GOTSOME;
+	*cp = savech;
+	switch (newhdr) {
+	case HDR_STATE_CONT_TYPE:
+		if (got_cont_type) {
+			error(line, "duplicate Content-Type");
+			return;
+		}
+		sprintf(cont_type_buf, "%s\n", line);
+		got_cont_type = 1;
+		break;
+	case HDR_STATE_CONT_TE:
+		if (got_cont_te) {
+			error(line, "duplicate Content-Transfer-Encoding");
+			return;
+		}
+		sprintf(cont_te_buf, "%s\n", line);
+		got_cont_te = 1;
+		break;
+	default:
+		puts(line);
+	}
+	hdr_state = newhdr;
+}