]> git.pld-linux.org Git - packages/dovecot.git/blob - dovecot-branch.diff
- added with_gssapi bcond
[packages/dovecot.git] / dovecot-branch.diff
1 diff --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",
14 diff --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 &&
38 diff --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  };
49 diff --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 */
62 diff --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;
81 diff --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                 }
100 diff --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  }
129 diff --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  
235 diff --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);
265 diff --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         }
286 diff --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         }
303 diff --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)
397 diff --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,
409 diff --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)
422 diff --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.08945 seconds and 3 git commands to generate.