Also, i'd like to know how to cut last '\n' from header stream. If I
don't remove a last lf symbol, then all my headers'll added to message
body :-(
On Apr 3, 2009, at 17:37 , Konstantin Lepa wrote:
I fixed the problem and I created another :-)
I removed header "Subject" and added "X-DSPAM: test value\n\n". Now,
problem is message_get_header_size in create_stream_for_msgbody. It
returns 0 :-( I don't know how to extract message body properly.
Help me to understand usage of struct message_size.Result: . fetch 1 rfc822.header
- 1 FETCH (RFC822.HEADER {625} Return-Path: pupkin@virtualworld.com Delivered-To: pitman@virtualworld.com Received: from localhost.virtualworld.com (localhost [127.0.0.1]) by bsdman.virtualworld.com (Postfix) with ESMTP id 8AB84254 for pitman@virtualworld.com; Thu, 2 Apr 2009 05:07:51
+0400 (MSD) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pupkin@virtualworld.com Reply-to: Konstantin@bsdman.virtualworld.com, Lepa@bsdman.virtualworld.com To: pitman@virtualworld.com Message-Id: 20090402010751.8AB84254@bsdman.virtualworld.com Date: Thu, 2 Apr 2009 05:07:51 +0400 (MSD)) . OK Fetch completed. . fetch 1 rfc822.text
- 1 FETCH (RFC822.TEXT {721} X-DSPAM: test value
X-DSPAM: test value
Return-Path: pupkin@virtualworld.com Delivered-To: pitman@virtualworld.com Received: from localhost.virtualworld.com (localhost [127.0.0.1]) by bsdman.virtualworld.com (Postfix) with ESMTP id 8AB84254 for pitman@virtualworld.com; Thu, 2 Apr 2009 05:07:51
+0400 (MSD) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 2009-04-02T05:07:51.464214+1 From: pupkin@virtualworld.com Reply-to: Konstantin@bsdman.virtualworld.com, Lepa@bsdman.virtualworld.com To: pitman@virtualworld.com Message-Id: 20090402010751.8AB84254@bsdman.virtualworld.com Date: Thu, 2 Apr 2009 05:07:51 +0400 (MSD)Message 1 ) . OK Fetch completed.
On Apr 3, 2009, at 14:12 , Konstantin Lepa wrote:
Hello.
I wrote the hook function for deliver. I want to add support of
editheaders in the plug-in for dovecot. For this purpose I wrote
the function rarules_get_stream. Remover of headrs works properly,
but adding does not work. I took Timo Sirainen's advice from http://markmail.org/message/skb6arnll5gaopdr . Do I use a correct way of creation of a message?I give backtrace and a part of my code.
Thanks, Konstantin
uname -a: FreeBSD bsdman.virtualworld.com 6.4-RELEASE FreeBSD 6.4-RELEASE #0:
Wed Nov 26 11:43:51 UTC 2008 root@dessler.cse.buffalo.edu:/usr/ obj/usr/src/sys/GENERIC i386dovecot --version: 1.1.11
build: $ ./configure --localstatedir=/var --with-statedir=/var/db/dovecot
--without-shadow --enable-debug --with-ioloop=kqueue --disable-ipv6
--with-gssapi --without-vpopmail --without-ldap --without-pgsql -- with-mysql --without-sqlite --prefix=/usr/local --mandir=/usr/local/ man --infodir=/usr/local/info/ --build=i386-portbld-freebsd6.4patches: in freebsd ports
(gdb) bt #0 0x282f3a01 in memcpy () from /lib/libc.so.6 #1 0x080df555 in i_stream_concat_read_next (cstream=0x814aa00) at
istream-concat.c:79 #2 0x080df784 in i_stream_concat_read (stream=0x814aa00) at
istream-concat.c:136 #3 0x080de659 in i_stream_read (stream=0x814aa28) at istream.c:78 #4 0x080cd99a in i_stream_header_filter_read (stream=0x814e400) at
istream-header-filter.c:322 #5 0x080de659 in i_stream_read (stream=0x814e428) at istream.c:78 #6 0x080dff26 in i_stream_crlf_read_common (cstream=0x814ad00) at
istream-crlf.c:41 #7 0x080e01b3 in i_stream_crlf_read_lf (stream=0x814ad00) at
istream-crlf.c:103 #8 0x080de659 in i_stream_read (stream=0x814ad28) at istream.c:78 #9 0x080e2611 in i_stream_tee_read (stream=0x814ae00) at istream- tee.c:122 #10 0x080de659 in i_stream_read (stream=0x814ae28) at istream.c:78 #11 0x080deea3 in i_stream_read_data (stream=0x814ae28,
data_r=0xbfbfea88, size_r=0xbfbfea8c, threshold=1) at istream.c:322 #12 0x080d1744 in message_parser_read_more (ctx=0x8156468,
block_r=0xbfbfea80, full_r=0xbfbfea27) at message-parser.c:117 #13 0x080d20ac in parse_next_body_to_eof (ctx=0x8156468,
block_r=0xbfbfea80) at message-parser.c:411 #14 0x080d2ccf in message_parser_parse_next_block (ctx=0x8156468,
block_r=0xbfbfea80) at message-parser.c:765 #15 0x080931d9 in index_mail_cache_parse_continue (_mail=0x8150060)
at index-mail.c:1316 #16 0x0807838d in mbox_save_continue (_ctx=0x811bb00) at mbox- save.c:582 #17 0x080a05a8 in mailbox_save_continue (ctx=0x811bb00) at mail- storage.c:740 #18 0x0809d9df in mail_storage_copy (t=0x811b980, mail=0x8141860,
flags=0, keywords=0x0, dest_mail=0x0) at mail-copy.c:33 #19 0x080a0632 in mailbox_copy (t=0x811b980, mail=0x8141860,
flags=0, keywords=0x0, dest_mail=0x0) at mail-storage.c:763 #20 0x0805960d in deliver_save (namespaces=0x8121c68,
storage_r=0xbfbfee14, mailbox=0x811a370 "Draft", mail=0x8141860, flags=0, keywords=0x0) at deliver.c:234 #21 0x2831fe8f in store_in (arg=0x811a370 "Draft", md=0xbfbfed00)
at /home/pitman/work/rarules/src/actions.c:220 #22 0x2831f759 in rarules_execute_action
(type=RARULES_ACTION_STORE_IN, arg=0x811a370 "Draft", md=0xbfbfed00) at /home/pitman/work/rarules/src/actions.c:57 #23 0x2831e70d in execute_actions (action=0x811a360, md=0xbfbfed00)
at /home/pitman/work/rarules/src/rarules.c:98 #24 0x2831e692 in apply_rules (rule=0x811a320, md=0xbfbfed00) at / home/pitman/work/rarules/src/rarules.c:80 #25 0x2831e56a in rarules_main (namespaces=0x8121c68,
storage_r=0xbfbfee14, mail=0x8141860, db=0x8121000, destaddr=0xbfbfef62 "pitman@virtualworld.com",
username=0x8113525 "pitman@virtualworld.com", mailbox=0x80f2a19
"INBOX") at /home/pitman/work/rarules/src/rarules.c:52 #26 0x2831da37 in rarules_deliver_mail (namespaces=0x8121c68,
storage_r=0xbfbfee14, mail=0x8141860, destaddr=0xbfbfef62 "pitman@virtualworld.com",
mailbox=0x80f2a19 "INBOX") at /home/pitman/work/rarules/src/rarules_plugin.c:126 #27 0x0805b69a in main (argc=3, argv=0xbfbfeeac) at deliver.c:1084(gdb) f 1 #1 0x080df555 in i_stream_concat_read_next (cstream=0x814aa00) at
istream-concat.c:79 79 memcpy(cstream->istream.w_buffer, data, data_size);(gdb) p data $4 = (const unsigned char *) 0x15
(gdb) p data_size $5 = 1/////////////////////////////////////////My
code/////////////////////////////////////////////////////////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 * ra_mail = RARULES_MAIL_CONTEXT(mail); struct istream * stream = NULL; struct istream ** chunks = NULL; const unsigned int max_chunks = 4;unsigned int i = 0; unsigned int cnt = 0; unsigned int exclude_cnt = 0; unsigned int include_cnt = 0;
int ret = 0;
#if 1 {/* Test code */ const char * str = "Subject"; const char * str2 = "X-DSPAM: test value\n\n";
array_append(&ra_mail->exclude_headers, &str, 1); array_append(&ra_mail->include_headers, &str2, 1);
} #endif
DPRINT("Standard get_stream for mail storage format"); ret = ra_mail->module_ctx.super.get_stream(mail, hdr_size,
body_size, &stream);include_cnt = array_count(&ra_mail->include_headers); exclude_cnt = array_count(&ra_mail->exclude_headers);
if ((!exclude_cnt && !include_cnt) || ret < 0) { *stream_r = stream; return ret; }
DPRINT("Create message from chunks with new headers and skip
excluded headers"); chunks = t_new(struct istream *, max_chunks); chunks[cnt++] = header_filter(stream, &ra_mail->exclude_headers,
exclude_cnt); if (include_cnt) { chunks[cnt++] = create_header_stream(&ra_mail->include_headers,
include_cnt); } chunks[cnt++] = create_stream_for_msgbody(stream); chunks[cnt++] = NULL;*stream_r = i_stream_create_concat(chunks);
DPRINT("Cleanup");
array_clear(&ra_mail->include_headers); array_clear(&ra_mail->exclude_headers);
for (i = 0; chunks[i] != NULL; ++i) { i_stream_unref(&chunks[i]); } i_stream_unref(&stream);
DPRINTF("Func `%s' executed", __FUNCTION__);
return ret; }
inline static struct istream * create_stream_for_msgbody(struct istream * stream) { struct istream * tmp = stream; struct message_size hdr_size; struct message_size body_size;
DPRINTF("Func `%s' called", __FUNCTION__);
message_get_body_size(stream, &body_size, NULL); message_get_header_size(stream, &hdr_size, NULL);
i_stream_seek(stream, hdr_size.physical_size); stream = i_stream_create_limit(stream, body_size.physical_size);
i_stream_unref(&tmp);
return stream; }
inline static struct istream * header_filter(struct istream * stream, ARRAY_TYPE(const_string) *
headers_arr, unsigned int count) { const char * const * headers = NULL;DPRINTF("Func `%s' called", __FUNCTION__);
if (count) { headers = (const char **)array_idx(headers_arr, 0); }
return i_stream_create_header_filter(stream, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, headers, count, null_header_filter_callback, NULL); }
inline static struct istream * create_header_stream(ARRAY_TYPE(const_string) * headers_arr,
unsigned int count) { unsigned int i = 0; struct istream * result = NULL; struct istream ** chunks = NULL; const char * const * headers = NULL;DPRINTF("Func `%s' called", __FUNCTION__); i_assert(count != 0);
headers = (const char **)array_idx(headers_arr, 0);
DPRINT("Create streams for new included headers from headers"); chunks = t_new(struct istream *, count + 1); for (i = 0; i < count; ++i) { struct istream * tmp = NULL;
tmp = i_stream_create_from_data(headers[i], strlen(headers[i])); chunks[i] = i_stream_create_lf(tmp); i_stream_unref(&tmp);
} chunks[count] = NULL; result = i_stream_create_concat(chunks);
for (i = 0; chunks[i] != NULL; ++i) { i_stream_unref(&chunks[i]); }
return result; }