]> git.pld-linux.org Git - packages/dovecot.git/blame - dovecot-branch.diff
- added with_gssapi bcond
[packages/dovecot.git] / dovecot-branch.diff
CommitLineData
fe91d611
AM
1diff --git a/src/auth/passdb-pam.c b/src/auth/passdb-pam.c
2--- a/src/auth/passdb-pam.c
3+++ b/src/auth/passdb-pam.c
4@@ -229,8 +229,7 @@ static int pam_auth(struct auth_request
5 }
6 }
7
8- /* FIXME: this doesn't actually work since we're in the child
9- process.. */
10+ /* FIXME: this works only with blocking=yes */
11 status = pam_get_item(pamh, PAM_USER, (linux_const void **)&item);
12 if (status != PAM_SUCCESS) {
13 *error = t_strdup_printf("pam_get_item() failed: %s",
14diff --git a/src/imap/client.c b/src/imap/client.c
15--- a/src/imap/client.c
16+++ b/src/imap/client.c
17@@ -485,13 +485,18 @@ int _client_output(void *context)
18
19 static void idle_timeout(void *context __attr_unused__)
20 {
21- time_t idle_time;
22+ time_t idle_time, last_change;
23
24 if (my_client == NULL)
25 return;
26
27- idle_time = ioloop_time -
28+ /* We mostly want to check last_input here, but if there is a very long
29+ running command (like copying thousands of messages), we don't want
30+ to disconnect the client just after the command was finished.
31+ But any output that IDLE has sent should be ignored. */
32+ last_change = my_client->idling ? my_client->last_input :
33 I_MAX(my_client->last_input, my_client->last_output);
34+ idle_time = ioloop_time - last_change;
35
36 if (my_client->command_pending &&
37 o_stream_get_buffer_used_size(my_client->output) > 0 &&
38diff --git a/src/imap/client.h b/src/imap/client.h
39--- a/src/imap/client.h
40+++ b/src/imap/client.h
41@@ -52,6 +52,7 @@ struct client {
42 unsigned int input_pending:1;
43 unsigned int output_pending:1;
44 unsigned int handling_input:1;
45+ unsigned int idling:1;
46 unsigned int input_skip_line:1; /* skip all the data until we've
47 found a new line */
48 };
49diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c
50--- a/src/imap/cmd-append.c
51+++ b/src/imap/cmd-append.c
52@@ -285,8 +285,7 @@ static bool cmd_append_continue_parsing(
53 if (ctx->msg_size == 0) {
54 /* no message data, abort */
55 client_send_tagline(cmd, "NO Append aborted.");
56- cmd_append_finish(ctx);
57- return TRUE;
58+ return cmd_append_cancel(ctx, nonsync);
59 }
60
61 /* save the mail */
62diff --git a/src/imap/cmd-idle.c b/src/imap/cmd-idle.c
63--- a/src/imap/cmd-idle.c
64+++ b/src/imap/cmd-idle.c
65@@ -56,6 +56,7 @@ static void idle_finish(struct cmd_idle_
66 if (client->mailbox != NULL)
67 mailbox_notify_changes(client->mailbox, 0, NULL, NULL);
68
69+ client->idling = FALSE;
70 if (done_ok)
71 client_send_tagline(ctx->cmd, "OK Idle completed.");
72 else
73@@ -263,6 +264,7 @@ bool cmd_idle(struct client_command_cont
74 client->io = io_add(i_stream_get_fd(client->input),
75 IO_READ, idle_client_input, ctx);
76
77+ client->idling = TRUE;
78 client->command_pending = TRUE;
79 cmd->func = cmd_idle_continue;
80 cmd->context = ctx;
81diff --git a/src/imap/cmd-list.c b/src/imap/cmd-list.c
82--- a/src/imap/cmd-list.c
83+++ b/src/imap/cmd-list.c
84@@ -135,6 +135,15 @@ list_namespace_mailboxes(struct client *
85 continue;
86 str_append(name_str, ctx->ns->prefix);
87 }
88+ if ((list->flags & MAILBOX_NOCHILDREN) != 0 &&
89+ strncmp(ctx->ns->prefix, "INBOX", 5) == 0 &&
90+ ctx->ns->prefix[5] == ctx->ns->sep) {
91+ /* FIXME: It's unlikely there's only a single
92+ INBOX mailbox, but it's possible. We should
93+ check that instead of assuming it. */
94+ list->flags |= MAILBOX_CHILDREN;
95+ list->flags &= ~MAILBOX_NOCHILDREN;
96+ }
97 } else {
98 str_append(name_str, ctx->ns->prefix);
99 }
100diff --git a/src/imap/imap-fetch.c b/src/imap/imap-fetch.c
101--- a/src/imap/imap-fetch.c
102+++ b/src/imap/imap-fetch.c
103@@ -322,6 +322,7 @@ int imap_fetch(struct imap_fetch_context
104 ctx->line_finished = TRUE;
105 if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0)
106 return -1;
107+ ctx->client->last_output = ioloop_time;
108
109 ctx->cur_mail = NULL;
110 ctx->cur_handler = 0;
111@@ -362,12 +363,11 @@ int imap_fetch_deinit(struct imap_fetch_
112 mailbox_header_lookup_deinit(&ctx->all_headers_ctx);
113
114 if (ctx->trans != NULL) {
115- if (ctx->failed)
116- mailbox_transaction_rollback(&ctx->trans);
117- else {
118- if (mailbox_transaction_commit(&ctx->trans, 0) < 0)
119- ctx->failed = TRUE;
120- }
121+ /* even if something failed, we want to commit changes to
122+ cache, as well as possible \Seen flag changes for FETCH
123+ replies we returned so far. */
124+ if (mailbox_transaction_commit(&ctx->trans, 0) < 0)
125+ ctx->failed = TRUE;
126 }
127 return ctx->failed ? -1 : 0;
128 }
129diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c
130--- a/src/lib-index/mail-transaction-log-view.c
131+++ b/src/lib-index/mail-transaction-log-view.c
132@@ -97,9 +97,10 @@ mail_transaction_log_view_set(struct mai
133 uint32_t max_file_seq, uoff_t max_file_offset,
134 enum mail_transaction_type type_mask)
135 {
136- struct mail_transaction_log_file *file, *first;
137+ struct mail_transaction_log_file *file, *const *files;
138+ unsigned int i;
139 uint32_t seq;
140- uoff_t end_offset;
141+ uoff_t start_offset, end_offset;
142 int ret;
143
144 i_assert(view->log != NULL);
145@@ -159,12 +160,8 @@ mail_transaction_log_view_set(struct mai
146 return -1;
147 }
148
149- end_offset = min_file_seq == max_file_seq ?
150- max_file_offset : (uoff_t)-1;
151- ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
152- if (ret <= 0)
153- return ret;
154- first = file;
155+ view->tail = file;
156+ view->head = file;
157
158 for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
159 file = file->next;
160@@ -192,40 +189,57 @@ mail_transaction_log_view_set(struct mai
161 /* missing files in the middle */
162 return 0;
163 }
164-
165+ view->head = file;
166+ }
167+
168+ /* we have all of them. update refcounts. */
169+ mail_transaction_log_view_unref_all(view);
170+
171+ /* reference all used files */
172+ for (file = view->tail;; file = file->next) {
173+ array_append(&view->file_refs, &file, 1);
174+ file->refcount++;
175+
176+ if (file == view->head)
177+ break;
178+ }
179+
180+ /* Map the files only after we've found them all. Otherwise if we map
181+ one file and then another file just happens to get rotated, we could
182+ include both files in the view but skip the last transactions from
183+ the first file.
184+
185+ We're mapping the files in reverse order so that _log_file_map()
186+ can verify that prev_file_offset matches how far it actually managed
187+ to sync the file. */
188+ files = array_idx(&view->file_refs, 0);
189+ for (i = array_count(&view->file_refs); i > 0; i--) {
190+ file = files[i-1];
191+ start_offset = file->hdr.file_seq == min_file_seq ?
192+ min_file_offset : file->hdr.hdr_size;
193 end_offset = file->hdr.file_seq == max_file_seq ?
194 max_file_offset : (uoff_t)-1;
195- ret = mail_transaction_log_file_map(file, file->hdr.hdr_size,
196+ ret = mail_transaction_log_file_map(file, start_offset,
197 end_offset);
198 if (ret <= 0)
199 return ret;
200 }
201
202+ i_assert(max_file_seq == (uint32_t)-1 ||
203+ max_file_seq == view->head->hdr.file_seq);
204 i_assert(max_file_offset == (uoff_t)-1 ||
205- max_file_offset <= file->sync_offset);
206-
207- /* we have all of them. update refcounts. */
208- mail_transaction_log_view_unref_all(view);
209-
210- view->tail = first;
211- view->head = view->log->head;
212-
213- /* reference all used files */
214- for (file = view->tail; file != NULL; file = file->next) {
215- array_append(&view->file_refs, &file, 1);
216- file->refcount++;
217- }
218+ max_file_offset <= view->head->sync_offset);
219
220 view->prev_file_seq = 0;
221 view->prev_file_offset = 0;
222
223- view->cur = first;
224+ view->cur = view->tail;
225 view->cur_offset = min_file_offset;
226
227 view->min_file_seq = min_file_seq;
228 view->min_file_offset = min_file_offset;
229 view->max_file_seq = max_file_seq;
230- view->max_file_offset = max_file_offset;
231+ view->max_file_offset = I_MIN(max_file_offset, view->head->sync_offset);
232 view->type_mask = type_mask;
233 view->broken = FALSE;
234
235diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c
236--- a/src/lib-index/mail-transaction-log.c
237+++ b/src/lib-index/mail-transaction-log.c
238@@ -1145,15 +1145,20 @@ mail_transaction_log_file_sync(struct ma
239 if (file->sync_offset - file->buffer_offset + hdr_size > size)
240 break;
241 file->sync_offset += hdr_size;
242+ hdr_size = 0;
243 }
244
245 avail = file->sync_offset - file->buffer_offset;
246- if (avail != size && avail >= sizeof(*hdr)) {
247- /* record goes outside the file we've seen. or if
248- we're accessing the log file via unlocked mmaped
249- memory, it may be just that the memory was updated
250- after we checked the file size. */
251- if (file->locked || file->mmap_base == NULL) {
252+ if (avail != size) {
253+ /* There's more data than we could sync at the moment. If the
254+ last record's size wasn't valid, we can't know if it will
255+ be updated unless we've locked the log.
256+
257+ Without locking we can be sure only if we're not using
258+ mmaping, because with mmaping the data and the file size
259+ can get updated at any time. */
260+ if (file->locked ||
261+ (hdr_size != 0 && file->mmap_base == NULL)) {
262 if (hdr_size != 0) {
263 mail_transaction_log_file_set_corrupted(file,
264 "hdr.size too large (%u)", hdr_size);
265diff --git a/src/lib-storage/mail-copy.c b/src/lib-storage/mail-copy.c
266--- a/src/lib-storage/mail-copy.c
267+++ b/src/lib-storage/mail-copy.c
268@@ -2,7 +2,7 @@
269
270 #include "lib.h"
271 #include "istream.h"
272-#include "mail-storage.h"
273+#include "mail-storage-private.h"
274 #include "mail-copy.h"
275
276 int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail,
277@@ -31,6 +31,8 @@ int mail_storage_copy(struct mailbox_tra
278 }
279
280 if (input->stream_errno != 0) {
281+ mail_storage_set_critical(t->box->storage,
282+ "copy: i_stream_read() failed: %m");
283 mailbox_save_cancel(&ctx);
284 return -1;
285 }
286diff --git a/src/lib/ioloop-notify-inotify.c b/src/lib/ioloop-notify-inotify.c
287--- a/src/lib/ioloop-notify-inotify.c
288+++ b/src/lib/ioloop-notify-inotify.c
289@@ -155,7 +155,12 @@ void io_loop_notify_handler_init(struct
290
291 ctx->inotify_fd = inotify_init();
292 if (ctx->inotify_fd == -1) {
293- i_error("inotify_init() failed: %m");
294+ if (errno != EMFILE)
295+ i_error("inotify_init() failed: %m");
296+ else {
297+ i_warning("Inotify instance limit for user exceeded, "
298+ "disabling.");
299+ }
300 ctx->disabled = TRUE;
301 return;
302 }
303diff --git a/src/lib/lib-signals.c b/src/lib/lib-signals.c
304--- a/src/lib/lib-signals.c
305+++ b/src/lib/lib-signals.c
306@@ -21,10 +21,11 @@ struct signal_handler {
307 /* Remember that these are accessed inside signal handler which may be called
308 even while we're initializing/deinitializing. Try hard to keep everything
309 in consistent state. */
310-static struct signal_handler *signal_handlers[MAX_SIGNAL_VALUE+1];
311-static int sig_pipe_fd[2];
312-
313-static struct io *io_sig;
314+static struct signal_handler *signal_handlers[MAX_SIGNAL_VALUE+1] = { NULL, };
315+static int sig_pipe_fd[2] = { -1, -1 };
316+
317+static bool signals_initialized = FALSE;
318+static struct io *io_sig = NULL;
319
320 static void sig_handler(int signo)
321 {
322@@ -99,6 +100,18 @@ static void signal_read(void *context __
323 }
324 }
325
326+static void lib_signals_set(int signo, bool ignore)
327+{
328+ struct sigaction act;
329+
330+ if (sigemptyset(&act.sa_mask) < 0)
331+ i_fatal("sigemptyset(): %m");
332+ act.sa_flags = 0;
333+ act.sa_handler = ignore ? sig_ignore : sig_handler;
334+ if (sigaction(signo, &act, NULL) < 0)
335+ i_fatal("sigaction(%d): %m", signo);
336+}
337+
338 void lib_signals_set_handler(int signo, bool delayed,
339 signal_handler_t *handler, void *context)
340 {
341@@ -109,17 +122,10 @@ void lib_signals_set_handler(int signo,
342 signo, MAX_SIGNAL_VALUE);
343 }
344
345- if (signal_handlers[signo] == NULL) {
346+ if (signal_handlers[signo] == NULL &&
347+ (handler == NULL || signals_initialized)) {
348 /* first handler for this signal */
349- struct sigaction act;
350-
351- if (sigemptyset(&act.sa_mask) < 0)
352- i_fatal("sigemptyset(): %m");
353- act.sa_flags = 0;
354- act.sa_handler = handler != NULL ? sig_handler : sig_ignore;
355- if (sigaction(signo, &act, NULL) < 0)
356- i_fatal("sigaction(%d): %m", signo);
357-
358+ lib_signals_set(signo, handler == NULL);
359 if (handler == NULL) {
360 /* we're ignoring the handler, just return */
361 return;
362@@ -133,7 +139,10 @@ void lib_signals_set_handler(int signo,
363 i_fatal("pipe() failed: %m");
364 fd_close_on_exec(sig_pipe_fd[0], TRUE);
365 fd_close_on_exec(sig_pipe_fd[1], TRUE);
366- io_sig = io_add(sig_pipe_fd[0], IO_READ, signal_read, NULL);
367+ if (signals_initialized) {
368+ io_sig = io_add(sig_pipe_fd[0], IO_READ,
369+ signal_read, NULL);
370+ }
371 }
372
373 h = i_new(struct signal_handler, 1);
374@@ -186,10 +195,18 @@ void lib_signals_unset_handler(int signo
375
376 void lib_signals_init(void)
377 {
378- sig_pipe_fd[0] = sig_pipe_fd[1] = -1;
379- io_sig = NULL;
380-
381- memset(signal_handlers, 0, sizeof(signal_handlers));
382+ int i;
383+
384+ signals_initialized = TRUE;
385+
386+ /* add signals that were already registered */
387+ for (i = 0; i < MAX_SIGNAL_VALUE; i++) {
388+ if (signal_handlers[i] != NULL)
389+ lib_signals_set(i, FALSE);
390+ }
391+
392+ if (sig_pipe_fd[0] != -1)
393+ io_sig = io_add(sig_pipe_fd[0], IO_READ, signal_read, NULL);
394 }
395
396 void lib_signals_deinit(void)
397diff --git a/src/plugins/quota/quota-maildir.c b/src/plugins/quota/quota-maildir.c
398--- a/src/plugins/quota/quota-maildir.c
399+++ b/src/plugins/quota/quota-maildir.c
400@@ -234,7 +234,7 @@ static int maildirsize_write(struct mail
401 if (fd == -1) {
402 if (errno == EAGAIN) {
403 /* someone's just in the middle of updating it */
404- return -1;
405+ return 1;
406 }
407
408 mail_storage_set_critical(storage,
409diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c
410--- a/src/plugins/quota/quota.c
411+++ b/src/plugins/quota/quota.c
412@@ -373,7 +373,8 @@ void quota_free(struct quota_transaction
413
414 const char *quota_last_error(struct quota *quota)
415 {
416- return quota->last_error != NULL ? quota->last_error : "Unknown error";
417+ return quota->last_error != NULL ? quota->last_error :
418+ "Unknown quota error";
419 }
420
421 void quota_set_error(struct quota *quota, const char *errormsg)
422diff --git a/src/pop3/client.c b/src/pop3/client.c
423--- a/src/pop3/client.c
424+++ b/src/pop3/client.c
425@@ -102,7 +102,7 @@ static int init_mailbox(struct client *c
426 mail_free(&mail);
427 if (mailbox_search_deinit(&ctx) < 0) {
428 client_send_storage_error(client);
429- mailbox_transaction_rollback(&t);
430+ (void)mailbox_transaction_commit(&t, 0);
431 break;
432 }
433
434@@ -113,8 +113,9 @@ static int init_mailbox(struct client *c
435 return TRUE;
436 }
437
438- /* well, sync and try again */
439- mailbox_transaction_rollback(&t);
440+ /* well, sync and try again. we might have cached virtual
441+ sizes, make sure they get committed. */
442+ (void)mailbox_transaction_commit(&t, 0);
443 }
444
445 if (i == 2)
This page took 0.289822 seconds and 4 git commands to generate.