* Makefile.am, configure.ac: Add maidag.
* frm/common.c, imap4d/sync.c, libsieve/runtime.c, mh/scan.c: Update declaration of observable actions . * imap4d/select.c, imap4d/status.c, mh/anno.c, mh/forw.c, mh/repl.c: Use mu_mailbox_sync instead of mu_mailbox_save_attributes. * include/mailutils/mailbox.h (mu_mailbox_sync): New function. (mu_mailbox_save_attributes): Deprecated. * include/mailutils/message.h (mu_message_get_qid) (mu_message_set_qid): New functions. * include/mailutils/observer.h (MU_EVT_MESSAGE_APPEND): New event. (mu_observer_set_action_data): New function. Registers action-specific data. (mu_observable_notify): Get call-specific data as the third argument. * include/mailutils/types.hin (mu_message_qid_t): New data type. * libproto/imap/folder.c, libproto/imap/mbox.c, libproto/include/amd.h, libproto/maildir/mbox.c, libproto/mailer/sendmail.c, libproto/mailer/smtp.c, libproto/mbox/mboxscan.c, libproto/mh/mbox.c, libproto/nntp/mbox.c, libproto/pop/mbox.c, mailbox/folder.c, mailbox/mailer.c : Update calls to mu_observable_notify. * libproto/include/mailbox0.h (struct _mu_mailbox): Rename _save_attributes to _sync. * mailbox/amd.c: Likewise (_quick_get_message): New member. (MAILBOX_NOTIFY): Remove. * libproto/include/message0.h (struct _mu_message): New member _get_qid. * libproto/include/observer0.h (struct _mu_observer): New member _action_data. * libproto/mbox/mbox.c: Implement mbox_message_qid. Update calls to mu_observable_notify. (mbox_append_message): Report MU_EVT_MESSAGE_APPEND * mailbox/observer.c (mu_observer_destroy): Call _destroy with _action_data as its third argument. (mu_observer_action, mu_observable_notify): Takes third argument (call data) (mu_observer_set_action, mu_observer_set_destroy): Update signature. (mu_observer_set_action_data): New function. * libproto/mbox/mbox0.h, mail.local/main.c: Minor change. * mail.local/Makefile.am (mail_local_LDADD): Add MU_LIB_MAILER * mailbox/file_stream.c (_file_open): Fix handling of MU_STREAM_APPEND. Remove assertion. * mailbox/mailbox.c (mu_mailbox_quick_get_message): New function (mu_mailbox_sync): New function (mu_mailbox_get_size): Implement brute-force approach in case the mailbox does not provide a method. * mailbox/message.c (mu_message_get_qid, mu_message_set_qid): New function. * maildag/: New directory. A general-purpose mail delivery agent. * maildag/deliver.c: New file. * maildag/lmtp.c: New file. * maildag/maidag.c: New file. * maildag/maidag.h: New file. * maildag/mailtmp.c: New file. * maildag/mailquota.c: New file. * maildag/script.c: New file. * maildag/util.c: New file. * maildag/Makefile.am: New file. * maildag/.cvsignore: New file.
Showing
59 changed files
with
1784 additions
and
197 deletions
1 | 2007-11-10 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | * Makefile.am, configure.ac: Add maidag. | ||
4 | * frm/common.c, imap4d/sync.c, libsieve/runtime.c, | ||
5 | mh/scan.c: Update declaration of observable actions. | ||
6 | * imap4d/select.c, imap4d/status.c, mh/anno.c, mh/forw.c, | ||
7 | mh/repl.c: Use mu_mailbox_sync instead of | ||
8 | mu_mailbox_save_attributes. | ||
9 | * include/mailutils/mailbox.h (mu_mailbox_sync): New function | ||
10 | (mu_mailbox_save_attributes): Deprecated. | ||
11 | * include/mailutils/message.h (mu_message_get_qid) | ||
12 | (mu_message_set_qid): New functions. | ||
13 | * include/mailutils/observer.h (MU_EVT_MESSAGE_APPEND): New event. | ||
14 | (mu_observer_set_action_data): New function. Registers | ||
15 | action-specific data. | ||
16 | (mu_observable_notify): Get call-specific data as the third | ||
17 | argument. | ||
18 | * include/mailutils/types.hin (mu_message_qid_t): New data type. | ||
19 | * libproto/imap/folder.c, libproto/imap/mbox.c, | ||
20 | libproto/include/amd.h, libproto/maildir/mbox.c, | ||
21 | libproto/mailer/sendmail.c, libproto/mailer/smtp.c, | ||
22 | libproto/mbox/mboxscan.c, libproto/mh/mbox.c, | ||
23 | libproto/nntp/mbox.c, libproto/pop/mbox.c, mailbox/folder.c, | ||
24 | mailbox/mailer.c : Update calls to mu_observable_notify. | ||
25 | * libproto/include/mailbox0.h (struct _mu_mailbox): Rename | ||
26 | _save_attributes to _sync. | ||
27 | * mailbox/amd.c: Likewise. | ||
28 | (_quick_get_message): New member. | ||
29 | (MAILBOX_NOTIFY): Remove. | ||
30 | * libproto/include/message0.h (struct _mu_message): New member | ||
31 | _get_qid. | ||
32 | * libproto/include/observer0.h (struct _mu_observer): New member | ||
33 | _action_data. | ||
34 | * libproto/mbox/mbox.c: Implement mbox_message_qid. Update calls | ||
35 | to mu_observable_notify. | ||
36 | (mbox_append_message): Report MU_EVT_MESSAGE_APPEND. | ||
37 | * mailbox/observer.c (mu_observer_destroy): Call _destroy with | ||
38 | _action_data as its third argument. | ||
39 | (mu_observer_action, mu_observable_notify): Takes third argument | ||
40 | (call data) | ||
41 | (mu_observer_set_action, mu_observer_set_destroy): Update signature. | ||
42 | (mu_observer_set_action_data): New function. | ||
43 | |||
44 | * libproto/mbox/mbox0.h, mail.local/main.c: Minor change | ||
45 | |||
46 | * mail.local/Makefile.am (mail_local_LDADD): Add MU_LIB_MAILER | ||
47 | |||
48 | * mailbox/file_stream.c (_file_open): Fix handling of | ||
49 | MU_STREAM_APPEND. Remove assertion. | ||
50 | |||
51 | * mailbox/mailbox.c (mu_mailbox_quick_get_message): New function | ||
52 | (mu_mailbox_sync): New function. | ||
53 | (mu_mailbox_get_size): Implement brute-force approach in case the | ||
54 | mailbox does not provide a method. | ||
55 | |||
56 | * mailbox/message.c (mu_message_get_qid, mu_message_set_qid): New | ||
57 | function. | ||
58 | |||
59 | * maildag/: New directory. A general-purpose mail delivery agent. | ||
60 | * maildag/deliver.c: New file. | ||
61 | * maildag/lmtp.c: New file. | ||
62 | * maildag/maidag.c: New file. | ||
63 | * maildag/maidag.h: New file. | ||
64 | * maildag/mailtmp.c: New file. | ||
65 | * maildag/mailquota.c: New file. | ||
66 | * maildag/script.c: New file. | ||
67 | * maildag/util.c: New file. | ||
68 | * maildag/Makefile.am: New file. | ||
69 | * maildag/.cvsignore: New file. | ||
70 | |||
1 | 2007-11-08 Sergey Poznyakoff <gray@gnu.org.ua> | 71 | 2007-11-08 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 72 | ||
3 | * mailbox/cfg_lexer.c: Do not use obstack. | 73 | * mailbox/cfg_lexer.c: Do not use obstack. | ... | ... |
... | @@ -1169,6 +1169,7 @@ AC_CONFIG_FILES([Makefile | ... | @@ -1169,6 +1169,7 @@ AC_CONFIG_FILES([Makefile |
1169 | libproto/include/Makefile | 1169 | libproto/include/Makefile |
1170 | libsieve/Makefile | 1170 | libsieve/Makefile |
1171 | libsieve/extensions/Makefile | 1171 | libsieve/extensions/Makefile |
1172 | maidag/Makefile | ||
1172 | mail/Makefile | 1173 | mail/Makefile |
1173 | mail/testsuite/Makefile | 1174 | mail/testsuite/Makefile |
1174 | mail.local/Makefile | 1175 | mail.local/Makefile | ... | ... |
... | @@ -421,7 +421,7 @@ static size_t msg_index; /* Index (1-based) of the current | ... | @@ -421,7 +421,7 @@ static size_t msg_index; /* Index (1-based) of the current |
421 | /* Observable action is being called on discovery of each message. */ | 421 | /* Observable action is being called on discovery of each message. */ |
422 | /* FIXME: The format of the display is poorly done, please correct. */ | 422 | /* FIXME: The format of the display is poorly done, please correct. */ |
423 | static int | 423 | static int |
424 | action (mu_observer_t o, size_t type) | 424 | action (mu_observer_t o, size_t type, void *data, void *action_data) |
425 | { | 425 | { |
426 | int status; | 426 | int status; |
427 | 427 | ... | ... |
... | @@ -49,7 +49,7 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags) | ... | @@ -49,7 +49,7 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags) |
49 | currently selected mailbox without doing an expunge. */ | 49 | currently selected mailbox without doing an expunge. */ |
50 | if (mbox) | 50 | if (mbox) |
51 | { | 51 | { |
52 | mu_mailbox_save_attributes (mbox); | 52 | mu_mailbox_sync (mbox); |
53 | mu_mailbox_close (mbox); | 53 | mu_mailbox_close (mbox); |
54 | mu_mailbox_destroy (&mbox); | 54 | mu_mailbox_destroy (&mbox); |
55 | /* Destroy the old uid table. */ | 55 | /* Destroy the old uid table. */ | ... | ... |
... | @@ -77,7 +77,7 @@ imap4d_status (struct imap4d_command *command, char *arg) | ... | @@ -77,7 +77,7 @@ imap4d_status (struct imap4d_command *command, char *arg) |
77 | 77 | ||
78 | /* We may be opening the current mailbox, so make sure the attributes are | 78 | /* We may be opening the current mailbox, so make sure the attributes are |
79 | preserved */ | 79 | preserved */ |
80 | mu_mailbox_save_attributes (mbox); | 80 | mu_mailbox_sync (mbox); |
81 | 81 | ||
82 | status = mu_mailbox_create_default (&smbox, mailbox_name); | 82 | status = mu_mailbox_create_default (&smbox, mailbox_name); |
83 | if (status == 0) | 83 | if (status == 0) | ... | ... |
... | @@ -276,7 +276,7 @@ imap4d_sync_flags (size_t msgno) | ... | @@ -276,7 +276,7 @@ imap4d_sync_flags (size_t msgno) |
276 | static int mailbox_corrupt; | 276 | static int mailbox_corrupt; |
277 | 277 | ||
278 | static int | 278 | static int |
279 | action (mu_observer_t observer, size_t type) | 279 | action (mu_observer_t observer, size_t type, void *data, void *action_data) |
280 | { | 280 | { |
281 | switch (type) | 281 | switch (type) |
282 | { | 282 | { | ... | ... |
... | @@ -52,13 +52,18 @@ extern int mu_mailbox_uidvalidity (mu_mailbox_t, unsigned long *); | ... | @@ -52,13 +52,18 @@ extern int mu_mailbox_uidvalidity (mu_mailbox_t, unsigned long *); |
52 | extern int mu_mailbox_uidnext (mu_mailbox_t, size_t *); | 52 | extern int mu_mailbox_uidnext (mu_mailbox_t, size_t *); |
53 | 53 | ||
54 | /* Messages. */ | 54 | /* Messages. */ |
55 | extern int mu_mailbox_get_message (mu_mailbox_t, size_t msgno, mu_message_t *); | 55 | extern int mu_mailbox_get_message (mu_mailbox_t, size_t msgno, |
56 | mu_message_t *); | ||
57 | extern int mu_mailbox_quick_get_message(mu_mailbox_t, mu_message_qid_t, | ||
58 | mu_message_t *); | ||
56 | extern int mu_mailbox_append_message (mu_mailbox_t, mu_message_t); | 59 | extern int mu_mailbox_append_message (mu_mailbox_t, mu_message_t); |
57 | extern int mu_mailbox_messages_count (mu_mailbox_t, size_t *); | 60 | extern int mu_mailbox_messages_count (mu_mailbox_t, size_t *); |
58 | extern int mu_mailbox_messages_recent (mu_mailbox_t, size_t *); | 61 | extern int mu_mailbox_messages_recent (mu_mailbox_t, size_t *); |
59 | extern int mu_mailbox_message_unseen (mu_mailbox_t, size_t *); | 62 | extern int mu_mailbox_message_unseen (mu_mailbox_t, size_t *); |
60 | extern int mu_mailbox_expunge (mu_mailbox_t); | 63 | extern int mu_mailbox_expunge (mu_mailbox_t); |
61 | extern int mu_mailbox_save_attributes (mu_mailbox_t); | 64 | extern int mu_mailbox_sync (mu_mailbox_t); |
65 | extern int mu_mailbox_save_attributes (mu_mailbox_t) | ||
66 | __attribute__ ((deprecated)); | ||
62 | 67 | ||
63 | /* Update and scanning. */ | 68 | /* Update and scanning. */ |
64 | extern int mu_mailbox_get_size (mu_mailbox_t, mu_off_t *size); | 69 | extern int mu_mailbox_get_size (mu_mailbox_t, mu_off_t *size); | ... | ... |
... | @@ -29,89 +29,102 @@ extern "C" { | ... | @@ -29,89 +29,102 @@ extern "C" { |
29 | /* A message is considered to be a container for: | 29 | /* A message is considered to be a container for: |
30 | mu_header_t, mu_body_t, and its mu_attribute_t. */ | 30 | mu_header_t, mu_body_t, and its mu_attribute_t. */ |
31 | 31 | ||
32 | extern int mu_message_create (mu_message_t *, void *owner); | 32 | extern int mu_message_create (mu_message_t *, void *owner); |
33 | extern void mu_message_destroy (mu_message_t *, void *owner); | 33 | extern void mu_message_destroy (mu_message_t *, void *owner); |
34 | 34 | ||
35 | extern int mu_message_create_copy (mu_message_t *to, mu_message_t from); | 35 | extern int mu_message_create_copy (mu_message_t *to, mu_message_t from); |
36 | 36 | ||
37 | extern void * mu_message_get_owner (mu_message_t); | 37 | extern void * mu_message_get_owner (mu_message_t); |
38 | extern int mu_message_is_modified (mu_message_t); | 38 | extern int mu_message_is_modified (mu_message_t); |
39 | extern int mu_message_clear_modified (mu_message_t); | 39 | extern int mu_message_clear_modified (mu_message_t); |
40 | extern int mu_message_get_mailbox (mu_message_t, mu_mailbox_t *); | 40 | extern int mu_message_get_mailbox (mu_message_t, mu_mailbox_t *); |
41 | extern int mu_message_set_mailbox (mu_message_t, mu_mailbox_t, void *); | 41 | extern int mu_message_set_mailbox (mu_message_t, mu_mailbox_t, void *); |
42 | 42 | ||
43 | extern int mu_message_ref (mu_message_t); | 43 | extern int mu_message_ref (mu_message_t); |
44 | #define mu_message_unref(msg) mu_message_destroy (&msg, NULL) | 44 | #define mu_message_unref(msg) mu_message_destroy (&msg, NULL) |
45 | 45 | ||
46 | extern int mu_message_get_envelope (mu_message_t, mu_envelope_t *); | 46 | extern int mu_message_get_envelope (mu_message_t, mu_envelope_t *); |
47 | extern int mu_message_set_envelope (mu_message_t, mu_envelope_t, void *); | 47 | extern int mu_message_set_envelope (mu_message_t, mu_envelope_t, void *); |
48 | 48 | ||
49 | extern int mu_message_get_header (mu_message_t, mu_header_t *); | 49 | extern int mu_message_get_header (mu_message_t, mu_header_t *); |
50 | extern int mu_message_set_header (mu_message_t, mu_header_t, void *); | 50 | extern int mu_message_set_header (mu_message_t, mu_header_t, void *); |
51 | 51 | ||
52 | extern int mu_message_get_body (mu_message_t, mu_body_t *); | 52 | extern int mu_message_get_body (mu_message_t, mu_body_t *); |
53 | extern int mu_message_set_body (mu_message_t, mu_body_t, void *); | 53 | extern int mu_message_set_body (mu_message_t, mu_body_t, void *); |
54 | 54 | ||
55 | extern int mu_message_get_stream (mu_message_t, mu_stream_t *); | 55 | extern int mu_message_get_stream (mu_message_t, mu_stream_t *); |
56 | extern int mu_message_set_stream (mu_message_t, mu_stream_t, void *); | 56 | extern int mu_message_set_stream (mu_message_t, mu_stream_t, void *); |
57 | 57 | ||
58 | extern int mu_message_get_attribute (mu_message_t, mu_attribute_t *); | 58 | extern int mu_message_get_attribute (mu_message_t, mu_attribute_t *); |
59 | extern int mu_message_set_attribute (mu_message_t, mu_attribute_t, void *); | 59 | extern int mu_message_set_attribute (mu_message_t, mu_attribute_t, void *); |
60 | 60 | ||
61 | extern int mu_message_get_observable (mu_message_t, mu_observable_t *); | 61 | extern int mu_message_get_observable (mu_message_t, mu_observable_t *); |
62 | 62 | ||
63 | extern int mu_message_is_multipart (mu_message_t, int *); | 63 | extern int mu_message_is_multipart (mu_message_t, int *); |
64 | extern int mu_message_set_is_multipart (mu_message_t, | 64 | extern int mu_message_set_is_multipart (mu_message_t, |
65 | int (*_is_multipart) (mu_message_t, int *), | 65 | int (*_is_multipart) (mu_message_t, |
66 | void *); | 66 | int *), |
67 | void *); | ||
67 | 68 | ||
68 | extern int mu_message_size (mu_message_t, size_t *); | 69 | extern int mu_message_size (mu_message_t, size_t *); |
69 | extern int mu_message_set_size (mu_message_t, | 70 | extern int mu_message_set_size (mu_message_t, |
70 | int (*_size) (mu_message_t, size_t *), | 71 | int (*_size) (mu_message_t, size_t *), |
71 | void *owner); | 72 | void *owner); |
72 | 73 | ||
73 | extern int mu_message_lines (mu_message_t, size_t *); | 74 | extern int mu_message_lines (mu_message_t, size_t *); |
74 | extern int mu_message_set_lines (mu_message_t, | 75 | extern int mu_message_set_lines (mu_message_t, |
75 | int (*_lines) (mu_message_t, size_t *), | 76 | int (*_lines) (mu_message_t, size_t *), |
76 | void *owner); | 77 | void *owner); |
77 | 78 | ||
78 | extern int mu_message_get_num_parts (mu_message_t, size_t *nparts); | 79 | extern int mu_message_get_num_parts (mu_message_t, size_t *nparts); |
79 | extern int mu_message_set_get_num_parts (mu_message_t, | 80 | extern int mu_message_set_get_num_parts (mu_message_t, |
80 | int (*_get_num_parts) (mu_message_t, | 81 | int (*_get_num_parts) (mu_message_t, |
81 | size_t *), | 82 | size_t *), |
82 | void *owner); | 83 | void *owner); |
83 | 84 | ||
84 | extern int mu_message_get_part (mu_message_t, size_t, mu_message_t *); | 85 | extern int mu_message_get_part (mu_message_t, size_t, mu_message_t *); |
85 | extern int mu_message_set_get_part (mu_message_t, | 86 | extern int mu_message_set_get_part (mu_message_t, |
86 | int (*_get_part) (mu_message_t, size_t, | 87 | int (*_get_part) (mu_message_t, size_t, |
87 | mu_message_t *), | 88 | mu_message_t *), |
88 | void *owner); | 89 | void *owner); |
89 | 90 | ||
90 | extern int mu_message_get_uidl (mu_message_t, char *, size_t, size_t *); | 91 | extern int mu_message_get_uidl (mu_message_t, char *, size_t, size_t *); |
91 | extern int mu_message_set_uidl (mu_message_t, | 92 | extern int mu_message_set_uidl (mu_message_t, |
92 | int (*_get_uidl) (mu_message_t, char *, | 93 | int (*_get_uidl) (mu_message_t, |
93 | size_t, size_t *), | 94 | char *, |
94 | void *owner); | 95 | size_t, size_t *), |
95 | extern int mu_message_get_uid (mu_message_t, size_t *); | 96 | void *owner); |
96 | extern int mu_message_set_uid (mu_message_t, | 97 | |
97 | int (*_get_uid) (mu_message_t, size_t *), | 98 | extern int mu_message_get_uid (mu_message_t, size_t *); |
98 | void *owner); | 99 | extern int mu_message_set_uid (mu_message_t, |
99 | 100 | int (*_get_uid) (mu_message_t, | |
101 | size_t *), | ||
102 | void *owner); | ||
103 | |||
104 | extern int mu_message_get_qid (mu_message_t, mu_message_qid_t *); | ||
105 | extern int mu_message_set_qid (mu_message_t, | ||
106 | int (*_get_qid) (mu_message_t, | ||
107 | mu_message_qid_t *), | ||
108 | void *owner); | ||
109 | |||
100 | /* misc functions */ | 110 | /* misc functions */ |
101 | extern int mu_message_create_attachment (const char *content_type, | 111 | extern int mu_message_create_attachment (const char *content_type, |
102 | const char *encoding, | 112 | const char *encoding, |
103 | const char *filename, | 113 | const char *filename, |
104 | mu_message_t *newmsg); | 114 | mu_message_t *newmsg); |
105 | extern int mu_message_save_attachment (mu_message_t msg, | 115 | extern int mu_message_save_attachment (mu_message_t msg, |
106 | const char *filename, void **data); | 116 | const char *filename, void **data); |
107 | extern int mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, void **data); | 117 | extern int mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, |
108 | extern int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, void **data); | 118 | void **data); |
109 | 119 | extern int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, | |
110 | extern int mu_message_get_attachment_name (mu_message_t, char *name, size_t bufsz, size_t* sz); | 120 | void **data); |
121 | |||
122 | extern int mu_message_get_attachment_name (mu_message_t, char *name, | ||
123 | size_t bufsz, size_t* sz); | ||
111 | extern int mu_message_aget_attachment_name (mu_message_t, char **name); | 124 | extern int mu_message_aget_attachment_name (mu_message_t, char **name); |
112 | 125 | ||
113 | extern int mu_message_save_to_mailbox (mu_message_t msg, mu_ticket_t ticket, | 126 | extern int mu_message_save_to_mailbox (mu_message_t msg, mu_ticket_t ticket, |
114 | mu_debug_t debug, const char *toname); | 127 | mu_debug_t debug, const char *toname); |
115 | 128 | ||
116 | 129 | ||
117 | extern int mu_stream_to_message (mu_stream_t instream, mu_message_t *pmsg); | 130 | extern int mu_stream_to_message (mu_stream_t instream, mu_message_t *pmsg); | ... | ... |
... | @@ -24,36 +24,42 @@ | ... | @@ -24,36 +24,42 @@ |
24 | #ifdef __cplusplus | 24 | #ifdef __cplusplus |
25 | extern "C" { | 25 | extern "C" { |
26 | #endif | 26 | #endif |
27 | 27 | /* Call data type: */ | |
28 | #define MU_EVT_MAILBOX_DESTROY 0x001 | 28 | #define MU_EVT_MAILBOX_DESTROY 0x001 /* mu_mailbox_t */ |
29 | #define MU_EVT_FOLDER_DESTROY 0x002 | 29 | #define MU_EVT_FOLDER_DESTROY 0x002 /* mu_folder_t */ |
30 | #define MU_EVT_MAILER_DESTROY 0x004 | 30 | #define MU_EVT_MAILER_DESTROY 0x004 /* mu_mailer_t */ |
31 | #define MU_EVT_MESSAGE_DESTROY 0x008 | 31 | #define MU_EVT_MESSAGE_DESTROY 0x008 /* mu_message_t */ |
32 | #define MU_EVT_MESSAGE_ADD 0x010 | 32 | #define MU_EVT_MESSAGE_ADD 0x010 /* size_t *: FIXME */ |
33 | #define MU_EVT_MAILBOX_PROGRESS 0x020 | 33 | #define MU_EVT_MAILBOX_PROGRESS 0x020 /* NULL: FIXME? */ |
34 | #define MU_EVT_AUTHORITY_FAILED 0x030 | 34 | #define MU_EVT_AUTHORITY_FAILED 0x030 /* NULL */ |
35 | #define MU_EVT_MAILBOX_CORRUPT 0x040 | 35 | #define MU_EVT_MAILBOX_CORRUPT 0x040 /* mu_mailbox_t */ |
36 | #define MU_EVT_MAILER_MESSAGE_SENT 0x080 | 36 | #define MU_EVT_MAILER_MESSAGE_SENT 0x080 /* mu_message_t */ |
37 | 37 | #define MU_EVT_MESSAGE_APPEND 0x100 /* mu_message_qid_t: FIXME */ | |
38 | |||
38 | #define MU_OBSERVER_NO_CHECK 1 | 39 | #define MU_OBSERVER_NO_CHECK 1 |
39 | 40 | ||
40 | extern int mu_observer_create (mu_observer_t *, void *owner); | 41 | extern int mu_observer_create (mu_observer_t *, void *owner); |
41 | extern void mu_observer_destroy (mu_observer_t *, void *owner); | 42 | extern void mu_observer_destroy (mu_observer_t *, void *owner); |
42 | extern void * mu_observer_get_owner (mu_observer_t); | 43 | extern void * mu_observer_get_owner(mu_observer_t); |
43 | extern int mu_observer_action (mu_observer_t, size_t type); | 44 | extern int mu_observer_action (mu_observer_t, size_t type, void *data); |
44 | extern int mu_observer_set_action (mu_observer_t, | 45 | extern int mu_observer_set_action (mu_observer_t, |
45 | int (*_action) (mu_observer_t, size_t), | 46 | int (*_action) (mu_observer_t, |
46 | void *owner); | 47 | size_t, void *, void *), |
48 | void *owner); | ||
49 | extern int mu_observer_set_action_data (mu_observer_t, void *data, | ||
50 | void *owner); | ||
47 | extern int mu_observer_set_destroy (mu_observer_t, | 51 | extern int mu_observer_set_destroy (mu_observer_t, |
48 | int (*_destroy) (mu_observer_t), void *owner); | 52 | int (*_destroy) (mu_observer_t, void *), |
53 | void *owner); | ||
49 | extern int mu_observer_set_flags (mu_observer_t, int flags); | 54 | extern int mu_observer_set_flags (mu_observer_t, int flags); |
50 | 55 | ||
51 | extern int mu_observable_create (mu_observable_t *, void *owner); | 56 | extern int mu_observable_create (mu_observable_t *, void *owner); |
52 | extern void mu_observable_destroy (mu_observable_t *, void *owner); | 57 | extern void mu_observable_destroy (mu_observable_t *, void *owner); |
53 | extern void * mu_observable_get_owner (mu_observable_t); | 58 | extern void * mu_observable_get_owner (mu_observable_t); |
54 | extern int mu_observable_attach (mu_observable_t, size_t type, mu_observer_t observer); | 59 | extern int mu_observable_attach (mu_observable_t, size_t type, |
60 | mu_observer_t observer); | ||
55 | extern int mu_observable_detach (mu_observable_t, mu_observer_t observer); | 61 | extern int mu_observable_detach (mu_observable_t, mu_observer_t observer); |
56 | extern int mu_observable_notify (mu_observable_t, int type); | 62 | extern int mu_observable_notify (mu_observable_t, int type, void *data); |
57 | 63 | ||
58 | #ifdef __cplusplus | 64 | #ifdef __cplusplus |
59 | } | 65 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail -*- c -*- |
2 | Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This library is free software; you can redistribute it and/or | 4 | This library is free software; you can redistribute it and/or |
... | @@ -99,6 +99,7 @@ typedef struct _mu_url *mu_url_t; | ... | @@ -99,6 +99,7 @@ typedef struct _mu_url *mu_url_t; |
99 | typedef struct _mu_wicket *mu_wicket_t; | 99 | typedef struct _mu_wicket *mu_wicket_t; |
100 | typedef void *mu_transport_t; | 100 | typedef void *mu_transport_t; |
101 | typedef struct _mu_assoc *mu_assoc_t; | 101 | typedef struct _mu_assoc *mu_assoc_t; |
102 | typedef char *mu_message_qid_t; | ||
102 | 103 | ||
103 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 | 104 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 |
104 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | 105 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | ... | ... |
... | @@ -2527,7 +2527,8 @@ imap_parse (f_imap_t f_imap) | ... | @@ -2527,7 +2527,8 @@ imap_parse (f_imap_t f_imap) |
2527 | { | 2527 | { |
2528 | mu_observable_t observable = NULL; | 2528 | mu_observable_t observable = NULL; |
2529 | mu_folder_get_observable (f_imap->folder, &observable); | 2529 | mu_folder_get_observable (f_imap->folder, &observable); |
2530 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED); | 2530 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED, |
2531 | NULL); | ||
2531 | status = MU_ERR_AUTH_FAILURE; | 2532 | status = MU_ERR_AUTH_FAILURE; |
2532 | } | 2533 | } |
2533 | else if (strncasecmp (remainder, "LIST", 4) == 0) | 2534 | else if (strncasecmp (remainder, "LIST", 4) == 0) | ... | ... |
... | @@ -798,12 +798,13 @@ imap_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int notif) | ... | @@ -798,12 +798,13 @@ imap_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int notif) |
798 | 798 | ||
799 | for (i = msgno; i <= count; i++) | 799 | for (i = msgno; i <= count; i++) |
800 | { | 800 | { |
801 | if (mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0) | 801 | size_t tmp = i; |
802 | if (mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD, | ||
803 | &tmp) != 0) | ||
802 | break; | 804 | break; |
803 | if (((i + 1) % 100) == 0) | 805 | if ((i + 1) % 100 == 0) |
804 | { | 806 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS, |
805 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS); | 807 | NULL); |
806 | } | ||
807 | } | 808 | } |
808 | return 0; | 809 | return 0; |
809 | } | 810 | } | ... | ... |
... | @@ -20,13 +20,17 @@ | ... | @@ -20,13 +20,17 @@ |
20 | #define MAX_OPEN_STREAMS 16 | 20 | #define MAX_OPEN_STREAMS 16 |
21 | 21 | ||
22 | /* Notifications ADD_MESG. */ | 22 | /* Notifications ADD_MESG. */ |
23 | #define DISPATCH_ADD_MSG(mbox,mhd) \ | 23 | #define DISPATCH_ADD_MSG(mbox,mhd,n) \ |
24 | do \ | 24 | do \ |
25 | { \ | 25 | { \ |
26 | int bailing = 0; \ | 26 | int bailing = 0; \ |
27 | mu_monitor_unlock (mbox->monitor); \ | 27 | mu_monitor_unlock (mbox->monitor); \ |
28 | if (mbox->observable) \ | 28 | if (mbox->observable) \ |
29 | bailing = mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD); \ | 29 | { \ |
30 | size_t tmp = (n); \ | ||
31 | bailing = mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD, \ | ||
32 | &tmp); \ | ||
33 | } \ | ||
30 | if (bailing != 0) \ | 34 | if (bailing != 0) \ |
31 | { \ | 35 | { \ |
32 | if (pcount) \ | 36 | if (pcount) \ | ... | ... |
... | @@ -55,7 +55,7 @@ struct _mu_mailbox | ... | @@ -55,7 +55,7 @@ struct _mu_mailbox |
55 | 55 | ||
56 | int (*_open) (mu_mailbox_t, int); | 56 | int (*_open) (mu_mailbox_t, int); |
57 | int (*_close) (mu_mailbox_t); | 57 | int (*_close) (mu_mailbox_t); |
58 | 58 | ||
59 | /* messages */ | 59 | /* messages */ |
60 | int (*_get_message) (mu_mailbox_t, size_t, mu_message_t *); | 60 | int (*_get_message) (mu_mailbox_t, size_t, mu_message_t *); |
61 | int (*_append_message) (mu_mailbox_t, mu_message_t); | 61 | int (*_append_message) (mu_mailbox_t, mu_message_t); |
... | @@ -63,7 +63,7 @@ struct _mu_mailbox | ... | @@ -63,7 +63,7 @@ struct _mu_mailbox |
63 | int (*_messages_recent) (mu_mailbox_t, size_t *); | 63 | int (*_messages_recent) (mu_mailbox_t, size_t *); |
64 | int (*_message_unseen) (mu_mailbox_t, size_t *); | 64 | int (*_message_unseen) (mu_mailbox_t, size_t *); |
65 | int (*_expunge) (mu_mailbox_t); | 65 | int (*_expunge) (mu_mailbox_t); |
66 | int (*_save_attributes) (mu_mailbox_t); | 66 | int (*_sync) (mu_mailbox_t); |
67 | int (*_uidvalidity) (mu_mailbox_t, unsigned long *); | 67 | int (*_uidvalidity) (mu_mailbox_t, unsigned long *); |
68 | int (*_uidnext) (mu_mailbox_t, size_t *); | 68 | int (*_uidnext) (mu_mailbox_t, size_t *); |
69 | int (*_get_property) (mu_mailbox_t, mu_property_t *); | 69 | int (*_get_property) (mu_mailbox_t, mu_property_t *); |
... | @@ -73,11 +73,9 @@ struct _mu_mailbox | ... | @@ -73,11 +73,9 @@ struct _mu_mailbox |
73 | 73 | ||
74 | int (*_get_size) (mu_mailbox_t, mu_off_t *); | 74 | int (*_get_size) (mu_mailbox_t, mu_off_t *); |
75 | 75 | ||
76 | int (*_quick_get_message) (mu_mailbox_t, mu_message_qid_t, mu_message_t *); | ||
76 | }; | 77 | }; |
77 | 78 | ||
78 | #define MAILBOX_NOTIFY(mbox, type) \ | ||
79 | if (mbox->observer) observer_notify (mbox->observer, type) | ||
80 | |||
81 | /* Moro(?)ic kluge. */ | 79 | /* Moro(?)ic kluge. */ |
82 | #define MAILBOX_DEBUG0(mbox, type, format) \ | 80 | #define MAILBOX_DEBUG0(mbox, type, format) \ |
83 | if (mbox->debug) mu_debug_print (mbox->debug, type, format) | 81 | if (mbox->debug) mu_debug_print (mbox->debug, type, format) | ... | ... |
... | @@ -60,6 +60,7 @@ struct _mu_message | ... | @@ -60,6 +60,7 @@ struct _mu_message |
60 | 60 | ||
61 | int (*_get_uidl) (mu_message_t, char *, size_t, size_t *); | 61 | int (*_get_uidl) (mu_message_t, char *, size_t, size_t *); |
62 | int (*_get_uid) (mu_message_t, size_t *); | 62 | int (*_get_uid) (mu_message_t, size_t *); |
63 | int (*_get_qid) (mu_message_t, mu_message_qid_t *); | ||
63 | int (*_get_num_parts) (mu_message_t, size_t *); | 64 | int (*_get_num_parts) (mu_message_t, size_t *); |
64 | int (*_get_part) (mu_message_t, size_t, mu_message_t *); | 65 | int (*_get_part) (mu_message_t, size_t, mu_message_t *); |
65 | int (*_is_multipart) (mu_message_t, int *); | 66 | int (*_is_multipart) (mu_message_t, int *); | ... | ... |
... | @@ -33,8 +33,9 @@ struct _mu_observer | ... | @@ -33,8 +33,9 @@ struct _mu_observer |
33 | { | 33 | { |
34 | int flags; | 34 | int flags; |
35 | void *owner; | 35 | void *owner; |
36 | int (*_action) (mu_observer_t, size_t); | 36 | int (*_action) (mu_observer_t, size_t, void *, void *); |
37 | int (*_destroy) (mu_observer_t); | 37 | void *_action_data; |
38 | int (*_destroy) (mu_observer_t, void *data); | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | struct _mu_observable | 41 | struct _mu_observable | ... | ... |
... | @@ -623,7 +623,7 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, | ... | @@ -623,7 +623,7 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, |
623 | size_t i; | 623 | size_t i; |
624 | for (i = 0; i < amd->msg_count; i++) | 624 | for (i = 0; i < amd->msg_count; i++) |
625 | { | 625 | { |
626 | DISPATCH_ADD_MSG(mailbox, amd); | 626 | DISPATCH_ADD_MSG(mailbox, amd, i); |
627 | } | 627 | } |
628 | } | 628 | } |
629 | 629 | ... | ... |
... | @@ -443,7 +443,8 @@ sendmail_send_message (mu_mailer_t mailer, mu_message_t msg, mu_address_t from, | ... | @@ -443,7 +443,8 @@ sendmail_send_message (mu_mailer_t mailer, mu_message_t msg, mu_address_t from, |
443 | status = MU_ERR_PROCESS_UNKNOWN_FAILURE; | 443 | status = MU_ERR_PROCESS_UNKNOWN_FAILURE; |
444 | 444 | ||
445 | /* Shouldn't this notification only happen on success? */ | 445 | /* Shouldn't this notification only happen on success? */ |
446 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT); | 446 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT, |
447 | msg); | ||
447 | } | 448 | } |
448 | default: | 449 | default: |
449 | break; | 450 | break; | ... | ... |
... | @@ -870,7 +870,8 @@ smtp_send_message (mu_mailer_t mailer, mu_message_t argmsg, mu_address_t argfrom | ... | @@ -870,7 +870,8 @@ smtp_send_message (mu_mailer_t mailer, mu_message_t argmsg, mu_address_t argfrom |
870 | if (smtp->rcpt_index <= smtp->rcpt_bcc_count) | 870 | if (smtp->rcpt_index <= smtp->rcpt_bcc_count) |
871 | goto ENV_FROM; | 871 | goto ENV_FROM; |
872 | 872 | ||
873 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT); | 873 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT, |
874 | argmsg); | ||
874 | 875 | ||
875 | default: | 876 | default: |
876 | break; | 877 | break; | ... | ... |
... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #include <mbox0.h> | 26 | #include <mbox0.h> |
27 | #include <mu_umaxtostr.h> | ||
27 | 28 | ||
28 | #define ATTRIBUTE_IS_DELETED(flag) (flag & MU_ATTRIBUTE_DELETED) | 29 | #define ATTRIBUTE_IS_DELETED(flag) (flag & MU_ATTRIBUTE_DELETED) |
29 | #define ATTRIBUTE_IS_EQUAL(flag1, flag2) (flag1 == flag2) | 30 | #define ATTRIBUTE_IS_EQUAL(flag1, flag2) (flag1 == flag2) |
... | @@ -41,7 +42,7 @@ static int mbox_messages_recent (mu_mailbox_t, size_t *); | ... | @@ -41,7 +42,7 @@ static int mbox_messages_recent (mu_mailbox_t, size_t *); |
41 | static int mbox_message_unseen (mu_mailbox_t, size_t *); | 42 | static int mbox_message_unseen (mu_mailbox_t, size_t *); |
42 | static int mbox_expunge0 (mu_mailbox_t, int); | 43 | static int mbox_expunge0 (mu_mailbox_t, int); |
43 | static int mbox_expunge (mu_mailbox_t); | 44 | static int mbox_expunge (mu_mailbox_t); |
44 | static int mbox_save_attributes (mu_mailbox_t); | 45 | static int mbox_sync (mu_mailbox_t); |
45 | static int mbox_uidvalidity (mu_mailbox_t, unsigned long *); | 46 | static int mbox_uidvalidity (mu_mailbox_t, unsigned long *); |
46 | static int mbox_uidnext (mu_mailbox_t, size_t *); | 47 | static int mbox_uidnext (mu_mailbox_t, size_t *); |
47 | static int mbox_scan (mu_mailbox_t, size_t, size_t *); | 48 | static int mbox_scan (mu_mailbox_t, size_t, size_t *); |
... | @@ -49,24 +50,35 @@ static int mbox_is_updated (mu_mailbox_t); | ... | @@ -49,24 +50,35 @@ static int mbox_is_updated (mu_mailbox_t); |
49 | static int mbox_get_size (mu_mailbox_t, mu_off_t *); | 50 | static int mbox_get_size (mu_mailbox_t, mu_off_t *); |
50 | 51 | ||
51 | /* private stuff */ | 52 | /* private stuff */ |
52 | static int mbox_append_message0 (mu_mailbox_t, mu_message_t, mu_off_t *, int, int); | 53 | static int mbox_append_message0 (mu_mailbox_t, mu_message_t, |
54 | mu_off_t *, int, int); | ||
53 | static int mbox_message_uid (mu_message_t, size_t *); | 55 | static int mbox_message_uid (mu_message_t, size_t *); |
54 | static int mbox_header_fill (mu_header_t, char *, size_t, mu_off_t, size_t *); | 56 | static int mbox_message_qid (mu_message_t, mu_message_qid_t *); |
55 | static int mbox_get_body_transport (mu_stream_t, mu_transport_t *, mu_transport_t *); | 57 | |
56 | static int mbox_get_transport2 (mbox_message_t, mu_transport_t *, mu_transport_t *); | 58 | static int mbox_header_fill (mu_header_t, char *, size_t, |
59 | mu_off_t, size_t *); | ||
60 | static int mbox_get_body_transport (mu_stream_t, mu_transport_t *, | ||
61 | mu_transport_t *); | ||
62 | static int mbox_get_transport2 (mbox_message_t, mu_transport_t *, | ||
63 | mu_transport_t *); | ||
57 | static int mbox_get_attr_flags (mu_attribute_t, int *); | 64 | static int mbox_get_attr_flags (mu_attribute_t, int *); |
58 | static int mbox_set_attr_flags (mu_attribute_t, int); | 65 | static int mbox_set_attr_flags (mu_attribute_t, int); |
59 | static int mbox_unset_attr_flags (mu_attribute_t, int); | 66 | static int mbox_unset_attr_flags (mu_attribute_t, int); |
60 | static int mbox_body_read (mu_stream_t, char *, size_t, mu_off_t, size_t *); | 67 | static int mbox_body_read (mu_stream_t, char *, size_t, |
61 | static int mbox_body_readline (mu_stream_t, char *, size_t, mu_off_t, size_t *); | 68 | mu_off_t, size_t *); |
69 | static int mbox_body_readline (mu_stream_t, char *, size_t, | ||
70 | mu_off_t, size_t *); | ||
62 | static int mbox_readstream (mbox_message_t, char *, size_t, | 71 | static int mbox_readstream (mbox_message_t, char *, size_t, |
63 | mu_off_t, size_t *, int, mu_off_t, mu_off_t); | 72 | mu_off_t, size_t *, int, mu_off_t, |
73 | mu_off_t); | ||
64 | static int mbox_stream_size (mu_stream_t stream, mu_off_t *psize); | 74 | static int mbox_stream_size (mu_stream_t stream, mu_off_t *psize); |
65 | 75 | ||
66 | static int mbox_body_size (mu_body_t, size_t *); | 76 | static int mbox_body_size (mu_body_t, size_t *); |
67 | static int mbox_body_lines (mu_body_t, size_t *); | 77 | static int mbox_body_lines (mu_body_t, size_t *); |
68 | static int mbox_envelope_sender (mu_envelope_t, char *, size_t, size_t *); | 78 | static int mbox_envelope_sender (mu_envelope_t, char *, size_t, |
69 | static int mbox_envelope_date (mu_envelope_t, char *, size_t, size_t *); | 79 | size_t *); |
80 | static int mbox_envelope_date (mu_envelope_t, char *, size_t, | ||
81 | size_t *); | ||
70 | static int mbox_tmpfile (mu_mailbox_t, char **pbox); | 82 | static int mbox_tmpfile (mu_mailbox_t, char **pbox); |
71 | 83 | ||
72 | /* Allocate the mbox_data_t struct(concrete mailbox), but don't do any | 84 | /* Allocate the mbox_data_t struct(concrete mailbox), but don't do any |
... | @@ -121,7 +133,7 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) | ... | @@ -121,7 +133,7 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) |
121 | mailbox->_messages_recent = mbox_messages_recent; | 133 | mailbox->_messages_recent = mbox_messages_recent; |
122 | mailbox->_message_unseen = mbox_message_unseen; | 134 | mailbox->_message_unseen = mbox_message_unseen; |
123 | mailbox->_expunge = mbox_expunge; | 135 | mailbox->_expunge = mbox_expunge; |
124 | mailbox->_save_attributes = mbox_save_attributes; | 136 | mailbox->_sync = mbox_sync; |
125 | mailbox->_uidvalidity = mbox_uidvalidity; | 137 | mailbox->_uidvalidity = mbox_uidvalidity; |
126 | mailbox->_uidnext = mbox_uidnext; | 138 | mailbox->_uidnext = mbox_uidnext; |
127 | 139 | ||
... | @@ -297,11 +309,14 @@ mbox_scan (mu_mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -297,11 +309,14 @@ mbox_scan (mu_mailbox_t mailbox, size_t msgno, size_t *pcount) |
297 | msgno--; /* The fist message is number "1", decrement for the C array. */ | 309 | msgno--; /* The fist message is number "1", decrement for the C array. */ |
298 | for (i = msgno; i < mud->messages_count; i++) | 310 | for (i = msgno; i < mud->messages_count; i++) |
299 | { | 311 | { |
300 | if (mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0) | 312 | size_t tmp = i; |
313 | if (mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD, | ||
314 | &tmp) != 0) | ||
301 | break; | 315 | break; |
302 | if (((i +1) % 50) == 0) | 316 | if (((i +1) % 50) == 0) |
303 | { | 317 | { |
304 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS); | 318 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS, |
319 | NULL); | ||
305 | } | 320 | } |
306 | } | 321 | } |
307 | *pcount = mud->messages_count; | 322 | *pcount = mud->messages_count; |
... | @@ -328,7 +343,8 @@ mbox_is_updated (mu_mailbox_t mailbox) | ... | @@ -328,7 +343,8 @@ mbox_is_updated (mu_mailbox_t mailbox) |
328 | return 1; | 343 | return 1; |
329 | if (size < mud->size) | 344 | if (size < mud->size) |
330 | { | 345 | { |
331 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT); | 346 | mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT, |
347 | mailbox); | ||
332 | /* And be verbose. ? */ | 348 | /* And be verbose. ? */ |
333 | mu_error (_("* BAD : Mailbox corrupted, shrank in size")); | 349 | mu_error (_("* BAD : Mailbox corrupted, shrank in size")); |
334 | /* FIXME: should I crash. */ | 350 | /* FIXME: should I crash. */ |
... | @@ -552,7 +568,7 @@ mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted) | ... | @@ -552,7 +568,7 @@ mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted) |
552 | if ((mum->attr_flags & MU_ATTRIBUTE_MODIFIED) || | 568 | if ((mum->attr_flags & MU_ATTRIBUTE_MODIFIED) || |
553 | (mum->message && mu_message_is_modified (mum->message))) | 569 | (mum->message && mu_message_is_modified (mum->message))) |
554 | { | 570 | { |
555 | /* The message was not instanciated, probably the dirty flag was | 571 | /* The message was not instantiated, probably the dirty flag was |
556 | set by mbox_scan(), create one here. */ | 572 | set by mbox_scan(), create one here. */ |
557 | if (mum->message == 0) | 573 | if (mum->message == 0) |
558 | { | 574 | { |
... | @@ -764,7 +780,7 @@ mbox_expunge (mu_mailbox_t mailbox) | ... | @@ -764,7 +780,7 @@ mbox_expunge (mu_mailbox_t mailbox) |
764 | } | 780 | } |
765 | 781 | ||
766 | static int | 782 | static int |
767 | mbox_save_attributes (mu_mailbox_t mailbox) | 783 | mbox_sync (mu_mailbox_t mailbox) |
768 | { | 784 | { |
769 | return mbox_expunge0 (mailbox, 0); | 785 | return mbox_expunge0 (mailbox, 0); |
770 | } | 786 | } |
... | @@ -779,6 +795,18 @@ mbox_message_uid (mu_message_t msg, size_t *puid) | ... | @@ -779,6 +795,18 @@ mbox_message_uid (mu_message_t msg, size_t *puid) |
779 | } | 795 | } |
780 | 796 | ||
781 | static int | 797 | static int |
798 | mbox_message_qid (mu_message_t msg, mu_message_qid_t *pqid) | ||
799 | { | ||
800 | mbox_message_t mum = mu_message_get_owner (msg); | ||
801 | char buf[UINTMAX_STRSIZE_BOUND]; | ||
802 | const char *p = umaxtostr (mum->header_from, buf); | ||
803 | *pqid = strdup (p); | ||
804 | if (*pqid == NULL) | ||
805 | return ENOMEM; | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static int | ||
782 | mbox_get_body_transport (mu_stream_t is, mu_transport_t *pin, | 810 | mbox_get_body_transport (mu_stream_t is, mu_transport_t *pin, |
783 | mu_transport_t *pout) | 811 | mu_transport_t *pout) |
784 | { | 812 | { |
... | @@ -1150,7 +1178,8 @@ mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -1150,7 +1178,8 @@ mbox_get_message (mu_mailbox_t mailbox, size_t msgno, mu_message_t *pmsg) |
1150 | 1178 | ||
1151 | /* Set the UID. */ | 1179 | /* Set the UID. */ |
1152 | mu_message_set_uid (msg, mbox_message_uid, mum); | 1180 | mu_message_set_uid (msg, mbox_message_uid, mum); |
1153 | 1181 | mu_message_set_qid (msg, mbox_message_qid, mum); | |
1182 | |||
1154 | /* Attach the message to the mailbox mbox data. */ | 1183 | /* Attach the message to the mailbox mbox data. */ |
1155 | mum->message = msg; | 1184 | mum->message = msg; |
1156 | mu_message_set_mailbox (msg, mailbox, mum); | 1185 | mu_message_set_mailbox (msg, mailbox, mum); |
... | @@ -1164,7 +1193,8 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -1164,7 +1193,8 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
1164 | { | 1193 | { |
1165 | int status = 0; | 1194 | int status = 0; |
1166 | mbox_data_t mud = mailbox->data; | 1195 | mbox_data_t mud = mailbox->data; |
1167 | 1196 | mu_off_t size; | |
1197 | |||
1168 | if (msg == NULL || mud == NULL) | 1198 | if (msg == NULL || mud == NULL) |
1169 | return EINVAL; | 1199 | return EINVAL; |
1170 | 1200 | ||
... | @@ -1184,7 +1214,6 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -1184,7 +1214,6 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
1184 | 1214 | ||
1185 | default: | 1215 | default: |
1186 | { | 1216 | { |
1187 | mu_off_t size; | ||
1188 | /* Move to the end of the file, not necesary if _APPEND mode. */ | 1217 | /* Move to the end of the file, not necesary if _APPEND mode. */ |
1189 | if ((status = mu_stream_size (mailbox->stream, &size)) != 0 | 1218 | if ((status = mu_stream_size (mailbox->stream, &size)) != 0 |
1190 | || (status = mbox_append_message0 (mailbox, msg, | 1219 | || (status = mbox_append_message0 (mailbox, msg, |
... | @@ -1197,6 +1226,14 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) | ... | @@ -1197,6 +1226,14 @@ mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg) |
1197 | } | 1226 | } |
1198 | } | 1227 | } |
1199 | mu_locker_unlock (mailbox->locker); | 1228 | mu_locker_unlock (mailbox->locker); |
1229 | |||
1230 | if (mailbox->observable) | ||
1231 | { | ||
1232 | char buf[UINTMAX_STRSIZE_BOUND]; | ||
1233 | mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_APPEND, | ||
1234 | umaxtostr (size, buf)); | ||
1235 | } | ||
1236 | |||
1200 | return 0; | 1237 | return 0; |
1201 | } | 1238 | } |
1202 | 1239 | ||
... | @@ -1294,10 +1331,10 @@ write_array (mu_stream_t stream, mu_off_t *poff, int count, const char **array) | ... | @@ -1294,10 +1331,10 @@ write_array (mu_stream_t stream, mu_off_t *poff, int count, const char **array) |
1294 | } | 1331 | } |
1295 | 1332 | ||
1296 | 1333 | ||
1297 | /* FIXME: We need to escape body line that begins with "From ", this | 1334 | /* FIXME: Do we need to escape body line that begins with "From "? This |
1298 | will required to read the body by line instead of by chuncks hurting | 1335 | will require reading the body line by line instead of by chunks, |
1299 | perfomance big time when expunging. But should not this be the | 1336 | considerably hurting perfomance when expunging. But should not this |
1300 | responsability of the client ? */ | 1337 | be the responsibility of the client ? */ |
1301 | static int | 1338 | static int |
1302 | mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, | 1339 | mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, |
1303 | int is_expunging, int first) | 1340 | int is_expunging, int first) |
... | @@ -1423,7 +1460,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, | ... | @@ -1423,7 +1460,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, |
1423 | do | 1460 | do |
1424 | { | 1461 | { |
1425 | status = mu_stream_readline (is, buffer, sizeof (buffer), mud->off, | 1462 | status = mu_stream_readline (is, buffer, sizeof (buffer), mud->off, |
1426 | &nread); | 1463 | &nread); |
1427 | if (status != 0) | 1464 | if (status != 0) |
1428 | { | 1465 | { |
1429 | if (status != EAGAIN) | 1466 | if (status != EAGAIN) |
... | @@ -1453,7 +1490,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, | ... | @@ -1453,7 +1490,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, |
1453 | continue; | 1490 | continue; |
1454 | 1491 | ||
1455 | status = mu_stream_write (mailbox->stream, buffer, nread, | 1492 | status = mu_stream_write (mailbox->stream, buffer, nread, |
1456 | *psize, &n); | 1493 | *psize, &n); |
1457 | if (status) | 1494 | if (status) |
1458 | break; | 1495 | break; |
1459 | *psize += n; | 1496 | *psize += n; |
... | @@ -1537,7 +1574,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, | ... | @@ -1537,7 +1574,7 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, |
1537 | do | 1574 | do |
1538 | { | 1575 | { |
1539 | status = mu_stream_read (is, buffer, sizeof (buffer), mud->off, | 1576 | status = mu_stream_read (is, buffer, sizeof (buffer), mud->off, |
1540 | &nread); | 1577 | &nread); |
1541 | if (status != 0) | 1578 | if (status != 0) |
1542 | { | 1579 | { |
1543 | if (status != EAGAIN) | 1580 | if (status != EAGAIN) | ... | ... |
... | @@ -122,7 +122,8 @@ struct _mbox_data | ... | @@ -122,7 +122,8 @@ struct _mbox_data |
122 | mu_mailbox_t mailbox; /* Back pointer. */ | 122 | mu_mailbox_t mailbox; /* Back pointer. */ |
123 | }; | 123 | }; |
124 | 124 | ||
125 | int mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif); | 125 | int mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, |
126 | int do_notif); | ||
126 | #ifdef WITH_PTHREAD | 127 | #ifdef WITH_PTHREAD |
127 | void mbox_cleanup (void *arg); | 128 | void mbox_cleanup (void *arg); |
128 | #endif | 129 | #endif | ... | ... |
... | @@ -412,7 +412,11 @@ do \ | ... | @@ -412,7 +412,11 @@ do \ |
412 | int bailing = 0; \ | 412 | int bailing = 0; \ |
413 | mu_monitor_unlock (mbox->monitor); \ | 413 | mu_monitor_unlock (mbox->monitor); \ |
414 | if (mbox->observable) \ | 414 | if (mbox->observable) \ |
415 | bailing = mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD); \ | 415 | { \ |
416 | size_t tmp = mud->messages_count + 1; \ | ||
417 | bailing = mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD, \ | ||
418 | &tmp); \ | ||
419 | } \ | ||
416 | if (bailing != 0) \ | 420 | if (bailing != 0) \ |
417 | { \ | 421 | { \ |
418 | if (pcount) \ | 422 | if (pcount) \ |
... | @@ -437,7 +441,7 @@ do \ | ... | @@ -437,7 +441,7 @@ do \ |
437 | mud->messages_count--; \ | 441 | mud->messages_count--; \ |
438 | if (mbox->observable) \ | 442 | if (mbox->observable) \ |
439 | bailing = mu_observable_notify (mbox->observable, \ | 443 | bailing = mu_observable_notify (mbox->observable, \ |
440 | MU_EVT_MAILBOX_PROGRESS); \ | 444 | MU_EVT_MAILBOX_PROGRESS, NULL); \ |
441 | if (bailing != 0) \ | 445 | if (bailing != 0) \ |
442 | { \ | 446 | { \ |
443 | if (pcount) \ | 447 | if (pcount) \ |
... | @@ -517,7 +521,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -517,7 +521,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
517 | return status; | 521 | return status; |
518 | } | 522 | } |
519 | 523 | ||
520 | if((status = mu_locker_lock (mailbox->locker))) | 524 | if ((status = mu_locker_lock (mailbox->locker))) |
521 | { | 525 | { |
522 | mu_monitor_unlock (mailbox->monitor); | 526 | mu_monitor_unlock (mailbox->monitor); |
523 | return status; | 527 | return status; |
... | @@ -540,7 +544,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -540,7 +544,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
540 | 544 | ||
541 | stream = mailbox->stream; | 545 | stream = mailbox->stream; |
542 | while ((status = mu_stream_readline (mailbox->stream, buf, sizeof (buf), | 546 | while ((status = mu_stream_readline (mailbox->stream, buf, sizeof (buf), |
543 | total, &n)) == 0 && n != 0) | 547 | total, &n)) == 0 && n != 0) |
544 | { | 548 | { |
545 | int nl; | 549 | int nl; |
546 | total += n; | 550 | total += n; |
... | @@ -577,7 +581,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -577,7 +581,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
577 | min_uid = mum->uid; | 581 | min_uid = mum->uid; |
578 | 582 | ||
579 | if (do_notif) | 583 | if (do_notif) |
580 | DISPATCH_ADD_MSG(mailbox, mud); | 584 | DISPATCH_ADD_MSG (mailbox, mud); |
581 | 585 | ||
582 | } | 586 | } |
583 | /* Allocate_msgs will initialize mum. */ | 587 | /* Allocate_msgs will initialize mum. */ |
... | @@ -640,7 +644,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -640,7 +644,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
640 | min_uid = mum->uid; | 644 | min_uid = mum->uid; |
641 | 645 | ||
642 | if (do_notif) | 646 | if (do_notif) |
643 | DISPATCH_ADD_MSG(mailbox, mud); | 647 | DISPATCH_ADD_MSG (mailbox, mud); |
644 | } | 648 | } |
645 | if (pcount) | 649 | if (pcount) |
646 | *pcount = mud->messages_count; | 650 | *pcount = mud->messages_count; | ... | ... |
... | @@ -211,7 +211,7 @@ mh_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, | ... | @@ -211,7 +211,7 @@ mh_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, size_t *pcount, |
211 | 211 | ||
212 | for (i = 0; i < amd->msg_count; i++) | 212 | for (i = 0; i < amd->msg_count; i++) |
213 | { | 213 | { |
214 | DISPATCH_ADD_MSG(mailbox, amd); | 214 | DISPATCH_ADD_MSG (mailbox, amd, i); |
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ... | ... |
... | @@ -446,12 +446,12 @@ nntp_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -446,12 +446,12 @@ nntp_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) |
446 | return 0; | 446 | return 0; |
447 | for (i = msgno; i <= count; i++) | 447 | for (i = msgno; i <= count; i++) |
448 | { | 448 | { |
449 | if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD) != 0) | 449 | size_t tmp = i; |
450 | if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD, | ||
451 | &tmp) != 0) | ||
450 | break; | 452 | break; |
451 | if (((i +1) % 10) == 0) | 453 | if ((i +1) % 10 == 0) |
452 | { | 454 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS, NULL); |
453 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS); | ||
454 | } | ||
455 | } | 455 | } |
456 | return 0; | 456 | return 0; |
457 | } | 457 | } | ... | ... |
... | @@ -528,7 +528,7 @@ _pop_user (mu_authority_t auth) | ... | @@ -528,7 +528,7 @@ _pop_user (mu_authority_t auth) |
528 | mu_observable_t observable = NULL; | 528 | mu_observable_t observable = NULL; |
529 | mu_mailbox_get_observable (mbox, &observable); | 529 | mu_mailbox_get_observable (mbox, &observable); |
530 | CLEAR_STATE (mpd); | 530 | CLEAR_STATE (mpd); |
531 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED); | 531 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED, NULL); |
532 | CHECK_ERROR_CLOSE (mbox, mpd, EACCES); | 532 | CHECK_ERROR_CLOSE (mbox, mpd, EACCES); |
533 | } | 533 | } |
534 | status = pop_get_passwd (auth); | 534 | status = pop_get_passwd (auth); |
... | @@ -566,7 +566,7 @@ _pop_user (mu_authority_t auth) | ... | @@ -566,7 +566,7 @@ _pop_user (mu_authority_t auth) |
566 | mu_observable_t observable = NULL; | 566 | mu_observable_t observable = NULL; |
567 | mu_mailbox_get_observable (mbox, &observable); | 567 | mu_mailbox_get_observable (mbox, &observable); |
568 | CLEAR_STATE (mpd); | 568 | CLEAR_STATE (mpd); |
569 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED); | 569 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED, NULL); |
570 | return MU_ERR_AUTH_FAILURE; | 570 | return MU_ERR_AUTH_FAILURE; |
571 | } | 571 | } |
572 | mpd->state = POP_AUTH_DONE; | 572 | mpd->state = POP_AUTH_DONE; |
... | @@ -638,7 +638,7 @@ _pop_apop (mu_authority_t auth) | ... | @@ -638,7 +638,7 @@ _pop_apop (mu_authority_t auth) |
638 | mu_observable_t observable = NULL; | 638 | mu_observable_t observable = NULL; |
639 | mu_mailbox_get_observable (mbox, &observable); | 639 | mu_mailbox_get_observable (mbox, &observable); |
640 | CLEAR_STATE (mpd); | 640 | CLEAR_STATE (mpd); |
641 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED); | 641 | mu_observable_notify (observable, MU_EVT_AUTHORITY_FAILED, NULL); |
642 | CHECK_ERROR_CLOSE (mbox, mpd, EACCES); | 642 | CHECK_ERROR_CLOSE (mbox, mpd, EACCES); |
643 | } | 643 | } |
644 | mpd->state = POP_AUTH_DONE; | 644 | mpd->state = POP_AUTH_DONE; |
... | @@ -1255,11 +1255,14 @@ pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -1255,11 +1255,14 @@ pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) |
1255 | return 0; | 1255 | return 0; |
1256 | for (i = msgno; i <= count; i++) | 1256 | for (i = msgno; i <= count; i++) |
1257 | { | 1257 | { |
1258 | if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD) != 0) | 1258 | size_t tmp = i; |
1259 | if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD, | ||
1260 | &tmp) != 0) | ||
1259 | break; | 1261 | break; |
1260 | if (((i +1) % 10) == 0) | 1262 | if (((i +1) % 10) == 0) |
1261 | { | 1263 | { |
1262 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS); | 1264 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS, |
1265 | NULL); | ||
1263 | } | 1266 | } |
1264 | } | 1267 | } |
1265 | return 0; | 1268 | return 0; | ... | ... |
... | @@ -305,7 +305,7 @@ mu_sieve_disass (mu_sieve_machine_t mach) | ... | @@ -305,7 +305,7 @@ mu_sieve_disass (mu_sieve_machine_t mach) |
305 | } | 305 | } |
306 | 306 | ||
307 | static int | 307 | static int |
308 | _sieve_action (mu_observer_t obs, size_t type) | 308 | _sieve_action (mu_observer_t obs, size_t type, void *data, void *action_data) |
309 | { | 309 | { |
310 | mu_sieve_machine_t mach; | 310 | mu_sieve_machine_t mach; |
311 | 311 | ... | ... |
maidag/Makefile.am
0 → 100644
1 | # Copyright (C) 2007 Free Software Foundation, Inc. | ||
2 | # | ||
3 | # GNU Mailutils is free software; you can redistribute it and/or | ||
4 | # modify it under the terms of the GNU General Public License as | ||
5 | # published by the Free Software Foundation; either version 3, or (at | ||
6 | # your option) any later version. | ||
7 | # | ||
8 | # This program is distributed in the hope that it will be useful, but | ||
9 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | # General Public License for more details. | ||
12 | # | ||
13 | # You should have received a copy of the GNU General Public License | ||
14 | # along with this program; if not, write to the Free Software | ||
15 | # Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA | ||
16 | # 02110-1301 USA | ||
17 | |||
18 | INCLUDES = -I${top_srcdir} @MU_COMMON_INCLUDES@ @GUILE_INCLUDES@ | ||
19 | |||
20 | sbin_PROGRAMS=maidag | ||
21 | maidag_SOURCES=\ | ||
22 | deliver.c\ | ||
23 | lmtp.c\ | ||
24 | maidag.c\ | ||
25 | maidag.h\ | ||
26 | mailtmp.c\ | ||
27 | mailquota.c\ | ||
28 | script.c\ | ||
29 | util.c | ||
30 | |||
31 | maidag_LDADD = \ | ||
32 | @LIBMU_SCM@ @GUILE_LIBS@\ | ||
33 | @LIBMU_SCM_DEPS@\ | ||
34 | ../lib/libmuaux.la \ | ||
35 | ${MU_LIB_SIEVE}\ | ||
36 | ${MU_LIB_MBOX}\ | ||
37 | ${MU_LIB_IMAP}\ | ||
38 | ${MU_LIB_POP}\ | ||
39 | ${MU_LIB_NNTP}\ | ||
40 | ${MU_LIB_MH}\ | ||
41 | ${MU_LIB_MAILDIR}\ | ||
42 | ${MU_LIB_AUTH}\ | ||
43 | ${MU_LIB_MAILER}\ | ||
44 | @MU_AUTHLIBS@\ | ||
45 | ${MU_LIB_MAILUTILS} \ | ||
46 | @MU_COMMON_LIBRARIES@ | ||
47 | |||
48 | install-exec-hook: | ||
49 | for i in $(sbin_PROGRAMS); do\ | ||
50 | chown root:mail $(DESTDIR)$(sbindir)/$$i;\ | ||
51 | chmod 4755 $(DESTDIR)$(sbindir)/$$i;\ | ||
52 | done |
maidag/deliver.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, | ||
3 | 2007 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, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | MA 02110-1301 USA */ | ||
19 | |||
20 | #include "maidag.h" | ||
21 | |||
22 | void | ||
23 | make_tmp (const char *from, mu_mailbox_t *mbox) | ||
24 | { | ||
25 | struct mail_tmp *mtmp; | ||
26 | char *buf = NULL; | ||
27 | size_t n = 0; | ||
28 | int rc; | ||
29 | |||
30 | if (mail_tmp_begin (&mtmp, from)) | ||
31 | exit (EX_TEMPFAIL); | ||
32 | |||
33 | while (getline (&buf, &n, stdin) > 0) | ||
34 | if ((rc = mail_tmp_add_line (mtmp, buf, strlen (buf)))) | ||
35 | break; | ||
36 | free (buf); | ||
37 | if (rc == 0) | ||
38 | rc = mail_tmp_finish (mtmp, mbox); | ||
39 | mail_tmp_destroy (&mtmp); | ||
40 | if (rc) | ||
41 | exit (EX_TEMPFAIL); | ||
42 | } | ||
43 | |||
44 | int | ||
45 | mda (mu_mailbox_t mbx, char *username) | ||
46 | { | ||
47 | deliver (mbx, username, NULL); | ||
48 | |||
49 | if (multiple_delivery) | ||
50 | exit_code = EX_OK; | ||
51 | |||
52 | return exit_code; | ||
53 | } | ||
54 | |||
55 | int | ||
56 | maidag_stdio_delivery (int argc, char **argv) | ||
57 | { | ||
58 | mu_mailbox_t mbox; | ||
59 | |||
60 | make_tmp (sender_address, &mbox); | ||
61 | |||
62 | if (multiple_delivery) | ||
63 | multiple_delivery = argc > 1; | ||
64 | |||
65 | #ifdef WITH_GUILE | ||
66 | if (progfile_pattern) | ||
67 | { | ||
68 | struct mda_data mda_data; | ||
69 | |||
70 | memset (&mda_data, 0, sizeof mda_data); | ||
71 | mda_data.mbox = mbox; | ||
72 | mda_data.argv = argv; | ||
73 | mda_data.progfile_pattern = progfile_pattern; | ||
74 | return prog_mda (&mda_data); | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | for (; *argv; argv++) | ||
79 | mda (mbox, *argv); | ||
80 | return exit_code; | ||
81 | } | ||
82 | |||
83 | static int biff_fd = -1; | ||
84 | static struct sockaddr_in biff_in; | ||
85 | static char *biff_user_name; | ||
86 | |||
87 | static int | ||
88 | notify_action (mu_observer_t obs, size_t type, void *data, void *action_data) | ||
89 | { | ||
90 | if (type == MU_EVT_MESSAGE_APPEND) | ||
91 | { | ||
92 | mu_message_qid_t qid = data; | ||
93 | mu_mailbox_t mbox = mu_observer_get_owner (obs); | ||
94 | mu_url_t url; | ||
95 | char *buf; | ||
96 | |||
97 | mu_mailbox_get_url (mbox, &url); | ||
98 | asprintf (&buf, "%s@%s:%s", biff_user_name, | ||
99 | qid, mu_url_to_string (url)); | ||
100 | if (buf) | ||
101 | { | ||
102 | sendto (biff_fd, buf, strlen (buf), 0, | ||
103 | (struct sockaddr *)&biff_in, sizeof biff_in); | ||
104 | free (buf); | ||
105 | } | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void | ||
111 | attach_notify (mu_mailbox_t mbox) | ||
112 | { | ||
113 | struct servent *sp; | ||
114 | mu_observer_t observer; | ||
115 | mu_observable_t observable; | ||
116 | |||
117 | if (biff_fd == -1) | ||
118 | { | ||
119 | if ((sp = getservbyname ("biff", "udp")) == NULL) | ||
120 | { | ||
121 | biff_fd = -2; | ||
122 | return; | ||
123 | } | ||
124 | biff_in.sin_family = AF_INET; | ||
125 | biff_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK); | ||
126 | biff_in.sin_port = sp->s_port; | ||
127 | |||
128 | biff_fd = socket (PF_INET, SOCK_DGRAM, 0); | ||
129 | if (biff_fd < 0) | ||
130 | { | ||
131 | biff_fd = -2; | ||
132 | return; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (biff_fd) | ||
137 | { | ||
138 | mu_observer_create (&observer, mbox); | ||
139 | mu_observer_set_action (observer, notify_action, mbox); | ||
140 | mu_mailbox_get_observable (mbox, &observable); | ||
141 | mu_observable_attach (observable, MU_EVT_MESSAGE_APPEND, observer); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | int | ||
146 | deliver (mu_mailbox_t imbx, char *name, char **errp) | ||
147 | { | ||
148 | mu_mailbox_t mbox; | ||
149 | mu_message_t msg; | ||
150 | char *path; | ||
151 | mu_url_t url = NULL; | ||
152 | mu_locker_t lock; | ||
153 | struct mu_auth_data *auth; | ||
154 | int status; | ||
155 | int failed = 0; | ||
156 | |||
157 | auth = mu_get_auth_by_name (name); | ||
158 | if (!auth) | ||
159 | { | ||
160 | mailer_err (_("%s: no such user"), name); | ||
161 | if (errp) | ||
162 | asprintf (errp, "%s: no such user", name); | ||
163 | exit_code = EX_UNAVAILABLE; | ||
164 | return EX_UNAVAILABLE; | ||
165 | } | ||
166 | if (current_uid) | ||
167 | auth->change_uid = 0; | ||
168 | |||
169 | if (!sieve_test (auth, imbx)) | ||
170 | { | ||
171 | exit_code = EX_OK; | ||
172 | mu_auth_data_free (auth); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0) | ||
177 | { | ||
178 | mailer_err (_("Cannot get message from the temporary mailbox: %s"), | ||
179 | mu_strerror (status)); | ||
180 | mu_auth_data_free (auth); | ||
181 | return EX_TEMPFAIL; | ||
182 | } | ||
183 | |||
184 | if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0) | ||
185 | { | ||
186 | mailer_err (_("Cannot open mailbox %s: %s"), | ||
187 | auth->mailbox, mu_strerror (status)); | ||
188 | mu_auth_data_free (auth); | ||
189 | return EX_TEMPFAIL; | ||
190 | } | ||
191 | |||
192 | mu_mailbox_get_url (mbox, &url); | ||
193 | path = (char*) mu_url_to_string (url); | ||
194 | |||
195 | biff_user_name = name; | ||
196 | |||
197 | /* Actually open the mailbox. Switch to the user's euid to make | ||
198 | sure the maildrop file will have right privileges, in case it | ||
199 | will be created */ | ||
200 | if (switch_user_id (auth, 1)) | ||
201 | return EX_TEMPFAIL; | ||
202 | status = mu_mailbox_open (mbox, MU_STREAM_APPEND|MU_STREAM_CREAT); | ||
203 | if (switch_user_id (auth, 0)) | ||
204 | return EX_TEMPFAIL; | ||
205 | |||
206 | if (status != 0) | ||
207 | { | ||
208 | mailer_err (_("Cannot open mailbox %s: %s"), path, mu_strerror (status)); | ||
209 | mu_mailbox_destroy (&mbox); | ||
210 | return EX_TEMPFAIL; | ||
211 | } | ||
212 | |||
213 | attach_notify (mbox); | ||
214 | |||
215 | /* FIXME: This is superfluous, as mu_mailbox_append_message takes care | ||
216 | of locking anyway. But I leave it here for the time being. */ | ||
217 | mu_mailbox_get_locker (mbox, &lock); | ||
218 | |||
219 | if (lock) | ||
220 | { | ||
221 | status = mu_locker_lock (lock); | ||
222 | |||
223 | if (status) | ||
224 | { | ||
225 | mailer_err (_("Cannot lock mailbox `%s': %s"), path, | ||
226 | mu_strerror (status)); | ||
227 | mu_mailbox_destroy (&mbox); | ||
228 | exit_code = EX_TEMPFAIL; | ||
229 | return EX_TEMPFAIL; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | #if defined(USE_MAILBOX_QUOTAS) | ||
234 | { | ||
235 | mu_off_t n; | ||
236 | mu_off_t msg_size; | ||
237 | mu_off_t mbsize; | ||
238 | |||
239 | if ((status = mu_mailbox_get_size (mbox, &mbsize))) | ||
240 | { | ||
241 | mailer_err (_("Cannot get size of mailbox %s: %s"), | ||
242 | path, mu_strerror (status)); | ||
243 | if (status == ENOSYS) | ||
244 | mbsize = 0; /* Try to continue anyway */ | ||
245 | else | ||
246 | { | ||
247 | mu_mailbox_destroy (&mbox); | ||
248 | return EX_TEMPFAIL; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | switch (check_quota (auth, mbsize, &n)) | ||
253 | { | ||
254 | case MQUOTA_EXCEEDED: | ||
255 | mailer_err (_("%s: mailbox quota exceeded for this recipient"), name); | ||
256 | if (errp) | ||
257 | asprintf (errp, "%s: mailbox quota exceeded for this recipient", | ||
258 | name); | ||
259 | exit_code = EX_QUOTA(); | ||
260 | failed++; | ||
261 | break; | ||
262 | |||
263 | case MQUOTA_UNLIMITED: | ||
264 | break; | ||
265 | |||
266 | default: | ||
267 | if ((status = mu_mailbox_get_size (imbx, &msg_size))) | ||
268 | { | ||
269 | mailer_err (_("Cannot get message size (input message %s): %s"), | ||
270 | path, mu_strerror (status)); | ||
271 | exit_code = EX_UNAVAILABLE; | ||
272 | failed++; | ||
273 | } | ||
274 | else if (msg_size > n) | ||
275 | { | ||
276 | mailer_err (_("%s: message would exceed maximum mailbox size for " | ||
277 | "this recipient"), | ||
278 | name); | ||
279 | if (errp) | ||
280 | asprintf (errp, | ||
281 | "%s: message would exceed maximum mailbox size " | ||
282 | "for this recipient", | ||
283 | name); | ||
284 | exit_code = EX_QUOTA(); | ||
285 | failed++; | ||
286 | } | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | #endif | ||
291 | |||
292 | if (!failed && switch_user_id (auth, 1) == 0) | ||
293 | { | ||
294 | status = mu_mailbox_append_message (mbox, msg); | ||
295 | if (status) | ||
296 | { | ||
297 | mailer_err (_("Error writing to mailbox %s: %s"), | ||
298 | path, mu_strerror (status)); | ||
299 | failed++; | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | status = mu_mailbox_sync (mbox); | ||
304 | if (status) | ||
305 | { | ||
306 | mailer_err (_("Error flushing mailbox %s: %s"), | ||
307 | path, mu_strerror (status)); | ||
308 | failed++; | ||
309 | } | ||
310 | } | ||
311 | switch_user_id (auth, 0); | ||
312 | } | ||
313 | |||
314 | mu_auth_data_free (auth); | ||
315 | mu_mailbox_close (mbox); | ||
316 | mu_locker_unlock (lock); | ||
317 | mu_mailbox_destroy (&mbox); | ||
318 | return failed ? exit_code : 0; | ||
319 | } |
maidag/lmtp.c
0 → 100644
This diff is collapsed.
Click to expand it.
maidag/maidag.c
0 → 100644
This diff is collapsed.
Click to expand it.
maidag/maidag.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2007 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, write to the Free Software | ||
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | MA 02110-1301 USA */ | ||
18 | |||
19 | #if defined(HAVE_CONFIG_H) | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <errno.h> | ||
25 | #include <grp.h> | ||
26 | #include <netdb.h> | ||
27 | #include <pwd.h> | ||
28 | #include <stdarg.h> | ||
29 | #include <stdio.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <string.h> | ||
32 | #include <syslog.h> | ||
33 | #include <unistd.h> | ||
34 | |||
35 | #include <arpa/inet.h> | ||
36 | #include <netinet/in.h> | ||
37 | #include <sys/socket.h> | ||
38 | #include <sys/stat.h> | ||
39 | |||
40 | #ifdef HAVE_STRINGS_H | ||
41 | # include <strings.h> | ||
42 | #endif | ||
43 | |||
44 | #ifdef HAVE_SYSEXITS_H | ||
45 | # include <sysexits.h> | ||
46 | #else | ||
47 | # define EX_OK 0 /* successful termination */ | ||
48 | # define EX__BASE 64 /* base value for error messages */ | ||
49 | # define EX_USAGE 64 /* command line usage error */ | ||
50 | # define EX_DATAERR 65 /* data format error */ | ||
51 | # define EX_NOINPUT 66 /* cannot open input */ | ||
52 | # define EX_NOUSER 67 /* addressee unknown */ | ||
53 | # define EX_NOHOST 68 /* host name unknown */ | ||
54 | # define EX_UNAVAILABLE 69 /* service unavailable */ | ||
55 | # define EX_SOFTWARE 70 /* internal software error */ | ||
56 | # define EX_OSERR 71 /* system error (e.g., can't fork) */ | ||
57 | # define EX_OSFILE 72 /* critical OS file missing */ | ||
58 | # define EX_CANTCREAT 73 /* can't create (user) output file */ | ||
59 | # define EX_IOERR 74 /* input/output error */ | ||
60 | # define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ | ||
61 | # define EX_PROTOCOL 76 /* remote error in protocol */ | ||
62 | # define EX_NOPERM 77 /* permission denied */ | ||
63 | # define EX_CONFIG 78 /* configuration error */ | ||
64 | # define EX__MAX 78 /* maximum listed value */ | ||
65 | #endif | ||
66 | |||
67 | #ifndef INADDR_LOOPBACK | ||
68 | # define INADDR_LOOPBAK 0x7f000001 | ||
69 | #endif | ||
70 | |||
71 | #include <mailutils/attribute.h> | ||
72 | #include <mailutils/errno.h> | ||
73 | #include <mailutils/error.h> | ||
74 | #include <mailutils/list.h> | ||
75 | #include <mailutils/locker.h> | ||
76 | #include <mailutils/mailbox.h> | ||
77 | #include <mailutils/message.h> | ||
78 | #include <mailutils/mutil.h> | ||
79 | #include <mailutils/registrar.h> | ||
80 | #include <mailutils/stream.h> | ||
81 | #include <mailutils/url.h> | ||
82 | #include <mailutils/mu_auth.h> | ||
83 | #include <mailutils/libsieve.h> | ||
84 | #include <mailutils/nls.h> | ||
85 | |||
86 | #include <mu_dbm.h> | ||
87 | #include <mu_asprintf.h> | ||
88 | #include <getline.h> | ||
89 | |||
90 | #if defined (USE_DBM) || defined (USE_SQL) | ||
91 | # define USE_MAILBOX_QUOTAS 1 | ||
92 | #endif | ||
93 | |||
94 | #include <mailutils/argp.h> | ||
95 | /* Debug */ | ||
96 | extern int debug_level; | ||
97 | #define dbg() if (debug_level) debug | ||
98 | |||
99 | /* mailquota settings */ | ||
100 | #define MQUOTA_OK 0 | ||
101 | #define MQUOTA_EXCEEDED 1 | ||
102 | #define MQUOTA_UNLIMITED 2 | ||
103 | |||
104 | #define MAXFD 64 | ||
105 | #define EX_QUOTA() (ex_quota_tempfail ? EX_TEMPFAIL : EX_UNAVAILABLE) | ||
106 | |||
107 | extern int exit_code; | ||
108 | extern int log_to_stderr; | ||
109 | extern int multiple_delivery; | ||
110 | extern int ex_quota_tempfail; | ||
111 | extern uid_t current_uid; | ||
112 | extern char *quotadbname; | ||
113 | extern char *quota_query; | ||
114 | |||
115 | extern char *sender_address; | ||
116 | extern char *progfile_pattern; | ||
117 | extern char *sieve_pattern; | ||
118 | |||
119 | extern int lmtp_mode; | ||
120 | extern char *lmtp_url_string; | ||
121 | extern int reuse_lmtp_address; | ||
122 | extern char *lmtp_group; | ||
123 | extern struct daemon_param daemon_param; | ||
124 | |||
125 | void close_fds (void); | ||
126 | int switch_user_id (struct mu_auth_data *auth, int user); | ||
127 | |||
128 | int maidag_stdio_delivery (int argc, char **argv); | ||
129 | int maidag_lmtp_server (void); | ||
130 | |||
131 | void mailer_err (char *fmt, ...); | ||
132 | void notify_biff (mu_mailbox_t mbox, char *name, size_t size); | ||
133 | void guess_retval (int ec); | ||
134 | |||
135 | int deliver (mu_mailbox_t imbx, char *name, char **errp); | ||
136 | int sieve_test (struct mu_auth_data *auth, mu_mailbox_t mbx); | ||
137 | int check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest); | ||
138 | |||
139 | #ifdef WITH_GUILE | ||
140 | struct mda_data | ||
141 | { | ||
142 | mu_mailbox_t mbox; | ||
143 | char *progfile; | ||
144 | char *progfile_pattern; | ||
145 | char **argv; | ||
146 | }; | ||
147 | |||
148 | int prog_mda (struct mda_data *data); | ||
149 | |||
150 | extern int debug_guile; | ||
151 | #endif | ||
152 | |||
153 | struct mail_tmp; | ||
154 | int mail_tmp_begin (struct mail_tmp **pmtmp, const char *from); | ||
155 | int mail_tmp_add_line (struct mail_tmp *mtmp, char *buf, size_t buflen); | ||
156 | int mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox); | ||
157 | void mail_tmp_destroy (struct mail_tmp **pmtmp); |
maidag/mailquota.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2004, | ||
3 | 2005, 2007 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, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | MA 02110-1301 USA */ | ||
19 | |||
20 | #include "maidag.h" | ||
21 | |||
22 | #if defined (USE_MAILBOX_QUOTAS) | ||
23 | |||
24 | #define DEFRETVAL MQUOTA_UNLIMITED | ||
25 | |||
26 | mu_off_t groupquota = 5*1024*1024UL; | ||
27 | static int get_size (char *, mu_off_t *, char **); | ||
28 | |||
29 | int | ||
30 | get_size (char *str, mu_off_t *size, char **endp) | ||
31 | { | ||
32 | mu_off_t s; | ||
33 | |||
34 | s = strtol (str, &str, 0); | ||
35 | switch (*str) | ||
36 | { | ||
37 | case 0: | ||
38 | break; | ||
39 | |||
40 | case 'k': | ||
41 | case 'K': | ||
42 | s *= 1024; | ||
43 | break; | ||
44 | |||
45 | case 'm': | ||
46 | case 'M': | ||
47 | s *= 1024*1024; | ||
48 | break; | ||
49 | |||
50 | default: | ||
51 | *endp = str; | ||
52 | return -1; | ||
53 | } | ||
54 | *size = s; | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | #define RETR_OK 0 | ||
59 | #define RETR_UNLIMITED -1 | ||
60 | #define RETR_FAILURE 1 | ||
61 | |||
62 | int | ||
63 | fail_retrieve_quota (char *name, mu_off_t *quota) | ||
64 | { | ||
65 | mu_error (_("No quota retrieving mechanism")); | ||
66 | return RETR_FAILURE; | ||
67 | } | ||
68 | |||
69 | #ifdef USE_DBM | ||
70 | int | ||
71 | dbm_retrieve_quota (char *name, mu_off_t *quota) | ||
72 | { | ||
73 | DBM_FILE db; | ||
74 | DBM_DATUM named, contentd; | ||
75 | char buffer[64]; | ||
76 | int unlimited = 0; | ||
77 | int rc; | ||
78 | |||
79 | if (!quotadbname) | ||
80 | return RETR_FAILURE; | ||
81 | |||
82 | if (mu_dbm_open (quotadbname, &db, MU_STREAM_READ, 0600)) | ||
83 | { | ||
84 | mu_error (_("Cannot open %s: %s"), quotadbname, mu_strerror (errno)); | ||
85 | return RETR_FAILURE; | ||
86 | } | ||
87 | |||
88 | memset (&named, 0, sizeof named); | ||
89 | memset (&contentd, 0, sizeof contentd); | ||
90 | MU_DATUM_PTR (named) = name; | ||
91 | MU_DATUM_SIZE (named) = strlen (name); | ||
92 | rc = mu_dbm_fetch (db, named, &contentd); | ||
93 | if (rc || !MU_DATUM_PTR (contentd)) | ||
94 | { | ||
95 | /* User not in database, try default quota */ | ||
96 | memset (&named, 0, sizeof named); | ||
97 | MU_DATUM_PTR (named) = "DEFAULT"; | ||
98 | MU_DATUM_SIZE (named) = strlen ("DEFAULT"); | ||
99 | rc = mu_dbm_fetch (db, named, &contentd); | ||
100 | if (rc) | ||
101 | { | ||
102 | /*mu_error (_("can't fetch data: %s"), strerror (rc));*/ | ||
103 | return RETR_FAILURE; | ||
104 | } | ||
105 | if (!MU_DATUM_PTR (contentd)) | ||
106 | return RETR_FAILURE; | ||
107 | } | ||
108 | |||
109 | if (strncasecmp("none", | ||
110 | MU_DATUM_PTR (contentd), | ||
111 | MU_DATUM_SIZE (contentd)) == 0) | ||
112 | unlimited = 1; | ||
113 | else if (MU_DATUM_SIZE (contentd) > sizeof(buffer)-1) | ||
114 | { | ||
115 | mu_error (ngettext ("Mailbox quota for `%s' is too big: %d digit", | ||
116 | "Mailbox quota for `%s' is too big: %d digits", | ||
117 | MU_DATUM_SIZE (contentd)), | ||
118 | name, MU_DATUM_SIZE (contentd)); | ||
119 | *quota = groupquota; | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | char *p; | ||
124 | |||
125 | strncpy(buffer, MU_DATUM_PTR (contentd), MU_DATUM_SIZE (contentd)); | ||
126 | buffer[MU_DATUM_SIZE (contentd)] = 0; | ||
127 | *quota = strtoul (buffer, &p, 0); | ||
128 | if (get_size (buffer, quota, &p)) | ||
129 | { | ||
130 | mu_error (_("Bogus mailbox quota for `%s' (near `%s')"), name, p); | ||
131 | *quota = groupquota; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | mu_dbm_close (db); | ||
136 | |||
137 | return unlimited ? RETR_UNLIMITED : RETR_OK; | ||
138 | } | ||
139 | |||
140 | # define default_retrieve_quota dbm_retrieve_quota | ||
141 | #else | ||
142 | # define default_retrieve_quota fail_retrieve_quota | ||
143 | #endif | ||
144 | |||
145 | #ifdef USE_SQL | ||
146 | #include <mailutils/sql.h> | ||
147 | |||
148 | /* FIXME: defined in auth/sql.c */ | ||
149 | #include <auth/sql.h> | ||
150 | |||
151 | int | ||
152 | sql_retrieve_quota (char *name, mu_off_t *quota) | ||
153 | { | ||
154 | mu_sql_connection_t conn; | ||
155 | char *query_str; | ||
156 | int rc, status; | ||
157 | char *tmp; | ||
158 | size_t n; | ||
159 | |||
160 | query_str = mu_sql_expand_query (quota_query, name); | ||
161 | if (!query_str) | ||
162 | return RETR_FAILURE; | ||
163 | |||
164 | status = mu_sql_connection_init (&conn, | ||
165 | sql_interface, | ||
166 | mu_sql_host, | ||
167 | mu_sql_port, | ||
168 | mu_sql_user, | ||
169 | mu_sql_passwd, | ||
170 | mu_sql_db); | ||
171 | |||
172 | if (status) | ||
173 | { | ||
174 | mu_error ("%s. SQL error: %s", | ||
175 | mu_strerror (status), mu_sql_strerror (conn)); | ||
176 | mu_sql_connection_destroy (&conn); | ||
177 | free (query_str); | ||
178 | return RETR_FAILURE; | ||
179 | } | ||
180 | |||
181 | status = mu_sql_connect (conn); | ||
182 | |||
183 | if (status) | ||
184 | { | ||
185 | mu_error ("%s. SQL error: %s", | ||
186 | mu_strerror (status), mu_sql_strerror (conn)); | ||
187 | mu_sql_connection_destroy (&conn); | ||
188 | free (query_str); | ||
189 | return RETR_FAILURE; | ||
190 | } | ||
191 | |||
192 | status = mu_sql_query (conn, query_str); | ||
193 | free (query_str); | ||
194 | |||
195 | if (status) | ||
196 | { | ||
197 | mu_error (_("SQL Query failed: %s"), | ||
198 | (status == MU_ERR_SQL) ? mu_sql_strerror (conn) : | ||
199 | mu_strerror (status)); | ||
200 | mu_sql_connection_destroy (&conn); | ||
201 | return RETR_FAILURE; | ||
202 | } | ||
203 | |||
204 | status = mu_sql_store_result (conn); | ||
205 | |||
206 | if (status) | ||
207 | { | ||
208 | mu_error (_("Cannot store SQL result: %s"), | ||
209 | (status == MU_ERR_SQL) ? mu_sql_strerror (conn) : | ||
210 | mu_strerror (status)); | ||
211 | mu_sql_connection_destroy (&conn); | ||
212 | return RETR_FAILURE; | ||
213 | } | ||
214 | |||
215 | mu_sql_num_tuples (conn, &n); | ||
216 | if (n == 0) | ||
217 | { | ||
218 | rc = RETR_FAILURE; | ||
219 | } | ||
220 | else | ||
221 | { | ||
222 | rc = RETR_OK; | ||
223 | tmp = NULL; | ||
224 | status = mu_sql_get_column (conn, 0, 0, &tmp); | ||
225 | if (status) | ||
226 | { | ||
227 | mu_error (_("Cannot retrieve mailbox quota from SQL: %s"), | ||
228 | (status == MU_ERR_SQL) ? mu_sql_strerror (conn) : | ||
229 | mu_strerror (status)); | ||
230 | rc = RETR_FAILURE; | ||
231 | } | ||
232 | else if (tmp == NULL || tmp[0] == 0 || strcasecmp (tmp, "none") == 0) | ||
233 | rc = RETR_UNLIMITED; | ||
234 | else | ||
235 | { | ||
236 | char *p; | ||
237 | |||
238 | if (get_size (tmp, quota, &p)) | ||
239 | { | ||
240 | mu_error (_("Bogus mailbox quota for `%s' (near `%s')"), | ||
241 | name, p); | ||
242 | *quota = groupquota; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | mu_sql_release_result (conn); | ||
248 | mu_sql_disconnect (conn); | ||
249 | mu_sql_connection_destroy (&conn); | ||
250 | return rc; | ||
251 | } | ||
252 | #endif | ||
253 | |||
254 | |||
255 | static int | ||
256 | retrieve_quota (struct mu_auth_data *auth, mu_off_t *quota) | ||
257 | { | ||
258 | if (MU_HAS_QUOTA (auth)) | ||
259 | { | ||
260 | if (auth->quota == 0) | ||
261 | return RETR_UNLIMITED; | ||
262 | *quota = auth->quota; | ||
263 | return RETR_OK; | ||
264 | } | ||
265 | |||
266 | #ifdef USE_SQL | ||
267 | if (quota_query) | ||
268 | return sql_retrieve_quota (auth->name, quota); | ||
269 | #endif | ||
270 | return default_retrieve_quota (auth->name, quota); | ||
271 | } | ||
272 | |||
273 | int | ||
274 | check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest) | ||
275 | { | ||
276 | mu_off_t quota; | ||
277 | |||
278 | switch (retrieve_quota (auth, "a)) | ||
279 | { | ||
280 | case RETR_FAILURE: | ||
281 | return DEFRETVAL; | ||
282 | |||
283 | case RETR_UNLIMITED: | ||
284 | return MQUOTA_UNLIMITED; | ||
285 | |||
286 | case RETR_OK: | ||
287 | if (quota < size) /* Mailbox full */ | ||
288 | return MQUOTA_EXCEEDED; | ||
289 | |||
290 | if (rest) | ||
291 | *rest = quota - size; | ||
292 | } | ||
293 | |||
294 | return MQUOTA_OK; | ||
295 | |||
296 | } | ||
297 | |||
298 | #endif /* USE_MAIL_QUOTA */ |
maidag/mailtmp.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, | ||
3 | 2007 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, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | MA 02110-1301 USA */ | ||
19 | |||
20 | #include "maidag.h" | ||
21 | |||
22 | struct mail_tmp | ||
23 | { | ||
24 | mu_stream_t stream; | ||
25 | size_t line; | ||
26 | char *tempfile; | ||
27 | const char *from; | ||
28 | int had_nl; | ||
29 | }; | ||
30 | |||
31 | int | ||
32 | mail_tmp_begin (struct mail_tmp **pmtmp, const char *from) | ||
33 | { | ||
34 | int status; | ||
35 | struct mail_tmp *mtmp = malloc (sizeof *mtmp); | ||
36 | |||
37 | if (!mtmp) | ||
38 | return ENOMEM; | ||
39 | |||
40 | memset (mtmp, 0, sizeof *mtmp); | ||
41 | |||
42 | mtmp->tempfile = mu_tempname (NULL); | ||
43 | if ((status = mu_file_stream_create (&mtmp->stream, mtmp->tempfile, | ||
44 | MU_STREAM_RDWR))) | ||
45 | { | ||
46 | free (mtmp); | ||
47 | mailer_err (_("Unable to open temporary file: %s"), | ||
48 | mu_strerror (status)); | ||
49 | return status; | ||
50 | } | ||
51 | |||
52 | if ((status = mu_stream_open (mtmp->stream))) | ||
53 | { | ||
54 | free (mtmp); | ||
55 | mailer_err (_("unable to open temporary file: %s"), | ||
56 | mu_strerror (status)); | ||
57 | return status; | ||
58 | } | ||
59 | mtmp->from = from; | ||
60 | *pmtmp = mtmp; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | int | ||
65 | mail_tmp_add_line (struct mail_tmp *mtmp, char *buf, size_t buflen) | ||
66 | { | ||
67 | int status = 0; | ||
68 | |||
69 | mtmp->line++; | ||
70 | if (mtmp->line == 1) | ||
71 | { | ||
72 | const char *from = mtmp->from; | ||
73 | |||
74 | if (buflen >= 5 && memcmp (buf, "From ", 5)) | ||
75 | { | ||
76 | struct mu_auth_data *auth = NULL; | ||
77 | if (!from) | ||
78 | { | ||
79 | auth = mu_get_auth_by_uid (getuid ()); | ||
80 | if (auth) | ||
81 | from = auth->name; | ||
82 | } | ||
83 | if (from) | ||
84 | { | ||
85 | time_t t; | ||
86 | char *envs; | ||
87 | |||
88 | time (&t); | ||
89 | asprintf (&envs, "From %s %s", from, ctime (&t)); | ||
90 | status = mu_stream_sequential_write (mtmp->stream, | ||
91 | envs, | ||
92 | strlen (envs)); | ||
93 | free (envs); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | mailer_err (_("Cannot determine sender address")); | ||
98 | return EINVAL; | ||
99 | } | ||
100 | if (auth) | ||
101 | mu_auth_data_free (auth); | ||
102 | } | ||
103 | } | ||
104 | else if (buflen >= 5 && !memcmp (buf, "From ", 5)) | ||
105 | { | ||
106 | static char *escape = ">"; | ||
107 | status = mu_stream_sequential_write (mtmp->stream, escape, 1); | ||
108 | } | ||
109 | |||
110 | if (!status) | ||
111 | status = mu_stream_sequential_write (mtmp->stream, buf, buflen); | ||
112 | |||
113 | if (status) | ||
114 | { | ||
115 | mailer_err (_("Error writing temporary file: %s"), mu_strerror (status)); | ||
116 | mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); | ||
117 | } | ||
118 | mtmp->had_nl = buf[buflen-1] == '\n'; | ||
119 | return status; | ||
120 | } | ||
121 | |||
122 | int | ||
123 | mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox) | ||
124 | { | ||
125 | int status; | ||
126 | static char *newline = "\n"; | ||
127 | size_t n; | ||
128 | |||
129 | if (!mtmp->had_nl) | ||
130 | status = mu_stream_sequential_write (mtmp->stream, newline, 1); | ||
131 | |||
132 | status = mu_stream_sequential_write (mtmp->stream, newline, 1); | ||
133 | unlink (mtmp->tempfile); | ||
134 | free (mtmp->tempfile); | ||
135 | mtmp->tempfile = NULL; | ||
136 | |||
137 | if (status) | ||
138 | { | ||
139 | errno = status; | ||
140 | mailer_err (_("Error writing temporary file: %s"), mu_strerror (status)); | ||
141 | mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); | ||
142 | return status; | ||
143 | } | ||
144 | |||
145 | mu_stream_flush (mtmp->stream); | ||
146 | if ((status = mu_mailbox_create (mbox, "/dev/null")) | ||
147 | || (status = mu_mailbox_open (*mbox, MU_STREAM_READ)) | ||
148 | || (status = mu_mailbox_set_stream (*mbox, mtmp->stream))) | ||
149 | { | ||
150 | mailer_err (_("Error opening temporary file: %s"), mu_strerror (status)); | ||
151 | mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); | ||
152 | return status; | ||
153 | } | ||
154 | |||
155 | status = mu_mailbox_messages_count (*mbox, &n); | ||
156 | if (status) | ||
157 | { | ||
158 | errno = status; | ||
159 | mailer_err (_("Error creating temporary message: %s"), | ||
160 | mu_strerror (status)); | ||
161 | mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); | ||
162 | return status; | ||
163 | } | ||
164 | |||
165 | mtmp->stream = NULL; | ||
166 | mtmp->line = 0; | ||
167 | |||
168 | return status; | ||
169 | |||
170 | } | ||
171 | |||
172 | void | ||
173 | mail_tmp_destroy (struct mail_tmp **pmtmp) | ||
174 | { | ||
175 | struct mail_tmp *mtmp = *pmtmp; | ||
176 | |||
177 | if (mtmp) | ||
178 | { | ||
179 | if (mtmp->tempfile) | ||
180 | { | ||
181 | unlink (mtmp->tempfile); | ||
182 | free (mtmp->tempfile); | ||
183 | } | ||
184 | mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream)); | ||
185 | free (*pmtmp); | ||
186 | *pmtmp = NULL; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | |||
191 |
maidag/script.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, | ||
3 | 2007 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, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | MA 02110-1301 USA */ | ||
19 | |||
20 | #include "maidag.h" | ||
21 | |||
22 | #ifdef WITH_GUILE | ||
23 | #include <mailutils/guile.h> | ||
24 | |||
25 | int debug_guile; | ||
26 | |||
27 | SCM mda_catch_body (void *data, mu_mailbox_t mbox); | ||
28 | SCM mda_catch_handler (void *unused, SCM tag, SCM throw_args); | ||
29 | int mda_next (void *data, mu_mailbox_t mbox); | ||
30 | int mda_exit (void *data, mu_mailbox_t mbox); | ||
31 | int mda_init (void *data); | ||
32 | |||
33 | int | ||
34 | prog_mda (struct mda_data *data) | ||
35 | { | ||
36 | char *x_argv[2]; | ||
37 | mu_guimb_param_t param; | ||
38 | |||
39 | x_argv[0] = "maidag"; | ||
40 | x_argv[1] = NULL; | ||
41 | |||
42 | param.debug_guile = debug_guile; | ||
43 | param.mbox = data->mbox; | ||
44 | param.user_name = NULL; | ||
45 | param.init = mda_init; | ||
46 | param.catch_body = mda_catch_body; | ||
47 | param.catch_handler = mda_catch_handler; | ||
48 | param.next = mda_next; | ||
49 | param.exit = mda_exit; | ||
50 | param.data = data; | ||
51 | |||
52 | mu_process_mailbox (1, x_argv, ¶m); | ||
53 | return EX_UNAVAILABLE; | ||
54 | } | ||
55 | |||
56 | int | ||
57 | mda_init (void *data) | ||
58 | { | ||
59 | struct mda_data *md = data; | ||
60 | md->progfile = mu_expand_path_pattern (md->progfile_pattern, md->argv[0]); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void | ||
65 | mda_switch_to_user (struct mda_data *md) | ||
66 | { | ||
67 | struct mu_auth_data *auth = NULL; | ||
68 | |||
69 | if (md && *md->argv != NULL) | ||
70 | auth = mu_get_auth_by_name (*md->argv); | ||
71 | |||
72 | if (auth) | ||
73 | { | ||
74 | switch_user_id (auth, 1); | ||
75 | chdir (auth->dir); | ||
76 | mu_auth_data_free (auth); | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | switch_user_id (auth, 0); | ||
81 | chdir ("/"); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | SCM | ||
86 | mda_catch_body (void *data, mu_mailbox_t mbox) | ||
87 | { | ||
88 | struct mda_data *md = data; | ||
89 | mu_message_t mesg = NULL; | ||
90 | mu_attribute_t attr = NULL; | ||
91 | |||
92 | if (access (md->progfile, R_OK)) | ||
93 | { | ||
94 | if (debug_level > 2) | ||
95 | syslog (LOG_DEBUG, _("Access to %s failed: %m"), md->progfile); | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | mda_switch_to_user (md); | ||
100 | scm_primitive_load (scm_makfrom0str (md->progfile)); | ||
101 | } | ||
102 | |||
103 | mu_mailbox_get_message (mbox, 1, &mesg); | ||
104 | mu_message_get_attribute (mesg, &attr); | ||
105 | if (mu_attribute_is_deleted (attr)) | ||
106 | return SCM_BOOL_F; | ||
107 | |||
108 | mda_switch_to_user (NULL); | ||
109 | mda (md->mbox, md->argv[0]); | ||
110 | return SCM_BOOL_F; | ||
111 | } | ||
112 | |||
113 | SCM | ||
114 | mda_catch_handler (void *data, SCM tag, SCM throw_args) | ||
115 | { | ||
116 | exit_code = EX_TEMPFAIL; | ||
117 | return scm_handle_by_message_noexit ("mail.local", tag, throw_args); | ||
118 | } | ||
119 | |||
120 | int | ||
121 | mda_next (void *data, mu_mailbox_t mbox) | ||
122 | { | ||
123 | struct mda_data *md = data; | ||
124 | mu_message_t mesg = NULL; | ||
125 | mu_attribute_t attr = NULL; | ||
126 | |||
127 | md->argv++; | ||
128 | if (*md->argv == NULL) | ||
129 | return 0; | ||
130 | if (md->progfile) | ||
131 | free (md->progfile); | ||
132 | md->progfile = mu_expand_path_pattern (md->progfile_pattern, *md->argv); | ||
133 | |||
134 | mu_mailbox_get_message (mbox, 1, &mesg); | ||
135 | mu_message_get_attribute (mesg, &attr); | ||
136 | mu_attribute_unset_deleted (attr); | ||
137 | |||
138 | return md->progfile != NULL; | ||
139 | } | ||
140 | |||
141 | int | ||
142 | mda_exit (void *data, mu_mailbox_t mbox) | ||
143 | { | ||
144 | return exit_code; | ||
145 | } | ||
146 | |||
147 | #endif |
maidag/util.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2007 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, write to the Free Software | ||
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | MA 02110-1301 USA */ | ||
18 | |||
19 | #include "maidag.h" | ||
20 | |||
21 | void | ||
22 | close_fds () | ||
23 | { | ||
24 | int i; | ||
25 | long fdlimit = MAXFD; | ||
26 | |||
27 | #if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) | ||
28 | fdlimit = sysconf (_SC_OPEN_MAX); | ||
29 | #elif defined (HAVE_GETDTABLESIZE) | ||
30 | fdlimit = getdtablesize (); | ||
31 | #endif | ||
32 | |||
33 | for (i = 3; i < fdlimit; i++) | ||
34 | close (i); | ||
35 | } | ||
36 | |||
37 | int | ||
38 | switch_user_id (struct mu_auth_data *auth, int user) | ||
39 | { | ||
40 | int rc; | ||
41 | uid_t uid; | ||
42 | |||
43 | if (!auth || auth->change_uid == 0) | ||
44 | return 0; | ||
45 | |||
46 | if (user) | ||
47 | uid = auth->uid; | ||
48 | else | ||
49 | uid = 0; | ||
50 | |||
51 | #if defined(HAVE_SETREUID) | ||
52 | rc = setreuid (0, uid); | ||
53 | #elif defined(HAVE_SETRESUID) | ||
54 | rc = setresuid (-1, uid, -1); | ||
55 | #elif defined(HAVE_SETEUID) | ||
56 | rc = seteuid (uid); | ||
57 | #else | ||
58 | # error "No way to reset user privileges?" | ||
59 | #endif | ||
60 | if (rc < 0) | ||
61 | mailer_err ("setreuid(0, %d): %s (r=%d, e=%d)", | ||
62 | uid, strerror (errno), getuid (), geteuid ()); | ||
63 | return rc; | ||
64 | } | ||
65 | |||
66 | void | ||
67 | mailer_err (char *fmt, ...) | ||
68 | { | ||
69 | va_list ap; | ||
70 | |||
71 | guess_retval (errno); | ||
72 | va_start (ap, fmt); | ||
73 | if (!lmtp_mode && !log_to_stderr) | ||
74 | { | ||
75 | vfprintf (stderr, fmt, ap); | ||
76 | fputc ('\n', stderr); | ||
77 | } | ||
78 | mu_verror (fmt, ap); | ||
79 | va_end (ap); | ||
80 | } | ||
81 | |||
82 | int temp_errors[] = { | ||
83 | #ifdef EAGAIN | ||
84 | EAGAIN, /* Try again */ | ||
85 | #endif | ||
86 | #ifdef EBUSY | ||
87 | EBUSY, /* Device or resource busy */ | ||
88 | #endif | ||
89 | #ifdef EPROCLIM | ||
90 | EPROCLIM, /* Too many processes */ | ||
91 | #endif | ||
92 | #ifdef EUSERS | ||
93 | EUSERS, /* Too many users */ | ||
94 | #endif | ||
95 | #ifdef ECONNABORTED | ||
96 | ECONNABORTED, /* Software caused connection abort */ | ||
97 | #endif | ||
98 | #ifdef ECONNREFUSED | ||
99 | ECONNREFUSED, /* Connection refused */ | ||
100 | #endif | ||
101 | #ifdef ECONNRESET | ||
102 | ECONNRESET, /* Connection reset by peer */ | ||
103 | #endif | ||
104 | #ifdef EDEADLK | ||
105 | EDEADLK, /* Resource deadlock would occur */ | ||
106 | #endif | ||
107 | #ifdef EDEADLOCK | ||
108 | EDEADLOCK, /* Resource deadlock would occur */ | ||
109 | #endif | ||
110 | #ifdef EFBIG | ||
111 | EFBIG, /* File too large */ | ||
112 | #endif | ||
113 | #ifdef EHOSTDOWN | ||
114 | EHOSTDOWN, /* Host is down */ | ||
115 | #endif | ||
116 | #ifdef EHOSTUNREACH | ||
117 | EHOSTUNREACH, /* No route to host */ | ||
118 | #endif | ||
119 | #ifdef EMFILE | ||
120 | EMFILE, /* Too many open files */ | ||
121 | #endif | ||
122 | #ifdef ENETDOWN | ||
123 | ENETDOWN, /* Network is down */ | ||
124 | #endif | ||
125 | #ifdef ENETUNREACH | ||
126 | ENETUNREACH, /* Network is unreachable */ | ||
127 | #endif | ||
128 | #ifdef ENETRESET | ||
129 | ENETRESET, /* Network dropped connection because of reset */ | ||
130 | #endif | ||
131 | #ifdef ENFILE | ||
132 | ENFILE, /* File table overflow */ | ||
133 | #endif | ||
134 | #ifdef ENOBUFS | ||
135 | ENOBUFS, /* No buffer space available */ | ||
136 | #endif | ||
137 | #ifdef ENOMEM | ||
138 | ENOMEM, /* Out of memory */ | ||
139 | #endif | ||
140 | #ifdef ENOSPC | ||
141 | ENOSPC, /* No space left on device */ | ||
142 | #endif | ||
143 | #ifdef EROFS | ||
144 | EROFS, /* Read-only file system */ | ||
145 | #endif | ||
146 | #ifdef ESTALE | ||
147 | ESTALE, /* Stale NFS file handle */ | ||
148 | #endif | ||
149 | #ifdef ETIMEDOUT | ||
150 | ETIMEDOUT, /* Connection timed out */ | ||
151 | #endif | ||
152 | #ifdef EWOULDBLOCK | ||
153 | EWOULDBLOCK, /* Operation would block */ | ||
154 | #endif | ||
155 | }; | ||
156 | |||
157 | |||
158 | void | ||
159 | guess_retval (int ec) | ||
160 | { | ||
161 | int i; | ||
162 | /* Temporary failures override hard errors. */ | ||
163 | if (exit_code == EX_TEMPFAIL) | ||
164 | return; | ||
165 | #ifdef EDQUOT | ||
166 | if (ec == EDQUOT) | ||
167 | { | ||
168 | exit_code = EX_QUOTA(); | ||
169 | return; | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | for (i = 0; i < sizeof (temp_errors)/sizeof (temp_errors[0]); i++) | ||
174 | if (temp_errors[i] == ec) | ||
175 | { | ||
176 | exit_code = EX_TEMPFAIL; | ||
177 | return; | ||
178 | } | ||
179 | exit_code = EX_UNAVAILABLE; | ||
180 | } |
... | @@ -35,6 +35,7 @@ mail_local_LDADD = \ | ... | @@ -35,6 +35,7 @@ mail_local_LDADD = \ |
35 | ${MU_LIB_MH}\ | 35 | ${MU_LIB_MH}\ |
36 | ${MU_LIB_MAILDIR}\ | 36 | ${MU_LIB_MAILDIR}\ |
37 | ${MU_LIB_AUTH}\ | 37 | ${MU_LIB_AUTH}\ |
38 | ${MU_LIB_MAILER}\ | ||
38 | @MU_AUTHLIBS@\ | 39 | @MU_AUTHLIBS@\ |
39 | ${MU_LIB_MAILUTILS} \ | 40 | ${MU_LIB_MAILUTILS} \ |
40 | @MU_COMMON_LIBRARIES@ | 41 | @MU_COMMON_LIBRARIES@ | ... | ... |
... | @@ -317,7 +317,8 @@ _sieve_action_log (void *user_name, | ... | @@ -317,7 +317,8 @@ _sieve_action_log (void *user_name, |
317 | { | 317 | { |
318 | char *diag = NULL; | 318 | char *diag = NULL; |
319 | vasprintf (&diag, fmt, ap); | 319 | vasprintf (&diag, fmt, ap); |
320 | syslog (LOG_NOTICE, _("(user %s) %s: %s"), (char*) user_name, text, diag); | 320 | syslog (LOG_NOTICE, _("(user %s) %s: %s"), |
321 | (char*) user_name, text, diag); | ||
321 | free (diag); | 322 | free (diag); |
322 | } | 323 | } |
323 | else | 324 | else |
... | @@ -360,7 +361,7 @@ main (int argc, char *argv[]) | ... | @@ -360,7 +361,7 @@ main (int argc, char *argv[]) |
360 | 361 | ||
361 | /* Default locker settings */ | 362 | /* Default locker settings */ |
362 | mu_locker_set_default_flags (MU_LOCKER_PID|MU_LOCKER_RETRY, | 363 | mu_locker_set_default_flags (MU_LOCKER_PID|MU_LOCKER_RETRY, |
363 | mu_locker_assign); | 364 | mu_locker_assign); |
364 | mu_locker_set_default_retry_timeout (1); | 365 | mu_locker_set_default_retry_timeout (1); |
365 | mu_locker_set_default_retry_count (300); | 366 | mu_locker_set_default_retry_count (300); |
366 | 367 | ... | ... |
... | @@ -81,7 +81,7 @@ static int amd_messages_count (mu_mailbox_t, size_t *); | ... | @@ -81,7 +81,7 @@ static int amd_messages_count (mu_mailbox_t, size_t *); |
81 | static int amd_messages_recent (mu_mailbox_t, size_t *); | 81 | static int amd_messages_recent (mu_mailbox_t, size_t *); |
82 | static int amd_message_unseen (mu_mailbox_t, size_t *); | 82 | static int amd_message_unseen (mu_mailbox_t, size_t *); |
83 | static int amd_expunge (mu_mailbox_t); | 83 | static int amd_expunge (mu_mailbox_t); |
84 | static int amd_save_attributes (mu_mailbox_t); | 84 | static int amd_sync (mu_mailbox_t); |
85 | static int amd_uidnext (mu_mailbox_t mailbox, size_t *puidnext); | 85 | static int amd_uidnext (mu_mailbox_t mailbox, size_t *puidnext); |
86 | static int amd_uidvalidity (mu_mailbox_t, unsigned long *); | 86 | static int amd_uidvalidity (mu_mailbox_t, unsigned long *); |
87 | static int amd_scan (mu_mailbox_t, size_t, size_t *); | 87 | static int amd_scan (mu_mailbox_t, size_t, size_t *); |
... | @@ -281,7 +281,7 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, | ... | @@ -281,7 +281,7 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, |
281 | mailbox->_messages_recent = amd_messages_recent; | 281 | mailbox->_messages_recent = amd_messages_recent; |
282 | mailbox->_message_unseen = amd_message_unseen; | 282 | mailbox->_message_unseen = amd_message_unseen; |
283 | mailbox->_expunge = amd_expunge; | 283 | mailbox->_expunge = amd_expunge; |
284 | mailbox->_save_attributes = amd_save_attributes; | 284 | mailbox->_sync = amd_sync; |
285 | mailbox->_uidvalidity = amd_uidvalidity; | 285 | mailbox->_uidvalidity = amd_uidvalidity; |
286 | mailbox->_uidnext = amd_uidnext; | 286 | mailbox->_uidnext = amd_uidnext; |
287 | 287 | ||
... | @@ -862,7 +862,7 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -862,7 +862,7 @@ amd_expunge (mu_mailbox_t mailbox) |
862 | } | 862 | } |
863 | 863 | ||
864 | static int | 864 | static int |
865 | amd_save_attributes (mu_mailbox_t mailbox) | 865 | amd_sync (mu_mailbox_t mailbox) |
866 | { | 866 | { |
867 | struct _amd_data *amd = mailbox->data; | 867 | struct _amd_data *amd = mailbox->data; |
868 | struct _amd_message *mhm; | 868 | struct _amd_message *mhm; | ... | ... |
... | @@ -419,24 +419,23 @@ _file_open (mu_stream_t stream) | ... | @@ -419,24 +419,23 @@ _file_open (mu_stream_t stream) |
419 | char* filename = 0; | 419 | char* filename = 0; |
420 | int flags = 0; | 420 | int flags = 0; |
421 | 421 | ||
422 | assert(fs); | 422 | if (!fs || !fs->filename) |
423 | 423 | return EINVAL; | |
424 | |||
424 | filename = fs->filename; | 425 | filename = fs->filename; |
425 | 426 | ||
426 | assert(filename); | ||
427 | |||
428 | if (fs->file) | 427 | if (fs->file) |
429 | { | 428 | { |
430 | fclose (fs->file); | 429 | fclose (fs->file); |
431 | fs->file = NULL; | 430 | fs->file = NULL; |
432 | } | 431 | } |
433 | 432 | ||
434 | mu_stream_get_flags(stream, &flags); | 433 | mu_stream_get_flags (stream, &flags); |
435 | 434 | ||
436 | /* Map the flags to the system equivalent. */ | 435 | /* Map the flags to the system equivalent. */ |
437 | if (flags & MU_STREAM_WRITE && flags & MU_STREAM_READ) | 436 | if (flags & MU_STREAM_WRITE && flags & MU_STREAM_READ) |
438 | return EINVAL; | 437 | return EINVAL; |
439 | else if (flags & MU_STREAM_WRITE) | 438 | else if (flags & (MU_STREAM_WRITE|MU_STREAM_APPEND)) |
440 | flg = O_WRONLY; | 439 | flg = O_WRONLY; |
441 | else if (flags & MU_STREAM_RDWR) | 440 | else if (flags & MU_STREAM_RDWR) |
442 | flg = O_RDWR; | 441 | flg = O_RDWR; |
... | @@ -453,14 +452,14 @@ _file_open (mu_stream_t stream) | ... | @@ -453,14 +452,14 @@ _file_open (mu_stream_t stream) |
453 | if (flags & MU_STREAM_CREAT) | 452 | if (flags & MU_STREAM_CREAT) |
454 | { | 453 | { |
455 | /* First see if the file already exists. */ | 454 | /* First see if the file already exists. */ |
456 | fd = open(filename, flg); | 455 | fd = open (filename, flg); |
457 | if (fd == -1) | 456 | if (fd == -1) |
458 | { | 457 | { |
459 | /* Oops bail out. */ | 458 | /* Oops bail out. */ |
460 | if (errno != ENOENT) | 459 | if (errno != ENOENT) |
461 | return errno; | 460 | return errno; |
462 | /* Race condition here when creating the file ??. */ | 461 | /* Race condition here when creating the file ??. */ |
463 | fd = open(filename, flg|O_CREAT|O_EXCL, 0600); | 462 | fd = open (filename, flg|O_CREAT|O_EXCL, 0600); |
464 | if (fd < 0) | 463 | if (fd < 0) |
465 | return errno; | 464 | return errno; |
466 | } | 465 | } |
... | @@ -474,16 +473,15 @@ _file_open (mu_stream_t stream) | ... | @@ -474,16 +473,15 @@ _file_open (mu_stream_t stream) |
474 | 473 | ||
475 | /* We have to make sure that We did not open | 474 | /* We have to make sure that We did not open |
476 | a symlink. From Casper D. in bugtraq. */ | 475 | a symlink. From Casper D. in bugtraq. */ |
477 | if ((flg & MU_STREAM_CREAT) || | 476 | if (flg & (MU_STREAM_CREAT | MU_STREAM_RDWR |
478 | (flg & MU_STREAM_RDWR) || | 477 | | MU_STREAM_WRITE | MU_STREAM_APPEND)) |
479 | (flg & MU_STREAM_WRITE)) | ||
480 | { | 478 | { |
481 | struct stat fdbuf, filebuf; | 479 | struct stat fdbuf, filebuf; |
482 | 480 | ||
483 | /* The next two stats should never fail. */ | 481 | /* The next two stats should never fail. */ |
484 | if (fstat(fd, &fdbuf) == -1) | 482 | if (fstat (fd, &fdbuf) == -1) |
485 | return errno; | 483 | return errno; |
486 | if (lstat(filename, &filebuf) == -1) | 484 | if (lstat (filename, &filebuf) == -1) |
487 | return errno; | 485 | return errno; |
488 | 486 | ||
489 | /* Now check that: file and fd reference the same file, | 487 | /* Now check that: file and fd reference the same file, | ... | ... |
... | @@ -177,8 +177,9 @@ mu_folder_destroy (mu_folder_t *pfolder) | ... | @@ -177,8 +177,9 @@ mu_folder_destroy (mu_folder_t *pfolder) |
177 | /* Notify the observers. */ | 177 | /* Notify the observers. */ |
178 | if (folder->observable) | 178 | if (folder->observable) |
179 | { | 179 | { |
180 | mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY); | 180 | mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY, |
181 | mu_observable_destroy (&(folder->observable), folder); | 181 | folder); |
182 | mu_observable_destroy (&folder->observable, folder); | ||
182 | } | 183 | } |
183 | if (folder->_destroy) | 184 | if (folder->_destroy) |
184 | folder->_destroy (folder); | 185 | folder->_destroy (folder); | ... | ... |
... | @@ -174,8 +174,8 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) | ... | @@ -174,8 +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); | 177 | mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_DESTROY, mbox); |
178 | mu_observable_destroy (&(mbox->observable), mbox); | 178 | mu_observable_destroy (&mbox->observable, mbox); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Call the concrete mailbox _destroy method. So it can clean itself. */ | 181 | /* Call the concrete mailbox _destroy method. So it can clean itself. */ |
... | @@ -244,7 +244,8 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) | ... | @@ -244,7 +244,8 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) |
244 | if (!mbox) | 244 | if (!mbox) |
245 | return EINVAL; | 245 | return EINVAL; |
246 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 246 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
247 | return EACCES; | 247 | return 0; |
248 | |||
248 | mu_mailbox_messages_count (mbox, &total); | 249 | mu_mailbox_messages_count (mbox, &total); |
249 | if (mbox->flags & MU_STREAM_APPEND) | 250 | if (mbox->flags & MU_STREAM_APPEND) |
250 | i = total; | 251 | i = total; |
... | @@ -258,10 +259,12 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) | ... | @@ -258,10 +259,12 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) |
258 | mu_message_get_attribute (msg, &attr); | 259 | mu_message_get_attribute (msg, &attr); |
259 | mu_attribute_set_seen (attr); | 260 | mu_attribute_set_seen (attr); |
260 | } | 261 | } |
262 | |||
261 | if (expunge) | 263 | if (expunge) |
262 | status = mu_mailbox_expunge (mbox); | 264 | status = mu_mailbox_expunge (mbox); |
263 | else | 265 | else |
264 | status = mu_mailbox_save_attributes (mbox); | 266 | status = mu_mailbox_sync (mbox); |
267 | |||
265 | return status; | 268 | return status; |
266 | } | 269 | } |
267 | 270 | ||
... | @@ -285,6 +288,15 @@ mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) | ... | @@ -285,6 +288,15 @@ mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) |
285 | } | 288 | } |
286 | 289 | ||
287 | int | 290 | int |
291 | mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, | ||
292 | mu_message_t *pmsg) | ||
293 | { | ||
294 | if (mbox == NULL || mbox->_quick_get_message == NULL) | ||
295 | return MU_ERR_EMPTY_VFN; | ||
296 | return mbox->_quick_get_message (mbox, qid, pmsg); | ||
297 | } | ||
298 | |||
299 | int | ||
288 | mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) | 300 | mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) |
289 | { | 301 | { |
290 | if (mbox == NULL || mbox->_messages_count == NULL) | 302 | if (mbox == NULL || mbox->_messages_count == NULL) |
... | @@ -309,13 +321,24 @@ mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) | ... | @@ -309,13 +321,24 @@ mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) |
309 | } | 321 | } |
310 | 322 | ||
311 | int | 323 | int |
324 | mu_mailbox_sync (mu_mailbox_t mbox) | ||
325 | { | ||
326 | if (mbox == NULL || mbox->_sync == NULL) | ||
327 | return MU_ERR_EMPTY_VFN; | ||
328 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | ||
329 | return 0; | ||
330 | return mbox->_sync (mbox); | ||
331 | } | ||
332 | |||
333 | /* Historic alias: */ | ||
334 | int | ||
312 | mu_mailbox_save_attributes (mu_mailbox_t mbox) | 335 | mu_mailbox_save_attributes (mu_mailbox_t mbox) |
313 | { | 336 | { |
314 | if (mbox == NULL || mbox->_save_attributes == NULL) | 337 | if (mbox == NULL || mbox->_sync == NULL) |
315 | return MU_ERR_EMPTY_VFN; | 338 | return MU_ERR_EMPTY_VFN; |
316 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 339 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
317 | return EACCES; | 340 | return EACCES; |
318 | return mbox->_save_attributes (mbox); | 341 | return mbox->_sync (mbox); |
319 | } | 342 | } |
320 | 343 | ||
321 | int | 344 | int |
... | @@ -347,9 +370,34 @@ mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) | ... | @@ -347,9 +370,34 @@ mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) |
347 | int | 370 | int |
348 | mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) | 371 | mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) |
349 | { | 372 | { |
350 | if (mbox == NULL || mbox->_get_size == NULL) | 373 | int status; |
374 | if (mbox == NULL) | ||
351 | return MU_ERR_EMPTY_VFN; | 375 | return MU_ERR_EMPTY_VFN; |
352 | return mbox->_get_size (mbox, psize); | 376 | if (mbox->_get_size == NULL |
377 | || (status = mbox->_get_size (mbox, psize)) == ENOSYS) | ||
378 | { | ||
379 | /* Fall back to brute-force method */ | ||
380 | size_t i, total; | ||
381 | mu_off_t size = 0; | ||
382 | |||
383 | status = mu_mailbox_messages_count (mbox, &total); | ||
384 | if (status) | ||
385 | return status; | ||
386 | for (i = 1; i <= total; i++) | ||
387 | { | ||
388 | mu_message_t msg; | ||
389 | size_t msgsize; | ||
390 | status = mu_mailbox_get_message (mbox, i, &msg); | ||
391 | if (status) | ||
392 | return status; | ||
393 | status = mu_message_size (msg, &msgsize); | ||
394 | if (status) | ||
395 | return status; | ||
396 | size += msgsize; | ||
397 | } | ||
398 | *psize = size; | ||
399 | } | ||
400 | return status; | ||
353 | } | 401 | } |
354 | 402 | ||
355 | int | 403 | int |
... | @@ -408,7 +456,7 @@ mu_mailbox_set_stream (mu_mailbox_t mbox, mu_stream_t stream) | ... | @@ -408,7 +456,7 @@ mu_mailbox_set_stream (mu_mailbox_t mbox, mu_stream_t stream) |
408 | if (mbox == NULL) | 456 | if (mbox == NULL) |
409 | return MU_ERR_MBX_NULL; | 457 | return MU_ERR_MBX_NULL; |
410 | if (mbox->stream) | 458 | if (mbox->stream) |
411 | mu_stream_destroy (&(mbox->stream), mbox); | 459 | mu_stream_destroy (&mbox->stream, mbox); |
412 | mbox->stream = stream; | 460 | mbox->stream = stream; |
413 | return 0; | 461 | return 0; |
414 | } | 462 | } |
... | @@ -451,7 +499,7 @@ mu_mailbox_get_observable (mu_mailbox_t mbox, mu_observable_t *pobservable) | ... | @@ -451,7 +499,7 @@ mu_mailbox_get_observable (mu_mailbox_t mbox, mu_observable_t *pobservable) |
451 | 499 | ||
452 | if (mbox->observable == NULL) | 500 | if (mbox->observable == NULL) |
453 | { | 501 | { |
454 | int status = mu_observable_create (&(mbox->observable), mbox); | 502 | int status = mu_observable_create (&mbox->observable, mbox); |
455 | if (status != 0) | 503 | if (status != 0) |
456 | return status; | 504 | return status; |
457 | } | 505 | } | ... | ... |
... | @@ -157,8 +157,9 @@ mu_mailer_destroy (mu_mailer_t * pmailer) | ... | @@ -157,8 +157,9 @@ mu_mailer_destroy (mu_mailer_t * pmailer) |
157 | 157 | ||
158 | if (mailer->observable) | 158 | if (mailer->observable) |
159 | { | 159 | { |
160 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_DESTROY); | 160 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_DESTROY, |
161 | mu_observable_destroy (&(mailer->observable), mailer); | 161 | mailer); |
162 | mu_observable_destroy (&mailer->observable, mailer); | ||
162 | } | 163 | } |
163 | 164 | ||
164 | /* Call the object destructor. */ | 165 | /* Call the object destructor. */ | ... | ... |
... | @@ -115,7 +115,8 @@ mu_message_destroy (mu_message_t *pmsg, void *owner) | ... | @@ -115,7 +115,8 @@ mu_message_destroy (mu_message_t *pmsg, void *owner) |
115 | /* FIXME: to be removed since we do not support this event. */ | 115 | /* FIXME: to be removed since we do not support this event. */ |
116 | if (msg->observable) | 116 | if (msg->observable) |
117 | { | 117 | { |
118 | mu_observable_notify (msg->observable, MU_EVT_MESSAGE_DESTROY); | 118 | mu_observable_notify (msg->observable, MU_EVT_MESSAGE_DESTROY, |
119 | msg); | ||
119 | mu_observable_destroy (&(msg->observable), msg); | 120 | mu_observable_destroy (&(msg->observable), msg); |
120 | } | 121 | } |
121 | 122 | ||
... | @@ -649,8 +650,31 @@ mu_message_get_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pwri | ... | @@ -649,8 +650,31 @@ mu_message_get_uidl (mu_message_t msg, char *buffer, size_t buflen, size_t *pwri |
649 | } | 650 | } |
650 | 651 | ||
651 | int | 652 | int |
653 | mu_message_get_qid (mu_message_t msg, mu_message_qid_t *pqid) | ||
654 | { | ||
655 | if (msg == NULL) | ||
656 | return EINVAL; | ||
657 | if (!msg->_get_qid) | ||
658 | return ENOSYS; | ||
659 | return msg->_get_qid (msg, pqid); | ||
660 | } | ||
661 | |||
662 | int | ||
663 | mu_message_set_qid (mu_message_t msg, | ||
664 | int (*_get_qid) (mu_message_t, mu_message_qid_t *), | ||
665 | void *owner) | ||
666 | { | ||
667 | if (msg == NULL) | ||
668 | return EINVAL; | ||
669 | if (msg->owner != owner) | ||
670 | return EACCES; | ||
671 | msg->_get_qid = _get_qid; | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | int | ||
652 | mu_message_set_uid (mu_message_t msg, int (*_get_uid) (mu_message_t, size_t *), | 676 | mu_message_set_uid (mu_message_t msg, int (*_get_uid) (mu_message_t, size_t *), |
653 | void *owner) | 677 | void *owner) |
654 | { | 678 | { |
655 | if (msg == NULL) | 679 | if (msg == NULL) |
656 | return EINVAL; | 680 | return EINVAL; | ... | ... |
... | @@ -49,7 +49,7 @@ mu_observer_destroy (mu_observer_t *pobserver, void *owner) | ... | @@ -49,7 +49,7 @@ mu_observer_destroy (mu_observer_t *pobserver, void *owner) |
49 | if (observer->owner == owner || observer->flags & MU_OBSERVER_NO_CHECK) | 49 | if (observer->owner == owner || observer->flags & MU_OBSERVER_NO_CHECK) |
50 | { | 50 | { |
51 | if (observer->_destroy) | 51 | if (observer->_destroy) |
52 | observer->_destroy (observer); | 52 | observer->_destroy (observer, observer->_action_data); |
53 | free (observer); | 53 | free (observer); |
54 | } | 54 | } |
55 | *pobserver = NULL; | 55 | *pobserver = NULL; |
... | @@ -63,18 +63,19 @@ mu_observer_get_owner (mu_observer_t observer) | ... | @@ -63,18 +63,19 @@ mu_observer_get_owner (mu_observer_t observer) |
63 | } | 63 | } |
64 | 64 | ||
65 | int | 65 | int |
66 | mu_observer_action (mu_observer_t observer, size_t type) | 66 | mu_observer_action (mu_observer_t observer, size_t type, void *data) |
67 | { | 67 | { |
68 | if (observer == NULL) | 68 | if (observer == NULL) |
69 | return EINVAL; | 69 | return EINVAL; |
70 | if (observer->_action) | 70 | if (observer->_action) |
71 | return observer->_action (observer, type); | 71 | return observer->_action (observer, type, data, observer->_action_data); |
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | int | 75 | int |
76 | mu_observer_set_action (mu_observer_t observer, | 76 | mu_observer_set_action (mu_observer_t observer, |
77 | int (*_action) (mu_observer_t, size_t), void *owner) | 77 | int (*_action) (mu_observer_t, size_t, void *, void *), |
78 | void *owner) | ||
78 | { | 79 | { |
79 | if (observer == NULL) | 80 | if (observer == NULL) |
80 | return EINVAL; | 81 | return EINVAL; |
... | @@ -85,8 +86,20 @@ mu_observer_set_action (mu_observer_t observer, | ... | @@ -85,8 +86,20 @@ mu_observer_set_action (mu_observer_t observer, |
85 | } | 86 | } |
86 | 87 | ||
87 | int | 88 | int |
88 | mu_observer_set_destroy (mu_observer_t observer, int (*_destroy) (mu_observer_t), | 89 | mu_observer_set_action_data (mu_observer_t observer, void *data, void *owner) |
89 | void *owner) | 90 | { |
91 | if (observer == NULL) | ||
92 | return EINVAL; | ||
93 | if (observer->owner != owner) | ||
94 | return EACCES; | ||
95 | observer->_action_data = data; | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | int | ||
100 | mu_observer_set_destroy (mu_observer_t observer, | ||
101 | int (*_destroy) (mu_observer_t, void *), | ||
102 | void *owner) | ||
90 | { | 103 | { |
91 | if (observer == NULL) | 104 | if (observer == NULL) |
92 | return EINVAL; | 105 | return EINVAL; |
... | @@ -214,7 +227,7 @@ mu_observable_detach (mu_observable_t observable, mu_observer_t observer) | ... | @@ -214,7 +227,7 @@ mu_observable_detach (mu_observable_t observable, mu_observer_t observer) |
214 | } | 227 | } |
215 | 228 | ||
216 | int | 229 | int |
217 | mu_observable_notify (mu_observable_t observable, int type) | 230 | mu_observable_notify (mu_observable_t observable, int type, void *data) |
218 | { | 231 | { |
219 | mu_iterator_t iterator; | 232 | mu_iterator_t iterator; |
220 | event_t event = NULL; | 233 | event_t event = NULL; |
... | @@ -231,7 +244,7 @@ mu_observable_notify (mu_observable_t observable, int type) | ... | @@ -231,7 +244,7 @@ mu_observable_notify (mu_observable_t observable, int type) |
231 | mu_iterator_current (iterator, (void **)&event); | 244 | mu_iterator_current (iterator, (void **)&event); |
232 | if (event && event->type & type) | 245 | if (event && event->type & type) |
233 | { | 246 | { |
234 | status |= mu_observer_action (event->observer, type); | 247 | status |= mu_observer_action (event->observer, type, data); |
235 | } | 248 | } |
236 | } | 249 | } |
237 | mu_iterator_destroy (&iterator); | 250 | mu_iterator_destroy (&iterator); | ... | ... |
... | @@ -148,7 +148,7 @@ main (int argc, char **argv) | ... | @@ -148,7 +148,7 @@ main (int argc, char **argv) |
148 | 148 | ||
149 | mh_msgset_current (mbox, &msgset, 0); | 149 | mh_msgset_current (mbox, &msgset, 0); |
150 | mh_global_save_state (); | 150 | mh_global_save_state (); |
151 | mu_mailbox_save_attributes (mbox); | 151 | mu_mailbox_sync (mbox); |
152 | mu_mailbox_close (mbox); | 152 | mu_mailbox_close (mbox); |
153 | mu_mailbox_destroy (&mbox); | 153 | mu_mailbox_destroy (&mbox); |
154 | return rc; | 154 | return rc; | ... | ... |
... | @@ -469,7 +469,7 @@ main (int argc, char **argv) | ... | @@ -469,7 +469,7 @@ main (int argc, char **argv) |
469 | 469 | ||
470 | rc = mh_whatnow (&wh_env, initial_edit); | 470 | rc = mh_whatnow (&wh_env, initial_edit); |
471 | 471 | ||
472 | mu_mailbox_save_attributes (mbox); | 472 | mu_mailbox_sync (mbox); |
473 | mu_mailbox_close (mbox); | 473 | mu_mailbox_close (mbox); |
474 | mu_mailbox_destroy (&mbox); | 474 | mu_mailbox_destroy (&mbox); |
475 | return rc; | 475 | return rc; | ... | ... |
... | @@ -442,7 +442,7 @@ main (int argc, char **argv) | ... | @@ -442,7 +442,7 @@ main (int argc, char **argv) |
442 | 442 | ||
443 | rc = mh_whatnow (&wh_env, initial_edit); | 443 | rc = mh_whatnow (&wh_env, initial_edit); |
444 | 444 | ||
445 | mu_mailbox_save_attributes (mbox); | 445 | mu_mailbox_sync (mbox); |
446 | mu_mailbox_close (mbox); | 446 | mu_mailbox_close (mbox); |
447 | mu_mailbox_destroy (&mbox); | 447 | mu_mailbox_destroy (&mbox); |
448 | return rc; | 448 | return rc; | ... | ... |
... | @@ -147,9 +147,9 @@ opt_handler (int key, char *arg, void *unused, struct argp_state *state) | ... | @@ -147,9 +147,9 @@ opt_handler (int key, char *arg, void *unused, struct argp_state *state) |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | /* Observable Action this is being call at every message discover. */ | 150 | /* Observable Action this is called at every message discover. */ |
151 | static int | 151 | static int |
152 | action (mu_observer_t o, size_t type) | 152 | action (mu_observer_t o, size_t type, void *data, void *action_data) |
153 | { | 153 | { |
154 | static int counter; | 154 | static int counter; |
155 | mu_mailbox_t mbox; | 155 | mu_mailbox_t mbox; | ... | ... |
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
-
Please register or sign in to post a comment