maildir-filename.c revision eac60b7aef3924a611656b184412be1e80b2ed5b
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2002-2007 Timo Sirainen */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* use secs + usecs to guarantee uniqueness within this process. */
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainenvoid maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (info == NULL || info[1] != '2' || info[2] != MAILDIR_FLAGS_SEP)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (info += 3; *info != '\0' && *info != MAILDIR_FLAGS_SEP; info++) {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* unknown keyword. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* unknown flag - ignore */
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainenstatic int char_cmp(const void *p1, const void *p2)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenmaildir_filename_append_keywords(struct maildir_keywords_sync_ctx *ctx,
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const unsigned int *indexes;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen unsigned int i, count, start = str_len(fname);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen for (i = 0; i < count; i++) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen chr = maildir_keywords_idx_char(ctx, indexes[i]);
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen qsort(str_c_modifiable(fname) + start, str_len(fname) - start, 1,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenconst char *maildir_filename_set_flags(struct maildir_keywords_sync_ctx *ctx,
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen /* remove the old :info from file name, and get the old flags */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (info != NULL && strrchr(fname, '/') > info)
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen if (info[1] == '2' && info[2] == MAILDIR_FLAGS_SEP)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen /* insert the new flags between old flags. flags must be sorted by
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen their ASCII code. unknown flags are kept. */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen str_append(flags_str, MAILDIR_FLAGS_FULL_SEP);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* skip all known flags */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen while (*oldflags == 'D' || *oldflags == 'F' ||
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen nextflag = *oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP ?
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if ((flags_left & MAIL_DRAFT) && nextflag > 'D') {
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen if ((flags_left & MAIL_FLAGGED) && nextflag > 'F') {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if ((flags_left & MAIL_ANSWERED) && nextflag > 'R') {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if ((flags_left & MAIL_SEEN) && nextflag > 'S') {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if ((flags_left & MAIL_DELETED) && nextflag > 'T') {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (keywords != NULL && array_is_created(keywords) &&
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen maildir_filename_append_keywords(ctx, keywords,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (*oldflags == '\0' || *oldflags == MAILDIR_FLAGS_SEP)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen /* another flagset, we don't know about these, just keep them */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenbool maildir_filename_get_size(const char *fname, char type, uoff_t *size_r)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (*fname == ',' && fname[1] == type && fname[2] == '=') {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen/* a char* hash function from ASU -- from glib */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenunsigned int maildir_filename_base_hash(const void *p)
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen const unsigned char *s = p;
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen unsigned int g, h = 0;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen while (*s != MAILDIR_INFO_SEP && *s != '\0') {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen h = (h << 4) + *s;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if ((g = h & 0xf0000000UL)) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen h = h ^ (g >> 24);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainenint maildir_filename_base_cmp(const void *p1, const void *p2)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen while (*fname1 == *fname2 && *fname1 != MAILDIR_INFO_SEP &&
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if ((*fname1 == '\0' || *fname1 == MAILDIR_INFO_SEP) &&
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (*fname2 == '\0' || *fname2 == MAILDIR_INFO_SEP))
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic bool maildir_fname_get_usecs(const char *fname, int *usecs_r)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* Assume we already read the timestamp. Next up is
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen ".<uniqueness>.<host>". Find usecs inside the uniqueness. */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen while (*fname != '\0' && *fname != '.' && *fname != MAILDIR_INFO_SEP) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenint maildir_filename_sort_cmp(const char *fname1, const char *fname2)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* sort primarily by the timestamp in file name */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen for (s1 = fname1; *s1 >= '0' && *s1 <= '9'; s1++)
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen for (s2 = fname2; *s2 >= '0' && *s2 <= '9'; s2++)
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen /* sort secondarily by microseconds, if they exist */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* fallback to comparing the base file name */