Mercurial > dovecot > core-2.2
view src/dsync/dsync-proxy.c @ 10582:615eef3139c2 HEAD
Updated copyright notices to include year 2010.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 25 Jan 2010 01:19:08 +0200 |
parents | 96db209efe22 |
children | 5ec28d7a5d13 |
line wrap: on
line source
/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "array.h" #include "str.h" #include "strescape.h" #include "ostream.h" #include "hex-binary.h" #include "mail-types.h" #include "imap-util.h" #include "dsync-data.h" #include "dsync-proxy.h" #include <stdlib.h> void dsync_proxy_strings_export(string_t *str, const ARRAY_TYPE(const_string) *strings) { const char *const *fields; unsigned int i, count; if (!array_is_created(strings)) return; fields = array_get(strings, &count); for (i = 0; i < count; i++) { str_append_c(str, '\t'); str_tabescape_write(str, fields[i]); } } void dsync_proxy_msg_export(string_t *str, const struct dsync_message *msg) { str_tabescape_write(str, msg->guid); str_printfa(str, "\t%u\t%llu\t", msg->uid, (unsigned long long)msg->modseq); if ((msg->flags & DSYNC_MAIL_FLAG_EXPUNGED) != 0) str_append(str, "\\dsync-expunged "); imap_write_flags(str, msg->flags & MAIL_FLAGS_MASK, msg->keywords); str_printfa(str, "\t%ld", (long)msg->save_date); } int dsync_proxy_msg_parse_flags(pool_t pool, const char *str, struct dsync_message *msg_r) { ARRAY_TYPE(const_string) keywords; const char *const *args, *kw; enum mail_flags flag; msg_r->flags = 0; p_array_init(&keywords, pool, 16); for (args = t_strsplit_spaces(str, " "); *args != NULL; args++) { if (**args != '\\') { kw = p_strdup(pool, *args); array_append(&keywords, &kw, 1); } else if (strcasecmp(*args, "\\dsync-expunged") == 0) { msg_r->flags |= DSYNC_MAIL_FLAG_EXPUNGED; } else { flag = imap_parse_system_flag(*args); if (flag == 0) return -1; msg_r->flags |= flag; } } (void)array_append_space(&keywords); msg_r->keywords = array_idx(&keywords, 0); return 0; } int dsync_proxy_msg_import_unescaped(pool_t pool, const char *const *args, struct dsync_message *msg_r, const char **error_r) { /* guid uid modseq flags save_date */ if (str_array_length(args) < 5) { *error_r = "Missing parameters"; return -1; } memset(msg_r, 0, sizeof(*msg_r)); msg_r->guid = p_strdup(pool, args[0]); msg_r->uid = strtoul(args[1], NULL, 10); msg_r->modseq = strtoull(args[2], NULL, 10); if (dsync_proxy_msg_parse_flags(pool, args[3], msg_r) < 0) { *error_r = "Invalid system flags"; return -1; } msg_r->save_date = strtoul(args[4], NULL, 10); return 0; } int dsync_proxy_msg_import(pool_t pool, const char *str, struct dsync_message *msg_r, const char **error_r) { char **args; unsigned int i; int ret; T_BEGIN { args = p_strsplit(pool_datastack_create(), str, "\t"); for (i = 0; args[i] != NULL; i++) args[i] = str_tabunescape(args[i]); ret = dsync_proxy_msg_import_unescaped(pool, (const char *const *)args, msg_r, error_r); } T_END; return ret; } void dsync_proxy_msg_static_export(string_t *str, const struct dsync_msg_static_data *msg) { str_printfa(str, "%ld\t", (long)msg->received_date); str_tabescape_write(str, msg->pop3_uidl); } int dsync_proxy_msg_static_import_unescaped(pool_t pool, const char *const *args, struct dsync_msg_static_data *msg_r, const char **error_r) { /* received_date pop3_uidl */ if (str_array_length(args) < 2) { *error_r = "Missing parameters"; return -1; } memset(msg_r, 0, sizeof(*msg_r)); msg_r->received_date = strtoul(args[0], NULL, 10); msg_r->pop3_uidl = p_strdup(pool, args[1]); return 0; } int dsync_proxy_msg_static_import(pool_t pool, const char *str, struct dsync_msg_static_data *msg_r, const char **error_r) { char **args; unsigned int i; int ret; T_BEGIN { args = p_strsplit(pool_datastack_create(), str, "\t"); for (i = 0; args[i] != NULL; i++) args[i] = str_tabunescape(args[i]); ret = dsync_proxy_msg_static_import_unescaped(pool, (const char *const *)args, msg_r, error_r); } T_END; return ret; } void dsync_proxy_mailbox_export(string_t *str, const struct dsync_mailbox *box) { char s[2]; str_tabescape_write(str, box->name); str_append_c(str, '\t'); s[0] = box->name_sep; s[1] = '\0'; str_tabescape_write(str, s); str_printfa(str, "\t%lu\t%u", (unsigned long)box->last_change, box->flags); if (dsync_mailbox_is_noselect(box)) { i_assert(box->uid_validity == 0); return; } i_assert(box->uid_validity != 0); str_append_c(str, '\t'); dsync_proxy_mailbox_guid_export(str, &box->mailbox_guid); str_printfa(str, "\t%u\t%u\t%llu", box->uid_validity, box->uid_next, (unsigned long long)box->highest_modseq); dsync_proxy_strings_export(str, &box->cache_fields); } int dsync_proxy_mailbox_import_unescaped(pool_t pool, const char *const *args, struct dsync_mailbox *box_r, const char **error_r) { unsigned int i = 0, count; char *p; memset(box_r, 0, sizeof(*box_r)); count = str_array_length(args); if (count != 4 && count < 8) { *error_r = "Mailbox missing parameters"; return -1; } /* name dir_guid mailbox_guid uid_validity uid_next highest_modseq */ box_r->name = p_strdup(pool, args[i++]); dsync_str_sha_to_guid(box_r->name, &box_r->name_sha1); if (strlen(args[i]) != 1) { *error_r = "Invalid mailbox name hierarchy separator"; return -1; } box_r->name_sep = args[i++][0]; box_r->last_change = strtoul(args[i++], &p, 10); if (*p != '\0') { *error_r = "Invalid mailbox last_change"; return -1; } box_r->flags = strtoul(args[i++], &p, 10); if (*p != '\0' || (dsync_mailbox_is_noselect(box_r) != (args[i] == NULL))) { *error_r = "Invalid mailbox flags"; return -1; } if (args[i] == NULL) { /* \noselect mailbox */ return 0; } if (dsync_proxy_mailbox_guid_import(args[i++], &box_r->mailbox_guid) < 0) { *error_r = "Invalid mailbox GUID"; return -1; } box_r->uid_validity = strtoul(args[i++], &p, 10); if (box_r->uid_validity == 0 || *p != '\0') { *error_r = "Invalid mailbox uid_validity"; return -1; } box_r->uid_next = strtoul(args[i++], &p, 10); if (box_r->uid_validity == 0 || *p != '\0') { *error_r = "Invalid mailbox uid_next"; return -1; } box_r->highest_modseq = strtoull(args[i++], &p, 10); if (*p != '\0') { *error_r = "Invalid mailbox highest_modseq"; return -1; } args += i; count -= i; p_array_init(&box_r->cache_fields, pool, count + 1); for (i = 0; i < count; i++) { const char *field_name = p_strdup(pool, args[i]); array_append(&box_r->cache_fields, &field_name, 1); } return 0; } int dsync_proxy_mailbox_import(pool_t pool, const char *str, struct dsync_mailbox *box_r, const char **error_r) { char **args; int ret; T_BEGIN { args = p_strsplit(pool_datastack_create(), str, "\t"); if (args[0] != NULL) args[0] = str_tabunescape(args[0]); ret = dsync_proxy_mailbox_import_unescaped(pool, (const char *const *)args, box_r, error_r); } T_END; return ret; } void dsync_proxy_mailbox_guid_export(string_t *str, const mailbox_guid_t *mailbox) { str_append(str, binary_to_hex(mailbox->guid, sizeof(mailbox->guid))); } int dsync_proxy_mailbox_guid_import(const char *str, mailbox_guid_t *guid_r) { buffer_t *buf; buf = buffer_create_dynamic(pool_datastack_create(), sizeof(guid_r->guid)); if (hex_to_binary(str, buf) < 0 || buf->used != sizeof(guid_r->guid)) return -1; memcpy(guid_r->guid, buf->data, sizeof(guid_r->guid)); return 0; } void dsync_proxy_send_dot_output(struct ostream *output, bool *last_lf, const unsigned char *data, size_t size) { size_t i, start; i_assert(size > 0); if (*last_lf && data[0] == '.') o_stream_send(output, ".", 1); for (i = 1, start = 0; i < size; i++) { if (data[i-1] == '\n' && data[i] == '.') { o_stream_send(output, data + start, i - start); o_stream_send(output, ".", 1); start = i; } } o_stream_send(output, data + start, i - start); *last_lf = data[i-1] == '\n'; i_assert(i == size); }