~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

Viewing changes to src/lib-mail/istream-attachment-connector.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2003-2013 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "lib.h"
 
4
#include "array.h"
 
5
#include "istream.h"
 
6
#include "istream-concat.h"
 
7
#include "istream-sized.h"
 
8
#include "istream-base64.h"
 
9
#include "istream-attachment-connector.h"
 
10
 
 
11
struct istream_attachment_connector {
 
12
        pool_t pool;
 
13
        struct istream *base_input;
 
14
        uoff_t base_input_offset, msg_size;
 
15
 
 
16
        uoff_t encoded_offset;
 
17
        ARRAY(struct istream *) streams;
 
18
};
 
19
 
 
20
struct istream_attachment_connector *
 
21
istream_attachment_connector_begin(struct istream *base_input, uoff_t msg_size)
 
22
{
 
23
        struct istream_attachment_connector *conn;
 
24
        pool_t pool;
 
25
 
 
26
        pool = pool_alloconly_create("istream-attachment-connector", 1024);
 
27
        conn = p_new(pool, struct istream_attachment_connector, 1);
 
28
        conn->pool = pool;
 
29
        conn->base_input = base_input;
 
30
        conn->base_input_offset = base_input->v_offset;
 
31
        conn->msg_size = msg_size;
 
32
        p_array_init(&conn->streams, pool, 8);
 
33
        i_stream_ref(conn->base_input);
 
34
        return conn;
 
35
}
 
36
 
 
37
int istream_attachment_connector_add(struct istream_attachment_connector *conn,
 
38
                                     struct istream *decoded_input,
 
39
                                     uoff_t start_offset, uoff_t encoded_size,
 
40
                                     unsigned int base64_blocks_per_line,
 
41
                                     bool base64_have_crlf,
 
42
                                     const char **error_r)
 
43
{
 
44
        struct istream *input, *input2;
 
45
        uoff_t base_prefix_size;
 
46
 
 
47
        if (start_offset < conn->encoded_offset) {
 
48
                *error_r = t_strdup_printf(
 
49
                        "Attachment %s points before the previous attachment "
 
50
                        "(%"PRIuUOFF_T" < %"PRIuUOFF_T")",
 
51
                        i_stream_get_name(decoded_input),
 
52
                        start_offset, conn->encoded_offset);
 
53
                return -1;
 
54
        }
 
55
        base_prefix_size = start_offset - conn->encoded_offset;
 
56
        if (start_offset + encoded_size > conn->msg_size) {
 
57
                *error_r = t_strdup_printf(
 
58
                        "Attachment %s points outside message "
 
59
                        "(%"PRIuUOFF_T" + %"PRIuUOFF_T" > %"PRIuUOFF_T")",
 
60
                        i_stream_get_name(decoded_input),
 
61
                        start_offset, encoded_size,
 
62
                        conn->msg_size);
 
63
                return -1;
 
64
        }
 
65
 
 
66
        if (base_prefix_size > 0) {
 
67
                /* add a part of the base message before the attachment */
 
68
                input = i_stream_create_range(conn->base_input,
 
69
                                              conn->base_input_offset,
 
70
                                              base_prefix_size);
 
71
                array_append(&conn->streams, &input, 1);
 
72
                conn->base_input_offset += base_prefix_size;
 
73
                conn->encoded_offset += base_prefix_size;
 
74
        }
 
75
        conn->encoded_offset += encoded_size;
 
76
 
 
77
        if (base64_blocks_per_line == 0) {
 
78
                input = decoded_input;
 
79
                i_stream_ref(input);
 
80
        } else {
 
81
                input = i_stream_create_base64_encoder(decoded_input,
 
82
                                                       base64_blocks_per_line*4,
 
83
                                                       base64_have_crlf);
 
84
                i_stream_set_name(input, t_strdup_printf("%s[base64:%u b/l%s]",
 
85
                                  i_stream_get_name(decoded_input),
 
86
                                  base64_blocks_per_line,
 
87
                                  base64_have_crlf ? ",crlf" : ""));
 
88
        }
 
89
        input2 = i_stream_create_sized(input, encoded_size);
 
90
        array_append(&conn->streams, &input2, 1);
 
91
        i_stream_unref(&input);
 
92
        return 0;
 
93
}
 
94
 
 
95
static void
 
96
istream_attachment_connector_free(struct istream_attachment_connector *conn)
 
97
{
 
98
        struct istream *const *streamp, *stream;
 
99
 
 
100
        array_foreach(&conn->streams, streamp) {
 
101
                stream = *streamp;
 
102
                if (stream != NULL)
 
103
                        i_stream_unref(&stream);
 
104
        }
 
105
        i_stream_unref(&conn->base_input);
 
106
        pool_unref(&conn->pool);
 
107
}
 
108
 
 
109
struct istream *
 
110
istream_attachment_connector_finish(struct istream_attachment_connector **_conn)
 
111
{
 
112
        struct istream_attachment_connector *conn = *_conn;
 
113
        struct istream **inputs, *input;
 
114
        uoff_t trailer_size;
 
115
 
 
116
        *_conn = NULL;
 
117
 
 
118
        if (conn->base_input_offset != conn->msg_size) {
 
119
                i_assert(conn->base_input_offset < conn->msg_size);
 
120
 
 
121
                trailer_size = conn->msg_size - conn->encoded_offset;
 
122
                input = i_stream_create_range(conn->base_input,
 
123
                                              conn->base_input_offset,
 
124
                                              trailer_size);
 
125
                array_append(&conn->streams, &input, 1);
 
126
        }
 
127
        array_append_zero(&conn->streams);
 
128
 
 
129
        inputs = array_idx_modifiable(&conn->streams, 0);
 
130
        input = i_stream_create_concat(inputs);
 
131
 
 
132
        istream_attachment_connector_free(conn);
 
133
        return input;
 
134
}
 
135
 
 
136
void istream_attachment_connector_abort(struct istream_attachment_connector **_conn)
 
137
{
 
138
        struct istream_attachment_connector *conn = *_conn;
 
139
 
 
140
        *_conn = NULL;
 
141
 
 
142
        istream_attachment_connector_free(conn);
 
143
}