Implement optional mailbox-independent locking for pop3d and imap4d.
* lib/manlock.c: New file. * lib/Makefile.am (libmuaux_a_SOURCES): Add manlock.c. * lib/muaux.h (manlock_mandatory_locking) (manlock_lock_dir): New externs. (manlock_open_mailbox, manlock_lock) (manlock_touchlock, manlock_unlock): New protos. * libmailutils/base/amd.c (amd_cleanup): Remove unbalanced call to mu_locker_unlock. * libmailutils/base/locker.c (mu_locker_create): Bugfixes. * imap4d/imap4d.c (imap4d_cfg_param): Add mandatory-locking construct. (main): Call manlock_cfg_init. * imap4d/select.c (imap4d_select0): Use mandatory locking if the mailbox is to be opened r/w. * imap4d/rename.c (imap4d_rename): Note FIXME! * imap4d/bye.c: Call manlock_unlock after closing the mailbox. * imap4d/close.c: Likewise. * imap4d/sync.c (imap4d_sync): Call manlock_touchlock. * pop3d/lock.c: Remove. * pop3d/Makefile.am (pop3d_SOURCES): Remove lock.c * pop3d/extra.c (pop3d_abquit): Unlock mailbox. * pop3d/pop3d.c (pop3d_cfg_param): Add mandatory-locking construct. (main): Call manlock_cfg_init. (pop3d_mainloop): Call manlock_touchlock. * pop3d/pop3d.h (pop3d_lock) (pop3d_touchlock, pop3d_unlock): Remove. * pop3d/quit.c (pop3d_quit): Unlock the mailbox. * pop3d/user.c (pop3d_begin_session): Use manlock_open_mailbox.
Showing
18 changed files
with
319 additions
and
100 deletions
... | @@ -60,6 +60,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) | ... | @@ -60,6 +60,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) |
60 | imap4d_enter_critical (); | 60 | imap4d_enter_critical (); |
61 | mu_mailbox_flush (mbox, 0); | 61 | mu_mailbox_flush (mbox, 0); |
62 | mu_mailbox_close (mbox); | 62 | mu_mailbox_close (mbox); |
63 | manlock_unlock (mbox); | ||
63 | mu_mailbox_destroy (&mbox); | 64 | mu_mailbox_destroy (&mbox); |
64 | imap4d_leave_critical (); | 65 | imap4d_leave_critical (); |
65 | } | 66 | } | ... | ... |
... | @@ -50,6 +50,7 @@ imap4d_close0 (struct imap4d_command *command, imap4d_tokbuf_t tok, | ... | @@ -50,6 +50,7 @@ imap4d_close0 (struct imap4d_command *command, imap4d_tokbuf_t tok, |
50 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_close", NULL, status); | 50 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_close", NULL, status); |
51 | msg = "closing mailbox failed"; | 51 | msg = "closing mailbox failed"; |
52 | } | 52 | } |
53 | manlock_unlock (mbox); | ||
53 | mu_mailbox_destroy (&mbox); | 54 | mu_mailbox_destroy (&mbox); |
54 | 55 | ||
55 | if (msg) | 56 | if (msg) | ... | ... |
... | @@ -284,6 +284,7 @@ static struct mu_cfg_param imap4d_cfg_param[] = { | ... | @@ -284,6 +284,7 @@ static struct mu_cfg_param imap4d_cfg_param[] = { |
284 | N_("Use only encrypted ident responses.") }, | 284 | N_("Use only encrypted ident responses.") }, |
285 | { "id-fields", MU_CFG_LIST_OF(mu_cfg_string), &imap4d_id_list, 0, NULL, | 285 | { "id-fields", MU_CFG_LIST_OF(mu_cfg_string), &imap4d_id_list, 0, NULL, |
286 | N_("List of fields to return in response to ID command.") }, | 286 | N_("List of fields to return in response to ID command.") }, |
287 | { "mandatory-locking", mu_cfg_section }, | ||
287 | { ".server", mu_cfg_section, NULL, 0, NULL, | 288 | { ".server", mu_cfg_section, NULL, 0, NULL, |
288 | N_("Server configuration.") }, | 289 | N_("Server configuration.") }, |
289 | { "transcript", mu_cfg_bool, &imap4d_transcript, 0, NULL, | 290 | { "transcript", mu_cfg_bool, &imap4d_transcript, 0, NULL, |
... | @@ -556,6 +557,7 @@ main (int argc, char **argv) | ... | @@ -556,6 +557,7 @@ main (int argc, char **argv) |
556 | mu_gocs_register ("gsasl", mu_gsasl_module_init); | 557 | mu_gocs_register ("gsasl", mu_gsasl_module_init); |
557 | #endif | 558 | #endif |
558 | mu_tcpwrapper_cfg_init (); | 559 | mu_tcpwrapper_cfg_init (); |
560 | manlock_cfg_init (); | ||
559 | mu_acl_cfg_init (); | 561 | mu_acl_cfg_init (); |
560 | mu_m_server_cfg_init (); | 562 | mu_m_server_cfg_init (); |
561 | 563 | ... | ... |
... | @@ -131,7 +131,8 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -131,7 +131,8 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok) |
131 | exist. */ | 131 | exist. */ |
132 | if (stat (newname, &newst) == 0) | 132 | if (stat (newname, &newst) == 0) |
133 | { | 133 | { |
134 | if (!S_ISDIR(newst.st_mode)) | 134 | /* FIXME: What if it's a maildir?!? */ |
135 | if (!S_ISDIR (newst.st_mode)) | ||
135 | { | 136 | { |
136 | free (newname); | 137 | free (newname); |
137 | return io_completion_response (command, RESP_NO, | 138 | return io_completion_response (command, RESP_NO, | ... | ... |
... | @@ -30,7 +30,7 @@ imap4d_select (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -30,7 +30,7 @@ imap4d_select (struct imap4d_command *command, imap4d_tokbuf_t tok) |
30 | MU_STREAM_RDWR); | 30 | MU_STREAM_RDWR); |
31 | } | 31 | } |
32 | 32 | ||
33 | /* This code is share with EXAMINE. */ | 33 | /* This code is shared with EXAMINE. */ |
34 | int | 34 | int |
35 | imap4d_select0 (struct imap4d_command *command, const char *mboxname, | 35 | imap4d_select0 (struct imap4d_command *command, const char *mboxname, |
36 | int flags) | 36 | int flags) |
... | @@ -49,6 +49,7 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, | ... | @@ -49,6 +49,7 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, |
49 | imap4d_enter_critical (); | 49 | imap4d_enter_critical (); |
50 | mu_mailbox_sync (mbox); | 50 | mu_mailbox_sync (mbox); |
51 | mu_mailbox_close (mbox); | 51 | mu_mailbox_close (mbox); |
52 | manlock_unlock (mbox); | ||
52 | imap4d_leave_critical (); | 53 | imap4d_leave_critical (); |
53 | mu_mailbox_destroy (&mbox); | 54 | mu_mailbox_destroy (&mbox); |
54 | /* Destroy the old uid table. */ | 55 | /* Destroy the old uid table. */ |
... | @@ -62,8 +63,31 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, | ... | @@ -62,8 +63,31 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, |
62 | if (!mailbox_name) | 63 | if (!mailbox_name) |
63 | return io_completion_response (command, RESP_NO, "Couldn't open mailbox"); | 64 | return io_completion_response (command, RESP_NO, "Couldn't open mailbox"); |
64 | 65 | ||
65 | if ((status = mu_mailbox_create_default (&mbox, mailbox_name)) == 0 | 66 | if (flags & MU_STREAM_RDWR) |
66 | && (status = mu_mailbox_open (mbox, flags)) == 0) | 67 | { |
68 | status = manlock_open_mailbox (&mbox, mailbox_name, 1, flags); | ||
69 | } | ||
70 | else | ||
71 | { | ||
72 | status = mu_mailbox_create_default (&mbox, mailbox_name); | ||
73 | if (status) | ||
74 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create_default", | ||
75 | mailbox_name, | ||
76 | status); | ||
77 | else | ||
78 | { | ||
79 | status = mu_mailbox_open (mbox, flags); | ||
80 | if (status) | ||
81 | { | ||
82 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_open", | ||
83 | mailbox_name, | ||
84 | status); | ||
85 | mu_mailbox_destroy (&mbox); | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if (status == 0) | ||
67 | { | 91 | { |
68 | select_flags = flags; | 92 | select_flags = flags; |
69 | state = STATE_SEL; | 93 | state = STATE_SEL; | ... | ... |
... | @@ -187,6 +187,7 @@ imap4d_set_observer (mu_mailbox_t mbox) | ... | @@ -187,6 +187,7 @@ imap4d_set_observer (mu_mailbox_t mbox) |
187 | int | 187 | int |
188 | imap4d_sync (void) | 188 | imap4d_sync (void) |
189 | { | 189 | { |
190 | manlock_touchlock (mbox); | ||
190 | /* If mbox --> NULL, it means to free all the resources. | 191 | /* If mbox --> NULL, it means to free all the resources. |
191 | It may be because of close or before select/examine a new mailbox. | 192 | It may be because of close or before select/examine a new mailbox. |
192 | If it was a close we do not send any notification. */ | 193 | If it was a close we do not send any notification. */ | ... | ... |
lib/manlock.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999-2011 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #ifdef HAVE_CONFIG_H | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | #include <stdlib.h> | ||
21 | #include <string.h> | ||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/errno.h> | ||
24 | #include <mailutils/diag.h> | ||
25 | #include <mailutils/locker.h> | ||
26 | #include <mailutils/mailbox.h> | ||
27 | #include <mailutils/util.h> | ||
28 | #include <mailutils/url.h> | ||
29 | #include <mailutils/stream.h> | ||
30 | #include <mailutils/registrar.h> | ||
31 | #include <mailutils/nls.h> | ||
32 | #include <mailutils/cfg.h> | ||
33 | #include "muaux.h" | ||
34 | |||
35 | /* This file implements mandatory locking for pop3d and imap4d. Mandatory | ||
36 | locking applies to all mailbox formats. It is enabled by the following | ||
37 | configuration clause: | ||
38 | |||
39 | mandatory-locking { | ||
40 | enable yes; | ||
41 | } | ||
42 | |||
43 | If the underlying mailbox mechanism does not provide a locker (as is | ||
44 | the case, e.g., for maildir or MH mailboxes), a new locker object is | ||
45 | created and attached to the mailbox. This new locker complies with | ||
46 | the "logging" configuration settings. The name of the corresponding | ||
47 | lock file is created based on the mailbox URL. It is created in | ||
48 | a "lock directory", which is configured by `lock-directory' clause in | ||
49 | the `mandatory-locking' block. | ||
50 | For example, a lock file for "/var/spool/mail/g/r/gray" would | ||
51 | be "/var/lock/subsys/mail/%2Fvar%2Fspool%2Fmail%2Fg%2Fr%2Fgray.lock". | ||
52 | */ | ||
53 | |||
54 | int manlock_mandatory_locking; | ||
55 | char *manlock_lock_dir = "/var/lock/subsys/mail"; | ||
56 | |||
57 | static char * | ||
58 | make_locker_file_name (const char *urlstr) | ||
59 | { | ||
60 | char *fname; | ||
61 | char *buf; | ||
62 | size_t size; | ||
63 | const char *p; | ||
64 | char *q; | ||
65 | static const char escapable_chars[] = "/%"; | ||
66 | static const char xchr[] = "0123456789ABCDEF"; | ||
67 | |||
68 | for (p = urlstr, size = 0; *p; p++, size++) | ||
69 | { | ||
70 | if (strchr (escapable_chars, *p)) | ||
71 | size += 2; | ||
72 | } | ||
73 | |||
74 | buf = malloc (size + 1); | ||
75 | if (!buf) | ||
76 | { | ||
77 | mu_diag_funcall (MU_DIAG_ERROR, "malloc", NULL, errno); | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | for (p = urlstr, q = buf; *p; p++) | ||
82 | { | ||
83 | if (strchr (escapable_chars, *p)) | ||
84 | { | ||
85 | unsigned char c = *p; | ||
86 | *q++ = '%'; | ||
87 | *q++ = xchr[c >> 4]; | ||
88 | *q++ = xchr[c & 0xf]; | ||
89 | } | ||
90 | else | ||
91 | *q++ = *p; | ||
92 | } | ||
93 | *q = 0; | ||
94 | |||
95 | fname = mu_make_file_name_suf (manlock_lock_dir, buf, NULL); | ||
96 | if (!fname) | ||
97 | mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name_suf", buf, errno); | ||
98 | free (buf); | ||
99 | return fname; | ||
100 | } | ||
101 | |||
102 | static int | ||
103 | mailbox_open_and_lock (mu_mailbox_t mbox, int flags) | ||
104 | { | ||
105 | mu_url_t url; | ||
106 | int status; | ||
107 | const char *urlstr; | ||
108 | mu_locker_t lock; | ||
109 | |||
110 | mu_mailbox_get_url (mbox, &url); | ||
111 | urlstr = mu_url_to_string (url); | ||
112 | |||
113 | status = mu_mailbox_get_locker (mbox, &lock); | ||
114 | if (status) | ||
115 | { | ||
116 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_locker", urlstr, status); | ||
117 | return MU_ERR_FAILURE; | ||
118 | } | ||
119 | |||
120 | if (!lock && manlock_mandatory_locking && manlock_lock_dir) | ||
121 | { | ||
122 | char *fname = NULL; | ||
123 | int res; | ||
124 | |||
125 | if (mu_registrar_test_local_url (url, &res) == 0 && res) | ||
126 | { | ||
127 | const char *path; | ||
128 | status = mu_url_sget_path (url, &path); | ||
129 | if (status == 0) | ||
130 | fname = make_locker_file_name (path); | ||
131 | } | ||
132 | if (!fname) | ||
133 | fname = make_locker_file_name (urlstr); | ||
134 | |||
135 | if (!fname) | ||
136 | return MU_ERR_FAILURE; | ||
137 | |||
138 | status = mu_locker_create (&lock, fname, 0); | ||
139 | if (status) | ||
140 | { | ||
141 | mu_diag_funcall (MU_DIAG_ERROR, "mu_locker_create", fname, status); | ||
142 | free (fname); | ||
143 | return MU_ERR_FAILURE; | ||
144 | } | ||
145 | mu_mailbox_set_locker (mbox, lock); | ||
146 | } | ||
147 | |||
148 | if ((status = mu_mailbox_open (mbox, flags)) != 0) | ||
149 | { | ||
150 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_open", urlstr, status); | ||
151 | return MU_ERR_FAILURE; | ||
152 | } | ||
153 | return manlock_lock (mbox); | ||
154 | } | ||
155 | |||
156 | int | ||
157 | manlock_open_mailbox (mu_mailbox_t *pmbox, const char *mailbox_name, int def, | ||
158 | int flags) | ||
159 | { | ||
160 | mu_mailbox_t mbox; | ||
161 | int status; | ||
162 | |||
163 | status = (def ? mu_mailbox_create_default : mu_mailbox_create) | ||
164 | (&mbox, mailbox_name); | ||
165 | if (status) | ||
166 | { | ||
167 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create", mailbox_name, | ||
168 | status); | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | status = mailbox_open_and_lock (mbox, flags); | ||
173 | |||
174 | if (status == 0) | ||
175 | *pmbox = mbox; | ||
176 | else | ||
177 | mu_mailbox_destroy (&mbox); | ||
178 | |||
179 | return status; | ||
180 | } | ||
181 | |||
182 | |||
183 | struct mu_cfg_param manlock_param[] = { | ||
184 | { "enable", mu_cfg_bool, &manlock_mandatory_locking, 0, NULL, | ||
185 | N_("Enable mandatory locking.") }, | ||
186 | { "lock-directory", mu_cfg_string, &manlock_lock_dir, 0, NULL, | ||
187 | N_("Set directory for mandatory lock files.") }, | ||
188 | { NULL } | ||
189 | }; | ||
190 | |||
191 | void | ||
192 | manlock_cfg_init () | ||
193 | { | ||
194 | struct mu_cfg_section *section; | ||
195 | mu_create_canned_section ("mandatory-locking", §ion); | ||
196 | mu_cfg_section_add_params (section, manlock_param); | ||
197 | } | ||
198 | |||
199 | |||
200 | |||
201 | |||
202 | |||
203 | int | ||
204 | manlock_lock (mu_mailbox_t mbox) | ||
205 | { | ||
206 | mu_url_t url = NULL; | ||
207 | mu_locker_t lock = NULL; | ||
208 | const char *name; | ||
209 | int status; | ||
210 | |||
211 | if (!manlock_mandatory_locking) | ||
212 | return 0; | ||
213 | mu_mailbox_get_url (mbox, &url); | ||
214 | name = mu_url_to_string (url); | ||
215 | mu_mailbox_get_locker (mbox, &lock); | ||
216 | mu_locker_mod_flags (lock, MU_LOCKER_PID, mu_locker_set_bit); | ||
217 | if ((status = mu_locker_lock (lock))) | ||
218 | { | ||
219 | mu_diag_output (MU_DIAG_NOTICE, _("locking mailbox `%s' failed: %s"), | ||
220 | name ? name : "?", mu_strerror(status)); | ||
221 | return status; | ||
222 | } | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | int | ||
227 | manlock_touchlock (mu_mailbox_t mbox) | ||
228 | { | ||
229 | if (manlock_mandatory_locking) | ||
230 | { | ||
231 | mu_locker_t lock = NULL; | ||
232 | mu_mailbox_get_locker (mbox, &lock); | ||
233 | mu_locker_touchlock (lock); | ||
234 | } | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | int | ||
239 | manlock_unlock (mu_mailbox_t mbox) | ||
240 | { | ||
241 | if (manlock_mandatory_locking) | ||
242 | { | ||
243 | mu_locker_t lock = NULL; | ||
244 | mu_mailbox_get_locker (mbox, &lock); | ||
245 | mu_locker_unlock (lock); | ||
246 | } | ||
247 | return 0; | ||
248 | } |
... | @@ -18,3 +18,14 @@ int mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups); | ... | @@ -18,3 +18,14 @@ int mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups); |
18 | void mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc); | 18 | void mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc); |
19 | const char *mu_strexit (int code); | 19 | const char *mu_strexit (int code); |
20 | 20 | ||
21 | extern int manlock_mandatory_locking; | ||
22 | extern char *manlock_lock_dir; | ||
23 | |||
24 | int manlock_open_mailbox (mu_mailbox_t *pmbox, const char *mailbox_name, | ||
25 | int def, int flags); | ||
26 | int manlock_lock (mu_mailbox_t mbox); | ||
27 | int manlock_touchlock (mu_mailbox_t mbox); | ||
28 | int manlock_unlock (mu_mailbox_t mbox); | ||
29 | |||
30 | void manlock_cfg_init (void); | ||
31 | ... | ... |
... | @@ -1361,7 +1361,6 @@ amd_cleanup (void *arg) | ... | @@ -1361,7 +1361,6 @@ amd_cleanup (void *arg) |
1361 | { | 1361 | { |
1362 | mu_mailbox_t mailbox = arg; | 1362 | mu_mailbox_t mailbox = arg; |
1363 | mu_monitor_unlock (mailbox->monitor); | 1363 | mu_monitor_unlock (mailbox->monitor); |
1364 | mu_locker_unlock (mailbox->locker); | ||
1365 | } | 1364 | } |
1366 | 1365 | ||
1367 | int | 1366 | int | ... | ... |
... | @@ -453,26 +453,28 @@ mu_locker_create (mu_locker_t *plocker, const char *fname, int flags) | ... | @@ -453,26 +453,28 @@ mu_locker_create (mu_locker_t *plocker, const char *fname, int flags) |
453 | /* Try the directory part. If it unrolls successfully (i.e. | 453 | /* Try the directory part. If it unrolls successfully (i.e. |
454 | all its components exist), tuck the filename part back in | 454 | all its components exist), tuck the filename part back in |
455 | the resulting path and use it as the lock filename. */ | 455 | the resulting path and use it as the lock filename. */ |
456 | char *p, *tmp = strdup (fname); | 456 | char *p, *new_name, *tmp = strdup (fname); |
457 | if (!tmp) | 457 | if (!tmp) |
458 | return ENOMEM; | 458 | return ENOMEM; |
459 | p = strchr (tmp, '/'); | 459 | p = strrchr (tmp, '/'); |
460 | if (!p) | 460 | if (!p) |
461 | filename = tmp; | 461 | filename = tmp; |
462 | else | 462 | else |
463 | { | 463 | { |
464 | *p = 0; | ||
464 | err = mu_unroll_symlink (tmp, &filename); | 465 | err = mu_unroll_symlink (tmp, &filename); |
465 | free (tmp); | ||
466 | if (err) | 466 | if (err) |
467 | return err; | ||
468 | tmp = realloc (filename, strlen (filename) + strlen (p) + 1); | ||
469 | if (!tmp) | ||
470 | { | 467 | { |
471 | free (filename); | 468 | free (tmp); |
472 | return ENOMEM; | 469 | return err; |
473 | } | 470 | } |
474 | strcat (tmp, p); | 471 | |
475 | filename = tmp; | 472 | new_name = mu_make_file_name_suf (filename, p + 1, NULL); |
473 | free (tmp); | ||
474 | free (filename); | ||
475 | if (!new_name) | ||
476 | return ENOMEM; | ||
477 | filename = new_name; | ||
476 | } | 478 | } |
477 | } | 479 | } |
478 | else | 480 | else | ... | ... |
... | @@ -49,9 +49,9 @@ pop3d_abquit (int reason) | ... | @@ -49,9 +49,9 @@ pop3d_abquit (int reason) |
49 | /* Unlock spool */ | 49 | /* Unlock spool */ |
50 | if (state != AUTHORIZATION) | 50 | if (state != AUTHORIZATION) |
51 | { | 51 | { |
52 | pop3d_unlock (); | ||
53 | mu_mailbox_flush (mbox, 0); | 52 | mu_mailbox_flush (mbox, 0); |
54 | mu_mailbox_close (mbox); | 53 | mu_mailbox_close (mbox); |
54 | manlock_unlock (mbox); | ||
55 | mu_mailbox_destroy (&mbox); | 55 | mu_mailbox_destroy (&mbox); |
56 | } | 56 | } |
57 | 57 | ... | ... |
pop3d/lock.c
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2008, 2009, 2010, | ||
3 | 2011 Free Software Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | int | ||
21 | pop3d_lock () | ||
22 | { | ||
23 | mu_url_t url = NULL; | ||
24 | mu_locker_t lock = NULL; | ||
25 | const char *name; | ||
26 | int status; | ||
27 | |||
28 | mu_mailbox_get_url (mbox, &url); | ||
29 | name = mu_url_to_string (url); | ||
30 | mu_mailbox_get_locker (mbox, &lock); | ||
31 | mu_locker_mod_flags (lock, MU_LOCKER_PID, mu_locker_set_bit); | ||
32 | if ((status = mu_locker_lock (lock))) | ||
33 | { | ||
34 | mu_diag_output (MU_DIAG_NOTICE, _("locking mailbox `%s' failed: %s"), | ||
35 | name ? name : "?", mu_strerror(status)); | ||
36 | return ERR_MBOX_LOCK; | ||
37 | } | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | int | ||
42 | pop3d_touchlock () | ||
43 | { | ||
44 | mu_locker_t lock = NULL; | ||
45 | mu_mailbox_get_locker (mbox, &lock); | ||
46 | mu_locker_touchlock (lock); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | int | ||
51 | pop3d_unlock () | ||
52 | { | ||
53 | mu_locker_t lock = NULL; | ||
54 | mu_mailbox_get_locker (mbox, &lock); | ||
55 | mu_locker_unlock (lock); | ||
56 | return 0; | ||
57 | } |
... | @@ -118,6 +118,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { | ... | @@ -118,6 +118,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { |
118 | #endif | 118 | #endif |
119 | { "output-buffer-size", mu_cfg_size, &pop3d_output_bufsize, 0, NULL, | 119 | { "output-buffer-size", mu_cfg_size, &pop3d_output_bufsize, 0, NULL, |
120 | N_("Size of the output buffer.") }, | 120 | N_("Size of the output buffer.") }, |
121 | { "mandatory-locking", mu_cfg_section }, | ||
121 | { ".server", mu_cfg_section, NULL, 0, NULL, | 122 | { ".server", mu_cfg_section, NULL, 0, NULL, |
122 | N_("Server configuration.") }, | 123 | N_("Server configuration.") }, |
123 | { "transcript", mu_cfg_bool, &pop3d_transcript, 0, NULL, | 124 | { "transcript", mu_cfg_bool, &pop3d_transcript, 0, NULL, |
... | @@ -269,7 +270,7 @@ pop3d_mainloop (int ifd, int ofd) | ... | @@ -269,7 +270,7 @@ pop3d_mainloop (int ifd, int ofd) |
269 | } | 270 | } |
270 | 271 | ||
271 | /* Refresh the Lock. */ | 272 | /* Refresh the Lock. */ |
272 | pop3d_touchlock (); | 273 | manlock_touchlock (mbox); |
273 | 274 | ||
274 | if ((handler = pop3d_find_command (cmd)) != NULL) | 275 | if ((handler = pop3d_find_command (cmd)) != NULL) |
275 | status = handler (arg); | 276 | status = handler (arg); |
... | @@ -320,6 +321,7 @@ main (int argc, char **argv) | ... | @@ -320,6 +321,7 @@ main (int argc, char **argv) |
320 | mu_gocs_register ("tls", mu_tls_module_init); | 321 | mu_gocs_register ("tls", mu_tls_module_init); |
321 | #endif /* WITH_TLS */ | 322 | #endif /* WITH_TLS */ |
322 | mu_tcpwrapper_cfg_init (); | 323 | mu_tcpwrapper_cfg_init (); |
324 | manlock_cfg_init (); | ||
323 | mu_acl_cfg_init (); | 325 | mu_acl_cfg_init (); |
324 | mu_m_server_cfg_init (); | 326 | mu_m_server_cfg_init (); |
325 | 327 | ... | ... |
... | @@ -220,7 +220,6 @@ void pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr, | ... | @@ -220,7 +220,6 @@ void pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr, |
220 | extern void pop3d_bye (void); | 220 | extern void pop3d_bye (void); |
221 | extern int pop3d_abquit (int); | 221 | extern int pop3d_abquit (int); |
222 | extern char *pop3d_apopuser (const char *); | 222 | extern char *pop3d_apopuser (const char *); |
223 | extern int pop3d_lock (void); | ||
224 | extern void process_cleanup (void); | 223 | extern void process_cleanup (void); |
225 | 224 | ||
226 | extern void pop3d_parse_command (char *cmd, char **pcmd, char **parg); | 225 | extern void pop3d_parse_command (char *cmd, char **pcmd, char **parg); |
... | @@ -232,8 +231,6 @@ extern RETSIGTYPE pop3d_child_signal (int); | ... | @@ -232,8 +231,6 @@ extern RETSIGTYPE pop3d_child_signal (int); |
232 | extern int pop3d_stls (char *); | 231 | extern int pop3d_stls (char *); |
233 | extern void enable_stls (void); | 232 | extern void enable_stls (void); |
234 | #endif /* WITH_TLS */ | 233 | #endif /* WITH_TLS */ |
235 | extern int pop3d_touchlock (void); | ||
236 | extern int pop3d_unlock (void); | ||
237 | extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2); | 234 | extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2); |
238 | 235 | ||
239 | extern void pop3d_setio (int, int); | 236 | extern void pop3d_setio (int, int); | ... | ... |
... | @@ -34,13 +34,13 @@ pop3d_quit (char *arg) | ... | @@ -34,13 +34,13 @@ pop3d_quit (char *arg) |
34 | 34 | ||
35 | if (state == TRANSACTION) | 35 | if (state == TRANSACTION) |
36 | { | 36 | { |
37 | pop3d_unlock (); | ||
38 | pop3d_fix_mark (); | 37 | pop3d_fix_mark (); |
39 | 38 | ||
40 | if (mu_mailbox_flush (mbox, 1) != 0) | 39 | if (mu_mailbox_flush (mbox, 1) != 0) |
41 | err = ERR_FILE; | 40 | err = ERR_FILE; |
42 | if (mu_mailbox_close (mbox) != 0) | 41 | if (mu_mailbox_close (mbox) != 0) |
43 | err = ERR_FILE; | 42 | err = ERR_FILE; |
43 | manlock_unlock (mbox); | ||
44 | mu_mailbox_destroy (&mbox); | 44 | mu_mailbox_destroy (&mbox); |
45 | mu_diag_output (MU_DIAG_INFO, _("session ended for user: %s"), username); | 45 | mu_diag_output (MU_DIAG_INFO, _("session ended for user: %s"), username); |
46 | } | 46 | } | ... | ... |
... | @@ -22,7 +22,8 @@ struct mu_auth_data *auth_data; | ... | @@ -22,7 +22,8 @@ struct mu_auth_data *auth_data; |
22 | int | 22 | int |
23 | pop3d_begin_session () | 23 | pop3d_begin_session () |
24 | { | 24 | { |
25 | int status; | 25 | mu_url_t url = NULL; |
26 | size_t total = 0; | ||
26 | 27 | ||
27 | mu_diag_output (MU_DIAG_INFO, _("POP3 login: user `%s', source %s"), | 28 | mu_diag_output (MU_DIAG_INFO, _("POP3 login: user `%s', source %s"), |
28 | auth_data->name, auth_data->source); | 29 | auth_data->name, auth_data->source); |
... | @@ -40,19 +41,9 @@ pop3d_begin_session () | ... | @@ -40,19 +41,9 @@ pop3d_begin_session () |
40 | if (auth_data->change_uid) | 41 | if (auth_data->change_uid) |
41 | setuid (auth_data->uid); | 42 | setuid (auth_data->uid); |
42 | 43 | ||
43 | if ((status = mu_mailbox_create (&mbox, auth_data->mailbox)) != 0 | 44 | if (manlock_open_mailbox (&mbox, auth_data->mailbox, 0, |
44 | || (status = mu_mailbox_open (mbox, MU_STREAM_CREAT | MU_STREAM_RDWR)) != 0) | 45 | MU_STREAM_CREAT | MU_STREAM_RDWR)) |
45 | { | 46 | { |
46 | mu_mailbox_destroy (&mbox); | ||
47 | state = AUTHORIZATION; | ||
48 | mu_auth_data_destroy (&auth_data); | ||
49 | return ERR_MBOX_LOCK; | ||
50 | } | ||
51 | |||
52 | if (pop3d_lock ()) | ||
53 | { | ||
54 | mu_mailbox_close (mbox); | ||
55 | mu_mailbox_destroy (&mbox); | ||
56 | mu_auth_data_destroy (&auth_data); | 47 | mu_auth_data_destroy (&auth_data); |
57 | state = AUTHORIZATION; | 48 | state = AUTHORIZATION; |
58 | return ERR_MBOX_LOCK; | 49 | return ERR_MBOX_LOCK; |
... | @@ -70,18 +61,14 @@ pop3d_begin_session () | ... | @@ -70,18 +61,14 @@ pop3d_begin_session () |
70 | 61 | ||
71 | deliver_pending_bulletins (); | 62 | deliver_pending_bulletins (); |
72 | 63 | ||
73 | /* mailbox name */ | 64 | /* log mailbox stats */ |
74 | { | 65 | mu_mailbox_get_url (mbox, &url); |
75 | mu_url_t url = NULL; | 66 | mu_mailbox_messages_count (mbox, &total); |
76 | size_t total = 0; | 67 | mu_diag_output (MU_DIAG_INFO, |
77 | mu_mailbox_get_url (mbox, &url); | ||
78 | mu_mailbox_messages_count (mbox, &total); | ||
79 | mu_diag_output (MU_DIAG_INFO, | ||
80 | ngettext ("user `%s' logged in with mailbox `%s' (%s message)", | 68 | ngettext ("user `%s' logged in with mailbox `%s' (%s message)", |
81 | "user `%s' logged in with mailbox `%s' (%s messages)", | 69 | "user `%s' logged in with mailbox `%s' (%s messages)", |
82 | (unsigned long) total), | 70 | (unsigned long) total), |
83 | username, mu_url_to_string (url), mu_umaxtostr (0, total)); | 71 | username, mu_url_to_string (url), mu_umaxtostr (0, total)); |
84 | } | ||
85 | 72 | ||
86 | return OK; | 73 | return OK; |
87 | } | 74 | } | ... | ... |
-
Please register or sign in to post a comment