Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5899:f29b93c0519c HEAD
Moved maildir filename related functions to maildir-filename.c
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 08 Jul 2007 20:13:12 +0300 |
parents | 54ef7dccdfc7 |
children | 025e92f4f75a |
files | src/lib-storage/index/maildir/Makefile.am src/lib-storage/index/maildir/maildir-copy.c src/lib-storage/index/maildir/maildir-filename.c src/lib-storage/index/maildir/maildir-filename.h src/lib-storage/index/maildir/maildir-mail.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-storage.h src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/maildir/maildir-sync.h src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/maildir/maildir-util.c |
diffstat | 11 files changed, 289 insertions(+), 259 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/Makefile.am Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/Makefile.am Sun Jul 08 20:13:12 2007 +0300 @@ -10,6 +10,7 @@ libstorage_maildir_a_SOURCES = \ maildir-copy.c \ + maildir-filename.c \ maildir-keywords.c \ maildir-mail.c \ maildir-save.c \ @@ -20,6 +21,7 @@ maildir-util.c headers = \ + maildir-filename.h \ maildir-keywords.h \ maildir-storage.h \ maildir-sync.h \
--- a/src/lib-storage/index/maildir/maildir-copy.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-copy.c Sun Jul 08 20:13:12 2007 +0300 @@ -6,6 +6,7 @@ #include "str.h" #include "maildir-storage.h" #include "maildir-uidlist.h" +#include "maildir-filename.h" #include "maildir-keywords.h" #include "maildir-sync.h" #include "index-mail.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename.c Sun Jul 08 20:13:12 2007 +0300 @@ -0,0 +1,260 @@ +/* Copyright (C) 2002-2007 Timo Sirainen */ + +#include "lib.h" +#include "ioloop.h" +#include "array.h" +#include "str.h" +#include "hostpid.h" +#include "maildir-storage.h" +#include "maildir-keywords.h" +#include "maildir-filename.h" + +#include <stdlib.h> + +const char *maildir_generate_tmp_filename(const struct timeval *tv) +{ + static unsigned int create_count = 0; + static time_t first_stamp = 0; + + if (first_stamp == 0 || first_stamp == ioloop_time) { + /* it's possible that within last second another process had + the same PID as us. Use usecs to make sure we don't create + duplicate base name. */ + first_stamp = ioloop_time; + return t_strdup_printf("%s.P%sQ%uM%s.%s", + dec2str(tv->tv_sec), my_pid, + create_count++, + dec2str(tv->tv_usec), my_hostname); + } else { + /* Don't bother with usecs. Saves a bit space :) */ + return t_strdup_printf("%s.P%sQ%u.%s", + dec2str(tv->tv_sec), my_pid, + create_count++, my_hostname); + } +} + +int 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 = strchr(fname, MAILDIR_INFO_SEP); + if (info == NULL || info[1] != '2' || info[2] != MAILDIR_FLAGS_SEP) + return 0; + + 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; + } + } + + return 1; +} + +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 *str) +{ + const unsigned int *indexes; + unsigned int i, count, start = str_len(str); + 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(str, chr); + } + + qsort(str_c_modifiable(str) + start, str_len(str) - 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; + + for (; *fname != '\0'; fname++) { + i_assert(*fname != '/'); + if (*fname == ',' && fname[1] == type && fname[2] == '=') { + fname += 3; + break; + } + } + + if (*fname == '\0') + return FALSE; + + while (*fname >= '0' && *fname <= '9') { + size = size * 10 + (*fname - '0'); + fname++; + } + + if (*fname != MAILDIR_INFO_SEP && + *fname != MAILDIR_EXTRA_SEP && + *fname != '\0') + return FALSE; + + *size_r = size; + return TRUE; +} + +/* a char* hash function from ASU -- from glib */ +unsigned int maildir_hash(const void *p) +{ + const unsigned char *s = p; + unsigned int g, h = 0; + + while (*s != MAILDIR_INFO_SEP && *s != '\0') { + i_assert(*s != '/'); + h = (h << 4) + *s; + if ((g = h & 0xf0000000UL)) { + h = h ^ (g >> 24); + h = h ^ g; + } + + s++; + } + + return h; +} + +int maildir_cmp(const void *p1, const void *p2) +{ + const char *s1 = p1, *s2 = p2; + + while (*s1 == *s2 && *s1 != MAILDIR_INFO_SEP && *s1 != '\0') { + i_assert(*s1 != '/'); + s1++; s2++; + } + if ((*s1 == '\0' || *s1 == MAILDIR_INFO_SEP) && + (*s2 == '\0' || *s2 == MAILDIR_INFO_SEP)) + return 0; + return *s1 - *s2; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/maildir/maildir-filename.h Sun Jul 08 20:13:12 2007 +0300 @@ -0,0 +1,21 @@ +#ifndef __MAILDIR_FILENAME_H +#define __MAILDIR_FILENAME_H + +struct maildir_keywords_sync_ctx; + +const char *maildir_generate_tmp_filename(const struct timeval *tv); + +int 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_hash(const void *p); +int maildir_cmp(const void *p1, const void *p2); + +#endif
--- a/src/lib-storage/index/maildir/maildir-mail.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-mail.c Sun Jul 08 20:13:12 2007 +0300 @@ -4,6 +4,7 @@ #include "istream.h" #include "index-mail.h" #include "maildir-storage.h" +#include "maildir-filename.h" #include "maildir-uidlist.h" #include <fcntl.h>
--- a/src/lib-storage/index/maildir/maildir-save.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Sun Jul 08 20:13:12 2007 +0300 @@ -12,6 +12,7 @@ #include "index-mail.h" #include "maildir-storage.h" #include "maildir-uidlist.h" +#include "maildir-filename.h" #include "maildir-sync.h" #include <stdio.h>
--- a/src/lib-storage/index/maildir/maildir-storage.h Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Sun Jul 08 20:13:12 2007 +0300 @@ -113,11 +113,9 @@ maildir_file_do(mbox, seq, (maildir_file_do_func *)callback, context) #endif -const char *maildir_generate_tmp_filename(const struct timeval *tv); int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir, mode_t mode, const char **fname_r); void maildir_tmp_cleanup(struct mail_storage *storage, const char *dir); -bool maildir_filename_get_size(const char *fname, char type, uoff_t *size_r); void maildir_transaction_class_init(void); void maildir_transaction_class_deinit(void); @@ -150,7 +148,4 @@ int maildir_transaction_copy_commit(struct maildir_copy_context *ctx); void maildir_transaction_copy_rollback(struct maildir_copy_context *ctx); -unsigned int maildir_hash(const void *p); -int maildir_cmp(const void *p1, const void *p2); - #endif
--- a/src/lib-storage/index/maildir/maildir-sync.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Sun Jul 08 20:13:12 2007 +0300 @@ -179,6 +179,7 @@ #include "maildir-storage.h" #include "maildir-uidlist.h" #include "maildir-keywords.h" +#include "maildir-filename.h" #include "maildir-sync.h" #include <stdio.h> @@ -243,169 +244,6 @@ return ctx->keywords_sync_ctx; } -int 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 = strchr(fname, MAILDIR_INFO_SEP); - if (info == NULL || info[1] != '2' || info[2] != MAILDIR_FLAGS_SEP) - return 0; - - 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; - } - } - - return 1; -} - -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 *str) -{ - const unsigned int *indexes; - unsigned int i, count, start = str_len(str); - 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(str, chr); - } - - qsort(str_c_modifiable(str) + start, str_len(str) - 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); -} - static int maildir_expunge(struct maildir_mailbox *mbox, const char *path, struct maildir_index_sync_context *ctx) {
--- a/src/lib-storage/index/maildir/maildir-sync.h Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.h Sun Jul 08 20:13:12 2007 +0300 @@ -23,13 +23,7 @@ int maildir_sync_last_commit(struct maildir_mailbox *mbox); -int maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx, - const char *fname, enum mail_flags *flags_r, - ARRAY_TYPE(keyword_indexes) *keywords); struct maildir_keywords_sync_ctx * maildir_sync_get_keywords_sync_ctx(struct maildir_index_sync_context *ctx); -const char *maildir_filename_set_flags(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-uidlist.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sun Jul 08 20:13:12 2007 +0300 @@ -12,6 +12,7 @@ #include "write-full.h" #include "maildir-storage.h" #include "maildir-sync.h" +#include "maildir-filename.h" #include "maildir-uidlist.h" #include <stdio.h>
--- a/src/lib-storage/index/maildir/maildir-util.c Sun Jul 08 19:57:09 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-util.c Sun Jul 08 20:13:12 2007 +0300 @@ -6,6 +6,7 @@ #include "str.h" #include "maildir-storage.h" #include "maildir-uidlist.h" +#include "maildir-filename.h" #include "maildir-keywords.h" #include "maildir-sync.h" @@ -83,28 +84,6 @@ return ret == -2 ? 0 : ret; } -const char *maildir_generate_tmp_filename(const struct timeval *tv) -{ - static unsigned int create_count = 0; - static time_t first_stamp = 0; - - if (first_stamp == 0 || first_stamp == ioloop_time) { - /* it's possible that within last second another process had - the same PID as us. Use usecs to make sure we don't create - duplicate base name. */ - first_stamp = ioloop_time; - return t_strdup_printf("%s.P%sQ%uM%s.%s", - dec2str(tv->tv_sec), my_pid, - create_count++, - dec2str(tv->tv_usec), my_hostname); - } else { - /* Don't bother with usecs. Saves a bit space :) */ - return t_strdup_printf("%s.P%sQ%u.%s", - dec2str(tv->tv_sec), my_pid, - create_count++, my_hostname); - } -} - int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir, mode_t mode, const char **fname_r) { @@ -235,66 +214,3 @@ "closedir(%s) failed: %m", dir); } } - -bool maildir_filename_get_size(const char *fname, char type, uoff_t *size_r) -{ - uoff_t size = 0; - - for (; *fname != '\0'; fname++) { - i_assert(*fname != '/'); - if (*fname == ',' && fname[1] == type && fname[2] == '=') { - fname += 3; - break; - } - } - - if (*fname == '\0') - return FALSE; - - while (*fname >= '0' && *fname <= '9') { - size = size * 10 + (*fname - '0'); - fname++; - } - - if (*fname != MAILDIR_INFO_SEP && - *fname != MAILDIR_EXTRA_SEP && - *fname != '\0') - return FALSE; - - *size_r = size; - return TRUE; -} - -/* a char* hash function from ASU -- from glib */ -unsigned int maildir_hash(const void *p) -{ - const unsigned char *s = p; - unsigned int g, h = 0; - - while (*s != MAILDIR_INFO_SEP && *s != '\0') { - i_assert(*s != '/'); - h = (h << 4) + *s; - if ((g = h & 0xf0000000UL)) { - h = h ^ (g >> 24); - h = h ^ g; - } - - s++; - } - - return h; -} - -int maildir_cmp(const void *p1, const void *p2) -{ - const char *s1 = p1, *s2 = p2; - - while (*s1 == *s2 && *s1 != MAILDIR_INFO_SEP && *s1 != '\0') { - i_assert(*s1 != '/'); - s1++; s2++; - } - if ((*s1 == '\0' || *s1 == MAILDIR_INFO_SEP) && - (*s2 == '\0' || *s2 == MAILDIR_INFO_SEP)) - return 0; - return *s1 - *s2; -}