1 /*	$OpenBSD$	*/
2 
3 /*
4  * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
5  * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef	_SMTPD_API_H_
21 #define	_SMTPD_API_H_
22 
23 #include <sys/queue.h>
24 #include <sys/tree.h>
25 #include <sys/socket.h>
26 
27 #include <stdio.h>
28 #include <netinet/in.h>
29 #include <netdb.h>
30 #include <limits.h>
31 
32 #include <event.h>
33 #include <imsg.h>
34 
35 #include "smtpd-defines.h"
36 #include "ioev.h"
37 #include "iobuf.h"
38 #include "log.h"
39 #include "rfc2822.h"
40 
41 #define	FILTER_API_VERSION	 52
42 
43 enum blockmodes {
44 	BM_NORMAL,
45 	BM_NONBLOCK
46 };
47 
48 struct mproc {
49 	pid_t		 pid;
50 	char		*name;
51 	int		 proc;
52 	void		(*handler)(struct mproc *, struct imsg *);
53 	struct imsgbuf	 imsgbuf;
54 
55 	char		*m_buf;
56 	size_t		 m_alloc;
57 	size_t		 m_pos;
58 	uint32_t	 m_type;
59 	uint32_t	 m_peerid;
60 	pid_t		 m_pid;
61 	int		 m_fd;
62 
63 	int		 enable;
64 	short		 events;
65 	struct event	 ev;
66 	void		*data;
67 
68 	off_t		 msg_in;
69 	off_t		 msg_out;
70 	off_t		 bytes_in;
71 	off_t		 bytes_out;
72 	size_t		 bytes_queued;
73 	size_t		 bytes_queued_max;
74 };
75 
76 struct msg {
77 	const uint8_t	*pos;
78 	const uint8_t	*end;
79 };
80 
81 struct mailaddr {
82 	char	user[SMTPD_MAXLOCALPARTSIZE];
83 	char	domain[SMTPD_MAXDOMAINPARTSIZE];
84 };
85 
86 SPLAY_HEAD(_dict, dictentry);
87 SPLAY_HEAD(_tree, treeentry);
88 
89 struct tree {
90 	struct _tree	tree;
91 	size_t		count;
92 };
93 
94 struct dict {
95 	struct _dict	dict;
96 	size_t		count;
97 };
98 
99 enum filter_status {
100 	FILTER_OK,
101 	FILTER_FAIL,
102 	FILTER_CLOSE,
103 };
104 
105 enum filter_imsg {
106 	IMSG_FILTER_REGISTER,
107 	IMSG_FILTER_EVENT,
108 	IMSG_FILTER_QUERY,
109 	IMSG_FILTER_PIPE,
110 	IMSG_FILTER_RESPONSE
111 };
112 
113 /* XXX - server side requires mfa_session.c update on filter_event */
114 enum filter_event_type {
115 	EVENT_CONNECT,
116 	EVENT_RESET,
117 	EVENT_DISCONNECT,
118 	EVENT_TX_BEGIN,
119 	EVENT_TX_COMMIT,
120 	EVENT_TX_ROLLBACK,
121 };
122 
123 /* XXX - server side requires mfa_session.c update on filter_hook changes */
124 enum filter_query_type {
125 	QUERY_CONNECT,
126 	QUERY_HELO,
127 	QUERY_MAIL,
128 	QUERY_RCPT,
129 	QUERY_DATA,
130 	QUERY_EOM,
131 	QUERY_DATALINE,
132 };
133 
134 struct filter_connect {
135 	struct sockaddr_storage	 local;
136 	struct sockaddr_storage	 remote;
137 	const char		*hostname;
138 };
139 
140 #define PROC_QUEUE_API_VERSION	2
141 
142 enum {
143 	PROC_QUEUE_OK,
144 	PROC_QUEUE_FAIL,
145 	PROC_QUEUE_INIT,
146 	PROC_QUEUE_CLOSE,
147 	PROC_QUEUE_MESSAGE_CREATE,
148 	PROC_QUEUE_MESSAGE_DELETE,
149 	PROC_QUEUE_MESSAGE_COMMIT,
150 	PROC_QUEUE_MESSAGE_FD_R,
151 	PROC_QUEUE_MESSAGE_CORRUPT,
152 	PROC_QUEUE_MESSAGE_UNCORRUPT,
153 	PROC_QUEUE_ENVELOPE_CREATE,
154 	PROC_QUEUE_ENVELOPE_DELETE,
155 	PROC_QUEUE_ENVELOPE_LOAD,
156 	PROC_QUEUE_ENVELOPE_UPDATE,
157 	PROC_QUEUE_ENVELOPE_WALK,
158 	PROC_QUEUE_MESSAGE_WALK,
159 };
160 
161 #define PROC_SCHEDULER_API_VERSION	2
162 
163 struct scheduler_info;
164 
165 enum {
166 	PROC_SCHEDULER_OK,
167 	PROC_SCHEDULER_FAIL,
168 	PROC_SCHEDULER_INIT,
169 	PROC_SCHEDULER_INSERT,
170 	PROC_SCHEDULER_COMMIT,
171 	PROC_SCHEDULER_ROLLBACK,
172 	PROC_SCHEDULER_UPDATE,
173 	PROC_SCHEDULER_DELETE,
174 	PROC_SCHEDULER_HOLD,
175 	PROC_SCHEDULER_RELEASE,
176 	PROC_SCHEDULER_BATCH,
177 	PROC_SCHEDULER_MESSAGES,
178 	PROC_SCHEDULER_ENVELOPES,
179 	PROC_SCHEDULER_SCHEDULE,
180 	PROC_SCHEDULER_REMOVE,
181 	PROC_SCHEDULER_SUSPEND,
182 	PROC_SCHEDULER_RESUME,
183 };
184 
185 enum envelope_flags {
186 	EF_AUTHENTICATED	= 0x01,
187 	EF_BOUNCE		= 0x02,
188 	EF_INTERNAL		= 0x04, /* Internal expansion forward */
189 
190 	/* runstate, not saved on disk */
191 
192 	EF_PENDING		= 0x10,
193 	EF_INFLIGHT		= 0x20,
194 	EF_SUSPEND		= 0x40,
195 	EF_HOLD			= 0x80,
196 };
197 
198 struct evpstate {
199 	uint64_t		evpid;
200 	uint16_t		flags;
201 	uint16_t		retry;
202 	time_t			time;
203 };
204 
205 enum delivery_type {
206 	D_MDA,
207 	D_MTA,
208 	D_BOUNCE,
209 };
210 
211 struct scheduler_info {
212 	uint64_t		evpid;
213 	enum delivery_type	type;
214 	uint16_t		retry;
215 	time_t			creation;
216 	time_t			expire;
217 	time_t			lasttry;
218 	time_t			lastbounce;
219 	time_t			nexttry;
220 };
221 
222 #define SCHED_REMOVE		0x01
223 #define SCHED_EXPIRE		0x02
224 #define SCHED_UPDATE		0x04
225 #define SCHED_BOUNCE		0x08
226 #define SCHED_MDA		0x10
227 #define SCHED_MTA		0x20
228 
229 #define PROC_TABLE_API_VERSION	2
230 
231 struct table_open_params {
232 	uint32_t	version;
233 	char		name[LINE_MAX];
234 };
235 
236 enum table_service {
237 	K_NONE		= 0x000,
238 	K_ALIAS		= 0x001,	/* returns struct expand	*/
239 	K_DOMAIN	= 0x002,	/* returns struct destination	*/
240 	K_CREDENTIALS	= 0x004,	/* returns struct credentials	*/
241 	K_NETADDR	= 0x008,	/* returns struct netaddr	*/
242 	K_USERINFO	= 0x010,	/* returns struct userinfo	*/
243 	K_SOURCE	= 0x020,	/* returns struct source	*/
244 	K_MAILADDR	= 0x040,	/* returns struct mailaddr	*/
245 	K_ADDRNAME	= 0x080,	/* returns struct addrname	*/
246 	K_MAILADDRMAP	= 0x100,	/* returns struct mailaddr	*/
247 };
248 #define K_ANY		  0xfff
249 
250 enum {
251 	PROC_TABLE_OK,
252 	PROC_TABLE_FAIL,
253 	PROC_TABLE_OPEN,
254 	PROC_TABLE_CLOSE,
255 	PROC_TABLE_UPDATE,
256 	PROC_TABLE_CHECK,
257 	PROC_TABLE_LOOKUP,
258 	PROC_TABLE_FETCH,
259 };
260 
261 enum enhanced_status_code {
262 	/* 0.0 */
263 	ESC_OTHER_STATUS				= 00,
264 
265 	/* 1.x */
266 	ESC_OTHER_ADDRESS_STATUS			= 10,
267 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS		= 11,
268 	ESC_BAD_DESTINATION_SYSTEM_ADDRESS		= 12,
269 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX     	= 13,
270 	ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS	= 14,
271 	ESC_DESTINATION_ADDRESS_VALID			= 15,
272 	ESC_DESTINATION_MAILBOX_HAS_MOVED      		= 16,
273 	ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX		= 17,
274 	ESC_BAD_SENDER_SYSTEM_ADDRESS			= 18,
275 
276 	/* 2.x */
277 	ESC_OTHER_MAILBOX_STATUS			= 20,
278 	ESC_MAILBOX_DISABLED				= 21,
279 	ESC_MAILBOX_FULL				= 22,
280 	ESC_MESSAGE_LENGTH_TOO_LARGE   			= 23,
281 	ESC_MAILING_LIST_EXPANSION_PROBLEM		= 24,
282 
283 	/* 3.x */
284 	ESC_OTHER_MAIL_SYSTEM_STATUS			= 30,
285 	ESC_MAIL_SYSTEM_FULL				= 31,
286 	ESC_SYSTEM_NOT_ACCEPTING_MESSAGES		= 32,
287 	ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES    	= 33,
288 	ESC_MESSAGE_TOO_BIG_FOR_SYSTEM		    	= 34,
289 	ESC_SYSTEM_INCORRECTLY_CONFIGURED      	    	= 35,
290 
291 	/* 4.x */
292 	ESC_OTHER_NETWORK_ROUTING_STATUS      	    	= 40,
293 	ESC_NO_ANSWER_FROM_HOST		      	    	= 41,
294 	ESC_BAD_CONNECTION		      	    	= 42,
295 	ESC_DIRECTORY_SERVER_FAILURE   	      	    	= 43,
296 	ESC_UNABLE_TO_ROUTE	   	      	    	= 44,
297 	ESC_MAIL_SYSTEM_CONGESTION   	      	    	= 45,
298 	ESC_ROUTING_LOOP_DETECTED   	      	    	= 46,
299 	ESC_DELIVERY_TIME_EXPIRED   	      	    	= 47,
300 
301 	/* 5.x */
302 	ESC_INVALID_RECIPIENT				= 50,
303 	ESC_INVALID_COMMAND	   	      	    	= 51,
304 	ESC_SYNTAX_ERROR	   	      	    	= 52,
305 	ESC_TOO_MANY_RECIPIENTS	   	      	    	= 53,
306 	ESC_INVALID_COMMAND_ARGUMENTS  	      	    	= 54,
307 	ESC_WRONG_PROTOCOL_VERSION  	      	    	= 55,
308 
309 	/* 6.x */
310 	ESC_OTHER_MEDIA_ERROR   	      	    	= 60,
311 	ESC_MEDIA_NOT_SUPPORTED   	      	    	= 61,
312 	ESC_CONVERSION_REQUIRED_AND_PROHIBITED		= 62,
313 	ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED      	= 63,
314 	ESC_CONVERSION_WITH_LOSS_PERFORMED	     	= 64,
315 	ESC_CONVERSION_FAILED			     	= 65,
316 
317 	/* 7.x */
318 	ESC_OTHER_SECURITY_STATUS      		     	= 70,
319 	ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED	= 71,
320 	ESC_MAILING_LIST_EXPANSION_PROHIBITED		= 72,
321 	ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE  	= 73,
322 	ESC_SECURITY_FEATURES_NOT_SUPPORTED	  	= 74,
323 	ESC_CRYPTOGRAPHIC_FAILURE			= 75,
324 	ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED	= 76,
325 	ESC_MESSAGE_INTEGRITY_FAILURE			= 77,
326 };
327 
328 enum enhanced_status_class {
329 	ESC_STATUS_OK		= 2,
330 	ESC_STATUS_TEMPFAIL	= 4,
331 	ESC_STATUS_PERMFAIL	= 5,
332 };
333 
334 static inline uint32_t
evpid_to_msgid(uint64_t evpid)335 evpid_to_msgid(uint64_t evpid)
336 {
337 	return (evpid >> 32);
338 }
339 
340 static inline uint64_t
msgid_to_evpid(uint32_t msgid)341 msgid_to_evpid(uint32_t msgid)
342 {
343         return ((uint64_t)msgid << 32);
344 }
345 
346 /* dict.c */
347 #define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0)
348 #define dict_empty(d) SPLAY_EMPTY(&((d)->dict))
349 #define dict_count(d) ((d)->count)
350 int dict_check(struct dict *, const char *);
351 void *dict_set(struct dict *, const char *, void *);
352 void dict_xset(struct dict *, const char *, void *);
353 void *dict_get(struct dict *, const char *);
354 void *dict_xget(struct dict *, const char *);
355 void *dict_pop(struct dict *, const char *);
356 void *dict_xpop(struct dict *, const char *);
357 int dict_poproot(struct dict *, void **);
358 int dict_root(struct dict *, const char **, void **);
359 int dict_iter(struct dict *, void **, const char **, void **);
360 int dict_iterfrom(struct dict *, void **, const char *, const char **, void **);
361 void dict_merge(struct dict *, struct dict *);
362 
363 
364 /* esc.c */
365 const char *esc_code(enum enhanced_status_class, enum enhanced_status_code);
366 const char *esc_description(enum enhanced_status_code);
367 
368 
369 /* filter_api.c */
370 void  filter_api_session_allocator(void *(*)(uint64_t));
371 void  filter_api_session_destructor(void (*)(void *));
372 void *filter_api_session(uint64_t);
373 
374 void  filter_api_transaction_allocator(void *(*)(uint64_t));
375 void  filter_api_transaction_destructor(void (*)(void *));
376 void *filter_api_transaction(uint64_t);
377 
378 void filter_api_setugid(uid_t, gid_t);
379 void filter_api_set_chroot(const char *);
380 void filter_api_no_chroot(void);
381 
382 void filter_api_data_buffered(void);
383 void filter_api_data_buffered_stream(uint64_t);
384 
385 void filter_api_loop(void);
386 int filter_api_accept(uint64_t);
387 int filter_api_reject(uint64_t, enum filter_status);
388 int filter_api_reject_code(uint64_t, enum filter_status, uint32_t,
389     const char *);
390 void filter_api_writeln(uint64_t, const char *);
391 void filter_api_printf(uint64_t id, const char *, ...);
392 void filter_api_timer(uint64_t, uint32_t, void (*)(uint64_t, void *), void *);
393 const char *filter_api_sockaddr_to_text(const struct sockaddr *);
394 const char *filter_api_mailaddr_to_text(const struct mailaddr *);
395 
396 FILE *filter_api_datahold_open(uint64_t, void (*callback)(uint64_t, FILE *, void *), void *);
397 void filter_api_datahold_close(uint64_t);
398 
399 void filter_api_on_connect(int(*)(uint64_t, struct filter_connect *));
400 void filter_api_on_helo(int(*)(uint64_t, const char *));
401 void filter_api_on_mail(int(*)(uint64_t, struct mailaddr *));
402 void filter_api_on_rcpt(int(*)(uint64_t, struct mailaddr *));
403 void filter_api_on_data(int(*)(uint64_t));
404 void filter_api_on_msg_line(void(*)(uint64_t, const char *));
405 void filter_api_on_msg_start(void(*)(uint64_t));
406 void filter_api_on_msg_end(int(*)(uint64_t, size_t));
407 void filter_api_on_reset(void(*)(uint64_t));
408 void filter_api_on_disconnect(void(*)(uint64_t));
409 void filter_api_on_tx_begin(void(*)(uint64_t));
410 void filter_api_on_tx_commit(void(*)(uint64_t));
411 void filter_api_on_tx_rollback(void(*)(uint64_t));
412 
413 const char *proc_name(enum smtp_proc_type);
414 const char *imsg_to_str(int);
415 
416 
417 /* mproc.c */
418 int mproc_fork(struct mproc *, const char*, char **);
419 void mproc_init(struct mproc *, int);
420 void mproc_clear(struct mproc *);
421 void mproc_enable(struct mproc *);
422 void mproc_disable(struct mproc *);
423 void mproc_event_add(struct mproc *);
424 void m_compose(struct mproc *, uint32_t, uint32_t, pid_t, int, void *, size_t);
425 void m_composev(struct mproc *, uint32_t, uint32_t, pid_t, int,
426     const struct iovec *, int);
427 void m_forward(struct mproc *, struct imsg *);
428 void m_create(struct mproc *, uint32_t, uint32_t, pid_t, int);
429 void m_add(struct mproc *, const void *, size_t);
430 void m_add_int(struct mproc *, int);
431 void m_add_u32(struct mproc *, uint32_t);
432 void m_add_size(struct mproc *, size_t);
433 void m_add_time(struct mproc *, time_t);
434 void m_add_string(struct mproc *, const char *);
435 void m_add_data(struct mproc *, const void *, size_t);
436 void m_add_evpid(struct mproc *, uint64_t);
437 void m_add_msgid(struct mproc *, uint32_t);
438 void m_add_id(struct mproc *, uint64_t);
439 void m_add_sockaddr(struct mproc *, const struct sockaddr *);
440 void m_add_mailaddr(struct mproc *, const struct mailaddr *);
441 void m_close(struct mproc *);
442 void m_flush(struct mproc *);
443 
444 void m_msg(struct msg *, struct imsg *);
445 int  m_is_eom(struct msg *);
446 void m_end(struct msg *);
447 void m_get_int(struct msg *, int *);
448 void m_get_size(struct msg *, size_t *);
449 void m_get_u32(struct msg *, uint32_t *);
450 void m_get_time(struct msg *, time_t *);
451 void m_get_string(struct msg *, const char **);
452 void m_get_data(struct msg *, const void **, size_t *);
453 void m_get_evpid(struct msg *, uint64_t *);
454 void m_get_msgid(struct msg *, uint32_t *);
455 void m_get_id(struct msg *, uint64_t *);
456 void m_get_sockaddr(struct msg *, struct sockaddr *);
457 void m_get_mailaddr(struct msg *, struct mailaddr *);
458 
459 #ifdef BUILD_DAEMON
460 void m_add_envelope(struct mproc *, const struct envelope *);
461 void m_get_envelope(struct msg *, struct envelope *);
462 #endif
463 
464 
465 /* queue */
466 void queue_api_on_close(int(*)(void));
467 void queue_api_on_message_create(int(*)(uint32_t *));
468 void queue_api_on_message_commit(int(*)(uint32_t, const char*));
469 void queue_api_on_message_delete(int(*)(uint32_t));
470 void queue_api_on_message_fd_r(int(*)(uint32_t));
471 void queue_api_on_message_corrupt(int(*)(uint32_t));
472 void queue_api_on_message_uncorrupt(int(*)(uint32_t));
473 void queue_api_on_envelope_create(int(*)(uint32_t, const char *, size_t, uint64_t *));
474 void queue_api_on_envelope_delete(int(*)(uint64_t));
475 void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t));
476 void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t));
477 void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t));
478 void queue_api_on_message_walk(int(*)(uint64_t *, char *, size_t,
479     uint32_t, int *, void **));
480 void queue_api_no_chroot(void);
481 void queue_api_set_chroot(const char *);
482 void queue_api_set_user(const char *);
483 int queue_api_dispatch(void);
484 
485 /* queue utils */
486 uint32_t queue_generate_msgid(void);
487 uint64_t queue_generate_evpid(uint32_t);
488 int mktmpfile(void);
489 
490 /* scheduler */
491 void scheduler_api_on_init(int(*)(void));
492 void scheduler_api_on_insert(int(*)(struct scheduler_info *));
493 void scheduler_api_on_commit(size_t(*)(uint32_t));
494 void scheduler_api_on_rollback(size_t(*)(uint32_t));
495 void scheduler_api_on_update(int(*)(struct scheduler_info *));
496 void scheduler_api_on_delete(int(*)(uint64_t));
497 void scheduler_api_on_hold(int(*)(uint64_t, uint64_t));
498 void scheduler_api_on_release(int(*)(int, uint64_t, int));
499 void scheduler_api_on_batch(int(*)(int, int *, size_t *, uint64_t *, int *));
500 void scheduler_api_on_messages(size_t(*)(uint32_t, uint32_t *, size_t));
501 void scheduler_api_on_envelopes(size_t(*)(uint64_t, struct evpstate *, size_t));
502 void scheduler_api_on_schedule(int(*)(uint64_t));
503 void scheduler_api_on_remove(int(*)(uint64_t));
504 void scheduler_api_on_suspend(int(*)(uint64_t));
505 void scheduler_api_on_resume(int(*)(uint64_t));
506 void scheduler_api_no_chroot(void);
507 void scheduler_api_set_chroot(const char *);
508 void scheduler_api_set_user(const char *);
509 int scheduler_api_dispatch(void);
510 
511 /* table */
512 void table_api_on_update(int(*)(void));
513 void table_api_on_check(int(*)(int, struct dict *, const char *));
514 void table_api_on_lookup(int(*)(int, struct dict *, const char *, char *, size_t));
515 void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t));
516 int table_api_dispatch(void);
517 const char *table_api_get_name(void);
518 
519 /* tree.c */
520 #define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0)
521 #define tree_empty(t) SPLAY_EMPTY(&((t)->tree))
522 #define tree_count(t) ((t)->count)
523 int tree_check(struct tree *, uint64_t);
524 void *tree_set(struct tree *, uint64_t, void *);
525 void tree_xset(struct tree *, uint64_t, void *);
526 void *tree_get(struct tree *, uint64_t);
527 void *tree_xget(struct tree *, uint64_t);
528 void *tree_pop(struct tree *, uint64_t);
529 void *tree_xpop(struct tree *, uint64_t);
530 int tree_poproot(struct tree *, uint64_t *, void **);
531 int tree_root(struct tree *, uint64_t *, void **);
532 int tree_iter(struct tree *, void **, uint64_t *, void **);
533 int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **);
534 void tree_merge(struct tree *, struct tree *);
535 
536 /* util.c */
537 struct iobuf; /* forward declaration */
538 void	*xmalloc(size_t, const char *);
539 void	*xcalloc(size_t, size_t, const char *);
540 char	*xstrdup(const char *, const char *);
541 void	*xmemdup(const void *, size_t, const char *);
542 void	 iobuf_xinit(struct iobuf *, size_t, size_t, const char *);
543 void	 iobuf_xfqueue(struct iobuf *, const char *, const char *, ...);
544 char	*strip(char *);
545 int	 base64_encode(unsigned char const *, size_t, char *, size_t);
546 int	 base64_decode(char const *, unsigned char *, size_t);
547 int	 lowercase(char *, const char *, size_t);
548 
549 #endif
550