1 #ifndef MAIL_DELIVER_H
2 #define MAIL_DELIVER_H
3 
4 #include "guid.h"
5 #include "mail-types.h"
6 #include "mail-error.h"
7 #include "smtp-params.h"
8 
9 #include <sys/time.h>
10 
11 struct smtp_address;
12 struct mail_storage;
13 struct mail_save_context;
14 struct mailbox;
15 
16 enum mail_deliver_error {
17 	MAIL_DELIVER_ERROR_NONE = 0,
18 
19 	/* Temporary error */
20 	MAIL_DELIVER_ERROR_TEMPORARY,
21 	/* Delivery rejected */
22 	MAIL_DELIVER_ERROR_REJECTED,
23 	/* Out of storage quota for mailbox or user */
24 	MAIL_DELIVER_ERROR_NOQUOTA,
25 	/* Internal error (BUG) */
26 	MAIL_DELIVER_ERROR_INTERNAL,
27 };
28 
29 struct mail_deliver_session {
30 	pool_t pool;
31 
32 	/* List of INBOX GUIDs where this mail has already been saved to */
33 	ARRAY(guid_128_t) inbox_guids;
34 };
35 
36 struct mail_deliver_input {
37 	const struct lda_settings *set;
38 	const struct smtp_submit_settings *smtp_set;
39 	struct mail_deliver_session *session;
40 	struct event *event_parent;
41 
42 	unsigned int session_time_msecs;
43 	struct timeval delivery_time_started;
44 
45 	/* Session ID, used as log line prefix if non-NULL. */
46 	const char *session_id;
47 	/* Mail to save */
48 	struct mail *src_mail;
49 
50 	/* Envelope sender, if known. */
51 	const struct smtp_address *mail_from;
52 	/* MAIL parameters */
53 	struct smtp_params_mail mail_params;
54 
55 	/* Envelope recipient (final recipient) */
56 	const struct smtp_address *rcpt_to;
57 	/* RCPT parameters (can contain original recipient) */
58 	struct smtp_params_rcpt rcpt_params;
59 	/* Destination user */
60 	struct mail_user *rcpt_user;
61 	/* Mailbox where mail should be saved, unless e.g. Sieve does
62 	   something to it. */
63 	const char *rcpt_default_mailbox;
64 
65 	bool save_dest_mail:1;
66 };
67 
68 struct mail_deliver_fields {
69 	const char *message_id;
70 	const char *subject;
71 	const char *from;
72 	const char *from_envelope;
73 	const char *storage_id;
74 
75 	uoff_t psize, vsize;
76 
77 	bool filled:1;
78 };
79 
80 struct mail_deliver_context {
81 	pool_t pool;
82 	const struct lda_settings *set;
83 	const struct smtp_submit_settings *smtp_set;
84 	struct mail_deliver_session *session;
85 	struct event *event;
86 
87 	unsigned int session_time_msecs;
88 	struct timeval delivery_time_started;
89 
90 	struct mail_duplicate_db *dup_db;
91 
92 	/* Session ID, used as log line prefix if non-NULL. */
93 	const char *session_id;
94 	/* Mail to save */
95 	struct mail *src_mail;
96 
97 	/* Envelope sender, if known. */
98 	const struct smtp_address *mail_from;
99 	/* MAIL parameters */
100 	struct smtp_params_mail mail_params;
101 
102 	/* Envelope recipient (final recipient) */
103 	const struct smtp_address *rcpt_to;
104 	/* RCPT parameters (can contain original recipient) */
105 	struct smtp_params_rcpt rcpt_params;
106 	/* Destination user */
107 	struct mail_user *rcpt_user;
108 	/* Mailbox where mail should be saved, unless e.g. Sieve does
109 	   something to it. */
110 	const char *rcpt_default_mailbox;
111 
112 	/* Filled with destination mail, if save_dest_mail=TRUE.
113 	   The caller must free the mail, its transaction and close
114 	   the mailbox. */
115 	struct mail *dest_mail;
116 
117 	/* Recorded field values for the transaction */
118 	struct mail_deliver_fields fields;
119 
120 	/* Error message for a temporary failure. This is necessary only when
121 	   there is no storage where to get the error message from. */
122 	const char *tempfail_error;
123 
124 	bool tried_default_save;
125 	bool saved_mail;
126 	bool save_dest_mail;
127 	/* Delivery failed because user is out of quota / disk space */
128 	bool mailbox_full;
129 	/* Send DSN instead of MDN */
130 	bool dsn;
131 };
132 
133 struct mail_deliver_save_open_context {
134 	struct mail_user *user;
135 	bool lda_mailbox_autocreate;
136 	bool lda_mailbox_autosubscribe;
137 };
138 
139 typedef int deliver_mail_func_t(struct mail_deliver_context *ctx,
140 				struct mail_storage **storage_r);
141 
142 extern deliver_mail_func_t *deliver_mail;
143 
144 const struct var_expand_table *
145 mail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context *ctx,
146 					  const char *message);
147 void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
148 	ATTR_FORMAT(2, 3);
149 
150 const struct smtp_address *
151 mail_deliver_get_address(struct mail *mail, const char *header);
152 const struct smtp_address *
153 mail_deliver_get_return_address(struct mail_deliver_context *ctx);
154 const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx);
155 
156 struct mail_deliver_session *mail_deliver_session_init(void);
157 void mail_deliver_session_deinit(struct mail_deliver_session **session);
158 
159 void mail_deliver_init(struct mail_deliver_context *ctx,
160 		       struct mail_deliver_input *input);
161 void mail_deliver_deinit(struct mail_deliver_context *ctx);
162 
163 /* Try to open mailbox for saving. Returns 0 if ok, -1 if error. The box may
164    be returned even with -1, and the caller must free it then. */
165 int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
166 			   const char *name, struct mailbox **box_r,
167 			   enum mail_error *error_r, const char **error_str_r);
168 int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
169 		      enum mail_flags flags, const char *const *keywords,
170 		      struct mail_storage **storage_r) ATTR_NULL(4);
171 void mail_deliver_deduplicate_guid_if_needed(struct mail_deliver_session *session,
172 					     struct mail_save_context *save_ctx);
173 
174 int mail_deliver(struct mail_deliver_context *ctx,
175 		 enum mail_deliver_error *error_code_r,
176 		 const char **error_r);
177 
178 /* Sets the deliver_mail hook and returns the previous hook,
179    which the new_hook should call if it's non-NULL. */
180 deliver_mail_func_t *mail_deliver_hook_set(deliver_mail_func_t *new_hook);
181 
182 /* Must be called before any storage is created. */
183 void mail_deliver_hooks_init(void);
184 
185 #endif
186