* auth/sql.c, libproto/mbox/folder.c: Rename MU_READ_ERROR to
MU_ERR_READ, for consistency. * comsat/Makefile.am (comsatd_LDADD): Add all mailbox formats. * comsat/cfg.c: Use mu_error instead of syslog. * comsat/comsat.c (comsat_daemon): Implement test mode. (notify_user): Use mailbox quick access mode instead of directly fiddling with the UNIX mailbox stream. * include/mailutils/stream.h (MU_STREAM_QACCESS): New define. * libproto/mbox/mbox.c: Implement _quick_get_message method. * libproto/mbox/mbox0.h (mbox_scan1): New function. * libproto/mbox/mboxscan.c (mbox_scan0): Split into mbox_scan0 proper and mbox_scan_internal. (mbox_scan1): New function. Remove unused defines. * libsieve/load.c: Do not deallocate loaded modules. * mail.local/main.c (set_debug_flags): Fix typo. * mailbox/amd.c: Implement get_qid method. (amd_append_message) Singal MU_EVT_MESSAGE_APPEND. * mailbox/errors (MU_ERR_BADOP): New error code. (MU_READ_ERROR): Rename to MU_ERR_READ, for consistency. * mailbox/file_stream.c (_prog_destroy,_prog_close): Fix waiting for the children to terminate. Do not forcefully kill them. * mailbox/mailbox.c: Control allowed operations, depending on MU_STREAM_QACCESS bit.
Showing
15 changed files
with
289 additions
and
159 deletions
... | @@ -417,7 +417,7 @@ get_field (mu_sql_connection_t conn, const char *id, char **ret, int mandatory) | ... | @@ -417,7 +417,7 @@ get_field (mu_sql_connection_t conn, const char *id, char **ret, int mandatory) |
417 | { | 417 | { |
418 | mu_error (_("SQL field `%s' (`%s') has NULL value"), | 418 | mu_error (_("SQL field `%s' (`%s') has NULL value"), |
419 | id, name ? *name : id); | 419 | id, name ? *name : id); |
420 | rc = MU_READ_ERROR; | 420 | rc = MU_ERR_READ; |
421 | } | 421 | } |
422 | 422 | ||
423 | return rc; | 423 | return rc; | ... | ... |
... | @@ -26,6 +26,11 @@ comsatd_SOURCES = action.c cfg.c comsat.c comsat.h | ... | @@ -26,6 +26,11 @@ comsatd_SOURCES = action.c cfg.c comsat.c comsat.h |
26 | comsatd_LDADD = \ | 26 | comsatd_LDADD = \ |
27 | ../lib/libmuaux.la\ | 27 | ../lib/libmuaux.la\ |
28 | ${MU_LIB_MBOX}\ | 28 | ${MU_LIB_MBOX}\ |
29 | ${MU_LIB_IMAP}\ | ||
30 | ${MU_LIB_POP}\ | ||
31 | ${MU_LIB_NNTP}\ | ||
32 | ${MU_LIB_MH}\ | ||
33 | ${MU_LIB_MAILDIR}\ | ||
29 | ${MU_LIB_MAILUTILS}\ | 34 | ${MU_LIB_MAILUTILS}\ |
30 | @MU_COMMON_LIBRARIES@ | 35 | @MU_COMMON_LIBRARIES@ |
31 | 36 | ... | ... |
... | @@ -110,7 +110,7 @@ netdef_parse (char *str) | ... | @@ -110,7 +110,7 @@ netdef_parse (char *str) |
110 | netdef = malloc (sizeof *netdef); | 110 | netdef = malloc (sizeof *netdef); |
111 | if (!netdef) | 111 | if (!netdef) |
112 | { | 112 | { |
113 | syslog (LOG_ERR, _("Out of memory")); | 113 | mu_error (_("Out of memory")); |
114 | exit (1); | 114 | exit (1); |
115 | } | 115 | } |
116 | 116 | ||
... | @@ -135,7 +135,8 @@ read_config (const char *config_file) | ... | @@ -135,7 +135,8 @@ read_config (const char *config_file) |
135 | fp = fopen (config_file, "r"); | 135 | fp = fopen (config_file, "r"); |
136 | if (!fp) | 136 | if (!fp) |
137 | { | 137 | { |
138 | syslog (LOG_ERR, _("Cannot open config file %s: %m"), config_file); | 138 | mu_error (_("Cannot open config file %s: %s"), config_file, |
139 | mu_strerror (errno)); | ||
139 | return; | 140 | return; |
140 | } | 141 | } |
141 | 142 | ||
... | @@ -162,7 +163,7 @@ read_config (const char *config_file) | ... | @@ -162,7 +163,7 @@ read_config (const char *config_file) |
162 | mu_argcv_get (ptr, "", NULL, &argc, &argv); | 163 | mu_argcv_get (ptr, "", NULL, &argc, &argv); |
163 | if (argc < 2) | 164 | if (argc < 2) |
164 | { | 165 | { |
165 | syslog (LOG_ERR, _("%s:%d: too few fields"), config_file, line); | 166 | mu_error (_("%s:%d: too few fields"), config_file, line); |
166 | mu_argcv_free (argc, argv); | 167 | mu_argcv_free (argc, argv); |
167 | continue; | 168 | continue; |
168 | } | 169 | } |
... | @@ -174,7 +175,7 @@ read_config (const char *config_file) | ... | @@ -174,7 +175,7 @@ read_config (const char *config_file) |
174 | else if (strcmp (argv[1], "no") == 0) | 175 | else if (strcmp (argv[1], "no") == 0) |
175 | allow_biffrc = 0; | 176 | allow_biffrc = 0; |
176 | else | 177 | else |
177 | syslog (LOG_ERR, _("%s:%d: yes or no expected"), config_file, line); | 178 | mu_error (_("%s:%d: yes or no expected"), config_file, line); |
178 | } | 179 | } |
179 | else if (strcmp (argv[0], "max-requests") == 0) | 180 | else if (strcmp (argv[0], "max-requests") == 0) |
180 | maxrequests = strtoul (argv[1], NULL, 0); | 181 | maxrequests = strtoul (argv[1], NULL, 0); |
... | @@ -194,7 +195,7 @@ read_config (const char *config_file) | ... | @@ -194,7 +195,7 @@ read_config (const char *config_file) |
194 | action = ACT_DENY; | 195 | action = ACT_DENY; |
195 | else | 196 | else |
196 | { | 197 | { |
197 | syslog (LOG_ERR, _("%s:%d: unknown keyword"), config_file, line); | 198 | mu_error (_("%s:%d: unknown keyword"), config_file, line); |
198 | mu_argcv_free (argc, argv); | 199 | mu_argcv_free (argc, argv); |
199 | continue; | 200 | continue; |
200 | } | 201 | } |
... | @@ -205,8 +206,8 @@ read_config (const char *config_file) | ... | @@ -205,8 +206,8 @@ read_config (const char *config_file) |
205 | netdef_t *cur = netdef_parse (argv[i]); | 206 | netdef_t *cur = netdef_parse (argv[i]); |
206 | if (!cur) | 207 | if (!cur) |
207 | { | 208 | { |
208 | syslog (LOG_ERR, _("%s:%d: cannot parse netdef: %s"), | 209 | mu_error (_("%s:%d: cannot parse netdef: %s"), |
209 | config_file, line, argv[i]); | 210 | config_file, line, argv[i]); |
210 | continue; | 211 | continue; |
211 | } | 212 | } |
212 | if (!tail) | 213 | if (!tail) |
... | @@ -221,7 +222,7 @@ read_config (const char *config_file) | ... | @@ -221,7 +222,7 @@ read_config (const char *config_file) |
221 | acl = malloc (sizeof *acl); | 222 | acl = malloc (sizeof *acl); |
222 | if (!acl) | 223 | if (!acl) |
223 | { | 224 | { |
224 | syslog (LOG_CRIT, _("Out of memory")); | 225 | mu_error (_("Out of memory")); |
225 | exit (1); | 226 | exit (1); |
226 | } | 227 | } |
227 | acl->next = NULL; | 228 | acl->next = NULL; | ... | ... |
... | @@ -57,7 +57,8 @@ static char doc[] = "GNU comsatd"; | ... | @@ -57,7 +57,8 @@ static char doc[] = "GNU comsatd"; |
57 | 57 | ||
58 | static struct argp_option options[] = | 58 | static struct argp_option options[] = |
59 | { | 59 | { |
60 | {"config", 'c', N_("FILE"), 0, N_("Read configuration from FILE"), 0}, | 60 | { "config", 'c', N_("FILE"), 0, N_("Read configuration from FILE"), 0 }, |
61 | { "test", 't', NULL, 0, N_("Run in test mode"), 0 }, | ||
61 | { NULL, 0, NULL, 0, NULL, 0 } | 62 | { NULL, 0, NULL, 0, NULL, 0 } |
62 | }; | 63 | }; |
63 | 64 | ||
... | @@ -104,7 +105,8 @@ static void comsat_init (void); | ... | @@ -104,7 +105,8 @@ static void comsat_init (void); |
104 | static void comsat_daemon_init (void); | 105 | static void comsat_daemon_init (void); |
105 | static void comsat_daemon (int _port); | 106 | static void comsat_daemon (int _port); |
106 | static int comsat_main (int fd); | 107 | static int comsat_main (int fd); |
107 | static void notify_user (const char *user, const char *device, const char *path, off_t offset); | 108 | static void notify_user (const char *user, const char *device, |
109 | const char *path, mu_message_qid_t qid); | ||
108 | static int find_user (const char *name, char *tty); | 110 | static int find_user (const char *name, char *tty); |
109 | static char *mailbox_path (const char *user); | 111 | static char *mailbox_path (const char *user); |
110 | static void change_user (const char *user); | 112 | static void change_user (const char *user); |
... | @@ -112,6 +114,7 @@ static void change_user (const char *user); | ... | @@ -112,6 +114,7 @@ static void change_user (const char *user); |
112 | static int xargc; | 114 | static int xargc; |
113 | static char **xargv; | 115 | static char **xargv; |
114 | char *config_file = NULL; | 116 | char *config_file = NULL; |
117 | int test_mode; | ||
115 | 118 | ||
116 | static error_t | 119 | static error_t |
117 | comsatd_parse_opt (int key, char *arg, struct argp_state *state) | 120 | comsatd_parse_opt (int key, char *arg, struct argp_state *state) |
... | @@ -125,6 +128,10 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -125,6 +128,10 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) |
125 | case 'c': | 128 | case 'c': |
126 | config_file = arg; | 129 | config_file = arg; |
127 | break; | 130 | break; |
131 | |||
132 | case 't': | ||
133 | test_mode = 1; | ||
134 | break; | ||
128 | 135 | ||
129 | default: | 136 | default: |
130 | return ARGP_ERR_UNKNOWN; | 137 | return ARGP_ERR_UNKNOWN; |
... | @@ -134,20 +141,59 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -134,20 +141,59 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) |
134 | 141 | ||
135 | 142 | ||
136 | int | 143 | int |
137 | main(int argc, char **argv) | 144 | main (int argc, char **argv) |
138 | { | 145 | { |
139 | int c; | 146 | int c; |
140 | 147 | int ind; | |
148 | |||
141 | /* Native Language Support */ | 149 | /* Native Language Support */ |
142 | mu_init_nls (); | 150 | mu_init_nls (); |
143 | 151 | ||
144 | mu_argp_init (program_version, NULL); | 152 | mu_argp_init (program_version, NULL); |
145 | mu_argp_parse (&argp, &argc, &argv, 0, comsat_argp_capa, | 153 | mu_argp_parse (&argp, &argc, &argv, 0, comsat_argp_capa, |
146 | NULL, &daemon_param); | 154 | &ind, &daemon_param); |
147 | 155 | ||
156 | argc -= ind; | ||
157 | argv += ind; | ||
158 | |||
159 | if (test_mode) | ||
160 | { | ||
161 | char *user, *url, *qid; | ||
162 | |||
163 | comsat_init (); | ||
164 | if (config_file) | ||
165 | read_config (config_file); | ||
166 | if (argc == 0) | ||
167 | exit (0); | ||
168 | if (argc < 2 || argc > 2) | ||
169 | { | ||
170 | mu_error (_("Mailbox URL and message QID are required in test mode")); | ||
171 | exit (EXIT_FAILURE); | ||
172 | } | ||
173 | |||
174 | user = getenv ("LOGNAME"); | ||
175 | if (!user) | ||
176 | { | ||
177 | user = getenv ("USER"); | ||
178 | if (!user) | ||
179 | { | ||
180 | struct passwd *pw = getpwuid (getuid ()); | ||
181 | if (!pw) | ||
182 | { | ||
183 | mu_error (_("Cannot determine user name")); | ||
184 | exit (EXIT_FAILURE); | ||
185 | } | ||
186 | user = pw->pw_name; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | notify_user (user, "/dev/tty", argv[0], argv[1]); | ||
191 | exit (0); | ||
192 | } | ||
193 | |||
148 | if (daemon_param.timeout > 0 && daemon_param.mode == MODE_DAEMON) | 194 | if (daemon_param.timeout > 0 && daemon_param.mode == MODE_DAEMON) |
149 | { | 195 | { |
150 | fprintf (stderr, _("--timeout and --daemon are incompatible\n")); | 196 | mu_error (_("--timeout and --daemon are incompatible")); |
151 | exit (EXIT_FAILURE); | 197 | exit (EXIT_FAILURE); |
152 | } | 198 | } |
153 | 199 | ||
... | @@ -194,7 +240,8 @@ sig_hup (int sig) | ... | @@ -194,7 +240,8 @@ sig_hup (int sig) |
194 | void | 240 | void |
195 | comsat_init () | 241 | comsat_init () |
196 | { | 242 | { |
197 | mu_registrar_record (mu_path_record); | 243 | /* Register mailbox formats */ |
244 | mu_register_all_mbox_formats (); | ||
198 | 245 | ||
199 | gethostname (hostname, sizeof hostname); | 246 | gethostname (hostname, sizeof hostname); |
200 | 247 | ||
... | @@ -324,10 +371,10 @@ comsat_main (int fd) | ... | @@ -324,10 +371,10 @@ comsat_main (int fd) |
324 | char buffer[216]; /*FIXME: Arbitrary size */ | 371 | char buffer[216]; /*FIXME: Arbitrary size */ |
325 | pid_t pid; | 372 | pid_t pid; |
326 | char tty[MAX_TTY_SIZE]; | 373 | char tty[MAX_TTY_SIZE]; |
327 | char *p, *endp; | 374 | char *p; |
328 | size_t offset; | ||
329 | char *path = NULL; | 375 | char *path = NULL; |
330 | 376 | mu_message_qid_t qid; | |
377 | |||
331 | len = sizeof sin_from; | 378 | len = sizeof sin_from; |
332 | rdlen = recvfrom (fd, buffer, sizeof buffer, 0, | 379 | rdlen = recvfrom (fd, buffer, sizeof buffer, 0, |
333 | (struct sockaddr*)&sin_from, &len); | 380 | (struct sockaddr*)&sin_from, &len); |
... | @@ -362,19 +409,8 @@ comsat_main (int fd) | ... | @@ -362,19 +409,8 @@ comsat_main (int fd) |
362 | } | 409 | } |
363 | *p++ = 0; | 410 | *p++ = 0; |
364 | 411 | ||
365 | offset = strtoul (p, &endp, 0); | 412 | qid = p; |
366 | switch (*endp) | 413 | |
367 | { | ||
368 | case 0: | ||
369 | break; | ||
370 | case ':': | ||
371 | path = endp+1; | ||
372 | break; | ||
373 | default: | ||
374 | if (!isspace (*endp)) | ||
375 | syslog (LOG_ERR, _("Malformed input: %s@%s (near %s)"), buffer, p, endp); | ||
376 | } | ||
377 | |||
378 | if (find_user (buffer, tty) != SUCCESS) | 414 | if (find_user (buffer, tty) != SUCCESS) |
379 | return 0; | 415 | return 0; |
380 | 416 | ||
... | @@ -400,7 +436,7 @@ comsat_main (int fd) | ... | @@ -400,7 +436,7 @@ comsat_main (int fd) |
400 | } | 436 | } |
401 | 437 | ||
402 | /* Child: do actual I/O */ | 438 | /* Child: do actual I/O */ |
403 | notify_user (buffer, tty, path, offset); | 439 | notify_user (buffer, tty, path, qid); |
404 | exit (0); | 440 | exit (0); |
405 | } | 441 | } |
406 | 442 | ||
... | @@ -423,17 +459,14 @@ get_newline_str (FILE *fp) | ... | @@ -423,17 +459,14 @@ get_newline_str (FILE *fp) |
423 | /* NOTE: Do not bother to free allocated memory, as the program exits | 459 | /* NOTE: Do not bother to free allocated memory, as the program exits |
424 | immediately after executing this */ | 460 | immediately after executing this */ |
425 | static void | 461 | static void |
426 | notify_user (const char *user, const char *device, const char *path, off_t offset) | 462 | notify_user (const char *user, const char *device, const char *path, |
463 | mu_message_qid_t qid) | ||
427 | { | 464 | { |
428 | FILE *fp; | 465 | FILE *fp; |
429 | const char *cr; | 466 | const char *cr; |
430 | char *blurb; | 467 | mu_mailbox_t mbox = NULL; |
431 | mu_mailbox_t mbox = NULL, tmp = NULL; | ||
432 | mu_message_t msg; | 468 | mu_message_t msg; |
433 | mu_stream_t stream = NULL; | ||
434 | int status; | 469 | int status; |
435 | off_t size; | ||
436 | size_t count, n; | ||
437 | 470 | ||
438 | change_user (user); | 471 | change_user (user); |
439 | if ((fp = fopen (device, "w")) == NULL) | 472 | if ((fp = fopen (device, "w")) == NULL) |
... | @@ -452,56 +485,21 @@ notify_user (const char *user, const char *device, const char *path, off_t offse | ... | @@ -452,56 +485,21 @@ notify_user (const char *user, const char *device, const char *path, off_t offse |
452 | } | 485 | } |
453 | 486 | ||
454 | if ((status = mu_mailbox_create (&mbox, path)) != 0 | 487 | if ((status = mu_mailbox_create (&mbox, path)) != 0 |
455 | || (status = mu_mailbox_open (mbox, MU_STREAM_READ)) != 0) | 488 | || (status = mu_mailbox_open (mbox, MU_STREAM_READ|MU_STREAM_QACCESS)) != 0) |
456 | { | 489 | { |
457 | syslog (LOG_ERR, _("Cannot open mailbox %s: %s"), | 490 | syslog (LOG_ERR, _("Cannot open mailbox %s: %s"), |
458 | path, mu_strerror (status)); | 491 | path, mu_strerror (status)); |
459 | return; | 492 | return; |
460 | } | 493 | } |
461 | 494 | ||
462 | if ((status = mu_mailbox_get_stream (mbox, &stream))) | 495 | status = mu_mailbox_quick_get_message (mbox, qid, &msg); |
463 | { | 496 | if (status) |
464 | syslog (LOG_ERR, _("Cannot get stream for mailbox %s: %s"), | ||
465 | path, mu_strerror (status)); | ||
466 | return; | ||
467 | } | ||
468 | |||
469 | if ((status = mu_stream_size (stream, &size))) | ||
470 | { | ||
471 | syslog (LOG_ERR, _("Cannot get stream size (mailbox %s): %s"), | ||
472 | path, mu_strerror (status)); | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | /* Read headers */ | ||
477 | size -= offset; | ||
478 | blurb = malloc (size + 1); | ||
479 | if (!blurb) | ||
480 | return; | ||
481 | |||
482 | mu_stream_read (stream, blurb, size, offset, &n); | ||
483 | blurb[size] = 0; | ||
484 | |||
485 | if ((status = mu_mailbox_create (&tmp, "/dev/null")) != 0 | ||
486 | || (status = mu_mailbox_open (tmp, MU_STREAM_READ)) != 0) | ||
487 | { | ||
488 | syslog (LOG_ERR, _("Cannot create temporary mailbox: %s"), | ||
489 | mu_strerror (status)); | ||
490 | return; | ||
491 | } | ||
492 | |||
493 | if ((status = mu_memory_stream_create (&stream, 0, 0))) | ||
494 | { | 497 | { |
495 | syslog (LOG_ERR, _("Cannot create temporary stream: %s"), | 498 | syslog (LOG_ERR, _("Cannot get message (mailbox %s, qid %s): %s"), |
496 | mu_strerror (status)); | 499 | path, qid, mu_strerror (status)); |
497 | return; | 500 | return; /* FIXME: Notify the user, anyway */ |
498 | } | 501 | } |
499 | 502 | ||
500 | mu_stream_write (stream, blurb, size, 0, &count); | ||
501 | mu_mailbox_set_stream (tmp, stream); | ||
502 | mu_mailbox_messages_count (tmp, &count); | ||
503 | mu_mailbox_get_message (tmp, 1, &msg); | ||
504 | |||
505 | run_user_action (fp, cr, msg); | 503 | run_user_action (fp, cr, msg); |
506 | fclose (fp); | 504 | fclose (fp); |
507 | } | 505 | } | ... | ... |
... | @@ -39,7 +39,9 @@ extern "C" { /*}*/ | ... | @@ -39,7 +39,9 @@ extern "C" { /*}*/ |
39 | #define MU_STREAM_NO_CLOSE 0x00000100 | 39 | #define MU_STREAM_NO_CLOSE 0x00000100 |
40 | #define MU_STREAM_ALLOW_LINKS 0x00000200 | 40 | #define MU_STREAM_ALLOW_LINKS 0x00000200 |
41 | #define MU_STREAM_NONLOCK 0x00000400 | 41 | #define MU_STREAM_NONLOCK 0x00000400 |
42 | 42 | /* This one affects only mailboxes */ | |
43 | #define MU_STREAM_QACCESS 0x00000800 | ||
44 | |||
43 | /* Functions useful to users of the pre-defined stream types. */ | 45 | /* Functions useful to users of the pre-defined stream types. */ |
44 | 46 | ||
45 | extern int mu_file_stream_create (mu_stream_t *stream, const char* filename, | 47 | extern int mu_file_stream_create (mu_stream_t *stream, const char* filename, | ... | ... |
... | @@ -358,7 +358,7 @@ list_helper (struct search_data *data, | ... | @@ -358,7 +358,7 @@ list_helper (struct search_data *data, |
358 | break; | 358 | break; |
359 | 359 | ||
360 | case GLOB_ABORTED: | 360 | case GLOB_ABORTED: |
361 | status = MU_READ_ERROR; | 361 | status = MU_ERR_READ; |
362 | break; | 362 | break; |
363 | 363 | ||
364 | case GLOB_NOMATCH: | 364 | case GLOB_NOMATCH: | ... | ... |
... | @@ -35,6 +35,9 @@ static void mbox_destroy (mu_mailbox_t); | ... | @@ -35,6 +35,9 @@ static void mbox_destroy (mu_mailbox_t); |
35 | static int mbox_open (mu_mailbox_t, int); | 35 | static int mbox_open (mu_mailbox_t, int); |
36 | static int mbox_close (mu_mailbox_t); | 36 | static int mbox_close (mu_mailbox_t); |
37 | static int mbox_get_message (mu_mailbox_t, size_t, mu_message_t *); | 37 | static int mbox_get_message (mu_mailbox_t, size_t, mu_message_t *); |
38 | static int mbox_quick_get_message (mu_mailbox_t, mu_message_qid_t, | ||
39 | mu_message_t *); | ||
40 | |||
38 | /* static int mbox_get_message_by_uid (mu_mailbox_t, size_t, mu_message_t *); */ | 41 | /* static int mbox_get_message_by_uid (mu_mailbox_t, size_t, mu_message_t *); */ |
39 | static int mbox_append_message (mu_mailbox_t, mu_message_t); | 42 | static int mbox_append_message (mu_mailbox_t, mu_message_t); |
40 | static int mbox_messages_count (mu_mailbox_t, size_t *); | 43 | static int mbox_messages_count (mu_mailbox_t, size_t *); |
... | @@ -136,6 +139,7 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) | ... | @@ -136,6 +139,7 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) |
136 | mailbox->_sync = mbox_sync; | 139 | mailbox->_sync = mbox_sync; |
137 | mailbox->_uidvalidity = mbox_uidvalidity; | 140 | mailbox->_uidvalidity = mbox_uidvalidity; |
138 | mailbox->_uidnext = mbox_uidnext; | 141 | mailbox->_uidnext = mbox_uidnext; |
142 | mailbox->_quick_get_message = mbox_quick_get_message; | ||
139 | 143 | ||
140 | mailbox->_scan = mbox_scan; | 144 | mailbox->_scan = mbox_scan; |
141 | mailbox->_is_updated = mbox_is_updated; | 145 | mailbox->_is_updated = mbox_is_updated; |
... | @@ -1065,45 +1069,10 @@ mbox_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, | ... | @@ -1065,45 +1069,10 @@ mbox_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, |
1065 | } | 1069 | } |
1066 | 1070 | ||
1067 | static int | 1071 | static int |
1068 | mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | 1072 | new_message (mu_mailbox_t mailbox, mbox_message_t mum, mu_message_t *pmsg) |
1069 | { | 1073 | { |
1070 | int status; | 1074 | int status; |
1071 | mbox_data_t mud = mailbox->data; | 1075 | mu_message_t msg; |
1072 | mbox_message_t mum; | ||
1073 | mu_message_t msg = NULL; | ||
1074 | |||
1075 | /* Sanity checks. */ | ||
1076 | if (pmsg == NULL) | ||
1077 | return MU_ERR_OUT_PTR_NULL; | ||
1078 | if (mud == NULL) | ||
1079 | return EINVAL; | ||
1080 | |||
1081 | /* If we did not start a scanning yet do it now. */ | ||
1082 | if (mud->messages_count == 0) | ||
1083 | { | ||
1084 | status = mbox_scan0 (mailbox, 1, NULL, 0); | ||
1085 | if (status != 0) | ||
1086 | return status; | ||
1087 | } | ||
1088 | |||
1089 | /* Second sanity: check the message number. */ | ||
1090 | if (!(mud->messages_count > 0 | ||
1091 | && msgno > 0 | ||
1092 | && msgno <= mud->messages_count)) | ||
1093 | return EINVAL; | ||
1094 | |||
1095 | mum = mud->umessages[msgno - 1]; | ||
1096 | |||
1097 | /* Check if we already have it. */ | ||
1098 | if (mum->message) | ||
1099 | { | ||
1100 | if (pmsg) | ||
1101 | *pmsg = mum->message; | ||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1105 | MAILBOX_DEBUG2 (mailbox, MU_DEBUG_TRACE, "mbox_get_message (%s, %d)\n", | ||
1106 | mud->name, msgno); | ||
1107 | 1076 | ||
1108 | /* Get an empty message struct. */ | 1077 | /* Get an empty message struct. */ |
1109 | status = mu_message_create (&msg, mum); | 1078 | status = mu_message_create (&msg, mum); |
... | @@ -1185,9 +1154,109 @@ mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -1185,9 +1154,109 @@ mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) |
1185 | mu_message_set_mailbox (msg, mailbox, mum); | 1154 | mu_message_set_mailbox (msg, mailbox, mum); |
1186 | 1155 | ||
1187 | *pmsg = msg; | 1156 | *pmsg = msg; |
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | static int | ||
1162 | mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | ||
1163 | { | ||
1164 | int status; | ||
1165 | mbox_data_t mud = mailbox->data; | ||
1166 | mbox_message_t mum; | ||
1167 | |||
1168 | /* Sanity checks. */ | ||
1169 | if (pmsg == NULL) | ||
1170 | return MU_ERR_OUT_PTR_NULL; | ||
1171 | if (mud == NULL) | ||
1172 | return EINVAL; | ||
1173 | |||
1174 | /* If we did not start a scanning yet do it now. */ | ||
1175 | if (mud->messages_count == 0) | ||
1176 | { | ||
1177 | status = mbox_scan0 (mailbox, 1, NULL, 0); | ||
1178 | if (status != 0) | ||
1179 | return status; | ||
1180 | } | ||
1181 | |||
1182 | /* Second sanity: check the message number. */ | ||
1183 | if (!(mud->messages_count > 0 | ||
1184 | && msgno > 0 | ||
1185 | && msgno <= mud->messages_count)) | ||
1186 | return EINVAL; | ||
1187 | |||
1188 | mum = mud->umessages[msgno - 1]; | ||
1189 | |||
1190 | /* Check if we already have it. */ | ||
1191 | if (mum->message) | ||
1192 | { | ||
1193 | if (pmsg) | ||
1194 | *pmsg = mum->message; | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | MAILBOX_DEBUG2 (mailbox, MU_DEBUG_TRACE, "mbox_get_message (%s, %d)\n", | ||
1199 | mud->name, msgno); | ||
1200 | |||
1201 | return new_message (mailbox, mum, pmsg); | ||
1202 | } | ||
1203 | |||
1204 | static int | ||
1205 | qid2off (mu_message_qid_t qid, mu_off_t *pret) | ||
1206 | { | ||
1207 | mu_off_t ret = 0; | ||
1208 | for (;*qid; qid++) | ||
1209 | { | ||
1210 | if (!('0' <= *qid && *qid <= '9')) | ||
1211 | return 1; | ||
1212 | ret = ret * 10 + *qid - '0'; | ||
1213 | } | ||
1214 | *pret = ret; | ||
1188 | return 0; | 1215 | return 0; |
1189 | } | 1216 | } |
1217 | |||
1218 | static int | ||
1219 | mbox_quick_get_message (mu_mailbox_t mailbox, mu_message_qid_t qid, | ||
1220 | mu_message_t *pmsg) | ||
1221 | { | ||
1222 | int status; | ||
1223 | mbox_data_t mud = mailbox->data; | ||
1224 | mbox_message_t mum; | ||
1225 | mu_off_t offset; | ||
1226 | |||
1227 | if (mailbox == NULL || qid2off (qid, &offset) | ||
1228 | || !(mailbox->flags & MU_STREAM_QACCESS)) | ||
1229 | return EINVAL; | ||
1190 | 1230 | ||
1231 | if (mud->messages_count == 0) | ||
1232 | { | ||
1233 | status = mbox_scan1 (mailbox, offset, 0); | ||
1234 | if (status != 0) | ||
1235 | return status; | ||
1236 | } | ||
1237 | |||
1238 | /* Quick access mode retrieves only one message */ | ||
1239 | mum = mud->umessages[0]; | ||
1240 | |||
1241 | /* Check if we already have it and verify if it is the right one. */ | ||
1242 | if (mum->message) | ||
1243 | { | ||
1244 | char *vqid; | ||
1245 | status = mu_message_get_qid (mum->message, &vqid); | ||
1246 | if (status) | ||
1247 | return status; | ||
1248 | status = strcmp (qid, vqid); | ||
1249 | free (vqid); | ||
1250 | if (status) | ||
1251 | return MU_ERR_EXISTS; | ||
1252 | if (pmsg) | ||
1253 | *pmsg = mum->message; | ||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1257 | return new_message (mailbox, mum, pmsg); | ||
1258 | } | ||
1259 | |||
1191 | static int | 1260 | static int |
1192 | mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) | 1261 | mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
1193 | { | 1262 | { | ... | ... |
... | @@ -124,6 +124,9 @@ struct _mbox_data | ... | @@ -124,6 +124,9 @@ struct _mbox_data |
124 | 124 | ||
125 | int mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, | 125 | int mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, |
126 | int do_notif); | 126 | int do_notif); |
127 | int mbox_scan1 (mu_mailbox_t mailbox, mu_off_t offset, int do_notif); | ||
128 | |||
127 | #ifdef WITH_PTHREAD | 129 | #ifdef WITH_PTHREAD |
128 | void mbox_cleanup (void *arg); | 130 | void mbox_cleanup (void *arg); |
129 | #endif | 131 | #endif |
132 | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -31,12 +31,15 @@ | ... | @@ -31,12 +31,15 @@ |
31 | 31 | ||
32 | typedef int (*sieve_module_init_t) (mu_sieve_machine_t mach); | 32 | typedef int (*sieve_module_init_t) (mu_sieve_machine_t mach); |
33 | 33 | ||
34 | #if 0 | ||
35 | /* FIXME: See comment below */ | ||
34 | static void | 36 | static void |
35 | _free_loaded_module (void *data) | 37 | _free_loaded_module (void *data) |
36 | { | 38 | { |
37 | lt_dlclose ((lt_dlhandle)data); | 39 | lt_dlclose ((lt_dlhandle)data); |
38 | lt_dlexit (); | 40 | lt_dlexit (); |
39 | } | 41 | } |
42 | #endif | ||
40 | 43 | ||
41 | static lt_dlhandle | 44 | static lt_dlhandle |
42 | load_module (mu_sieve_machine_t mach, const char *name) | 45 | load_module (mu_sieve_machine_t mach, const char *name) |
... | @@ -54,7 +57,13 @@ load_module (mu_sieve_machine_t mach, const char *name) | ... | @@ -54,7 +57,13 @@ load_module (mu_sieve_machine_t mach, const char *name) |
54 | if (init) | 57 | if (init) |
55 | { | 58 | { |
56 | init (mach); | 59 | init (mach); |
57 | mu_sieve_machine_add_destructor (mach, _free_loaded_module, handle); | 60 | /* FIXME: We used to have this: |
61 | mu_sieve_machine_add_destructor (mach, _free_loaded_module, | ||
62 | handle); | ||
63 | However, unloading modules can lead to random segfaults in | ||
64 | case they allocated any global-access data (e.g. mach->msg). | ||
65 | In particular, this was the case with extensions/pipe.c. | ||
66 | */ | ||
58 | return handle; | 67 | return handle; |
59 | } | 68 | } |
60 | else | 69 | else | ... | ... |
... | @@ -131,7 +131,7 @@ char *saved_envelope; /* A hack to spare mu_envelope_ calls */ | ... | @@ -131,7 +131,7 @@ char *saved_envelope; /* A hack to spare mu_envelope_ calls */ |
131 | static void | 131 | static void |
132 | set_debug_flags (const mu_cfg_locus_t *locus, const char *arg) | 132 | set_debug_flags (const mu_cfg_locus_t *locus, const char *arg) |
133 | { | 133 | { |
134 | for (; *arg; arg++); | 134 | for (; *arg; arg++) |
135 | { | 135 | { |
136 | switch (*arg) | 136 | switch (*arg) |
137 | { | 137 | { |
... | @@ -508,7 +508,7 @@ sieve_test (struct mu_auth_data *auth, mu_mailbox_t mbx) | ... | @@ -508,7 +508,7 @@ sieve_test (struct mu_auth_data *auth, mu_mailbox_t mbx) |
508 | chdir (auth->dir); | 508 | chdir (auth->dir); |
509 | 509 | ||
510 | rc = mu_sieve_message (mach, msg); | 510 | rc = mu_sieve_message (mach, msg); |
511 | if (rc == 0) | 511 | if (rc == 0) |
512 | rc = mu_attribute_is_deleted (attr) == 0; | 512 | rc = mu_attribute_is_deleted (attr) == 0; |
513 | 513 | ||
514 | switch_user_id (auth, 0); | 514 | switch_user_id (auth, 0); | ... | ... |
... | @@ -380,6 +380,16 @@ amd_close (mu_mailbox_t mailbox) | ... | @@ -380,6 +380,16 @@ amd_close (mu_mailbox_t mailbox) |
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | 382 | ||
383 | static int | ||
384 | amd_message_qid (mu_message_t msg, mu_message_qid_t *pqid) | ||
385 | { | ||
386 | struct _amd_message *mhm = mu_message_get_owner (msg); | ||
387 | |||
388 | *pqid = mhm->amd->msg_file_name (mhm, | ||
389 | mhm->attr_flags & MU_ATTRIBUTE_DELETED); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
383 | struct _amd_message * | 393 | struct _amd_message * |
384 | _amd_get_message (struct _amd_data *amd, size_t msgno) | 394 | _amd_get_message (struct _amd_data *amd, size_t msgno) |
385 | { | 395 | { |
... | @@ -480,7 +490,8 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm, | ... | @@ -480,7 +490,8 @@ _amd_attach_message (mu_mailbox_t mailbox, struct _amd_message *mhm, |
480 | /* Set the UID. */ | 490 | /* Set the UID. */ |
481 | if (mhm->amd->message_uid) | 491 | if (mhm->amd->message_uid) |
482 | mu_message_set_uid (msg, mhm->amd->message_uid, mhm); | 492 | mu_message_set_uid (msg, mhm->amd->message_uid, mhm); |
483 | 493 | mu_message_set_qid (msg, amd_message_qid, mhm); | |
494 | |||
484 | /* Attach the message to the mailbox mbox data. */ | 495 | /* Attach the message to the mailbox mbox data. */ |
485 | mhm->message = msg; | 496 | mhm->message = msg; |
486 | mu_message_set_mailbox (msg, mailbox, mhm); | 497 | mu_message_set_mailbox (msg, mailbox, mhm); |
... | @@ -725,7 +736,15 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -725,7 +736,15 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
725 | 736 | ||
726 | if (amd->msg_finish_delivery) | 737 | if (amd->msg_finish_delivery) |
727 | amd->msg_finish_delivery (amd, mhm); | 738 | amd->msg_finish_delivery (amd, mhm); |
728 | 739 | ||
740 | if (mailbox->observable) | ||
741 | { | ||
742 | char *qid = amd->msg_file_name (mhm, | ||
743 | mhm->attr_flags & MU_ATTRIBUTE_DELETED); | ||
744 | mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_APPEND, qid); | ||
745 | free (qid); | ||
746 | } | ||
747 | |||
729 | return status; | 748 | return status; |
730 | } | 749 | } |
731 | 750 | ... | ... |
... | @@ -80,5 +80,6 @@ MU_ERR_BAD_COLUMN _("Bad column address") | ... | @@ -80,5 +80,6 @@ MU_ERR_BAD_COLUMN _("Bad column address") |
80 | MU_ERR_NO_RESULT _("No result from the previous query available") | 80 | MU_ERR_NO_RESULT _("No result from the previous query available") |
81 | MU_ERR_NO_INTERFACE _("No such interface") | 81 | MU_ERR_NO_INTERFACE _("No such interface") |
82 | 82 | ||
83 | MU_ERR_BADOP _("Inappropriate operation for this mode") | ||
83 | MU_ERR_BAD_FILENAME _("Badly formed file or directory name") | 84 | MU_ERR_BAD_FILENAME _("Badly formed file or directory name") |
84 | MU_READ_ERROR _("Read error") | 85 | MU_ERR_READ _("Read error") | ... | ... |
... | @@ -704,28 +704,6 @@ _prog_stream_unregister (struct _prog_stream *stream) | ... | @@ -704,28 +704,6 @@ _prog_stream_unregister (struct _prog_stream *stream) |
704 | mu_list_remove (prog_stream_list, stream); | 704 | mu_list_remove (prog_stream_list, stream); |
705 | } | 705 | } |
706 | 706 | ||
707 | static int | ||
708 | _prog_waitpid (void *item, void *data MU_ARG_UNUSED) | ||
709 | { | ||
710 | struct _prog_stream *str = item; | ||
711 | int status; | ||
712 | if (str->pid > 0) | ||
713 | { | ||
714 | if (waitpid (str->pid, &str->status, WNOHANG) == str->pid) | ||
715 | str->pid = -1; | ||
716 | } | ||
717 | if (str->writer_pid > 0) | ||
718 | waitpid (str->writer_pid, &status, WNOHANG); | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | static void | ||
723 | _prog_stream_wait (struct _prog_stream *fs) | ||
724 | { | ||
725 | if (fs->pid > 0) | ||
726 | waitpid (fs->pid, &fs->status, 0); | ||
727 | } | ||
728 | |||
729 | #if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) | 707 | #if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) |
730 | # define getmaxfd() sysconf (_SC_OPEN_MAX) | 708 | # define getmaxfd() sysconf (_SC_OPEN_MAX) |
731 | #elif defined (HAVE_GETDTABLESIZE) | 709 | #elif defined (HAVE_GETDTABLESIZE) |
... | @@ -841,23 +819,34 @@ start_program_filter (pid_t *pid, int *p, int argc, char **argv, | ... | @@ -841,23 +819,34 @@ start_program_filter (pid_t *pid, int *p, int argc, char **argv, |
841 | } | 819 | } |
842 | 820 | ||
843 | static void | 821 | static void |
822 | _prog_wait (pid_t pid, int *pstatus) | ||
823 | { | ||
824 | if (pid > 0) | ||
825 | { | ||
826 | pid_t t; | ||
827 | do | ||
828 | t = waitpid (pid, pstatus, 0); | ||
829 | while (t == -1 && errno == EINTR); | ||
830 | } | ||
831 | } | ||
832 | |||
833 | static void | ||
844 | _prog_destroy (mu_stream_t stream) | 834 | _prog_destroy (mu_stream_t stream) |
845 | { | 835 | { |
846 | struct _prog_stream *fs = mu_stream_get_owner (stream); | 836 | struct _prog_stream *fs = mu_stream_get_owner (stream); |
837 | int status; | ||
838 | |||
847 | mu_argcv_free (fs->argc, fs->argv); | 839 | mu_argcv_free (fs->argc, fs->argv); |
848 | if (fs->in) | 840 | if (fs->in) |
849 | mu_stream_destroy (&fs->in, mu_stream_get_owner (fs->in)); | 841 | mu_stream_destroy (&fs->in, mu_stream_get_owner (fs->in)); |
850 | if (fs->out) | 842 | if (fs->out) |
851 | mu_stream_destroy (&fs->out, mu_stream_get_owner (fs->out)); | 843 | mu_stream_destroy (&fs->out, mu_stream_get_owner (fs->out)); |
852 | if (fs->pid > 0) | 844 | |
853 | { | 845 | _prog_wait (fs->pid, &fs->status); |
854 | kill (fs->pid, SIGTERM); | 846 | fs->pid = -1; |
855 | mu_list_do (prog_stream_list, _prog_waitpid, NULL); | 847 | _prog_wait (fs->writer_pid, &status); |
856 | kill (fs->pid, SIGKILL); | 848 | fs->writer_pid = -1; |
857 | if (fs->writer_pid > 0) | 849 | |
858 | kill (fs->writer_pid, SIGKILL); | ||
859 | mu_list_do (prog_stream_list, _prog_waitpid, NULL); | ||
860 | } | ||
861 | _prog_stream_unregister (fs); | 850 | _prog_stream_unregister (fs); |
862 | } | 851 | } |
863 | 852 | ||
... | @@ -865,6 +854,7 @@ static int | ... | @@ -865,6 +854,7 @@ static int |
865 | _prog_close (mu_stream_t stream) | 854 | _prog_close (mu_stream_t stream) |
866 | { | 855 | { |
867 | struct _prog_stream *fs = mu_stream_get_owner (stream); | 856 | struct _prog_stream *fs = mu_stream_get_owner (stream); |
857 | int status; | ||
868 | 858 | ||
869 | if (!stream) | 859 | if (!stream) |
870 | return EINVAL; | 860 | return EINVAL; |
... | @@ -875,7 +865,10 @@ _prog_close (mu_stream_t stream) | ... | @@ -875,7 +865,10 @@ _prog_close (mu_stream_t stream) |
875 | mu_stream_close (fs->out); | 865 | mu_stream_close (fs->out); |
876 | mu_stream_destroy (&fs->out, mu_stream_get_owner (fs->out)); | 866 | mu_stream_destroy (&fs->out, mu_stream_get_owner (fs->out)); |
877 | 867 | ||
878 | _prog_stream_wait (fs); | 868 | _prog_wait (fs->pid, &fs->status); |
869 | fs->pid = -1; | ||
870 | _prog_wait (fs->writer_pid, &status); | ||
871 | fs->writer_pid = -1; | ||
879 | 872 | ||
880 | mu_stream_close (fs->in); | 873 | mu_stream_close (fs->in); |
881 | mu_stream_destroy (&fs->in, mu_stream_get_owner (fs->in)); | 874 | mu_stream_destroy (&fs->in, mu_stream_get_owner (fs->in)); |
... | @@ -1101,7 +1094,7 @@ mu_prog_stream_create (mu_stream_t *stream, const char *progname, int flags) | ... | @@ -1101,7 +1094,7 @@ mu_prog_stream_create (mu_stream_t *stream, const char *progname, int flags) |
1101 | 1094 | ||
1102 | int | 1095 | int |
1103 | mu_filter_prog_stream_create (mu_stream_t *stream, const char *progname, | 1096 | mu_filter_prog_stream_create (mu_stream_t *stream, const char *progname, |
1104 | mu_stream_t input) | 1097 | mu_stream_t input) |
1105 | { | 1098 | { |
1106 | struct _prog_stream *fs; | 1099 | struct _prog_stream *fs; |
1107 | int rc = _prog_stream_create (&fs, stream, progname, MU_STREAM_RDWR); | 1100 | int rc = _prog_stream_create (&fs, stream, progname, MU_STREAM_RDWR); | ... | ... |
... | @@ -174,7 +174,8 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) | ... | @@ -174,7 +174,8 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) |
174 | /* Notify the observers. */ | 174 | /* Notify the observers. */ |
175 | if (mbox->observable) | 175 | if (mbox->observable) |
176 | { | 176 | { |
177 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_DESTROY, mbox); | 177 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_DESTROY, |
178 | mbox); | ||
178 | mu_observable_destroy (&mbox->observable, mbox); | 179 | mu_observable_destroy (&mbox->observable, mbox); |
179 | } | 180 | } |
180 | 181 | ||
... | @@ -223,6 +224,13 @@ mu_mailbox_open (mu_mailbox_t mbox, int flag) | ... | @@ -223,6 +224,13 @@ mu_mailbox_open (mu_mailbox_t mbox, int flag) |
223 | { | 224 | { |
224 | if (mbox == NULL || mbox->_open == NULL) | 225 | if (mbox == NULL || mbox->_open == NULL) |
225 | return MU_ERR_EMPTY_VFN; | 226 | return MU_ERR_EMPTY_VFN; |
227 | if (flag & MU_STREAM_QACCESS) | ||
228 | { | ||
229 | /* Quick access mailboxes are read-only */ | ||
230 | if (flag & (MU_STREAM_WRITE | MU_STREAM_RDWR | ||
231 | | MU_STREAM_APPEND | MU_STREAM_CREAT)) | ||
232 | return EINVAL; /* FIXME: Better error code, please? */ | ||
233 | } | ||
226 | return mbox->_open (mbox, flag); | 234 | return mbox->_open (mbox, flag); |
227 | } | 235 | } |
228 | 236 | ||
... | @@ -284,6 +292,8 @@ mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -284,6 +292,8 @@ mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) |
284 | { | 292 | { |
285 | if (mbox == NULL || mbox->_get_message == NULL) | 293 | if (mbox == NULL || mbox->_get_message == NULL) |
286 | return MU_ERR_EMPTY_VFN; | 294 | return MU_ERR_EMPTY_VFN; |
295 | if (mbox->flags & MU_STREAM_QACCESS) | ||
296 | return MU_ERR_BADOP; | ||
287 | return mbox->_get_message (mbox, msgno, pmsg); | 297 | return mbox->_get_message (mbox, msgno, pmsg); |
288 | } | 298 | } |
289 | 299 | ||
... | @@ -293,6 +303,8 @@ mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, | ... | @@ -293,6 +303,8 @@ mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, |
293 | { | 303 | { |
294 | if (mbox == NULL || mbox->_quick_get_message == NULL) | 304 | if (mbox == NULL || mbox->_quick_get_message == NULL) |
295 | return MU_ERR_EMPTY_VFN; | 305 | return MU_ERR_EMPTY_VFN; |
306 | if (!(mbox->flags & MU_STREAM_QACCESS)) | ||
307 | return MU_ERR_BADOP; | ||
296 | return mbox->_quick_get_message (mbox, qid, pmsg); | 308 | return mbox->_quick_get_message (mbox, qid, pmsg); |
297 | } | 309 | } |
298 | 310 | ||
... | @@ -301,6 +313,8 @@ mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) | ... | @@ -301,6 +313,8 @@ mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) |
301 | { | 313 | { |
302 | if (mbox == NULL || mbox->_messages_count == NULL) | 314 | if (mbox == NULL || mbox->_messages_count == NULL) |
303 | return MU_ERR_EMPTY_VFN; | 315 | return MU_ERR_EMPTY_VFN; |
316 | if (mbox->flags & MU_STREAM_QACCESS) | ||
317 | return MU_ERR_BADOP; | ||
304 | return mbox->_messages_count (mbox, num); | 318 | return mbox->_messages_count (mbox, num); |
305 | } | 319 | } |
306 | 320 | ||
... | @@ -309,6 +323,8 @@ mu_mailbox_messages_recent (mu_mailbox_t mbox, size_t *num) | ... | @@ -309,6 +323,8 @@ mu_mailbox_messages_recent (mu_mailbox_t mbox, size_t *num) |
309 | { | 323 | { |
310 | if (mbox == NULL || mbox->_messages_recent == NULL) | 324 | if (mbox == NULL || mbox->_messages_recent == NULL) |
311 | return MU_ERR_EMPTY_VFN; | 325 | return MU_ERR_EMPTY_VFN; |
326 | if (mbox->flags & MU_STREAM_QACCESS) | ||
327 | return MU_ERR_BADOP; | ||
312 | return mbox->_messages_recent (mbox, num); | 328 | return mbox->_messages_recent (mbox, num); |
313 | } | 329 | } |
314 | 330 | ||
... | @@ -317,6 +333,8 @@ mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) | ... | @@ -317,6 +333,8 @@ mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) |
317 | { | 333 | { |
318 | if (mbox == NULL || mbox->_message_unseen == NULL) | 334 | if (mbox == NULL || mbox->_message_unseen == NULL) |
319 | return MU_ERR_EMPTY_VFN; | 335 | return MU_ERR_EMPTY_VFN; |
336 | if (mbox->flags & MU_STREAM_QACCESS) | ||
337 | return MU_ERR_BADOP; | ||
320 | return mbox->_message_unseen (mbox, num); | 338 | return mbox->_message_unseen (mbox, num); |
321 | } | 339 | } |
322 | 340 | ||
... | @@ -356,6 +374,8 @@ mu_mailbox_is_updated (mu_mailbox_t mbox) | ... | @@ -356,6 +374,8 @@ mu_mailbox_is_updated (mu_mailbox_t mbox) |
356 | { | 374 | { |
357 | if (mbox == NULL || mbox->_is_updated == NULL) | 375 | if (mbox == NULL || mbox->_is_updated == NULL) |
358 | return 1; | 376 | return 1; |
377 | if (mbox->flags & MU_STREAM_QACCESS) | ||
378 | return 1; | ||
359 | return mbox->_is_updated (mbox); | 379 | return mbox->_is_updated (mbox); |
360 | } | 380 | } |
361 | 381 | ||
... | @@ -364,6 +384,8 @@ mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -364,6 +384,8 @@ mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) |
364 | { | 384 | { |
365 | if (mbox == NULL || mbox->_scan == NULL) | 385 | if (mbox == NULL || mbox->_scan == NULL) |
366 | return MU_ERR_EMPTY_VFN; | 386 | return MU_ERR_EMPTY_VFN; |
387 | if (mbox->flags & MU_STREAM_QACCESS) | ||
388 | return MU_ERR_BADOP; | ||
367 | return mbox->_scan (mbox, msgno, pcount); | 389 | return mbox->_scan (mbox, msgno, pcount); |
368 | } | 390 | } |
369 | 391 | ||
... | @@ -373,6 +395,8 @@ mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) | ... | @@ -373,6 +395,8 @@ mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) |
373 | int status; | 395 | int status; |
374 | if (mbox == NULL) | 396 | if (mbox == NULL) |
375 | return MU_ERR_EMPTY_VFN; | 397 | return MU_ERR_EMPTY_VFN; |
398 | if (mbox->flags & MU_STREAM_QACCESS) | ||
399 | return MU_ERR_BADOP; | ||
376 | if (mbox->_get_size == NULL | 400 | if (mbox->_get_size == NULL |
377 | || (status = mbox->_get_size (mbox, psize)) == ENOSYS) | 401 | || (status = mbox->_get_size (mbox, psize)) == ENOSYS) |
378 | { | 402 | { |
... | @@ -405,6 +429,8 @@ mu_mailbox_uidvalidity (mu_mailbox_t mbox, unsigned long *pvalid) | ... | @@ -405,6 +429,8 @@ mu_mailbox_uidvalidity (mu_mailbox_t mbox, unsigned long *pvalid) |
405 | { | 429 | { |
406 | if (mbox == NULL || mbox->_uidvalidity == NULL) | 430 | if (mbox == NULL || mbox->_uidvalidity == NULL) |
407 | return MU_ERR_EMPTY_VFN; | 431 | return MU_ERR_EMPTY_VFN; |
432 | if (mbox->flags & MU_STREAM_QACCESS) | ||
433 | return MU_ERR_BADOP; | ||
408 | return mbox->_uidvalidity (mbox, pvalid); | 434 | return mbox->_uidvalidity (mbox, pvalid); |
409 | } | 435 | } |
410 | 436 | ||
... | @@ -413,6 +439,8 @@ mu_mailbox_uidnext (mu_mailbox_t mbox, size_t *puidnext) | ... | @@ -413,6 +439,8 @@ mu_mailbox_uidnext (mu_mailbox_t mbox, size_t *puidnext) |
413 | { | 439 | { |
414 | if (mbox == NULL || mbox->_uidnext == NULL) | 440 | if (mbox == NULL || mbox->_uidnext == NULL) |
415 | return MU_ERR_EMPTY_VFN; | 441 | return MU_ERR_EMPTY_VFN; |
442 | if (mbox->flags & MU_STREAM_QACCESS) | ||
443 | return MU_ERR_BADOP; | ||
416 | return mbox->_uidnext (mbox, puidnext); | 444 | return mbox->_uidnext (mbox, puidnext); |
417 | } | 445 | } |
418 | 446 | ||
... | @@ -455,6 +483,8 @@ mu_mailbox_set_stream (mu_mailbox_t mbox, mu_stream_t stream) | ... | @@ -455,6 +483,8 @@ mu_mailbox_set_stream (mu_mailbox_t mbox, mu_stream_t stream) |
455 | { | 483 | { |
456 | if (mbox == NULL) | 484 | if (mbox == NULL) |
457 | return MU_ERR_MBX_NULL; | 485 | return MU_ERR_MBX_NULL; |
486 | if (mbox->flags & MU_STREAM_QACCESS) | ||
487 | return MU_ERR_BADOP; | ||
458 | if (mbox->stream) | 488 | if (mbox->stream) |
459 | mu_stream_destroy (&mbox->stream, mbox); | 489 | mu_stream_destroy (&mbox->stream, mbox); |
460 | mbox->stream = stream; | 490 | mbox->stream = stream; | ... | ... |
-
Please register or sign in to post a comment