1 /* $Id$ */
2 
3 /*
4  * Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef FDM_H
20 #define FDM_H
21 
22 #include <sys/param.h>
23 #include <sys/cdefs.h>
24 #include <sys/stat.h>
25 
26 #ifdef HAVE_QUEUE_H
27 #include <sys/queue.h>
28 #else
29 #include "compat/queue.h"
30 #endif
31 
32 #ifdef HAVE_TREE_H
33 #include <sys/tree.h>
34 #else
35 #include "compat/tree.h"
36 #endif
37 
38 #include <dirent.h>
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stdint.h>
42 #ifndef _PUBLIC_
43 #define _PUBLIC_
44 #endif
45 #include <tdb.h>
46 #include <regex.h>
47 
48 #ifdef PCRE
49 #include <pcre.h>
50 #endif
51 
52 #include <openssl/ssl.h>
53 #include <openssl/err.h>
54 
55 #define CHILDUSER	"_fdm"
56 #define CONFFILE	".fdm.conf"
57 #define LOCKFILE	".fdm.lock"
58 #define DEFLOCKTIMEOUT	10
59 #define MAXQUEUEVALUE	50
60 #define DEFMAILQUEUE	2
61 #define DEFMAILSIZE	(32 * 1024 * 1024)		/* 32 MB */
62 #define MAXMAILSIZE	(1 * 1024 * 1024 * 1024)	/*  1 GB */
63 #define DEFSTRIPCHARS	"\\<>$%^&*|{}[]\"'`;"
64 #define MAXACTIONCHAIN	5
65 #define DEFTIMEOUT	(900 * 1000)
66 #define LOCKSLEEPTIME	10000				/* 0.1 seconds */
67 #define MAXNAMESIZE	64
68 #define DEFUMASK	(S_IRWXG|S_IRWXO)
69 #define FILEMODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
70 #define DIRMODE		(S_IRWXU|S_IRWXG|S_IRWXO)
71 #define MAXUSERLEN	256
72 
73 extern char	*__progname;
74 
75 /* Various compatibility stuff. */
76 #ifndef UID_MAX
77 #define UID_MAX UINT_MAX
78 #endif
79 #ifndef GID_MAX
80 #define GID_MAX UINT_MAX
81 #endif
82 
83 #ifndef INFTIM
84 #define INFTIM -1
85 #endif
86 
87 #ifndef WAIT_ANY
88 #define WAIT_ANY -1
89 #endif
90 
91 #ifndef GLOB_BRACE
92 #define GLOB_BRACE 0
93 #endif
94 
95 #ifndef ACCESSPERMS
96 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
97 #endif
98 
99 #ifndef MAXNAMLEN
100 #define MAXNAMLEN 255
101 #endif
102 
103 #ifndef __dead
104 #define __dead __attribute__ ((__noreturn__))
105 #endif
106 #ifndef __packed
107 #define __packed __attribute__ ((__packed__))
108 #endif
109 
110 /* Databases are not portable between endiness on OSs without these. */
111 #ifndef htole64
112 #define htole64
113 #endif
114 #ifndef letoh64
115 #define letoh64
116 #endif
117 
118 /* Fatal errors. */
119 #define fatal(msg) log_fatal("%s: %s", __func__, msg);
120 #define fatalx(msg) log_fatalx("%s: %s", __func__, msg);
121 
122 /* Apply umask. */
123 #define UMASK(mask) ((mask) & ~conf.file_umask)
124 
125 /* Convert a file mode for %o%o%o printf. */
126 #define MODE(m) \
127 	(m & S_IRUSR ? 4 : 0) + (m & S_IWUSR ? 2 : 0) + (m & S_IXUSR ? 1 : 0), \
128 	(m & S_IRGRP ? 4 : 0) +	(m & S_IWGRP ? 2 : 0) +	(m & S_IXGRP ? 1 : 0), \
129 	(m & S_IROTH ? 4 : 0) +	(m & S_IWOTH ? 2 : 0) + (m & S_IXOTH ? 1 : 0)
130 
131 /* Definition to shut gcc up about unused arguments. */
132 #define unused __attribute__ ((unused))
133 
134 /* Attribute to make gcc check printf-like arguments. */
135 #define printflike1 __attribute__ ((format (printf, 1, 2)))
136 #define printflike2 __attribute__ ((format (printf, 2, 3)))
137 #define printflike3 __attribute__ ((format (printf, 3, 4)))
138 #define printflike4 __attribute__ ((format (printf, 4, 5)))
139 #define printflike5 __attribute__ ((format (printf, 5, 6)))
140 #define printflike6 __attribute__ ((format (printf, 6, 7)))
141 
142 /* Ensure buffer size. */
143 #define ENSURE_SIZE(buf, len, size) do {				\
144 	(buf) = ensure_size(buf, &(len), 1, size);			\
145 } while (0)
146 #define ENSURE_FOR(buf, len, size, adj) do {				\
147 	(buf) = ensure_for(buf, &(len), size, adj);			\
148 } while (0)
149 
150 /* Description buffer size. */
151 #define DESCBUFSIZE 512
152 
153 /* Replace buffer size. */
154 #define REPLBUFSIZE 64
155 
156 /* Lengths of time. */
157 #define TIME_MINUTE 60LL
158 #define TIME_HOUR 3600LL
159 #define TIME_DAY 86400LL
160 #define TIME_WEEK 604800LL
161 #define TIME_MONTH 2419200LL
162 #define TIME_YEAR 29030400LL
163 
164 /* Number of matches to use. */
165 #define NPMATCH 10
166 
167 /* Account and action name match. */
168 #define account_match(p, n) (fnmatch(p, n, 0) == 0)
169 #define action_match(p, n) (fnmatch(p, n, 0) == 0)
170 
171 #include "array.h"
172 #include "io.h"
173 
174 /* Macros in configuration file. */
175 struct macro {
176 	char			 name[MAXNAMESIZE];
177 	union {
178 		long long	 num;
179 		char		*str;
180 	} value;
181 	enum {
182 		MACRO_NUMBER,
183 		MACRO_STRING
184 	} type;
185 
186 	TAILQ_ENTRY(macro)	 entry;
187 };
188 TAILQ_HEAD(macros, macro);
189 
190 /* Command-line commands. */
191 enum fdmop {
192 	FDMOP_NONE = 0,
193 	FDMOP_POLL,
194 	FDMOP_FETCH,
195 	FDMOP_CACHE
196 };
197 
198 /*
199  * Wrapper struct for a string that needs tag replacement before it is used.
200  * This is used for anything that needs to be replaced after account and mail
201  * data are available, everything else is replaced at parse time.
202  */
203 struct replstr {
204 	char		*str;
205 } __packed;
206 ARRAY_DECL(replstrs, struct replstr);
207 
208 /* Similar to replstr but needs expand_path too. */
209 struct replpath {
210 	char		*str;
211 } __packed;
212 
213 /* Server description. */
214 struct server {
215 	char		*host;
216 	char		*port;
217 	struct addrinfo	*ai;
218 	int		 ssl;
219 	int		 verify;
220 	int		 insecure;
221 };
222 
223 /* Proxy type. */
224 enum proxytype {
225 	PROXY_HTTP,
226 	PROXY_HTTPS,
227 	PROXY_SOCKS5
228 };
229 
230 /* Proxy definition. */
231 struct proxy {
232 	enum proxytype	 type;
233 	char		*user;
234 	char		*pass;
235 	struct server	 server;
236 };
237 
238 /* Shared memory. */
239 struct shm {
240 	char	 name[MAXNAMLEN];
241 	int	 fd;
242 #define SHM_REGISTER(shm) cleanup_register(shm_path(shm))
243 #define SHM_DEREGISTER(shm) cleanup_deregister(shm_path(shm))
244 
245 	void	*data;
246 	size_t	 size;
247 };
248 
249 /* Generic array of strings. */
250 ARRAY_DECL(strings, char *);
251 
252 /* Options for final mail handling. */
253 enum decision {
254 	DECISION_NONE,
255 	DECISION_DROP,
256 	DECISION_KEEP
257 };
258 
259 /* String block entry. */
260 struct strbent {
261 	size_t	key;
262 	size_t	value;
263 };
264 
265 /* String block header. */
266 struct strb {
267 	u_int		 ent_used;
268 	u_int		 ent_max;
269 
270 	size_t		 str_used;
271 	size_t		 str_size;
272 };
273 
274 /* Initial string block slots and block size. */
275 #define STRBOFFSET (((sizeof (struct strb)) + 0x3f) & ~0x3f)
276 #define STRBENTRIES 64
277 #define STRBBLOCK 1024
278 
279 /* String block access macros. */
280 #define STRB_BASE(sb) (((char *) (sb)) + STRBOFFSET)
281 
282 #define STRB_KEY(sb, sbe) (STRB_BASE(sb) + (sbe)->key)
283 #define STRB_VALUE(sb, sbe) (STRB_BASE(sb) + (sbe)->value)
284 
285 #define STRB_ENTBASE(sb) (STRB_BASE(sb) + (sb)->str_size)
286 #define STRB_ENTOFF(sb, n) ((n) * (sizeof (struct strbent)))
287 #define STRB_ENTSIZE(sb) STRB_ENTOFF(sb, (sb)->ent_max)
288 
289 #define STRB_ENTRY(sb, n) ((void *) (STRB_ENTBASE(sb) + STRB_ENTOFF(sb, n)))
290 #define STRB_SIZE(sb) (STRBOFFSET + (sb)->str_size + STRB_ENTSIZE((sb)))
291 
292 /* Regexp wrapper structs. */
293 struct re {
294 	char		*str;
295 #ifndef PCRE
296 	regex_t		 re;
297 #else
298 	pcre		*pcre;
299 #endif
300 	int		 flags;
301 };
302 
303 struct rm {
304 	int		 valid;
305 
306 	size_t		 so;
307 	size_t		 eo;
308 };
309 
310 struct rmlist {
311 	int		 valid;
312 
313 	struct rm	 list[NPMATCH];
314 };
315 
316 /* Regexp flags. */
317 #define RE_IGNCASE 0x1
318 #define RE_NOSUBST 0x2
319 
320 /* Cache data. */
321 struct cache {
322 	TDB_CONTEXT		*db;
323 
324 	char			*path;
325 	uint64_t		 expire;
326 
327 	TAILQ_ENTRY(cache)	 entry;
328 };
329 struct cacheitem {
330 	uint64_t		 tim;
331 	uint32_t		 pad[4];
332 } __packed;
333 
334 /* A single mail. */
335 struct mail {
336 	u_int			 idx;
337 	double			 tim;
338 
339 	struct strb		*tags;
340 
341 	struct shm		 shm;
342 
343 	struct attach		*attach;
344 	int			 attach_built;
345 
346 	char			*base;
347 
348 	char			*data;
349 	size_t			 off;
350 
351 	size_t			 size;		/* size of mail */
352 	size_t			 space;		/* size of allocated area */
353 
354 	size_t			 body;		/* offset of body */
355 
356 	ARRAY_DECL(, size_t)	 wrapped;	/* list of wrapped lines */
357 	char			 wrapchar;	/* wrapped character */
358 
359 	/* XXX move below into special struct and just cp it in mail_*? */
360 	struct rmlist		 rml;		/* regexp matches */
361 
362 	enum decision		 decision;	/* final deliver decision */
363 
364 	void			 (*auxfree)(void *);
365 	void			*auxdata;
366 };
367 
368 /* Mail match/delivery return codes. */
369 #define MAIL_CONTINUE 0
370 #define MAIL_DELIVER 1
371 #define MAIL_MATCH 2
372 #define MAIL_ERROR 3
373 #define MAIL_BLOCKED 4
374 #define MAIL_DONE 5
375 
376 /* Mail match/delivery context. */
377 struct mail_ctx {
378 	int				 done;
379 	u_int				 msgid;
380 
381 	struct account			*account;
382 	struct io			*io;
383 	struct mail			*mail;
384 
385 	u_int				 ruleidx;
386 	struct rule			*rule;
387 	ARRAY_DECL(, struct rule *)	 stack;
388 	struct expritem			*expritem;
389 	int				 result;
390 	int				 matched;
391 
392 	TAILQ_HEAD(, deliver_ctx)	 dqueue;
393 
394 	TAILQ_ENTRY(mail_ctx)		 entry;
395 };
396 TAILQ_HEAD(mail_queue, mail_ctx);
397 
398 /* An attachment. */
399 struct attach {
400 	u_int			 idx;
401 
402 	size_t			 data;
403 	size_t			 body;
404 	size_t			 size;
405 
406 	char			*type;
407 	char			*name;
408 
409 	struct attach		*parent;
410 	TAILQ_HEAD(, attach)	 children;
411 
412 	TAILQ_ENTRY(attach)	 entry;
413 };
414 
415 /* Privsep message types. */
416 enum msgtype {
417 	MSG_ACTION,
418 	MSG_EXIT,
419 	MSG_DONE,
420 	MSG_COMMAND
421 };
422 
423 /* Privsep message data. */
424 struct msgdata {
425 	int				 error;
426 	struct mail			 mail;
427 
428 	/* These only work so long as they aren't moved in either process. */
429 	struct account			*account;
430 	struct actitem			*actitem;
431 	struct match_command_data	*cmddata;
432 
433 	uid_t				 uid;
434 	gid_t				 gid;
435 };
436 
437 /* Privsep message buffer. */
438 struct msgbuf {
439 	void		*buf;
440 	size_t		 len;
441 };
442 
443 /* Privsep message. */
444 struct msg {
445 	u_int		 id;
446 	enum msgtype	 type;
447 	size_t		 size;
448 
449 	struct msgdata	 data;
450 };
451 
452 /* A single child. */
453 struct child {
454 	pid_t		 pid;
455 	struct child	*parent;
456 	struct io	*io;
457 
458 	void		*data;
459 	int		 (*msg)(struct child *, struct msg *, struct msgbuf *);
460 
461 	void		*buf;
462 	size_t		 len;
463 };
464 
465 /* List of children. */
466 ARRAY_DECL(children, struct child *);
467 
468 /* Fetch child data. */
469 struct child_fetch_data {
470 	struct account	*account;
471 	enum fdmop	 op;
472 	struct children	*children;
473 };
474 
475 /* Deliver child data. */
476 struct child_deliver_data {
477 	void			 (*hook)(int, struct account *, struct msg *,
478 				      struct child_deliver_data *, int *);
479 
480 	struct child		*child; /* the source of the request */
481 
482 	uid_t			 uid;
483 	gid_t			 gid;
484 
485 	u_int			 msgid;
486 	const char		*name;
487 
488 	struct account		*account;
489 	struct mail		*mail;
490 	struct actitem		*actitem;
491 
492 	struct deliver_ctx	*dctx;
493 	struct mail_ctx		*mctx;
494 
495 	struct match_command_data *cmddata;
496 };
497 
498 /* Account entry. */
499 struct account {
500 	u_int			 idx;
501 
502 	char			 name[MAXNAMESIZE];
503 
504 	struct replstrs		*users;
505 
506 	int			 disabled;
507 	int			 keep;
508 
509 	struct fetch		*fetch;
510 	void			*data;
511 
512 	TAILQ_ENTRY(account)	 entry;
513 	TAILQ_ENTRY(account)	 active_entry;
514 };
515 
516 /* Action item. */
517 struct actitem {
518 	u_int			 idx;
519 
520 	struct deliver		*deliver;
521 	void			*data;
522 
523 	TAILQ_ENTRY(actitem)	 entry;
524 };
525 
526 /* Action list. */
527 TAILQ_HEAD(actlist, actitem);
528 
529 /* Action definition. */
530 struct action {
531 	char			 name[MAXNAMESIZE];
532 
533 	struct replstrs		*users;
534 
535 	struct actlist		*list;
536 
537 	TAILQ_ENTRY(action)	 entry;
538 };
539 
540 /* Actions arrays. */
541 ARRAY_DECL(actions, struct action *);
542 
543 /* Match areas. */
544 enum area {
545 	AREA_BODY,
546 	AREA_HEADERS,
547 	AREA_ANY
548 };
549 
550 /* Expression operators. */
551 enum exprop {
552 	OP_NONE,
553 	OP_AND,
554 	OP_OR
555 };
556 
557 /* Expression item. */
558 struct expritem {
559 	struct match		*match;
560 	void			*data;
561 
562 	enum exprop		 op;
563 	int			 inverted;
564 
565 	TAILQ_ENTRY(expritem)	 entry;
566 };
567 
568 /* Expression struct. */
569 TAILQ_HEAD(expr, expritem);
570 
571 /* Rule list. */
572 TAILQ_HEAD(rules, rule);
573 
574 /* Rule entry. */
575 struct rule {
576 	u_int			 idx;
577 
578 	struct expr		*expr;
579 
580 	struct replstrs		*users;
581 
582 	int			 stop;		/* stop matching at this rule */
583 
584 	struct rules		 rules;
585 	struct action		*lambda;
586 	struct replstrs		*actions;
587 
588 	TAILQ_ENTRY(rule)	 entry;
589 };
590 
591 /* Lock types. */
592 #define LOCK_FCNTL 0x1
593 #define LOCK_FLOCK 0x2
594 #define LOCK_DOTLOCK 0x4
595 
596 /* User info settings. */
597 struct userdata {
598 	char	*name;
599 	char	*home;
600 
601 	uid_t	 uid;
602 	gid_t	 gid;
603 };
604 
605 /* User lookup order. */
606 typedef struct userdata *(*userfunction)(const char *);
607 ARRAY_DECL(userfunctions, userfunction);
608 
609 /* Configuration settings. */
610 struct conf {
611 	int			 debug;
612 	int			 syslog;
613 
614 	uid_t			 child_uid;
615 	gid_t			 child_gid;
616 	char			*tmp_dir;
617 
618 	struct strings		 incl;
619 	struct strings		 excl;
620 
621 	struct proxy		*proxy;
622 
623 	char			*user_home;
624 	struct userfunctions	*user_order;
625 
626 	char			*host_name;
627 	char			*host_fqdn;
628 	char			*host_address;
629 
630 	char			*conf_file;
631 	char			*strip_chars;
632 	int			 check_only;
633 	int			 allow_many;
634 	int			 keep_all;
635 	int			 no_received;
636 	int			 no_create;
637 	int			 verify_certs;
638 	u_int			 purge_after;
639 	enum decision		 impl_act;
640 	int			 max_accts;
641 
642 	char			*lock_file;
643 	int			 lock_wait;
644 	int			 lock_timeout;
645 
646 	int			 queue_high;
647 	int			 queue_low;
648 
649 	mode_t			 file_umask;
650 	gid_t			 file_group;
651 
652 	size_t			 max_size;
653 	int			 timeout;
654 	int			 del_big;
655 	int			 ignore_errors;
656 	u_int			 lock_types;
657 
658 	char			*def_user;
659 	char			*cmd_user;
660 
661 	TAILQ_HEAD(, cache)	 caches;
662 	TAILQ_HEAD(, account)	 accounts;
663 	TAILQ_HEAD(, action)	 actions;
664 	struct rules		 rules;
665 };
666 extern struct conf		 conf;
667 
668 /* Command flags. */
669 #define CMD_IN	0x1
670 #define CMD_OUT 0x2
671 #define CMD_ONCE 0x4
672 
673 /* Command data. */
674 struct cmd {
675 	pid_t		 pid;
676 	int		 status;
677 	int		 flags;
678 
679 	const char	*buf;
680 	size_t		 len;
681 
682 	struct io	*io_in;
683 	struct io	*io_out;
684 	struct io	*io_err;
685 };
686 
687 /* Comparison operators. */
688 enum cmp {
689 	CMP_EQ,
690 	CMP_NE,
691 	CMP_LT,
692 	CMP_GT
693 };
694 
695 /* Configuration file (used by parser). */
696 struct file {
697 	FILE		*f;
698 	int		 line;
699 	const char	*path;
700 };
701 ARRAY_DECL(files, struct file *);
702 
703 #ifndef HAVE_SETRESUID
704 #define setresuid(r, e, s) setreuid(r, e)
705 #endif
706 
707 #ifndef HAVE_SETRESGID
708 #define setresgid(r, e, s) setregid(r, e)
709 #endif
710 
711 #ifndef HAVE_STRTONUM
712 /* strtonum.c */
713 long long	 strtonum(const char *, long long, long long, const char **);
714 #endif
715 
716 #ifndef HAVE_STRLCPY
717 /* strlcpy.c */
718 size_t		 strlcpy(char *, const char *, size_t);
719 #endif
720 
721 #ifndef HAVE_STRLCAT
722 /* strlcat.c */
723 size_t		 strlcat(char *, const char *, size_t);
724 #endif
725 
726 #ifndef HAVE_B64_NTOP
727 /* base64.c */
728 int b64_ntop(src, srclength, target, targsize);
729 int b64_pton(src, target, targsize);
730 #endif
731 
732 /* shm.c */
733 char		*shm_path(struct shm *);
734 void		*shm_create(struct shm *, size_t);
735 int		 shm_owner(struct shm *, uid_t, gid_t);
736 void		 shm_destroy(struct shm *);
737 void		 shm_close(struct shm *);
738 void		*shm_reopen(struct shm *);
739 void		*shm_resize(struct shm *, size_t, size_t);
740 
741 /* lex.c */
742 int			yylex(void);
743 
744 /* parse.y */
745 extern struct macros	parse_macros;
746 extern struct files	parse_filestack;
747 extern struct file     *parse_file;
748 extern struct strb     *parse_tags;
749 int			parse_conf(const char *, struct strings *);
750 __dead printflike1 void yyerror(const char *, ...);
751 
752 /* parse-fn.c */
753 char		*expand_path(const char *, const char *);
754 char		*run_command(const char *, const char *);
755 char		*fmt_replstrs(const char *, struct replstrs *);
756 char		*fmt_strings(const char *, struct strings *);
757 int		 have_accounts(char *);
758 struct account	*find_account(char *);
759 struct action	*find_action(char *);
760 struct actions	*match_actions(const char *);
761 struct macro	*extract_macro(char *);
762 struct macro	*find_macro(const char *);
763 void		 find_netrc(const char *, char **, char **);
764 int		 find_netrc1(const char *, char **, char **, char **);
765 void		 free_account(struct account *);
766 void		 free_action(struct action *);
767 void		 free_actitem(struct actitem *);
768 void		 free_cache(struct cache *);
769 void		 free_replstrs(struct replstrs *);
770 void		 free_rule(struct rule *);
771 void		 free_strings(struct strings *);
772 void		 make_actlist(struct actlist *, char *, size_t);
773 void		 print_action(struct action *);
774 void		 print_rule(struct rule *);
775 
776 /* netrc.c */
777 FILE		*netrc_open(const char *, char **);
778 void		 netrc_close(FILE *);
779 int		 netrc_lookup(FILE *, const char *, char **, char **);
780 
781 /* fdm.c */
782 extern volatile sig_atomic_t sigusr1;
783 extern volatile sig_atomic_t sigint;
784 extern volatile sig_atomic_t sigterm;
785 double		 get_time(void);
786 void		 dropto(uid_t, gid_t);
787 int		 check_incl(const char *);
788 int		 check_excl(const char *);
789 int		 use_account(struct account *, char **);
790 void		 fill_host(void);
791 __dead void	 usage(void);
792 
793 /* cache-op.c */
794 __dead void	 cache_op(int, char **);
795 
796 /* re.c */
797 int		 re_compile(struct re *, const char *, int, char **);
798 int		 re_string(struct re *, const char *, struct rmlist *, char **);
799 int		 re_block(struct re *, const void *, size_t, struct rmlist *,
800 		     char **);
801 void		 re_free(struct re *);
802 
803 /* attach.c */
804 struct attach	*attach_visit(struct attach *, u_int *);
805 void printflike2 attach_log(struct attach *, const char *, ...);
806 struct attach	*attach_build(struct mail *);
807 void		 attach_free(struct attach *);
808 
809 /* lookup.c */
810 struct userdata *user_lookup(const char *, struct userfunctions *);
811 void		 user_free(struct userdata *);
812 struct userdata *user_copy(struct userdata *);
813 
814 /* lookup-passwd.c */
815 struct userdata *passwd_lookup(const char *);
816 
817 
818 /* privsep.c */
819 int		 privsep_send(struct io *, struct msg *, struct msgbuf *);
820 int		 privsep_check(struct io *);
821 int		 privsep_recv(struct io *, struct msg *, struct msgbuf *);
822 
823 /* command.c */
824 struct cmd	*cmd_start(const char *, int, const char *, size_t, char **);
825 int		 cmd_poll(struct cmd *, char **, char **, char **, size_t *,
826 		     int, char **);
827 void		 cmd_free(struct cmd *);
828 
829 /* child.c */
830 int		 child_fork(void);
831 __dead void	 child_exit(int);
832 struct child	*child_start(struct children *, uid_t, gid_t,
833 		     int (*)(struct child *, struct io *),
834 		     int (*)(struct child *, struct msg *, struct msgbuf *),
835 		     void *, struct child *);
836 
837 /* child-fetch.c */
838 int		 open_cache(struct account *, struct cache *);
839 int		 child_fetch(struct child *, struct io *);
840 
841 /* child-deliver.c */
842 int		 child_deliver(struct child *, struct io *);
843 void		 child_deliver_action_hook(int, struct account *, struct msg *,
844 		     struct child_deliver_data *, int *);
845 void		 child_deliver_cmd_hook(int, struct account *, struct msg *,
846 		     struct child_deliver_data *, int *);
847 
848 /* parent-fetch.c */
849 int		 parent_fetch(struct child *, struct msg *, struct msgbuf *);
850 
851 /* parent-deliver.c */
852 int		 parent_deliver(struct child *, struct msg *, struct msgbuf *);
853 
854 /* timer.c */
855 int		 timer_expired(void);
856 void		 timer_set(int);
857 void		 timer_cancel(void);
858 
859 /* connect.c */
860 char		*sslerror(const char *);
861 char		*sslerror2(int, const char *);
862 SSL		*makessl(struct server *, int, int, int, char **);
863 void		 getaddrs(const char *, char **, char **);
864 struct proxy	*getproxy(const char *);
865 struct io	*connectproxy(struct server *, int, struct proxy *,
866 		     const char *, int, char **);
867 struct io	*connectio(struct server *, int, const char *, int, char **);
868 
869 /* file.c */
870 int printflike3	 ppath(char *, size_t, const char *, ...);
871 int		 vppath(char *, size_t, const char *, va_list);
872 int		 openlock(const char *, int, u_int);
873 int		 createlock(const char *, int, uid_t, gid_t, mode_t, u_int);
874 void		 closelock(int, const char *, u_int);
875 int		 locksleep(const char *, const char *, long long *);
876 int		 xcreate(const char *, int, uid_t, gid_t, mode_t);
877 int		 xmkdir(const char *, uid_t, gid_t, mode_t);
878 int		 xmkpath(const char *, uid_t, gid_t, mode_t);
879 const char	*checkmode(struct stat *, mode_t);
880 const char	*checkowner(struct stat *, uid_t);
881 const char	*checkgroup(struct stat *, gid_t);
882 int		 safemove(const char *, const char *);
883 
884 /* mail.c */
885 int		 mail_open(struct mail *, size_t);
886 void		 mail_send(struct mail *, struct msg *);
887 int		 mail_receive(struct mail *, struct msg *, int);
888 void		 mail_close(struct mail *);
889 void		 mail_destroy(struct mail *);
890 int		 mail_resize(struct mail *, size_t);
891 void		 line_init(struct mail *, char **, size_t *);
892 void		 line_next(struct mail *, char **, size_t *);
893 int printflike3	 insert_header(struct mail *, const char *, const char *, ...);
894 int		 remove_header(struct mail *, const char *);
895 char		*find_header(struct mail *, const char *, size_t *, int);
896 char		*match_header(struct mail *, const char *, size_t *, int);
897 size_t		 find_body(struct mail *);
898 void		 count_lines(struct mail *, u_int *, u_int *);
899 int		 append_line(struct mail *, const char *, size_t);
900 char		*find_address(char *, size_t, size_t *);
901 void		 trim_from(struct mail *);
902 char		*make_from(struct mail *, char *);
903 u_int		 fill_wrapped(struct mail *);
904 void		 set_wrapped(struct mail *, char);
905 
906 /* mail-time.c */
907 char		*rfc822time(time_t, char *, size_t);
908 int		 mailtime(struct mail *, time_t *);
909 
910 /* mail-state.c */
911 int		 mail_match(struct mail_ctx *, struct msg *, struct msgbuf *);
912 int		 mail_deliver(struct mail_ctx *, struct msg *, struct msgbuf *);
913 
914 /* db-tdb.c */
915 TDB_CONTEXT	*db_open(char *);
916 void		 db_close(TDB_CONTEXT *);
917 int		 db_add(TDB_CONTEXT *, char *);
918 int		 db_remove(TDB_CONTEXT *, char *);
919 int		 db_contains(TDB_CONTEXT *, char *);
920 int		 db_size(TDB_CONTEXT *);
921 int		 db_print(TDB_CONTEXT *, void (*)(const char *, ...));
922 int		 db_expire(TDB_CONTEXT *, uint64_t);
923 int		 db_clear(TDB_CONTEXT *);
924 
925 /* cleanup.c */
926 void		 cleanup_check(void);
927 void		 cleanup_flush(void);
928 void		 cleanup_purge(void);
929 void		 cleanup_register(const char *);
930 void		 cleanup_deregister(const char *);
931 
932 /* strb.c */
933 void		 strb_create(struct strb **);
934 void		 strb_clear(struct strb **);
935 void		 strb_destroy(struct strb **);
936 void		 strb_dump(struct strb *, const char *,
937 		     void (*)(const char *, ...));
938 void printflike3 strb_add(struct strb **, const char *, const char *, ...);
939 void		 strb_vadd(struct strb **, const char *, const char *, va_list);
940 struct strbent	*strb_find(struct strb *, const char *);
941 struct strbent	*strb_match(struct strb *, const char *);
942 
943 /* replace.c */
944 void printflike3 add_tag(struct strb **, const char *, const char *, ...);
945 const char	*find_tag(struct strb *, const char *);
946 const char	*match_tag(struct strb *, const char *);
947 void		 default_tags(struct strb **, const char *);
948 void		 update_tags(struct strb **, struct userdata *);
949 void		 reset_tags(struct strb **);
950 char		*replacestr(struct replstr *, struct strb *, struct mail *,
951 		     struct rmlist *);
952 char		*replacepath(struct replpath *, struct strb *, struct mail *,
953 		     struct rmlist *, const char *);
954 
955 /* log.c */
956 #define LOG_FACILITY LOG_MAIL
957 void		 log_open_syslog(int);
958 void		 log_open_tty(int);
959 void		 log_open_file(int, const char *);
960 void		 log_close(void);
961 void		 log_vwrite(int, const char *, va_list);
962 void		 log_write(int, const char *, ...);
963 void printflike1 log_warn(const char *, ...);
964 void printflike1 log_warnx(const char *, ...);
965 void printflike1 log_info(const char *, ...);
966 void printflike1 log_debug(const char *, ...);
967 void printflike1 log_debug2(const char *, ...);
968 void printflike1 log_debug3(const char *, ...);
969 __dead void	 log_vfatal(const char *, va_list);
970 __dead void	 log_fatal(const char *, ...);
971 __dead void	 log_fatalx(const char *, ...);
972 
973 /* xmalloc.c */
974 void		*ensure_size(void *, size_t *, size_t, size_t);
975 void		*ensure_for(void *, size_t *, size_t, size_t);
976 char		*xstrdup(const char *);
977 void		*xcalloc(size_t, size_t);
978 void		*xmalloc(size_t);
979 void		*xrealloc(void *, size_t, size_t);
980 void		 xfree(void *);
981 int printflike2	 xasprintf(char **, const char *, ...);
982 int		 xvasprintf(char **, const char *, va_list);
983 int printflike3	 xsnprintf(char *, size_t, const char *, ...);
984 int		 xvsnprintf(char *, size_t, const char *, va_list);
985 int printflike3	 printpath(char *, size_t, const char *, ...);
986 char		*xdirname(const char *);
987 char		*xbasename(const char *);
988 
989 #endif /* FDM_H */
990