mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-09 21:28:51 +01:00
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.
This commit is contained in:
parent
c4ff9c5def
commit
675b12ddd8
@ -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);
|
||||
}
|
||||
|
@ -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 *
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -279,7 +279,7 @@ t2body (void *cookie, int level)
|
||||
{
|
||||
if (atoi(value+valueoff) >= 2 )
|
||||
ctx->draft_version_2 = 1;
|
||||
free (value);
|
||||
rfc822_free (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user