[Dovecot] How can I skip EOH in headers?

Konstantin Lepa konstantin.lepa at gmail.com
Mon Apr 13 18:33:29 EEST 2009


Hello.

My callback for get_stream is called from mail_get_stream in  
mail_storage_copy. Further, mbox_save_init is called and it called  
mbox_save_get_input_stream.


backtrace (A) for my callback:
#0  i_stream_header_filter_read (stream=0x8147e00) at istream-header- 
filter.c:314
#1  0x080cdbaa in parse_header (mstream=0x8147e00) at istream-header- 
filter.c:356
#2  0x080cdc0c in i_stream_header_filter_seek (stream=0x8147e00,  
v_offset=0, mark=false) at istream-header-filter.c:370
#3  0x080dea5b in i_stream_seek (stream=0x8147e28, v_offset=0) at  
istream.c:155
#4  0x080dfeae in i_stream_create_concat (input=0x8115528) at istream- 
concat.c:260
#5  0x2831e03d in rarules_get_stream (mail=0x8141860, hdr_size=0x0,  
body_size=0x0, stream_r=0xbfbfe920)
     at /home/pitman/work/rarules/src/rarules-plugin.c:181
#6  0x0809d830 in mail_get_stream (mail=0x8141860, hdr_size=0x0,  
body_size=0x0, stream_r=0xbfbfe920) at mail.c:149
#7  0x0809d936 in mail_storage_copy (t=0x811b980, mail=0x8141860,  
flags=0, keywords=0x0, dest_mail=0x0) at mail-copy.c:17
#8  0x080a0632 in mailbox_copy (t=0x811b980, mail=0x8141860, flags=0,  
keywords=0x0, dest_mail=0x0) at mail-storage.c:763
#9  0x0805960d in deliver_save (namespaces=0x8121c68,  
storage_r=0xbfbfeb94, mailbox=0x811a360 "Draft", mail=0x8141860,
     flags=0, keywords=0x0) at deliver.c:234
...


backtrace (B) for mbox_save_init:
#0  mbox_save_get_input_stream (ctx=0x811bb00, input=0x814c728) at  
mbox-save.c:384
#1  0x08078165 in mbox_save_init (_t=0x811b980, flags=0, keywords=0x0,  
received_date=1239634649, timezone_offset=0,
     from_envelope=0x80f292b "MAILER-DAEMON", input=0x814c728,  
dest_mail=0x8150060, ctx_r=0xbfbfe924) at mbox-save.c:512
#2  0x080a0560 in mailbox_save_init (t=0x811b980, flags=0,  
keywords=0x0, received_date=-1, timezone_offset=0,
     from_envelope=0x80f292b "MAILER-DAEMON", input=0x814c728,  
dest_mail=0x0, ctx_r=0xbfbfe924) at mail-storage.c:728
#3  0x0809d9c4 in mail_storage_copy (t=0x811b980, mail=0x8141860,  
flags=0, keywords=0x0, dest_mail=0x0) at mail-copy.c:28
#4  0x080a0632 in mailbox_copy (t=0x811b980, mail=0x8141860, flags=0,  
keywords=0x0, dest_mail=0x0) at mail-storage.c:763
#5  0x0805960d in deliver_save (namespaces=0x8121c68,  
storage_r=0xbfbfeb94, mailbox=0x80f2af9 "INBOX", mail=0x8141860,
     flags=0, keywords=0x0) at deliver.c:234
...


The function mbox_save_get_input_stream calls  
i_stream_create_header_filter and i_stream_create_concat.
The function read_header (istream-header-filter.c) finds EOH for call  
of i_stream_seek (backtrace B), but my calls of  
i_stream_create_header_filter and i_stream_create_concat doesn't find   
EOH (backtrace A). Why? I don't understand.

I want to call rarules_header_callback for disable eoh so as to add my  
headers.

Thanks

P.S. Sorry for my bad english :-(


It's  mbox_save_get_input_stream:
--------------------------------------------
mbox_save_get_input_stream(struct mbox_save_context *ctx, struct  
istream *input)
{
         struct istream *filter, *ret, *cache_input, *streams[3];

         /* filter out unwanted headers and keep track of headers' MD5  
sum */
         filter = i_stream_create_header_filter(input,  
HEADER_FILTER_EXCLUDE |
                                                HEADER_FILTER_NO_CR |
                                                 
HEADER_FILTER_ADD_MISSING_EOH,
                                                mbox_save_drop_headers,
                                                 
mbox_save_drop_headers_count,
                                                save_header_callback,  
ctx);

         if ((ctx->mbox->storage->storage.flags &
              MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) {
                 /* we're using MD5 sums to generate POP3 UIDLs.
                    clients don't like it much if there are duplicates,
                    so make sure that there can't be any by appending
                    our own X-Delivery-ID header. */
                 const char *hdr;

                 T_BEGIN {
                         mbox_save_x_delivery_id(ctx);
                 } T_END;
                 hdr = ctx->x_delivery_id_header;

                 streams[0] = i_stream_create_from_data(hdr,  
strlen(hdr));
                 streams[1] = filter;
                 streams[2] = NULL;
                 ret = i_stream_create_concat(streams);
                 i_stream_unref(&filter);
                 filter = ret;
         }

It's my callback for get_stream:
---------------------------------------
static int rarules_get_stream(struct mail *mail, struct message_size  
*hdr_size,
                               struct message_size *body_size,
                               struct istream **stream_r)
{
         struct rarules_mail *m = RA_MAIL_CONTEXT(mail);
         struct istream *stream = NULL;

         unsigned int deleted = 0;
         unsigned int added = 0;

         int ret = 0;

         DPRINT("func is called");

         /* standard get_stream for mail storage format */
         ret = m->module_ctx.super.get_stream(mail, hdr_size,
                                                    body_size, &stream);

         added = array_count(&m->add_hdr_arr);
         deleted = array_count(&m->del_hdr_arr);

         if (m->enabled && (deleted || added)) {
                 struct istream * tmp = NULL;
                 struct istream **chunks = NULL;
                 const unsigned int max_chunks = 4;
                 unsigned int i = 0;
                 unsigned int cnt = 0;

                 DPRINT("modifing message headers");
                 /* create message from chunks with new hdrs
                    and skip excluded hdrs */
                 chunks = t_new(struct istream *, max_chunks);
                 chunks[cnt++] =
                         make_header_filter(stream, &m->del_hdr_arr,  
deleted);
                 if (added) {
                         chunks[cnt++] =
                                 create_header_stream(&m->add_hdr_arr,  
added);
                 }
                 chunks[cnt++] = create_stream_for_msgbody(stream);
                 chunks[cnt++] = NULL;

                 tmp = i_stream_create_concat(chunks);

                 for (i = 0; chunks[i] != NULL; ++i) {
                         i_stream_unref(&chunks[i]);
                 }
                 i_stream_unref(&stream);
                 stream = tmp;
         }

         *stream_r = stream;

         DPRINT("func is executed");

         return ret;
}



More information about the dovecot mailing list