~ubuntu-branches/ubuntu/trusty/dovecot/trusty-updates

« back to all changes in this revision

Viewing changes to src/doveadm/dsync/dsync-deserializer.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (1.15.3) (96.1.1 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20140108093549-814nkqdcxfbvgktg
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) 2013 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "lib.h"
 
4
#include "str.h"
 
5
#include "strescape.h"
 
6
#include "dsync-serializer.h"
 
7
#include "dsync-deserializer.h"
 
8
 
 
9
struct dsync_deserializer {
 
10
        pool_t pool;
 
11
        const char *name;
 
12
        const char *const *required_fields;
 
13
        const char *const *keys;
 
14
        unsigned int *required_field_indexes;
 
15
        unsigned int required_field_count;
 
16
};
 
17
 
 
18
struct dsync_deserializer_decoder {
 
19
        pool_t pool;
 
20
        struct dsync_deserializer *deserializer;
 
21
        const char *const *values;
 
22
        unsigned int values_count;
 
23
};
 
24
 
 
25
static bool field_find(const char *const *names, const char *name,
 
26
                       unsigned int *idx_r)
 
27
{
 
28
        unsigned int i;
 
29
 
 
30
        for (i = 0; names[i] != NULL; i++) {
 
31
                if (strcmp(names[i], name) == 0) {
 
32
                        *idx_r = i;
 
33
                        return TRUE;
 
34
                }
 
35
        }
 
36
        return FALSE;
 
37
}
 
38
 
 
39
int dsync_deserializer_init(const char *name, const char *const *required_fields,
 
40
                            const char *header_line,
 
41
                            struct dsync_deserializer **deserializer_r,
 
42
                            const char **error_r)
 
43
{
 
44
        struct dsync_deserializer *deserializer;
 
45
        const char **dup_required_fields;
 
46
        unsigned int i, required_count;
 
47
        pool_t pool;
 
48
 
 
49
        *deserializer_r = NULL;
 
50
 
 
51
        pool = pool_alloconly_create("dsync deserializer", 1024);
 
52
        deserializer = p_new(pool, struct dsync_deserializer, 1);
 
53
        deserializer->pool = pool;
 
54
        deserializer->name = p_strdup(pool, name);
 
55
        deserializer->keys = (void *)p_strsplit_tabescaped(pool, header_line);
 
56
 
 
57
        deserializer->required_field_count = required_count =
 
58
                required_fields == NULL ? 0 :
 
59
                str_array_length(required_fields);
 
60
        dup_required_fields = p_new(pool, const char *, required_count + 1);
 
61
        deserializer->required_field_indexes =
 
62
                p_new(pool, unsigned int, required_count + 1);
 
63
        for (i = 0; i < required_count; i++) {
 
64
                dup_required_fields[i] =
 
65
                        p_strdup(pool, required_fields[i]);
 
66
                if (!field_find(deserializer->keys, required_fields[i],
 
67
                                &deserializer->required_field_indexes[i])) {
 
68
                        *error_r = t_strdup_printf(
 
69
                                "Header missing required field %s",
 
70
                                required_fields[i]);
 
71
                        pool_unref(&pool);
 
72
                        return -1;
 
73
                }
 
74
        }
 
75
        deserializer->required_fields = dup_required_fields;
 
76
 
 
77
        *deserializer_r = deserializer;
 
78
        return 0;
 
79
}
 
80
 
 
81
void dsync_deserializer_deinit(struct dsync_deserializer **_deserializer)
 
82
{
 
83
        struct dsync_deserializer *deserializer = *_deserializer;
 
84
 
 
85
        *_deserializer = NULL;
 
86
 
 
87
        pool_unref(&deserializer->pool);
 
88
}
 
89
 
 
90
int dsync_deserializer_decode_begin(struct dsync_deserializer *deserializer,
 
91
                                    const char *input,
 
92
                                    struct dsync_deserializer_decoder **decoder_r,
 
93
                                    const char **error_r)
 
