dovecot-2.2-pigeonhole: lib-sieve: util: edit-mail: Added header...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Wed Jul 30 23:37:30 UTC 2014
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b68ddffa0ac1
changeset: 1903:b68ddffa0ac1
user: Stephan Bosch <stephan at rename-it.nl>
date: Thu Jul 31 01:37:22 2014 +0200
description:
lib-sieve: util: edit-mail: Added header replacement API.
diffstat:
src/lib-sieve/util/edit-mail.c | 336 +++++++++++++++++++++++++++++++---------
src/lib-sieve/util/edit-mail.h | 7 +
2 files changed, 269 insertions(+), 74 deletions(-)
diffs (truncated from 429 to 300 lines):
diff -r 6962669ad2e6 -r b68ddffa0ac1 src/lib-sieve/util/edit-mail.c
--- a/src/lib-sieve/util/edit-mail.c Wed Jul 30 19:57:17 2014 +0200
+++ b/src/lib-sieve/util/edit-mail.c Thu Jul 31 01:37:22 2014 +0200
@@ -430,6 +430,45 @@
/* Header modification */
+static inline char *_header_value_unfold
+(const char *value)
+{
+ string_t *out;
+ unsigned int i;
+
+ for ( i = 0; value[i] != '\0'; i++ ) {
+ if (value[i] == '\r' || value[i] == '\n')
+ break;
+ }
+ if ( value[i] == '\0' ) {
+ return i_strdup(value);
+ }
+
+ out = t_str_new(i + strlen(value+i) + 10);
+ str_append_n(out, value, i);
+ for ( ; value[i] != '\0'; i++ ) {
+ if (value[i] == '\n') {
+ i++;
+ if (value[i] == '\0')
+ break;
+
+ switch ( value[i] ) {
+ case ' ':
+ str_append_c(out, ' ');
+ break;
+ case '\t':
+ default:
+ str_append_c(out, '\t');
+ }
+ } else {
+ if (value[i] != '\r')
+ str_append_c(out, value[i]);
+ }
+ }
+
+ return i_strndup(str_c(out), str_len(out));
+}
+
static struct _header_index *edit_mail_header_find
(struct edit_mail *edmail, const char *field_name)
{
@@ -482,6 +521,50 @@
return header_idx;
}
+static struct _header_field_index *
+edit_mail_header_field_create
+(struct edit_mail *edmail, const char *field_name, const char *value)
+{
+ struct _header_index *header_idx;
+ struct _header *header;
+ struct _header_field_index *field_idx;
+ struct _header_field *field;
+ unsigned int lines;
+
+ /* Get/create header index item */
+ header_idx = edit_mail_header_create(edmail, field_name);
+ header = header_idx->header;
+
+ /* Create new field index item */
+ field_idx = i_new(struct _header_field_index, 1);
+ field_idx->header = header_idx;
+ field_idx->field = field = _header_field_create(header);
+
+ /* Create header field data (folded if necessary) */
+ T_BEGIN {
+ string_t *enc_value, *data;
+
+ enc_value = t_str_new(strlen(field_name) + strlen(value) + 64);
+ data = t_str_new(strlen(field_name) + strlen(value) + 128);
+
+ message_header_encode(value, enc_value);
+
+ lines = rfc2822_header_append
+ (data, field_name, str_c(enc_value), edmail->crlf, &field->body_offset);
+
+ /* Copy to new field */
+ field->data = i_strndup(str_data(data), str_len(data));
+ field->size = str_len(data);
+ field->virtual_size = ( edmail->crlf ? field->size : field->size + lines );
+ field->lines = lines;
+ } T_END;
+
+ /* Record original (utf8) value */
+ field->utf8_value = _header_value_unfold(value);
+
+ return field_idx;
+}
+
static void edit_mail_header_field_delete
(struct edit_mail *edmail, struct _header_field_index *field_idx,
bool update_index)
@@ -528,6 +611,86 @@
i_free(field_idx);
}
+static void edit_mail_header_field_replace
+(struct edit_mail *edmail, struct _header_field_index *field_idx,
+ const char *newname, const char *newvalue, bool update_index)
+{
+ struct _header_field_index *field_idx_new;
+ struct _header_index *header_idx = field_idx->header, *header_idx_new;
+ struct _header_field *field = field_idx->field, *field_new;
+
+ i_assert( header_idx != NULL );
+ i_assert( newname != NULL || newvalue != NULL );
+
+ if ( newname == NULL )
+ newname = header_idx->header->name;
+ if ( newvalue == NULL )
+ newvalue = field_idx->field->utf8_value;
+ field_idx_new = edit_mail_header_field_create
+ (edmail, newname, newvalue);
+ field_new = field_idx_new->field;
+ header_idx_new = field_idx_new->header;
+
+ edmail->hdr_size.physical_size -= field->size;
+ edmail->hdr_size.virtual_size -= field->virtual_size;
+ edmail->hdr_size.lines -= field->lines;
+
+ edmail->hdr_size.physical_size += field_new->size;
+ edmail->hdr_size.virtual_size += field_new->virtual_size;
+ edmail->hdr_size.lines += field_new->lines;
+
+ /* Replace header field index */
+ field_idx_new->prev = field_idx->prev;
+ field_idx_new->next = field_idx->next;
+ if ( field_idx->prev != NULL )
+ field_idx->prev->next = field_idx_new;
+ if ( field_idx->next != NULL )
+ field_idx->next->prev = field_idx_new;
+ if (edmail->header_fields_head == field_idx)
+ edmail->header_fields_head = field_idx_new;
+ if (edmail->header_fields_tail == field_idx)
+ edmail->header_fields_tail = field_idx_new;
+
+ if ( header_idx_new == header_idx ) {
+ if (header_idx->first == field_idx)
+ header_idx->first = field_idx_new;
+ if (header_idx->last == field_idx)
+ header_idx->last = field_idx_new;
+ } else {
+ header_idx->count--;
+ header_idx_new->count++;
+
+ if ( update_index ) {
+ if ( header_idx->count == 0 ) {
+ DLLIST2_REMOVE(&edmail->headers_head, &edmail->headers_tail, header_idx);
+ _header_unref(header_idx->header);
+ i_free(header_idx);
+ } else if ( header_idx->first == field_idx ) {
+ struct _header_field_index *hfield = header_idx->first->next;
+
+ while ( hfield != NULL && hfield->header != header_idx ) {
+ hfield = hfield->next;
+ }
+
+ i_assert( hfield != NULL );
+ header_idx->first = hfield;
+ } else if ( header_idx->last == field_idx ) {
+ struct _header_field_index *hfield = header_idx->last->prev;
+
+ while ( hfield != NULL && hfield->header != header_idx ) {
+ hfield = hfield->prev;
+ }
+
+ i_assert( hfield != NULL );
+ header_idx->last = hfield;
+ }
+ }
+ }
+
+ _header_field_unref(field_idx->field);
+ i_free(field_idx);
+}
+
static inline char *_header_decode
(const unsigned char *hdr_data, size_t hdr_data_len)
{
@@ -704,86 +867,19 @@
return 1;
}
-static inline char *_header_value_unfold
-(const char *value)
-{
- string_t *out;
- unsigned int i;
-
- for ( i = 0; value[i] != '\0'; i++ ) {
- if (value[i] == '\r' || value[i] == '\n')
- break;
- }
- if ( value[i] == '\0' ) {
- return i_strdup(value);
- }
-
- out = t_str_new(i + strlen(value+i) + 10);
- str_append_n(out, value, i);
- for ( ; value[i] != '\0'; i++ ) {
- if (value[i] == '\n') {
- i++;
- if (value[i] == '\0')
- break;
-
- switch ( value[i] ) {
- case ' ':
- str_append_c(out, ' ');
- break;
- case '\t':
- default:
- str_append_c(out, '\t');
- }
- } else {
- if (value[i] != '\r')
- str_append_c(out, value[i]);
- }
- }
-
- return i_strndup(str_c(out), str_len(out));
-}
-
void edit_mail_header_add
-(struct edit_mail *edmail, const char *field_name, const char *value, bool last)
+(struct edit_mail *edmail, const char *field_name, const char *value,
+ bool last)
{
struct _header_index *header_idx;
- struct _header *header;
struct _header_field_index *field_idx;
struct _header_field *field;
- unsigned int lines;
edit_mail_modify(edmail);
- /* Get/create header index item */
- header_idx = edit_mail_header_create(edmail, field_name);
- header = header_idx->header;
-
- /* Create new field index item */
- field_idx = i_new(struct _header_field_index, 1);
- field_idx->header = header_idx;
- field_idx->field = field = _header_field_create(header);
-
- /* Create header field data (folded if necessary) */
- T_BEGIN {
- string_t *enc_value, *data;
-
- enc_value = t_str_new(strlen(field_name) + strlen(value) + 64);
- data = t_str_new(strlen(field_name) + strlen(value) + 128);
-
- message_header_encode(value, enc_value);
-
- lines = rfc2822_header_append
- (data, field_name, str_c(enc_value), edmail->crlf, &field->body_offset);
-
- /* Copy to new field */
- field->data = i_strndup(str_data(data), str_len(data));
- field->size = str_len(data);
- field->virtual_size = ( edmail->crlf ? field->size : field->size + lines );
- field->lines = lines;
- } T_END;
-
- /* Record original (utf8) value */
- field->utf8_value = _header_value_unfold(value);
+ field_idx = edit_mail_header_field_create(edmail, field_name, value);
+ header_idx = field_idx->header;
+ field = field_idx->field;
/* Add it to the header field index */
if ( last ) {
@@ -802,7 +898,7 @@
edmail->appended_hdr_size.physical_size += field->size;
edmail->appended_hdr_size.virtual_size += field->virtual_size;
- edmail->appended_hdr_size.lines += lines;
+ edmail->appended_hdr_size.lines += field->lines;
}
} else {
DLLIST2_PREPEND
@@ -817,7 +913,7 @@
edmail->hdr_size.physical_size += field->size;
edmail->hdr_size.virtual_size += field->virtual_size;
- edmail->hdr_size.lines += lines;
+ edmail->hdr_size.lines += field->lines;
}
int edit_mail_header_delete
@@ -892,6 +988,80 @@
return ret;
}
More information about the dovecot-cvs
mailing list