Mercurial > dovecot > core-2.2
annotate src/lib-storage/index/dbox-common/dbox-file.c @ 11180:0eff8ef104e6 HEAD
mdbox: If flock() isn't available, use dotlock files.
This allows again using client_limit > 1 without corrupting dbox files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 20 Apr 2010 18:07:56 +0300 |
parents | 3d585e69aa95 |
children | 4f6fa828d0c9 |
rev | line source |
---|---|
10582
615eef3139c2
Updated copyright notices to include year 2010.
Timo Sirainen <tss@iki.fi>
parents:
10524
diff
changeset
|
1 /* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */ |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "ioloop.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "array.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "hex-dec.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "hex-binary.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include "hostpid.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include "istream.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "ostream.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #include "file-lock.h" |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
12 #include "file-dotlock.h" |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include "mkdir-parents.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 #include "fdatasync-path.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 #include "eacces-error.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 #include "str.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 #include "dbox-storage.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 #include "dbox-file.h" |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 #include <stdio.h> |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 #include <stdlib.h> |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 #include <unistd.h> |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 #include <ctype.h> |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 #include <fcntl.h> |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 #define DBOX_READ_BLOCK_SIZE 4096 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
28 #if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
29 static const struct dotlock_settings dotlock_set = { |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
30 .stale_timeout = 60*10, |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
31 .use_excl_lock = TRUE |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
32 }; |
11132
3d585e69aa95
dbox: Use flock() for file locking if possible. If not, require client_limit=1.
Timo Sirainen <tss@iki.fi>
parents:
11033
diff
changeset
|
33 #endif |
3d585e69aa95
dbox: Use flock() for file locking if possible. If not, require client_limit=1.
Timo Sirainen <tss@iki.fi>
parents:
11033
diff
changeset
|
34 |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 const char *dbox_generate_tmp_filename(void) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 static unsigned int create_count = 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 return t_strdup_printf("temp.%lu.P%sQ%uM%u.%s", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 (unsigned long)ioloop_timeval.tv_sec, my_pid, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 create_count++, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 (unsigned int)ioloop_timeval.tv_usec, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 my_hostname); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 void dbox_file_set_syscall_error(struct dbox_file *file, const char *function) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 "%s failed for file %s: %m", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 function, file->cur_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 void dbox_file_set_corrupted(struct dbox_file *file, const char *reason, ...) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 va_list args; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 file->storage->files_corrupted = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 va_start(args, reason); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 "Corrupted dbox file %s (around offset=%"PRIuUOFF_T"): %s", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 file->cur_path, file->input == NULL ? 0 : file->input->v_offset, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 t_strdup_vprintf(reason, args)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 va_end(args); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 void dbox_file_init(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 file->refcount = 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 file->fd = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 file->cur_offset = (uoff_t)-1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 file->cur_path = file->primary_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 void dbox_file_free(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 i_assert(file->refcount == 0); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 if (file->metadata_pool != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 pool_unref(&file->metadata_pool); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 dbox_file_close(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 i_free(file->primary_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 i_free(file->alt_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 i_free(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 void dbox_file_unref(struct dbox_file **_file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 struct dbox_file *file = *_file; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 *_file = NULL; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 i_assert(file->refcount > 0); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 if (--file->refcount == 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 file->storage->v.file_unrefed(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 static int dbox_file_parse_header(struct dbox_file *file, const char *line) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 const char *const *tmp, *value; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 unsigned int pos; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 enum dbox_header_key key; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 file->file_version = *line - '0'; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 if (!i_isdigit(line[0]) || line[1] != ' ' || |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 (file->file_version != 1 && file->file_version != DBOX_VERSION)) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 dbox_file_set_corrupted(file, "Invalid dbox version"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 line += 2; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 pos = 2; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 file->msg_header_size = 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 for (tmp = t_strsplit(line, " "); *tmp != NULL; tmp++) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 key = **tmp; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 value = *tmp + 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 switch (key) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 case DBOX_HEADER_OLDV1_APPEND_OFFSET: |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 break; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 case DBOX_HEADER_MSG_HEADER_SIZE: |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 file->msg_header_size = strtoul(value, NULL, 16); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 break; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 case DBOX_HEADER_CREATE_STAMP: |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 file->create_time = strtoul(value, NULL, 16); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 break; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 pos += strlen(value) + 2; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 if (file->msg_header_size == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 dbox_file_set_corrupted(file, "Missing message header size"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
135 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 static int dbox_file_read_header(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 const char *line; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 unsigned int hdr_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 i_stream_seek(file->input, 0); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 line = i_stream_read_next_line(file->input); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 if (line == NULL) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 if (file->input->stream_errno == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 dbox_file_set_corrupted(file, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 "EOF while reading file header"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 dbox_file_set_syscall_error(file, "read()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 hdr_size = file->input->v_offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 T_BEGIN { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 ret = dbox_file_parse_header(file, line) < 0 ? 0 : 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 } T_END; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 if (ret > 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 file->file_header_size = hdr_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
166 static int dbox_file_open_fd(struct dbox_file *file, bool try_altpath) |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 const char *path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 bool alt = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 /* try the primary path first */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 path = file->primary_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
173 while ((file->fd = open(path, O_RDWR)) == -1) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
174 if (errno != ENOENT) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
175 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
176 "open(%s) failed: %m", path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
177 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
178 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
180 if (file->alt_path == NULL || alt || !try_altpath) { |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 /* not found */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 /* try the alternative path */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 path = file->alt_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 alt = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
188 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 file->cur_path = path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
193 static int dbox_file_open_full(struct dbox_file *file, bool try_altpath, |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
194 bool *notfound_r) |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
195 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
196 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
197 |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
198 *notfound_r = FALSE; |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 if (file->input != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 if (file->fd == -1) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 T_BEGIN { |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
204 ret = dbox_file_open_fd(file, try_altpath); |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 } T_END; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 if (ret <= 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 if (ret < 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 return -1; |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
209 *notfound_r = TRUE; |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
210 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
212 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 file->input = i_stream_create_fd(file->fd, 0, FALSE); |
10849
638c4ea4a9ce
Set input stream names for mail file streams.
Timo Sirainen <tss@iki.fi>
parents:
10765
diff
changeset
|
215 i_stream_set_name(file->input, file->cur_path); |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 i_stream_set_init_buffer_size(file->input, DBOX_READ_BLOCK_SIZE); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 return dbox_file_read_header(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
219 |
10635
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
220 int dbox_file_open(struct dbox_file *file, bool *deleted_r) |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
221 { |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
222 return dbox_file_open_full(file, TRUE, deleted_r); |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
223 } |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
224 |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
225 int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r) |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
226 { |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
227 return dbox_file_open_full(file, FALSE, notfound_r); |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
228 } |
c60910419861
mdbox: Purging now also moves mails to alt storage (if it's used).
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
229 |
10964
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
230 int dbox_file_stat(struct dbox_file *file, struct stat *st_r) |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
231 { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
232 const char *path; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
233 bool alt = FALSE; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
234 |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
235 if (dbox_file_is_open(file)) { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
236 if (fstat(file->fd, st_r) < 0) { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
237 mail_storage_set_critical(&file->storage->storage, |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
238 "fstat(%s) failed: %m", file->cur_path); |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
239 return -1; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
240 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
241 return 0; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
242 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
243 |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
244 /* try the primary path first */ |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
245 path = file->primary_path; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
246 while (stat(path, st_r) < 0) { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
247 if (errno != ENOENT) { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
248 mail_storage_set_critical(&file->storage->storage, |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
249 "stat(%s) failed: %m", path); |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
250 return -1; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
251 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
252 |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
253 if (file->alt_path == NULL || alt) { |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
254 /* not found */ |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
255 return -1; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
256 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
257 |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
258 /* try the alternative path */ |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
259 path = file->alt_path; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
260 alt = TRUE; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
261 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
262 file->cur_path = path; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
263 return 0; |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
264 } |
cc42255736ad
dbox: Don't write save-date to metadata, use file's ctime as fallback.
Timo Sirainen <tss@iki.fi>
parents:
10849
diff
changeset
|
265 |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
266 int dbox_file_header_write(struct dbox_file *file, struct ostream *output) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 string_t *hdr; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 hdr = t_str_new(128); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 str_printfa(hdr, "%u %c%x %c%x\n", DBOX_VERSION, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
272 DBOX_HEADER_MSG_HEADER_SIZE, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
273 (unsigned int)sizeof(struct dbox_message_header), |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 DBOX_HEADER_CREATE_STAMP, (unsigned int)ioloop_time); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 file->file_version = DBOX_VERSION; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
277 file->file_header_size = str_len(hdr); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
278 file->msg_header_size = sizeof(struct dbox_message_header); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
279 return o_stream_send(output, str_data(hdr), str_len(hdr)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
280 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 void dbox_file_close(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 dbox_file_unlock(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 if (file->input != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 i_stream_unref(&file->input); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
287 if (file->fd != -1) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 if (close(file->fd) < 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
289 dbox_file_set_syscall_error(file, "close()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 file->fd = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 file->cur_offset = (uoff_t)-1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 int dbox_file_try_lock(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 i_assert(file->fd != -1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
301 #if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
302 ret = file_dotlock_create(&dotlock_set, file->cur_path, |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
303 DOTLOCK_CREATE_FLAG_NONBLOCK, &file->lock); |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
304 if (ret < 0) { |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
305 mail_storage_set_critical(&file->storage->storage, |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
306 "file_dotlock_create(%s) failed: %m", file->cur_path); |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
307 } |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
308 #else |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 ret = file_try_lock(file->fd, file->cur_path, F_WRLCK, |
11132
3d585e69aa95
dbox: Use flock() for file locking if possible. If not, require client_limit=1.
Timo Sirainen <tss@iki.fi>
parents:
11033
diff
changeset
|
310 DBOX_FILE_LOCK_METHOD, &file->lock); |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 if (ret < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 "file_try_lock(%s) failed: %m", file->cur_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 } |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
315 #endif |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 void dbox_file_unlock(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 { |
10683
9c68c8d42ff2
mdbox: Saving now closes newly created files if they become full.
Timo Sirainen <tss@iki.fi>
parents:
10635
diff
changeset
|
321 i_assert(!file->appending || file->lock == NULL); |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
323 if (file->lock != NULL) { |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
324 #if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
325 (void)file_dotlock_delete(&file->lock); |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
326 #else |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 file_unlock(&file->lock); |
11180
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
328 #endif |
0eff8ef104e6
mdbox: If flock() isn't available, use dotlock files.
Timo Sirainen <tss@iki.fi>
parents:
11132
diff
changeset
|
329 } |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 if (file->input != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 i_stream_sync(file->input); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
332 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
333 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 int dbox_file_read_mail_header(struct dbox_file *file, uoff_t *physical_size_r) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
335 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 struct dbox_message_header hdr; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
337 const unsigned char *data; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
338 size_t size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
339 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
340 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
341 ret = i_stream_read_data(file->input, &data, &size, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 file->msg_header_size - 1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
343 if (ret <= 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 if (file->input->stream_errno == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 /* EOF, broken offset or file truncated */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
346 dbox_file_set_corrupted(file, "EOF reading msg header " |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
347 "(got %"PRIuSIZE_T"/%u bytes)", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
348 size, file->msg_header_size); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
349 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
350 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
351 dbox_file_set_syscall_error(file, "read()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
352 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
353 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 memcpy(&hdr, data, I_MIN(sizeof(hdr), file->msg_header_size)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 if (memcmp(hdr.magic_pre, DBOX_MAGIC_PRE, sizeof(hdr.magic_pre)) != 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 /* probably broken offset */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 dbox_file_set_corrupted(file, "msg header has bad magic value"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
358 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
360 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 if (data[file->msg_header_size-1] != '\n') { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 dbox_file_set_corrupted(file, "msg header doesn't end with LF"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
363 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
364 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
365 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
366 *physical_size_r = hex2dec(hdr.message_size_hex, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 sizeof(hdr.message_size_hex)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
371 int dbox_file_get_mail_stream(struct dbox_file *file, uoff_t offset, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 struct istream **stream_r) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
373 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 uoff_t size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
375 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
377 i_assert(file->input != NULL); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
378 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
379 if (offset == 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
380 offset = file->file_header_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
381 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
382 if (offset != file->cur_offset) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
383 i_stream_seek(file->input, offset); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
384 ret = dbox_file_read_mail_header(file, &size); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
385 if (ret <= 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
386 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
387 file->cur_offset = offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
388 file->cur_physical_size = size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
389 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
390 i_stream_seek(file->input, offset + file->msg_header_size); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
391 if (stream_r != NULL) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
392 *stream_r = i_stream_create_limit(file->input, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
393 file->cur_physical_size); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
394 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
395 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
396 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
397 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
398 static int |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
399 dbox_file_seek_next_at_metadata(struct dbox_file *file, uoff_t *offset) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
400 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
401 const char *line; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
402 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
403 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
404 i_stream_seek(file->input, *offset); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
405 if ((ret = dbox_file_metadata_skip_header(file)) <= 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
406 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
407 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
408 /* skip over the actual metadata */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
409 while ((line = i_stream_read_next_line(file->input)) != NULL) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
410 if (*line == DBOX_METADATA_OLDV1_SPACE || *line == '\0') { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
411 /* end of metadata */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
412 break; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
413 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
414 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
415 *offset = file->input->v_offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
416 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
417 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
418 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
419 void dbox_file_seek_rewind(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
420 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
421 file->cur_offset = (uoff_t)-1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
422 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
423 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
424 int dbox_file_seek_next(struct dbox_file *file, uoff_t *offset_r, bool *last_r) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
425 { |
10765
19df4309e389
lib-storage: Added support for plugins to specify message's physical size when saving.
Timo Sirainen <tss@iki.fi>
parents:
10683
diff
changeset
|
426 uoff_t offset; |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
427 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
428 |
10524 | 429 i_assert(file->input != NULL); |
430 | |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
431 if (file->cur_offset == (uoff_t)-1) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
432 /* first mail. we may not have read the file at all yet, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
433 so set the offset afterwards. */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
434 offset = 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
435 } else { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
436 offset = file->cur_offset + file->msg_header_size + |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
437 file->cur_physical_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
438 if ((ret = dbox_file_seek_next_at_metadata(file, &offset)) <= 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
439 *offset_r = file->cur_offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
440 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
441 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
442 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
443 *offset_r = offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
444 |
10524 | 445 if (i_stream_is_eof(file->input)) { |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
446 *last_r = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
447 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
448 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
449 *last_r = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
450 |
10765
19df4309e389
lib-storage: Added support for plugins to specify message's physical size when saving.
Timo Sirainen <tss@iki.fi>
parents:
10683
diff
changeset
|
451 ret = dbox_file_get_mail_stream(file, offset, NULL); |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
452 if (*offset_r == 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
453 *offset_r = file->file_header_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
454 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
455 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
456 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
457 struct dbox_file_append_context *dbox_file_append_init(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
458 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
459 struct dbox_file_append_context *ctx; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
460 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
461 i_assert(!file->appending); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
462 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
463 file->appending = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
464 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
465 ctx = i_new(struct dbox_file_append_context, 1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
466 ctx->file = file; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
467 if (file->fd != -1) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
468 ctx->output = o_stream_create_fd_file(file->fd, 0, FALSE); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
469 o_stream_cork(ctx->output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
470 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
471 return ctx; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
472 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
473 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
474 int dbox_file_append_commit(struct dbox_file_append_context **_ctx) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
475 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
476 struct dbox_file_append_context *ctx = *_ctx; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
477 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
478 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
479 i_assert(ctx->file->appending); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
480 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
481 *_ctx = NULL; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
482 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
483 ret = dbox_file_append_flush(ctx); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
484 o_stream_unref(&ctx->output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
485 ctx->file->appending = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
486 i_free(ctx); |
11033
0bc933c35a17
dbox: Save error handling fix.
Timo Sirainen <tss@iki.fi>
parents:
10964
diff
changeset
|
487 return ret; |
9977
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
488 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
489 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
490 void dbox_file_append_rollback(struct dbox_file_append_context **_ctx) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
491 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
492 struct dbox_file_append_context *ctx = *_ctx; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
493 struct dbox_file *file = ctx->file; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
494 bool close_file = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
495 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
496 i_assert(ctx->file->appending); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
497 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
498 *_ctx = NULL; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
499 if (ctx->first_append_offset == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
500 /* nothing changed */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
501 } else if (ctx->first_append_offset == file->file_header_size) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
502 /* rollbacking everything */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 if (unlink(file->cur_path) < 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
504 dbox_file_set_syscall_error(file, "unlink()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
505 close_file = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
506 } else { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
507 /* truncating only some mails */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
508 o_stream_close(ctx->output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
509 if (ftruncate(file->fd, ctx->first_append_offset) < 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
510 dbox_file_set_syscall_error(file, "ftruncate()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
511 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
512 if (ctx->output != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
513 o_stream_unref(&ctx->output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
514 i_free(ctx); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
515 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
516 if (close_file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
517 dbox_file_close(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
518 file->appending = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
519 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
520 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
521 int dbox_file_append_flush(struct dbox_file_append_context *ctx) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
522 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
523 if (ctx->last_flush_offset == ctx->output->offset) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
524 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
525 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
526 if (o_stream_flush(ctx->output) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
527 dbox_file_set_syscall_error(ctx->file, "write()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
528 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
529 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
530 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
531 if (!ctx->file->storage->storage.set->fsync_disable) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
532 if (fdatasync(ctx->file->fd) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
533 dbox_file_set_syscall_error(ctx->file, "fdatasync()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
534 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
535 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
536 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
537 ctx->last_flush_offset = ctx->output->offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
538 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
539 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
540 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
541 int dbox_file_get_append_stream(struct dbox_file_append_context *ctx, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
542 struct ostream **output_r) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
543 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
544 struct dbox_file *file = ctx->file; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
545 struct stat st; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
546 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
547 if (ctx->output == NULL) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
548 /* file creation had failed */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
549 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
550 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
551 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
552 if (file->file_version == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
553 /* newly created file, write the file header */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
554 if (dbox_file_header_write(file, ctx->output) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
555 dbox_file_set_syscall_error(file, "write()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
556 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
557 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
558 *output_r = ctx->output; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
559 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
560 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
561 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
562 /* file has existing mails */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
563 if (file->file_version != DBOX_VERSION || |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
564 file->msg_header_size != sizeof(struct dbox_message_header)) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
565 /* created by an incompatible version, can't append */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
566 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
567 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
568 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
569 if (ctx->output->offset == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
570 /* first append to existing file. seek to eof first. */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
571 if (fstat(file->fd, &st) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
572 dbox_file_set_syscall_error(file, "fstat()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
573 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
574 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
575 o_stream_seek(ctx->output, st.st_size); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
576 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
577 *output_r = ctx->output; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
578 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
579 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
580 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
581 int dbox_file_metadata_skip_header(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
582 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
583 struct dbox_metadata_header metadata_hdr; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
584 const unsigned char *data; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
585 size_t size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
586 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
587 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
588 ret = i_stream_read_data(file->input, &data, &size, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
589 sizeof(metadata_hdr) - 1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
590 if (ret <= 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
591 if (file->input->stream_errno == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
592 /* EOF, broken offset */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
593 dbox_file_set_corrupted(file, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
594 "Unexpected EOF while reading metadata header"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
595 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
596 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
597 dbox_file_set_syscall_error(file, "read()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
598 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
599 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
600 memcpy(&metadata_hdr, data, sizeof(metadata_hdr)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
601 if (memcmp(metadata_hdr.magic_post, DBOX_MAGIC_POST, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
602 sizeof(metadata_hdr.magic_post)) != 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
603 /* probably broken offset */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
604 dbox_file_set_corrupted(file, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
605 "metadata header has bad magic value"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
606 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
607 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
608 i_stream_skip(file->input, sizeof(metadata_hdr)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
609 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
610 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
611 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
612 static int |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
613 dbox_file_metadata_read_at(struct dbox_file *file, uoff_t metadata_offset) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
614 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
615 const char *line; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
616 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
617 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
618 if (file->metadata_pool != NULL) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
619 p_clear(file->metadata_pool); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
620 else { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
621 file->metadata_pool = |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
622 pool_alloconly_create("dbox metadata", 1024); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
623 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
624 p_array_init(&file->metadata, file->metadata_pool, 16); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
625 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
626 i_stream_seek(file->input, metadata_offset); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
627 if ((ret = dbox_file_metadata_skip_header(file)) <= 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
628 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
629 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
630 ret = 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
631 while ((line = i_stream_read_next_line(file->input)) != NULL) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
632 if (*line == DBOX_METADATA_OLDV1_SPACE || *line == '\0') { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
633 /* end of metadata */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
634 ret = 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
635 break; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
636 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
637 line = p_strdup(file->metadata_pool, line); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
638 array_append(&file->metadata, &line, 1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
639 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
640 if (ret == 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
641 dbox_file_set_corrupted(file, "missing end-of-metadata line"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
642 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
643 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
644 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
645 int dbox_file_metadata_read(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
646 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
647 uoff_t metadata_offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
648 int ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
649 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
650 i_assert(file->cur_offset != (uoff_t)-1); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
651 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
652 if (file->metadata_read_offset == file->cur_offset) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
653 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
654 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
655 metadata_offset = file->cur_offset + file->msg_header_size + |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
656 file->cur_physical_size; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
657 ret = dbox_file_metadata_read_at(file, metadata_offset); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
658 if (ret <= 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
659 return ret; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
660 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
661 file->metadata_read_offset = file->cur_offset; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
662 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
663 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
664 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
665 const char *dbox_file_metadata_get(struct dbox_file *file, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
666 enum dbox_metadata_key key) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
667 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
668 const char *const *metadata; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
669 unsigned int i, count; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
670 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
671 metadata = array_get(&file->metadata, &count); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
672 for (i = 0; i < count; i++) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
673 if (*metadata[i] == (char)key) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
674 return metadata[i] + 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
675 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
676 return NULL; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
677 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
678 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
679 int dbox_file_move(struct dbox_file *file, bool alt_path) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
680 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
681 struct ostream *output; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
682 const char *dest_dir, *temp_path, *dest_path, *p; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
683 struct stat st; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
684 bool deleted; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
685 int out_fd, ret = 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
686 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
687 i_assert(file->input != NULL); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
688 i_assert(file->lock != NULL); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
689 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
690 if (dbox_file_is_in_alt(file) == alt_path) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
691 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
692 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
693 if (stat(file->cur_path, &st) < 0 && errno == ENOENT) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
694 /* already expunged/moved by another session */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
695 dbox_file_unlock(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
696 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
697 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
698 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
699 dest_path = !alt_path ? file->primary_path : file->alt_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
700 p = strrchr(dest_path, '/'); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
701 i_assert(p != NULL); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
702 dest_dir = t_strdup_until(dest_path, p); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
703 temp_path = t_strdup_printf("%s/%s", dest_dir, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
704 dbox_generate_tmp_filename()); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
705 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
706 /* first copy the file. make sure to catch every possible error |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
707 since we really don't want to break the file. */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
708 out_fd = file->storage->v.file_create_fd(file, temp_path, TRUE); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
709 if (out_fd == -1) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
710 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
711 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
712 output = o_stream_create_fd_file(out_fd, 0, FALSE); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
713 i_stream_seek(file->input, 0); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
714 while ((ret = o_stream_send_istream(output, file->input)) > 0) ; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
715 if (ret == 0) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
716 ret = o_stream_flush(output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
717 if (output->stream_errno != 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
718 errno = output->stream_errno; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
719 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
720 "write(%s) failed: %m", temp_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
721 ret = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
722 } else if (file->input->stream_errno != 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
723 errno = file->input->stream_errno; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
724 dbox_file_set_syscall_error(file, "ftruncate()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
725 ret = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
726 } else if (ret < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
727 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
728 "o_stream_send_istream(%s, %s) " |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
729 "failed with unknown error", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
730 temp_path, file->cur_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
731 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
732 o_stream_unref(&output); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
733 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
734 if (!file->storage->storage.set->fsync_disable && ret == 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
735 if (fsync(out_fd) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
736 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
737 "fsync(%s) failed: %m", temp_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
738 ret = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
739 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
740 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
741 if (close(out_fd) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
742 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
743 "close(%s) failed: %m", temp_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
744 ret = -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
745 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
746 if (ret < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
747 (void)unlink(temp_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
748 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
749 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
750 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
751 /* the temp file was successfully written. rename it now to the |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
752 destination file. the destination shouldn't exist, but if it does |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
753 its contents should be the same (except for maybe older metadata) */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
754 if (rename(temp_path, dest_path) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
755 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
756 "rename(%s, %s) failed: %m", temp_path, dest_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
757 (void)unlink(temp_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
758 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
759 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
760 if (!file->storage->storage.set->fsync_disable) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
761 if (fdatasync_path(dest_dir) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
762 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
763 "fdatasync(%s) failed: %m", dest_dir); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
764 (void)unlink(dest_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
765 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
766 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
767 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
768 if (unlink(file->cur_path) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
769 dbox_file_set_syscall_error(file, "unlink()"); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
770 if (errno == EACCES) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
771 /* configuration problem? revert the write */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
772 (void)unlink(dest_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
773 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
774 /* who knows what happened to the file. keep both just to be |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
775 sure both won't get deleted. */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
776 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
777 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
778 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
779 /* file was successfully moved - reopen it */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
780 dbox_file_close(file); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
781 if (dbox_file_open(file, &deleted) <= 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
782 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
783 "dbox_file_move(%s): reopening file failed", dest_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
784 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
785 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
786 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
787 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
788 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
789 void dbox_msg_header_fill(struct dbox_message_header *dbox_msg_hdr, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
790 uoff_t message_size) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
791 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
792 memset(dbox_msg_hdr, ' ', sizeof(*dbox_msg_hdr)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
793 memcpy(dbox_msg_hdr->magic_pre, DBOX_MAGIC_PRE, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
794 sizeof(dbox_msg_hdr->magic_pre)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
795 dbox_msg_hdr->type = DBOX_MESSAGE_TYPE_NORMAL; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
796 dec2hex(dbox_msg_hdr->message_size_hex, message_size, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
797 sizeof(dbox_msg_hdr->message_size_hex)); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
798 dbox_msg_hdr->save_lf = '\n'; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
799 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
800 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
801 int dbox_file_unlink(struct dbox_file *file) |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
802 { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
803 const char *path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
804 bool alt = FALSE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
805 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
806 path = file->primary_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
807 while (unlink(path) < 0) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
808 if (errno != ENOENT) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
809 mail_storage_set_critical(&file->storage->storage, |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
810 "unlink(%s) failed: %m", path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
811 return -1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
812 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
813 if (file->alt_path == NULL || alt) { |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
814 /* not found */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
815 i_warning("dbox: File unexpectedly lost: %s", |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
816 file->primary_path); |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
817 return 0; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
818 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
819 |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
820 /* try the alternative path */ |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
821 path = file->alt_path; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
822 alt = TRUE; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
823 } |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
824 return 1; |
0bb321c347ae
Split dbox (single-dbox) and mdbox (multi-dbox) into separate storage backends.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
825 } |