94
{
 
95
        struct dsync_deserializer_decoder *decoder;
 
96
        unsigned int i;
 
97
        char **values;
 
98
        pool_t pool;
 
99
 
 
100
        *decoder_r = NULL;
 
101
 
 
102
        pool = pool_alloconly_create("dsync deserializer decode", 1024);
 
103
        decoder = p_new(pool, struct dsync_deserializer_decoder, 1);
 
104
        decoder->pool = pool;
 
105
        decoder->deserializer = deserializer;
 
106
        values = p_strsplit_tabescaped(pool, input);
 
107
 
 
108
        /* fix NULLs */
 
109
        for (i = 0; values[i] != NULL; i++) {
 
110
                if (values[i][0] == NULL_CHR) {
 
111
                        /* NULL? */
 
112
                        if (values[i][1] == '\0')
 
113
                                values[i] = NULL;
 
114
                        else
 
115
                                values[i] += 1;
 
116
                }
 
117
        }
 
118
        decoder->values_count = i;
 
119
 
 
120
        /* see if all required fields exist */
 
121
        for (i = 0; i < deserializer->required_field_count; i++) {
 
122
                unsigned int ridx = deserializer->required_field_indexes[i];
 
123
 
 
124
                if (ridx >= decoder->values_count || values[ridx] == NULL) {
 
125
                        *error_r = t_strdup_printf("Missing required field %s",
 
126
                                deserializer->required_fields[i]);
 
127
                        pool_unref(&pool);
 
128
                        return -1;
 
129
                }
 
130
        }
 
131
        decoder->values = (void *)values;
 
132
 
 
133
        *decoder_r = decoder;
 
134
        return 0;
 
135
}
 
136
 
 
137
static bool
 
138
dsync_deserializer_find_field(struct dsync_deserializer *deserializer,
 
139
                              const char *key, unsigned int *idx_r)
 
140
{
 
141
        unsigned int i;
 
142
 
 
143
        for (i = 0; deserializer->keys[i] != NULL; i++) {
 
144
                if (strcmp(deserializer->keys[i], key) == 0) {
 
145
                        *idx_r = i;
 
146
                        return TRUE;
 
147
                }
 
148
        }
 
149
        return FALSE;
 
150
}
 
151
 
 
152
bool dsync_deserializer_decode_try(struct dsync_deserializer_decoder *decoder,
 
153
                                   const char *key, const char **value_r)
 
154
{
 
155
        unsigned int idx;
 
156
 
 
157
        if (!dsync_deserializer_find_field(decoder->deserializer, key, &idx) ||
 
158
            idx >= decoder->values_count) {
 
159
                *value_r = NULL;
 
160
                return FALSE;
 
161
        } else {
 
162
                *value_r = decoder->values[idx];
 
163
                return *value_r != NULL;
 
164
        }
 
165
}
 
166
 
 
167
const char *
 
168
dsync_deserializer_decode_get(struct dsync_deserializer_decoder *decoder,
 
169
                              const char *key)
 
170
{
 
171
        const char *value;
 
172
 
 
173
        if (!dsync_deserializer_decode_try(decoder, key, &value)) {
 
174
                i_panic("dsync_deserializer_decode_get() "
 
175
                        "used for non-required key %s", key);
 
176
        }
 
177
        return value;
 
178
}
 
179
 
 
180
const char *
 
181
dsync_deserializer_decoder_get_name(struct dsync_deserializer_decoder *decoder)
 
182
{
 
183
        return decoder->deserializer->name;
 
184
}
 
185
 
 
186
void dsync_deserializer_decode_finish(struct dsync_deserializer_decoder **_decoder)
 
187
{
 
188
        struct dsync_deserializer_decoder *decoder = *_decoder;
 
189
 
 
190
        *_decoder = NULL;
 
191
 
 
192
        pool_unref(&decoder->pool);
 
193
}