dsync-proxy.c revision 16aef418492cb8d18c5196fd573a487177a9cab2
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "array.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "strescape.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "ostream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "hex-binary.h"
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen#include "mail-types.h"
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen#include "imap-util.h"
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen#include "dsync-data.h"
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen#include "dsync-proxy.h"
d7a56951e519c28ac9b1fd5810a455a9ba238327Timo Sirainen
d7a56951e519c28ac9b1fd5810a455a9ba238327Timo Sirainen#include <stdlib.h>
15b9759df8e4f6fb00c115353827a2aebbebfebcTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenvoid dsync_proxy_strings_export(string_t *str,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const ARRAY_TYPE(const_string) *strings)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *const *fields;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int i, count;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (!array_is_created(strings))
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen fields = array_get(strings, &count);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen for (i = 0; i < count; i++) {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen str_append_c(str, '\t');
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen str_tabescape_write(str, fields[i]);
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen }
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid dsync_proxy_msg_export(string_t *str,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen const struct dsync_message *msg)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_tabescape_write(str, msg->guid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(str, "\t%u\t%llu\t", msg->uid,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen (unsigned long long)msg->modseq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((msg->flags & DSYNC_MAIL_FLAG_EXPUNGED) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "\\dsync-expunged ");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_write_flags(str, msg->flags & MAIL_FLAGS_MASK, msg->keywords);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen str_printfa(str, "\t%ld", (long)msg->save_date);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenint dsync_proxy_msg_parse_flags(pool_t pool, const char *str,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct dsync_message *msg_r)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ARRAY_TYPE(const_string) keywords;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *const *args, *kw;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen enum mail_flags flag;
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen msg_r->flags = 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen p_array_init(&keywords, pool, 16);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen for (args = t_strsplit_spaces(str, " "); *args != NULL; args++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (**args != '\\') {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen kw = p_strdup(pool, *args);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen array_append(&keywords, &kw, 1);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen } else if (strcasecmp(*args, "\\dsync-expunged") == 0) {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen msg_r->flags |= DSYNC_MAIL_FLAG_EXPUNGED;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen } else {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen flag = imap_parse_system_flag(*args);
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen if (flag == 0)
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen return -1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen msg_r->flags |= flag;
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen }
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen }
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen (void)array_append_space(&keywords);
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen msg_r->keywords = array_idx(&keywords, 0);
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen return 0;
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen}
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenint dsync_proxy_msg_import_unescaped(pool_t pool, const char *const *args,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct dsync_message *msg_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* guid uid modseq flags save_date */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (str_array_length(args) < 5) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen *error_r = "Missing parameters";
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(msg_r, 0, sizeof(*msg_r));
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen msg_r->guid = p_strdup(pool, args[0]);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen msg_r->uid = strtoul(args[1], NULL, 10);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen msg_r->modseq = strtoull(args[2], NULL, 10);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (dsync_proxy_msg_parse_flags(pool, args[3], msg_r) < 0) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen *error_r = "Invalid system flags";
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen return -1;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen msg_r->save_date = strtoul(args[4], NULL, 10);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen return 0;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen}
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainenint dsync_proxy_msg_import(pool_t pool, const char *str,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen struct dsync_message *msg_r, const char **error_r)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen{
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen char **args;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen unsigned int i;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen int ret;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen T_BEGIN {
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen args = p_strsplit(pool_datastack_create(), str, "\t");
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen for (i = 0; args[i] != NULL; i++)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen args[i] = str_tabunescape(args[i]);
4b41116563110d00330896a568eff1078c382827Timo Sirainen ret = dsync_proxy_msg_import_unescaped(pool,
4b41116563110d00330896a568eff1078c382827Timo Sirainen (const char *const *)args,
4b41116563110d00330896a568eff1078c382827Timo Sirainen msg_r, error_r);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen } T_END;
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen return ret;
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen}
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid dsync_proxy_msg_static_export(string_t *str,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct dsync_msg_static_data *msg)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen str_printfa(str, "%ld\t", (long)msg->received_date);
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen str_tabescape_write(str, msg->pop3_uidl);
ccec5f82349eae44087900c0e64ed1fd5a1a6fcaTimo Sirainen}
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainen
4d2211dac61c615c5bdfd501ea54d46c89d41b0fTimo Sirainenint dsync_proxy_msg_static_import_unescaped(pool_t pool,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *args,
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen struct dsync_msg_static_data *msg_r,
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen const char **error_r)
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* received_date pop3_uidl */
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen if (str_array_length(args) < 2) {
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen *error_r = "Missing parameters";
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen return -1;
cb05ecbd96ddb5e53c1850d27434541138a3f284Timo Sirainen }
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen
e3796bfd2bc0fd5ba664893d346df9334a5b3af0Timo Sirainen memset(msg_r, 0, sizeof(*msg_r));
e3796bfd2bc0fd5ba664893d346df9334a5b3af0Timo Sirainen msg_r->received_date = strtoul(args[0], NULL, 10);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen msg_r->pop3_uidl = p_strdup(pool, args[1]);
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen return 0;
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen}
408e5be344c9131fdebe771718a5bf49f88cc51cTimo Sirainen
408e5be344c9131fdebe771718a5bf49f88cc51cTimo Sirainenint dsync_proxy_msg_static_import(pool_t pool, const char *str,
408e5be344c9131fdebe771718a5bf49f88cc51cTimo Sirainen struct dsync_msg_static_data *msg_r,
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen const char **error_r)
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen{
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen char **args;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen T_BEGIN {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen args = p_strsplit(pool_datastack_create(), str, "\t");
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen for (i = 0; args[i] != NULL; i++)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen args[i] = str_tabunescape(args[i]);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen ret = dsync_proxy_msg_static_import_unescaped(pool,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (const char *const *)args,
f95b3d29bc56f139c18c880aa574a0ca72b0cffbTimo Sirainen msg_r, error_r);
f95b3d29bc56f139c18c880aa574a0ca72b0cffbTimo Sirainen } T_END;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainenvoid dsync_proxy_mailbox_export(string_t *str,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const struct dsync_mailbox *box)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen char s[2];
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen str_tabescape_write(str, box->name);
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen str_append_c(str, '\t');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen s[0] = box->name_sep; s[1] = '\0';
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen str_tabescape_write(str, s);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_change,
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen box->flags);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen if (dsync_mailbox_is_noselect(box)) {
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen i_assert(box->uid_validity == 0);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen return;
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen }
c13f3df87bc8ec1fb279fc0ffa6e8517f74dc07cTimo Sirainen i_assert(box->uid_validity != 0);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(str, '\t');
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen dsync_proxy_mailbox_guid_export(str, &box->mailbox_guid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(str, "\t%u\t%u\t%llu",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen box->uid_validity, box->uid_next,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen (unsigned long long)box->highest_modseq);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen dsync_proxy_strings_export(str, &box->cache_fields);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenint dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct dsync_mailbox *box_r,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const char **error_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int i = 0, count;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen char *p;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen memset(box_r, 0, sizeof(*box_r));
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen count = str_array_length(args);
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen if (count != 4 && count < 8) {
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen *error_r = "Mailbox missing parameters";
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen return -1;
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen }
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen
f23ede27743c1aa03eacbfc634d6a10de9110c91Timo Sirainen /* name dir_guid mailbox_guid uid_validity uid_next highest_modseq */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen box_r->name = p_strdup(pool, args[i++]);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen dsync_str_sha_to_guid(box_r->name, &box_r->name_sha1);
47001341950b8588c5f3a96b75864dab48e279aeTimo Sirainen
47001341950b8588c5f3a96b75864dab48e279aeTimo Sirainen if (strlen(args[i]) != 1) {
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen *error_r = "Invalid mailbox name hierarchy separator";
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen return -1;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen }
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen box_r->name_sep = args[i++][0];
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen box_r->last_change = strtoul(args[i++], &p, 10);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (*p != '\0') {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen *error_r = "Invalid mailbox last_change";
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return -1;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen box_r->flags = strtoul(args[i++], &p, 10);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen if (*p != '\0' ||
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen (dsync_mailbox_is_noselect(box_r) != (args[i] == NULL))) {
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen *error_r = "Invalid mailbox flags";
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen return -1;
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (args[i] == NULL) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* \noselect mailbox */
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen return 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (dsync_proxy_mailbox_guid_import(args[i++],
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen &box_r->mailbox_guid) < 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen *error_r = "Invalid mailbox GUID";
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return -1;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen }
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen box_r->uid_validity = strtoul(args[i++], &p, 10);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (box_r->uid_validity == 0 || *p != '\0') {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *error_r = "Invalid mailbox uid_validity";
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen box_r->uid_next = strtoul(args[i++], &p, 10);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (box_r->uid_validity == 0 || *p != '\0') {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *error_r = "Invalid mailbox uid_next";
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen box_r->highest_modseq = strtoull(args[i++], &p, 10);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (*p != '\0') {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen *error_r = "Invalid mailbox highest_modseq";
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return -1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen args += i;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen count -= i;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen p_array_init(&box_r->cache_fields, pool, count + 1);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen for (i = 0; i < count; i++) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char *field_name = p_strdup(pool, args[i]);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen array_append(&box_r->cache_fields, &field_name, 1);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint dsync_proxy_mailbox_import(pool_t pool, const char *str,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen struct dsync_mailbox *box_r,
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen const char **error_r)
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen{
01404d41657a104c5ea1c12bb87f9c321e9c1ac4Timo Sirainen char **args;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen T_BEGIN {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen args = p_strsplit(pool_datastack_create(), str, "\t");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (args[0] != NULL)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen args[0] = str_tabunescape(args[0]);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ret = dsync_proxy_mailbox_import_unescaped(pool,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (const char *const *)args,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen box_r, error_r);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen } T_END;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid dsync_proxy_mailbox_guid_export(string_t *str,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const mailbox_guid_t *mailbox)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, dsync_guid_to_str(mailbox));
e4c90f0b88e40a8f92b8f5e1f1a3ea701e5c965cTimo Sirainen}
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint dsync_proxy_mailbox_guid_import(const char *str, mailbox_guid_t *guid_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen buffer_t *buf;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(),
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen sizeof(guid_r->guid));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (hex_to_binary(str, buf) < 0 || buf->used != sizeof(guid_r->guid))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
194603b35061fea1ee8d171a7104b6985c610966Timo Sirainen memcpy(guid_r->guid, buf->data, sizeof(guid_r->guid));
194603b35061fea1ee8d171a7104b6985c610966Timo Sirainen return 0;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenvoid dsync_proxy_send_dot_output(struct ostream *output, bool *last_lf,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const unsigned char *data, size_t size)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen size_t i, start;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(size > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (*last_lf && data[0] == '.')
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen o_stream_send(output, ".", 1);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen for (i = 1, start = 0; i < size; i++) {
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen if (data[i-1] == '\n' && data[i] == '.') {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen o_stream_send(output, data + start, i - start);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen o_stream_send(output, ".", 1);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen start = i;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen o_stream_send(output, data + start, i - start);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen *last_lf = data[i-1] == '\n';
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen i_assert(i == size);
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen