masqmail-0.2

view src/masqmail.h @ 75:257a9e6d1a8e

fixed correct processing of mails with data lines longer 4096 chars Mail messages with lines longer than 4096 chars were already read correctly, i.e. the spool files were correct. This commit fixes the reading of spool files with long lines. The old behavior was that the message body was truncated right before the first line longer 4096 chars. The number comes from MAX_DATALINE.
author meillo@marmaro.de
date Wed, 16 Jun 2010 19:06:34 +0200
parents 08114f7dcc23
children f4719cffc48c
line source
1 /* MasqMail
2 Copyright (C) 1999-2001 Oliver Kurth
4 This program 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 2 of the License, or
7 (at your option) any later version.
9 This program 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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include <config.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <unistd.h>
27 #include <pwd.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <time.h>
32 #include <sys/time.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <netdb.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <fcntl.h>
40 #include <glib.h>
42 #ifdef ENABLE_IDENT
43 #include "libident/ident.h"
44 #endif
46 #include "lookup.h"
48 typedef struct _interface {
49 gchar *address;
50 gint port;
51 } interface;
53 #define ADDR_FLAG_DELIVERED 0x01
54 #define ADDR_FLAG_DEFERED 0x02
55 #define ADDR_FLAG_FAILED 0x04
56 #define ADDR_FLAG_LAST_ROUTE 0x40
57 #define ADDR_FLAG_NOEXPAND 0x80
59 typedef struct _address {
60 gchar *address;
61 gchar *local_part;
62 gchar *domain;
63 gint flags;
64 GList *children;
65 struct _address *parent;
66 } address;
68 #define addr_mark_delivered(addr) { addr->flags |= ADDR_FLAG_DELIVERED; }
69 #define addr_unmark_delivered(addr) { addr->flags &= ~ADDR_FLAG_DELIVERED; }
70 #define addr_is_delivered(addr) ((addr->flags & ADDR_FLAG_DELIVERED) != 0 )
72 #define addr_mark_defered(addr) { addr->flags |= ADDR_FLAG_DEFERED; }
73 #define addr_unmark_defered(addr) { addr->flags &= ~ADDR_FLAG_DEFERED; }
74 #define addr_is_defered(addr) ((addr->flags & ADDR_FLAG_DEFERED) != 0 )
76 #define addr_mark_failed(addr) { addr->flags |= ADDR_FLAG_FAILED; }
77 #define addr_unmark_failed(addr) { addr->flags &= ~ADDR_FLAG_FAILED; }
78 #define addr_is_failed(addr) ((addr->flags & ADDR_FLAG_FAILED) != 0 )
80 typedef struct _connect_route {
81 gchar *name;
82 gchar *filename;
84 gchar *protocol;
86 gboolean is_local_net;
87 gboolean last_route;
89 GList *allowed_return_paths;
90 GList *not_allowed_return_paths;
91 GList *allowed_mail_locals;
92 GList *not_allowed_mail_locals;
93 GList *allowed_rcpt_domains;
94 GList *not_allowed_rcpt_domains;
96 interface *mail_host;
97 gchar *wrapper;
98 gboolean connect_error_fail;
100 gchar *helo_name;
101 gboolean do_correct_helo;
102 gboolean do_pipelining;
104 gchar *set_h_from_domain;
105 gchar *set_h_reply_to_domain;
106 gchar *set_return_path_domain;
108 GList *map_h_from_addresses;
109 GList *map_h_reply_to_addresses;
110 GList *map_h_mail_followup_to_addresses;
111 GList *map_return_path_addresses;
113 gboolean expand_h_sender_domain;
114 gboolean expand_h_sender_address;
116 GList *resolve_list;
118 gchar *auth_name;
119 gchar *auth_login;
120 gchar *auth_secret;
122 gchar *pop3_login;
124 gchar *pipe;
126 gboolean pipe_fromline;
127 gboolean pipe_fromhack;
128 } connect_route;
130 typedef struct _get_conf {
131 gchar *protocol;
132 gchar *server_name;
133 guint server_port;
134 gchar *wrapper;
135 gchar *login_user;
136 gchar *login_pass;
137 address *address;
138 address *return_path;
139 gboolean do_keep;
140 gboolean do_uidl;
141 gboolean do_uidl_dele;
142 gint max_size;
143 gboolean max_size_delete;
144 gint max_count;
146 GList *resolve_list;
148 } get_conf;
150 typedef struct _masqmail_conf {
151 gint mail_uid;
152 gint mail_gid;
154 gint orig_uid;
155 gint orig_gid;
157 gboolean run_as_user;
159 gchar *mail_dir;
160 gchar *lock_dir;
161 gchar *spool_dir;
162 gchar *log_dir;
164 gint debug_level;
165 gboolean use_syslog;
166 guint log_max_pri;
168 gchar *host_name;
169 GList *local_hosts;
170 GList *local_addresses;
171 GList *not_local_addresses;
172 GList *local_nets;
173 GList *listen_addresses;
175 guint remote_port;
177 gboolean do_save_envelope_to;
179 gboolean defer_all;
180 gboolean do_relay;
182 GList *ident_trusted_nets;
184 gboolean do_queue;
186 gboolean do_verbose;
188 gchar *mbox_default;
189 GList *mbox_users;
190 GList *mda_users;
191 GList *maildir_users;
193 gchar *mda;
194 gboolean mda_fromline;
195 gboolean mda_fromhack;
197 gboolean pipe_fromline;
198 gboolean pipe_fromhack;
200 gchar *alias_file;
201 int (*alias_local_cmp) (const char *, const char *);
203 GList *local_net_routes;
204 GList *connect_routes; /* list of pairs which point to lists */
206 gchar *online_detect;
207 gchar *online_file;
208 gchar *online_pipe;
209 interface *mserver_iface;
211 GList *get_names;
212 GList *online_gets; /* list of pairs which point to lists */
214 gchar *errmsg_file;
215 gchar *warnmsg_file;
216 GList *warn_intervals;
217 gint max_defer_time;
219 gchar *log_user;
220 } masqmail_conf;
222 extern masqmail_conf conf;
224 typedef struct _table_pair {
225 gchar *key;
226 gpointer *value;
227 } table_pair;
230 typedef enum _prot_id {
231 PROT_LOCAL = 0,
232 PROT_BSMTP,
233 PROT_SMTP,
234 PROT_ESMTP,
235 PROT_POP3,
236 PROT_APOP,
237 PROT_NUM
238 } prot_id;
240 extern gchar *prot_names[];
242 typedef enum _header_id {
243 HEAD_FROM = 0,
244 HEAD_SENDER,
245 HEAD_TO,
246 HEAD_CC,
247 HEAD_BCC,
248 HEAD_DATE,
249 HEAD_MESSAGE_ID,
250 HEAD_REPLY_TO,
251 HEAD_SUBJECT,
252 HEAD_RETURN_PATH,
253 HEAD_ENVELOPE_TO,
254 HEAD_RECEIVED,
255 HEAD_NUM_IDS,
256 HEAD_STATUS,
257 HEAD_UNKNOWN = HEAD_NUM_IDS,
258 HEAD_NONE = -1,
259 } header_id;
261 typedef struct _header_name {
262 gchar *header;
263 header_id id;
264 } header_name;
266 typedef struct _header {
267 header_id id;
268 gchar *header;
269 gchar *value;
270 } header;
273 typedef struct _message {
274 gchar *uid;
276 gchar *received_host;
277 prot_id received_prot;
278 gchar *ident;
279 gint transfer_id; /* for multiple messages per transfer */
281 address *return_path;
282 GList *rcpt_list;
283 GList *non_rcpt_list;
285 GList *hdr_list;
286 GList *data_list;
288 gint data_size;
289 time_t received_time;
290 time_t warned_time;
292 gchar *full_sender_name;
293 } message;
295 typedef struct _msg_out {
296 message *msg;
298 address *return_path;
299 GList *rcpt_list;
301 GList *hdr_list;
302 GList *xtra_hdr_list;
303 } msg_out;
305 typedef struct _msgout_perhost {
306 gchar *host;
307 GList *msgout_list;
308 } msgout_perhost;
310 /* flags for accept() */
311 /*#define ACC_LOCAL 0x01 (we better use received_host == NULL) */
312 #define ACC_HEAD_FROM_RCPT 0x01 /* create To: Header from rcpt_list (cmd line) */
313 #define ACC_DEL_RCPTS 0x02 /* -t option, delete rcpts */
314 #define ACC_DEL_BCC 0x04 /* -t option, delete Bcc header */
315 #define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */
316 #define ACC_NODOT_TERM 0x10 /* a dot on a line itself does not end the message (-oi option) */
317 #define ACC_NO_RECVD_HDR 0x20 /* do not create a Received: header */
318 #define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */
319 #define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */
320 #define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */
322 #define DLVR_LOCAL 0x01
323 #define DLVR_LAN 0x02
324 #define DLVR_ONLINE 0x04
325 #define DLVR_ALL (DLVR_LOCAL|DLVR_LAN|DLVR_ONLINE)
327 /* transport flags */
328 #define MSGSTR_FROMLINE 0x01
329 #define MSGSTR_FROMHACK 0x02
331 typedef enum _accept_error {
332 AERR_OK = 0,
333 AERR_TIMEOUT,
334 AERR_EOF,
335 AERR_OVERFLOW,
336 AERR_SYNTAX,
337 AERR_NOSPOOL,
338 AERR_NORCPT,
339 AERR_UNKNOWN
340 } accept_error;
342 #define BUF_LEN 1024
343 #define MAX_ADDRESS 256
344 #define MAX_DATALINE 4096
346 typedef enum _smtp_cmd_id {
347 SMTP_HELO = 0,
348 SMTP_EHLO,
349 SMTP_MAIL_FROM,
350 SMTP_RCPT_TO,
351 SMTP_DATA,
352 SMTP_QUIT,
353 SMTP_RSET,
354 SMTP_NOOP,
355 SMTP_HELP,
356 SMTP_NUM_IDS,
357 SMTP_EOF = -1,
358 SMTP_ERROR = -2,
359 } smtp_cmd_id;
361 typedef struct _smtp_cmd {
362 smtp_cmd_id id;
363 gchar *cmd;
364 } smtp_cmd;
366 typedef struct _smtp_connection {
367 gchar *remote_host;
369 prot_id prot;
370 gint next_id;
372 gboolean helo_seen;
373 gboolean from_seen;
374 gboolean rcpt_seen;
376 message *msg;
377 } smtp_connection;
379 /* alias.c*/
380 gboolean addr_is_local(address * addr);
381 GList *alias_expand(GList * alias_table, GList * rcpt_list, GList * non_rcpt_list);
383 /* child.c */
384 int child(const char *command);
386 /* conf.c */
387 void init_conf();
388 gboolean read_conf(gchar * filename);
389 connect_route *read_route(gchar * filename, gboolean is_local_net);
390 GList *read_route_list(GList * rf_list, gboolean is_local_net);
391 void destroy_route(connect_route * r);
392 void destroy_route_list(GList * list);
393 get_conf *read_get_conf(gchar * filename);
394 void destroy_get_conf(get_conf * gc);
395 connect_route *create_local_route();
397 /* expand.c */
398 GList *var_table_rcpt(GList * var_table, address * rcpt);
399 GList *var_table_msg(GList * var_table, message * msg);
400 GList *var_table_conf(GList * var_table);
401 gint expand(GList * var_list, gchar * format, gchar * result, gint result_len);
403 /* message.c */
404 message *create_message(void);
405 void destroy_message(message * msg);
406 void destroy_msg_list(GList * msg_list);
407 void msg_free_data(message * msg);
408 gint msg_calc_size(message * msg, gboolean is_smtp);
410 msg_out *create_msg_out(message * msg);
411 msg_out *clone_msg_out(msg_out * msgout_orig);
412 GList *create_msg_out_list(GList * msg_list);
413 void destroy_msg_out(msg_out * msgout);
414 void destroy_msg_out_list(GList * msgout_list);
416 /* address.c */
417 address *create_address(gchar * path, gboolean is_rfc821);
418 address *create_address_qualified(gchar * path, gboolean is_rfc821, gchar * domain);
419 address *create_address_pipe(gchar * path);
420 void destroy_address(address * addr);
421 address *copy_modify_address(const address * orig, gchar * l_part, gchar * dom);
422 #define copy_address(addr) copy_modify_address(addr, NULL, NULL)
423 gboolean addr_isequal(address * addr1, address * addr2);
424 gboolean addr_isequal_parent(address * addr1, address * addr2);
425 address *addr_find_ancestor(address * addr);
426 gboolean addr_is_delivered_children(address * addr);
427 gboolean addr_is_finished_children(address * addr);
428 gchar *addr_string(address * addr);
429 gint addr_match(address * addr1, address * addr2);
431 /* accept.c */
432 accept_error accept_message(FILE * in, message * msg, guint flags);
433 accept_error accept_message_prepare(message * msg, guint flags);
435 /* header.c */
436 gchar *rec_timestamp();
437 GList *find_header(GList * hdr_list, header_id id, gchar * hdr_str);
438 void header_unfold(header * hdr);
439 void header_fold(header * hdr);
440 header *create_header(header_id id, gchar * fmt, ...);
441 void destroy_header(header * hdr);
442 header *copy_header(header * hdr);
443 header *get_header(gchar * line);
445 /* smtp_in.c */
446 void smtp_in(FILE * in, FILE * out, gchar * remote_host, gchar * ident);
448 /* listen.c */
449 void listen_port(GList * addr_list, gint qival, char *argv[]);
451 /* parse.c */
452 gboolean split_address(const gchar * path, gchar ** local_part, gchar ** domain, gboolean is_rfc821);
453 gboolean parse_address_rfc822(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end);
454 gboolean parse_address_rfc821(gchar * string, gchar ** local_begin, gchar ** local_end, gchar ** domain_begin, gchar ** domain_end, gchar ** address_end);
455 address *_create_address(gchar * string, gchar ** end, gboolean is_rfc821);
456 address *create_address_rfc821(gchar * string, gchar ** end);
457 address *create_address_rfc822(gchar * string, gchar ** end);
458 GList *addr_list_append_rfc822(GList * addr_list, gchar * string, gchar * domain);
459 gboolean addr_isequal(address * addr1, address * addr2);
461 /* connect.c */
462 mxip_addr *connect_hostlist(int *psockfd, gchar * host, guint port, GList * addr_list);
463 mxip_addr *connect_resolvelist(int *psockfd, gchar * host, guint port, GList * res_funcs);
465 /* deliver.c */
466 void msg_rcptlist_local(GList * rcpt_list, GList **, GList **);
467 gboolean deliver_local(msg_out * msgout);
468 gboolean deliver_msglist_host(connect_route * route, GList * msg_list, gchar * host, GList * res_list);
469 gboolean deliver_route_msgout_list(connect_route * route, GList * msgout_list);
470 gboolean deliver_route_msg_list(connect_route * route, GList * msgout_list);
471 gboolean deliver_finish(msg_out * msgout);
472 gboolean deliver_finish_list(GList * msgout_list);
473 gboolean deliver_msg_list(GList * msg_list, guint flags);
474 gboolean deliver(message * msg);
476 /* fail_msg.c */
477 gboolean fail_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args);
478 gboolean warn_msg(message * msg, gchar * template, GList * failed_rcpts, gchar * err_fmt, va_list args);
480 /* get.c */
481 gboolean get_from_file(gchar * fname);
482 gboolean get_from_name(gchar * name);
483 gboolean get_all(void);
484 void get_online(void);
485 void get_daemon(gint gival, char *argv[]);
486 gboolean pop_before_smtp(gchar * fname);
488 /* interface.c */
489 gboolean init_sockaddr(struct sockaddr_in *name, interface * iface);
490 int make_server_socket(interface * iface);
492 /* local.c */
493 gboolean append_file(message * msg, GList * hdr_list, gchar * user);
494 gboolean maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags);
495 gboolean pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags);
497 /* log.c */
498 gchar *ext_strerror(int err);
499 gboolean logopen(void);
500 void logclose(void);
501 void vlogwrite(int pri, const char *fmt, va_list args);
502 void logwrite(int pri, const char *fmt, ...);
503 void debugf(const char *fmt, ...);
504 void vdebugf(const char *fmt, va_list args);
505 void maillog(const char *fmt, ...);
507 /* spool.c */
508 gboolean spool_read_data(message * msg);
509 gboolean spool_read_data(message * msg);
510 message *msg_spool_read(gchar * uid, gboolean do_readdata);
511 gboolean spool_write(message * msg, gboolean do_writedata);
512 gboolean spool_lock(gchar * uid);
513 gboolean spool_unlock(gchar * uid);
514 gboolean spool_delete_all(message * msg);
516 /* queue.c */
517 GList *read_queue(gboolean do_readdata);
518 gboolean queue_run(void);
519 gboolean queue_run_online(void);
520 void queue_list(void);
521 gboolean queue_delete(gchar * uid);
523 /* online.c */
524 gchar *detect_online();
525 void set_online_name(gchar * name);
527 /* permissions.c */
528 gboolean is_ingroup(uid_t uid, gid_t gid);
529 void set_euidgid(gint uid, gint gid, uid_t * old_uid, gid_t * old_gid);
530 void set_identity(uid_t old_uid, gchar * task_name);
532 /* rewrite.c */
533 gboolean set_address_header_domain(header * hdr, gchar * domain);
534 gboolean map_address_header(header * hdr, GList * table);
536 /* route.c */
537 msgout_perhost *create_msgout_perhost(gchar * host);
538 void destroy_msgout_perhost(msgout_perhost * mo_ph);
539 void rewrite_headers(msg_out * msgout, connect_route * route);
540 void rcptlist_with_one_of_hostlist(GList * rcpt_list, GList * host_list, GList **, GList **);
541 void rcptlist_with_addr_is_local(GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list);
542 gboolean route_strip_msgout(connect_route * route, msg_out * msgout);
543 msg_out *route_prepare_msgout(connect_route * route, msg_out * msgout);
544 GList *route_msgout_list(connect_route * route, GList * msgout_list);
545 gboolean route_is_allowed_return_path(connect_route * route, address * ret_path);
546 gboolean route_is_allowed_mail_local(connect_route * route, address * ret_path);
547 void msg_rcptlist_route(connect_route * route, GList * rcpt_list, GList ** p_rcpt_list, GList ** p_non_rcpt_list);
549 /* tables.c */
550 table_pair *create_pair(gchar * key, gpointer value);
551 table_pair *create_pair_string(gchar * key, gpointer value);
552 table_pair *parse_table_pair(gchar * line, char delim);
553 gpointer *table_find_func(GList * table_list, gchar * key, int (*cmp_func) (const char *, const char *));
554 gpointer *table_find(GList * table_list, gchar * key);
555 gpointer *table_find_case(GList * table_list, gchar * key);
556 gpointer *table_find_fnmatch(GList * table_list, gchar * key);
557 GList *table_read(gchar * fname, gchar delim);
558 void destroy_table(GList * table);
560 /* timeival.c */
561 gint time_interval(gchar * str, gint * pos);
563 /* permissions.c */
564 gboolean is_privileged_user(uid_t uid);
566 /* other things */
568 #define foreach(list, node)\
569 for((node) = g_list_first(list);\
570 (node);\
571 (node) = g_list_next(node))
573 #ifdef ENABLE_DEBUG
574 #define DEBUG(level) if(level <= conf.debug_level)
575 #else
576 /* hopefully the compiler optmizes this away... */
577 #define DEBUG(level) if(0)
578 #endif
580 #define LOG_VERBOSE 0x100
582 #ifndef HAVE_GETLINE
583 #define getline(buf, size, file) getdelim(buf, size, '\n', file)
584 #endif
586 #ifndef HAVE_FDATASYNC
587 #define fdatasync(fd) fsync(fd)
588 #endif
590 #ifndef CONF_DIR
591 #define CONF_DIR "/etc/masqmail"
592 #endif
594 #define CONF_FILE CONF_DIR"/masqmail.conf"
596 #define PIDFILEDIR "/var/run/masqmail/"
598 #ifndef va_copy
599 #ifdef __va_copy
600 #define va_copy(ap1, ap2) __va_copy(ap1, ap2)
601 #else
602 #define va_copy(ap1, ap2) G_VA_COPY(ap1, ap2)
603 #endif
604 #endif
606 /* *BSD needs this: */
607 extern char **environ;