[Dovecot] Plugin Handle input messages

Alex Baule alexwbaule at gmail.com
Thu Jul 22 22:49:32 EEST 2010


Hi Timo....

Let's try to work with my plugin !

I Try to do this in "save_begin"

static int
emexis_mail_save_encrypted_begin(struct mail_save_context *ctx,
                  struct istream *input)
{
    struct mailbox *box = ctx->transaction->box;
    struct emexis_user *zuser = EMEXIS_USER_CONTEXT(box->storage->user);
    union mailbox_module_context *zbox = EMEXIS_CONTEXT(box);
    struct ostream *output;
    struct istream *new_input;

    /* This is when a try to change the INPUT stream to include my header
line */
    new_input =* i_stream_create_emx*(input);
    if (zbox->super.save_begin(ctx, new_input) < 0)
        return -1;
    i_stream_unref(&new_input);
    /* END INPUT modification */

     /* This part is to handle the saved email like zlib do, and works ! */
    zuser->writer =  emexis_uis_init(zuser->mountPoint, zuser->save_mail,
zuser->kSize, zuser->kValue, zuser->userAuth);
    output = o_stream_create_emexis(ctx->output, &zuser->writer, input);
    o_stream_unref(&ctx->output);
    ctx->output = output;
    o_stream_cork(ctx->output);
    /* END handle saved email */

    return 0;
}

The i_stream_create_emx is basically the istream-zlib.c  modifed, (i use it
to read my splited email from file, and works fine).

Theoretically, the emexis_mail_save_encrypted_begin is right, calling my
i_stream_create_emx correctly.

I got some error in read function:

Panic: file istream-add_header.c: line 125 (i_stream_emx_read): assertion
failed: (ret > 0)
Jul 21 14:50:49 brc dovecot: imap(alex at exemplo.com.br): Error: Raw
backtrace: /opt/addons/lib/dovecot/libdovecot.so.0 [0xb76d4a8e] ->
/opt/addons/lib/dovecot/libdovecot.so.0 [0xb76d4ae5] ->
/opt/addons/lib/dovecot/libdovecot.so.0 [0xb76d4146] ->
/opt/addons/lib/dovecot/lib20_emexis_uis_plugin.so [0xb73ade62] ->
/opt/addons/lib/dovecot/libdovecot.so.0(i_stream_read+0x7a) [0xb76db0da] ->
/opt/addons/lib/dovecot/libdovecot.so.0 [0xb76dcab6] ->
/opt/addons/lib/dovecot/libdovecot.so.0 [0xb76dcb8c] ->
/opt/addons/lib/dovecot/libdovecot.so.0(i_stream_read+0x7a) [0xb76db0da] ->
/opt/addons/lib/dovecot/libdovecot.so.0 [0xb76df5fc] ->
/opt/addons/lib/dovecot/libdovecot.so.0(i_stream_read+0x7a) [0xb76db0da] ->
/opt/addons/lib/dovecot/libdovecot.so.0(i_stream_read_data+0x2b)
[0xb76db35b] -> /opt/addons/lib/dovecot/libdovecot.so.0(io_stream_copy+0x5d)
[0xb76e7f1d] -> /opt/addons/lib/dovecot/libdovecot.so.0 [0xb76e7fc0] ->
/opt/addons/lib/dovecot/libdovecot.so.0(o_stream_send_istream+0x4b)
[0xb76e820b] -> /opt/addons/lib

my read is like this:


    do {
        ret = read(emx_stream->fd ,stream->w_buffer + stream->pos, size);
        fprintf(emx_stream->debug,"RET FROM READ = %d -- ERRNO = %d -- STR =
|%s|\n", ret, errno, strerror(errno));
    } while (ret < 0 && errno == EINTR && stream->istream.blocking);

    if (ret == 0 ) {
        /* EOF */
        stream->istream.eof = TRUE;
        fprintf(emx_stream->debug,"EOF EOF EOF TRUE\n");
        return -1;
    }

    if (ret < 0) {
        if (errno == EAGAIN) {
            i_assert(!stream->istream.blocking);
            ret = 0;
        }
    }

    fprintf(emx_stream->debug,"READ RET = %d -- ERRNO = %d -- STR = |%s|\n",
ret, errno, strerror(errno));
    fprintf(emx_stream->debug,"stream->pos = %d -- emx_stream->seek_offset =
%d\n", stream->pos, emx_stream->seek_offset);

    emx_stream->seek_offset += ret;
    stream->pos += ret;

    i_assert(ret > 0); // The error is here.

    fprintf(emx_stream->debug,"READ RET DECRYPT  = %d -- stream->pos = %d --
emx_stream->seek_offset = %d\n", ret, stream->pos, emx_stream->seek_offset);
    fprintf(emx_stream->debug,"********************** FINISH READ
*********************\n");
    fflush(emx_stream->debug);

    return ret;


There is some wrong in read like this ?

The better to do is copy the istream.c and change the funcions name to do
the same thing, and add my header line ?




2010/6/26 Alex Baule <alexwbaule at gmail.com>

> I will try to do like you said, and i will return later to said the result
> !
>
> Tks.
>
> 2010/6/25 Timo Sirainen <tss at iki.fi>
>
> On Mon, 2010-06-21 at 16:43 -0300, Alex Baule wrote:
>> >     if (imail->data.stream != NULL ||
>> >        (_mail->uid == 0 && zuser->save_handler == NULL)) {
>> >        return zmail->super.get_stream(_mail, hdr_size, body_size,
>> >                           stream_r);
>> >    }
>> >
>> > I think this is the line that return the stream that is the stream sent
>> by
>> > client.
>> >
>> > I try to change this line and put inside this IF , a call to my function
>> to
>> > handle with the input email from client. But i got some errors about the
>> > input part.
>>
>> I'm not really sure what you mean by this. What input are you sending
>> where? Show some example non-working code?
>>
>> > In other email, Timo said, to get the S and W flags in the email name, i
>> > need to intercept the email input from client to dovecot, in this part
>> is
>> > done the W and S calculation.
>> >
>> > Timo, where is the part that i can get the input from client ?
>>
>> IIRC you wanted to add some extra headers to the mail (and you wanted it
>> to be visible to clients, right? if not, you could do it similarly than
>> how mbox hides some headers). All mails are saved via:
>>
>> int mailbox_save_begin(struct mail_save_context **ctx, struct istream
>> *input);
>>
>> And the input comes from there. You need to replace that input with your
>> own input stream that contains the wanted headers and other changes
>> (probably something built with istream-concat and
>> istream-header-filter). You can replace the input by overriding
>> mailbox.save_begin() method, for example see acl plugin how it uses
>> acl_save_begin(). Maybe something like:
>>
>> static int
>> your_save_begin(struct mail_save_context *ctx, struct istream *input)
>> {
>>        struct mailbox *box = ctx->transaction->box;
>>        struct your_mailbox *abox = YOUR_CONTEXT(box);
>>        struct istream *new_input;
>>        int ret;
>>
>>        new_input = build_changed_input(input);
>>        ret = abox->module_ctx.super.save_begin(ctx, new_input);
>>        i_stream_unref(&new_input);
>>        return ret;
>> }
>>
>>
>>
>


More information about the dovecot mailing list