Mercurial > dovecot > core-2.2
changeset 12516:dc75c71b4671
maildir: Moved maildir_filename_flags_*() to a separate file.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 06 Sep 2010 19:07:49 +0100 |
parents | 820d370eb2fe |
children | 7c147f053c9b |
files | src/lib-storage/index/maildir/Makefile.am src/lib-storage/index/maildir/maildir-filename-flags.c src/lib-storage/index/maildir/maildir-filename-flags.h src/lib-storage/index/maildir/maildir-filename.c src/lib-storage/index/maildir/maildir-filename.h src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-sync-index.c src/lib-storage/index/maildir/maildir-util.c |
diffstat | 8 files changed, 196 insertions(+), 184 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/Makefile.am Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/Makefile.am Mon Sep 06 19:07:49 2010 +0100 @@ -12,6 +12,7 @@ libstorage_maildir_la_SOURCES = \ maildir-copy.c \ maildir-filename.c \ + maildir-filename-flags.c \ maildir-keywords.c \ maildir-mail.c \ maildir-save.c \ @@ -24,6 +25,7 @@ headers = \ maildir-filename.h \ + maildir-filename-flags.h \ maildir-keywords.h \ maildir-storage.h \ maildir-settings.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename-flags.c Mon Sep 06 19:07:49 2010 +0100 @@ -0,0 +1,172 @@ +/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "str.h" +#include "maildir-storage.h" +#include "maildir-keywords.h" +#include "maildir-filename-flags.h" + +#include <stdlib.h> + +void maildir_filename_flags_get(struct maildir_keywords_sync_ctx *ctx, + const char *fname, enum mail_flags *flags_r, + ARRAY_TYPE(keyword_indexes) *keywords_r) +{ + const char *info; + + array_clear(keywords_r); + *flags_r = 0; + + info = strrchr(fname, MAILDIR_INFO_SEP); + if (info == NULL || info[1] != '2' || info[2] != MAILDIR_FLAGS_SEP) + return; + + for (info += 3; *info != '\0' && *info != MAILDIR_FLAGS_SEP; info++) { + switch (*info) { + case 'R': /* replied */ + *flags_r |= MAIL_ANSWERED; + break; + case 'S': /* seen */ + *flags_r |= MAIL_SEEN; + break; + case 'T': /* trashed */ + *flags_r |= MAIL_DELETED; + break; + case 'D': /* draft */ + *flags_r |= MAIL_DRAFT; + break; + case 'F': /* flagged */ + *flags_r |= MAIL_FLAGGED; + break; + default: + if (*info >= MAILDIR_KEYWORD_FIRST && + *info <= MAILDIR_KEYWORD_LAST) { + int idx; + + idx = maildir_keywords_char_idx(ctx, *info); + if (idx < 0) { + /* unknown keyword. */ + break; + } + + array_append(keywords_r, + (unsigned int *)&idx, 1); + break; + } + + /* unknown flag - ignore */ + break; + } + } +} + +static int char_cmp(const void *p1, const void *p2) +{ + const unsigned char *c1 = p1, *c2 = p2; + + return *c1 - *c2; +} + +static void +maildir_filename_append_keywords(struct maildir_keywords_sync_ctx *ctx, + ARRAY_TYPE(keyword_indexes) *keywords, + string_t *fname) +{ + const unsigned int *indexes; + unsigned int i, count, start = str_len(fname); + char chr; + + indexes = array_get(keywords, &count); + for (i = 0; i < count; i++) { + chr = maildir_keywords_idx_char(ctx, indexes[i]); + if (chr != '\0') + str_append_c(fname, chr); + } + + qsort(str_c_modifiable(fname) + start, str_len(fname) - start, 1, + char_cmp); +} + +const char *maildir_filename_flags_set(struct maildir_keywords_sync_ctx *ctx, + const char *fname, enum mail_flags flags, + ARRAY_TYPE(keyword_indexes) *keywords) +{ + string_t *flags_str; + enum mail_flags flags_left; + const char *info, *oldflags; + int nextflag; + + /* remove the old :info from file name, and get the old flags */ + info = strrchr(fname, MAILDIR_INFO_SEP); + if (info != NULL && strrchr(fname, '/') > info) + info = NULL; + + oldflags = ""; + if (info != NULL) { + fname = t_strdup_until(fname, info); + if (info[1] == '2' && info[2] == MAILDIR_FLAGS_SEP) + oldflags = info+3; + } + + /* insert the new flags between old flags. flags must be sorted by + their ASCII code. unknown flags are kept. */ + flags_str = t_str_new(256); + str_append(flags_str, fname); + str_append(flags_str, MAILDIR_FLAGS_FULL_SEP); + flags_left = flags; + for (;;) { + /* skip all known flags */ + while (*oldflags == 'D' || *oldflags == 'F' || + *oldflags == 'R' || *oldflags == 'S' || + *oldflags == 'T' || + (*oldflags >= MAILDIR_KEYWORD_FIRST && + *oldflags <= MAILDIR_KEYWORD_LAST)) + oldflags++; + + nextflag = *oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP ? + 256 : (unsigned char) *oldflags; + + if ((flags_left & MAIL_DRAFT) && nextflag > 'D') { + str_append_c(flags_str, 'D'); + flags_left &= ~MAIL_DRAFT; + } + if ((flags_left & MAIL_FLAGGED) && nextflag > 'F') { + str_append_c(flags_str, 'F'); + flags_left &= ~MAIL_FLAGGED; + } + if ((flags_left & MAIL_ANSWERED) && nextflag > 'R') { + str_append_c(flags_str, 'R'); + flags_left &= ~MAIL_ANSWERED; + } + if ((flags_left & MAIL_SEEN) && nextflag > 'S') { + str_append_c(flags_str, 'S'); + flags_left &= ~MAIL_SEEN; + } + if ((flags_left & MAIL_DELETED) && nextflag > 'T') { + str_append_c(flags_str, 'T'); + flags_left &= ~MAIL_DELETED; + } + + if (keywords != NULL && array_is_created(keywords) && + nextflag > MAILDIR_KEYWORD_FIRST) { + maildir_filename_append_keywords(ctx, keywords, + flags_str); + keywords = NULL; + } + + if (*oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP) + break; + + str_append_c(flags_str, *oldflags); + oldflags++; + } + + if (*oldflags == MAILDIR_FLAGS_SEP) { + /* another flagset, we don't know about these, just keep them */ + while (*oldflags != '\0') + str_append_c(flags_str, *oldflags++); + } + + return str_c(flags_str); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename-flags.h Mon Sep 06 19:07:49 2010 +0100 @@ -0,0 +1,12 @@ +#ifndef MAILDIR_FILENAME_FLAGS_H +#define MAILDIR_FILENAME_FLAGS_H + +void maildir_filename_flags_get(struct maildir_keywords_sync_ctx *ctx, + const char *fname, enum mail_flags *flags_r, + ARRAY_TYPE(keyword_indexes) *keywords_r); + +const char *maildir_filename_flags_set(struct maildir_keywords_sync_ctx *ctx, + const char *fname, enum mail_flags flags, + ARRAY_TYPE(keyword_indexes) *keywords); + +#endif
--- a/src/lib-storage/index/maildir/maildir-filename.c Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename.c Mon Sep 06 19:07:49 2010 +0100 @@ -2,16 +2,11 @@ #include "lib.h" #include "ioloop.h" -#include "array.h" -#include "str.h" #include "time-util.h" #include "hostpid.h" #include "maildir-storage.h" -#include "maildir-keywords.h" #include "maildir-filename.h" -#include <stdlib.h> - const char *maildir_filename_generate(void) { static struct timeval last_tv = { 0, 0 }; @@ -34,168 +29,6 @@ my_pid, my_hostname); } -void maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx, - const char *fname, enum mail_flags *flags_r, - ARRAY_TYPE(keyword_indexes) *keywords_r) -{ - const char *info; - - array_clear(keywords_r); - *flags_r = 0; - - info = strrchr(fname, MAILDIR_INFO_SEP); - if (info == NULL || info[1] != '2' || info[2] != MAILDIR_FLAGS_SEP) - return; - - for (info += 3; *info != '\0' && *info != MAILDIR_FLAGS_SEP; info++) { - switch (*info) { - case 'R': /* replied */ - *flags_r |= MAIL_ANSWERED; - break; - case 'S': /* seen */ - *flags_r |= MAIL_SEEN; - break; - case 'T': /* trashed */ - *flags_r |= MAIL_DELETED; - break; - case 'D': /* draft */ - *flags_r |= MAIL_DRAFT; - break; - case 'F': /* flagged */ - *flags_r |= MAIL_FLAGGED; - break; - default: - if (*info >= MAILDIR_KEYWORD_FIRST && - *info <= MAILDIR_KEYWORD_LAST) { - int idx; - - idx = maildir_keywords_char_idx(ctx, *info); - if (idx < 0) { - /* unknown keyword. */ - break; - } - - array_append(keywords_r, - (unsigned int *)&idx, 1); - break; - } - - /* unknown flag - ignore */ - break; - } - } -} - -static int char_cmp(const void *p1, const void *p2) -{ - const unsigned char *c1 = p1, *c2 = p2; - - return *c1 - *c2; -} - -static void -maildir_filename_append_keywords(struct maildir_keywords_sync_ctx *ctx, - ARRAY_TYPE(keyword_indexes) *keywords, - string_t *fname) -{ - const unsigned int *indexes; - unsigned int i, count, start = str_len(fname); - char chr; - - indexes = array_get(keywords, &count); - for (i = 0; i < count; i++) { - chr = maildir_keywords_idx_char(ctx, indexes[i]); - if (chr != '\0') - str_append_c(fname, chr); - } - - qsort(str_c_modifiable(fname) + start, str_len(fname) - start, 1, - char_cmp); -} - -const char *maildir_filename_set_flags(struct maildir_keywords_sync_ctx *ctx, - const char *fname, enum mail_flags flags, - ARRAY_TYPE(keyword_indexes) *keywords) -{ - string_t *flags_str; - enum mail_flags flags_left; - const char *info, *oldflags; - int nextflag; - - /* remove the old :info from file name, and get the old flags */ - info = strrchr(fname, MAILDIR_INFO_SEP); - if (info != NULL && strrchr(fname, '/') > info) - info = NULL; - - oldflags = ""; - if (info != NULL) { - fname = t_strdup_until(fname, info); - if (info[1] == '2' && info[2] == MAILDIR_FLAGS_SEP) - oldflags = info+3; - } - - /* insert the new flags between old flags. flags must be sorted by - their ASCII code. unknown flags are kept. */ - flags_str = t_str_new(256); - str_append(flags_str, fname); - str_append(flags_str, MAILDIR_FLAGS_FULL_SEP); - flags_left = flags; - for (;;) { - /* skip all known flags */ - while (*oldflags == 'D' || *oldflags == 'F' || - *oldflags == 'R' || *oldflags == 'S' || - *oldflags == 'T' || - (*oldflags >= MAILDIR_KEYWORD_FIRST && - *oldflags <= MAILDIR_KEYWORD_LAST)) - oldflags++; - - nextflag = *oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP ? - 256 : (unsigned char) *oldflags; - - if ((flags_left & MAIL_DRAFT) && nextflag > 'D') { - str_append_c(flags_str, 'D'); - flags_left &= ~MAIL_DRAFT; - } - if ((flags_left & MAIL_FLAGGED) && nextflag > 'F') { - str_append_c(flags_str, 'F'); - flags_left &= ~MAIL_FLAGGED; - } - if ((flags_left & MAIL_ANSWERED) && nextflag > 'R') { - str_append_c(flags_str, 'R'); - flags_left &= ~MAIL_ANSWERED; - } - if ((flags_left & MAIL_SEEN) && nextflag > 'S') { - str_append_c(flags_str, 'S'); - flags_left &= ~MAIL_SEEN; - } - if ((flags_left & MAIL_DELETED) && nextflag > 'T') { - str_append_c(flags_str, 'T'); - flags_left &= ~MAIL_DELETED; - } - - if (keywords != NULL && array_is_created(keywords) && - nextflag > MAILDIR_KEYWORD_FIRST) { - maildir_filename_append_keywords(ctx, keywords, - flags_str); - keywords = NULL; - } - - if (*oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP) - break; - - str_append_c(flags_str, *oldflags); - oldflags++; - } - - if (*oldflags == MAILDIR_FLAGS_SEP) { - /* another flagset, we don't know about these, just keep them */ - while (*oldflags != '\0') - str_append_c(flags_str, *oldflags++); - } - - return str_c(flags_str); -} - bool maildir_filename_get_size(const char *fname, char type, uoff_t *size_r) { uoff_t size = 0;
--- a/src/lib-storage/index/maildir/maildir-filename.h Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename.h Mon Sep 06 19:07:49 2010 +0100 @@ -5,14 +5,6 @@ const char *maildir_filename_generate(void); -void maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx, - const char *fname, enum mail_flags *flags_r, - ARRAY_TYPE(keyword_indexes) *keywords_r); - -const char *maildir_filename_set_flags(struct maildir_keywords_sync_ctx *ctx, - const char *fname, enum mail_flags flags, - ARRAY_TYPE(keyword_indexes) *keywords); - bool maildir_filename_get_size(const char *fname, char type, uoff_t *size_r); unsigned int maildir_filename_base_hash(const void *p);
--- a/src/lib-storage/index/maildir/maildir-save.c Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/maildir-save.c Mon Sep 06 19:07:49 2010 +0100 @@ -15,6 +15,7 @@ #include "maildir-uidlist.h" #include "maildir-keywords.h" #include "maildir-filename.h" +#include "maildir-filename-flags.h" #include "maildir-sync.h" #include <stdio.h> @@ -268,7 +269,7 @@ return TRUE; } - *fname_r = maildir_filename_set_flags(NULL, basename, + *fname_r = maildir_filename_flags_set(NULL, basename, mf->flags & MAIL_FLAGS_MASK, NULL); return FALSE; } @@ -276,7 +277,7 @@ i_assert(ctx->keywords_sync_ctx != NULL || mf->keywords_count == 0); buffer_create_const_data(&ctx->keywords_buffer, mf + 1, mf->keywords_count * sizeof(unsigned int)); - *fname_r = maildir_filename_set_flags(ctx->keywords_sync_ctx, basename, + *fname_r = maildir_filename_flags_set(ctx->keywords_sync_ctx, basename, mf->flags & MAIL_FLAGS_MASK, &ctx->keywords_array); return FALSE;
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/maildir-sync-index.c Mon Sep 06 19:07:49 2010 +0100 @@ -8,7 +8,7 @@ #include "index-sync-changes.h" #include "maildir-uidlist.h" #include "maildir-keywords.h" -#include "maildir-filename.h" +#include "maildir-filename-flags.h" #include "maildir-sync.h" #include <stdio.h> @@ -123,7 +123,7 @@ i_assert(*fname != '\0'); /* get the current flags and keywords */ - maildir_filename_get_flags(ctx->keywords_sync_ctx, + maildir_filename_flags_get(ctx->keywords_sync_ctx, fname, &ctx->flags, &ctx->keywords); /* apply changes */ @@ -133,7 +133,7 @@ ctx->flags = flags8; /* and try renaming with the new name */ - newfname = maildir_filename_set_flags(ctx->keywords_sync_ctx, fname, + newfname = maildir_filename_flags_set(ctx->keywords_sync_ctx, fname, ctx->flags, &ctx->keywords); newpath = t_strconcat(dir, newfname, NULL); if (strcmp(path, newpath) == 0) { @@ -497,7 +497,7 @@ i_array_init(&ctx->idx_keywords, MAILDIR_MAX_KEYWORDS); iter = maildir_uidlist_iter_init(mbox->uidlist); while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) { - maildir_filename_get_flags(ctx->keywords_sync_ctx, filename, + maildir_filename_flags_get(ctx->keywords_sync_ctx, filename, &ctx->flags, &ctx->keywords); i_assert(uid > prev_uid);
--- a/src/lib-storage/index/maildir/maildir-util.c Sun Dec 05 21:07:01 2010 +0000 +++ b/src/lib-storage/index/maildir/maildir-util.c Mon Sep 06 19:07:49 2010 +0100 @@ -9,7 +9,7 @@ #include "maildir-storage.h" #include "maildir-uidlist.h" #include "maildir-keywords.h" -#include "maildir-filename.h" +#include "maildir-filename-flags.h" #include "maildir-sync.h" #include <stdio.h> @@ -41,12 +41,12 @@ mail_index_lookup_view_flags(view, seq, &flags, &keywords); if (array_count(&keywords) == 0) { *have_flags_r = (flags & MAIL_FLAGS_NONRECENT) != 0; - fname = maildir_filename_set_flags(NULL, fname, flags, NULL); + fname = maildir_filename_flags_set(NULL, fname, flags, NULL); } else { *have_flags_r = TRUE; kw_ctx = maildir_keywords_sync_init_readonly(mbox->keywords, mbox->box.index); - fname = maildir_filename_set_flags(kw_ctx, fname, + fname = maildir_filename_flags_set(kw_ctx, fname, flags, &keywords); maildir_keywords_sync_deinit(&kw_ctx); }