aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-06-28 15:50:23 +0000
committerWerner Koch <[email protected]>2024-06-28 15:59:55 +0000
commit675b12ddd8ca742314d96a02bc95b837841070fb (patch)
tree9ff52a10c5740f568ae9ffa8cc7f6bc637c7533e
parentagent: Require use of "SCD DEVINFO --watch" command with socket. (diff)
downloadgnupg-675b12ddd8ca742314d96a02bc95b837841070fb.tar.gz
gnupg-675b12ddd8ca742314d96a02bc95b837841070fb.zip
tools: New support functions for the mail parser.
* tools/rfc822parse.h (RFC822PARSE_HEADER_SEEN): New. * tools/rfc822parse.c (rfc822_cmp_header_name): New. (insert_header): Run header seen callback. (rfc822parse_last_header_line): New. (rfc822_free): New. * tools/wks-receive.c (t2body): Use it here. * tools/mime-parser.c (parse_message_cb): and here.
-rw-r--r--tools/gpgtar-create.c1
-rw-r--r--tools/mime-maker.c4
-rw-r--r--tools/mime-parser.c2
-rw-r--r--tools/rfc822parse.c51
-rw-r--r--tools/rfc822parse.h4
-rw-r--r--tools/wks-receive.c2
6 files changed, 58 insertions, 6 deletions
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index 76eb47449..825ac4df3 100644
--- a/tools/gpgtar-create.c
+++ b/tools/gpgtar-create.c
@@ -1317,6 +1317,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
xfree (argv);
if (err)
goto leave;
+ /* Note that OUTSTREAM is our tar output which is fed to gpg. */
gnupg_process_get_streams (proc, 0, &outstream, NULL, NULL);
es_set_binary (outstream);
}
diff --git a/tools/mime-maker.c b/tools/mime-maker.c
index 91eab8258..12dae910e 100644
--- a/tools/mime-maker.c
+++ b/tools/mime-maker.c
@@ -216,8 +216,8 @@ find_part (part_t root, unsigned int partid)
}
-/* Create a boundary string. Outr codes is aware of the general
- * structure of that string (gebins with "=-=") so that
+/* Create a boundary string. Our codes is aware of the general
+ * structure of that string (begins with "=-=") so that
* it can protect against accidentally-used boundaries within the
* content. */
static char *
diff --git a/tools/mime-parser.c b/tools/mime-parser.c
index 31f766ca5..594b2e2fa 100644
--- a/tools/mime-parser.c
+++ b/tools/mime-parser.c
@@ -416,7 +416,7 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
if (!ctx->b64state)
rc = gpg_error_from_syserror ();
}
- free (value); /* Right, we need a plain free. */
+ rfc822_free (value);
}
}
diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c
index ac6ecb17c..4d0668007 100644
--- a/tools/rfc822parse.c
+++ b/tools/rfc822parse.c
@@ -86,6 +86,7 @@ struct part
struct part *down; /* A contained part. */
HDR_LINE hdr_lines; /* Header lines os that part. */
HDR_LINE *hdr_lines_tail; /* Helper for adding lines. */
+ const char *last_hdr_line;/* NULL or a ptr to the last inserted hdr. */
char *boundary; /* Only used in the first part. */
};
typedef struct part *part_t;
@@ -237,6 +238,15 @@ release_handle_data (rfc822parse_t msg)
}
+/* Wrapper around free becuase in this moulde we use a plain free. */
+void
+rfc822_free (void *a)
+{
+ if (a)
+ free (a);
+}
+
+
/* Check that the header name is valid. We allow all lower and
* uppercase letters and, except for the first character, digits and
* the dash. The check stops at the first colon or at string end.
@@ -292,6 +302,22 @@ rfc822_capitalize_header_name (char *name)
}
+/* This is an strcmp which considers a colon also as end-of-string.
+ * Use this function to compare capitalized header names. */
+int
+rfc822_cmp_header_name (const char *a, const char *b)
+{
+ for (; *a && *a != ':' && *b && *b != ':'; a++, b++)
+ {
+ if (*a != *b )
+ break;
+ }
+ if (*a == *b || (!*a && *b == ':') || (!*b && *a == ':'))
+ return 0;
+ else
+ return (*(signed char *)a - *(signed char *)b);
+}
+
/* Create a new parsing context for an entire rfc822 message and
return it. CB and CB_VALUE may be given to callback for certain
@@ -488,6 +514,7 @@ static int
insert_header (rfc822parse_t msg, const unsigned char *line, size_t length)
{
HDR_LINE hdr;
+ int new_hdr = 0;
if (!msg->current_part)
{
@@ -515,11 +542,19 @@ insert_header (rfc822parse_t msg, const unsigned char *line, size_t length)
/* Transform a field name into canonical format. */
if (!hdr->cont && strchr (line, ':'))
- rfc822_capitalize_header_name (hdr->line);
+ {
+ rfc822_capitalize_header_name (hdr->line);
+ msg->current_part->last_hdr_line = hdr->line;
+ new_hdr = 1;
+ }
+ else
+ msg->current_part->last_hdr_line = NULL;
*msg->current_part->hdr_lines_tail = hdr;
msg->current_part->hdr_lines_tail = &hdr->next;
+ if (new_hdr)
+ do_callback (msg, RFC822PARSE_HEADER_SEEN);
/* Lets help the caller to prevent mail loops and issue an event for
* every Received header. */
if (length >= 9 && !memcmp (line, "Received:", 9))
@@ -588,6 +623,18 @@ rfc822parse_finish (rfc822parse_t msg)
}
+/* If the last inserted line was a header and not a continuation of a
+ * header line, return a pointer to that line. This function may be
+ * used on the RFC822PARSE_HEADER_SEEN event to get the name of the
+ * current header. Returns NULL if no header is available. */
+const char *
+rfc822parse_last_header_line (rfc822parse_t msg)
+{
+ if (!msg || !msg->current_part)
+ return NULL;
+ return msg->current_part->last_hdr_line;
+}
+
/****************
* Get a copy of a header line. The line is returned as one long
@@ -697,7 +744,7 @@ rfc822parse_enum_header_lines (rfc822parse_t msg, void **context)
*
* which -1 : Retrieve the last field
* >0 : Retrieve the n-th field
-
+ *
* RPREV may be used to return the predecessor of the returned field;
* which may be NULL for the very first one. It has to be initialized
* to either NULL in which case the search start at the first header line,
diff --git a/tools/rfc822parse.h b/tools/rfc822parse.h
index e2f2bedac..84315a50d 100644
--- a/tools/rfc822parse.h
+++ b/tools/rfc822parse.h
@@ -29,6 +29,7 @@ typedef enum
RFC822PARSE_CANCEL,
RFC822PARSE_T2BODY,
RFC822PARSE_FINISH,
+ RFC822PARSE_HEADER_SEEN,
RFC822PARSE_RCVD_SEEN,
RFC822PARSE_LEVEL_DOWN,
RFC822PARSE_LEVEL_UP,
@@ -48,8 +49,10 @@ typedef int (*rfc822parse_cb_t) (void *opaque,
rfc822parse_event_t event,
rfc822parse_t msg);
+void rfc822_free (void *);
int rfc822_valid_header_name_p (const char *name);
void rfc822_capitalize_header_name (char *name);
+int rfc822_cmp_header_name (const char *a, const char *b);
rfc822parse_t rfc822parse_open (rfc822parse_cb_t cb, void *opaque_value);
@@ -60,6 +63,7 @@ int rfc822parse_finish (rfc822parse_t msg);
int rfc822parse_insert (rfc822parse_t msg,
const unsigned char *line, size_t length);
+const char *rfc822parse_last_header_line (rfc822parse_t msg);
char *rfc822parse_get_field (rfc822parse_t msg, const char *name, int which,
size_t *valueoff);
diff --git a/tools/wks-receive.c b/tools/wks-receive.c
index e5d2ed4b2..ecd8cafe3 100644
--- a/tools/wks-receive.c
+++ b/tools/wks-receive.c
@@ -279,7 +279,7 @@ t2body (void *cookie, int level)
{
if (atoi(value+valueoff) >= 2 )
ctx->draft_version_2 = 1;
- free (value);
+ rfc822_free (value);
}
}
}