summaryrefslogtreecommitdiffabout
path: root/lib/libmf.h
blob: 9842b75c1f1d58d3c23cf106fe7ea64be4dda34b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/* This file is part of Mailfromd.
   Copyright (C) 2005-2006, 2008, 2010-2011, 2015-2017 Sergey Poznyakoff

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <gettext.h>
#include <limits.h>
#include <mailutils/types.h>
#include <mailutils/cfg.h>
#include <mailutils/stdstream.h>
#include <mailutils/cli.h>
#include <pwd.h>
#include <grp.h>

#include "dns.h"

#define _(String) gettext(String)
#define N_(String) String

#if defined HAVE_SYSCONF && defined _SC_OPEN_MAX
# define getmaxfd() sysconf(_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
# define getmaxfd() getdtablesize()
#else
# define getmaxfd() 256
#endif


/* The following defines are borrowed from intprops.h (gnulib) */

/* True if the arithmetic type T is signed.  */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))

/* Return zero if T can be determined to be an unsigned type.
   Otherwise, return 1.
   When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
   tighter bound.  Otherwise, it overestimates the true bound by one byte
   when applied to unsigned types of size 2, 4, 16, ... bytes.
   The symbol signed_type_or_expr__ is private to this header file.  */
#if __GNUC__ >= 2
# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
#else
# define signed_type_or_expr__(t) 1
#endif

/* Bound on length of the string representing an integer type or expression T.
   Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
   add 1 for integer division truncation; add 1 more for a minus sign
   if needed.  */
#define INT_STRLEN_BOUND(t) \
  ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
   + signed_type_or_expr__ (t) + 1)

/* Bound on buffer size needed to represent an integer type or expression T,
   including the terminating null.  */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)

/* Size of the buffer able to accomodate mailfromd numeric type */
#define NUMERIC_BUFSIZE_BOUND INT_BUFSIZE_BOUND(long)


/* Status values used throughout the program */
typedef enum mf_status_code {
	mf_success,
	mf_not_found,
	mf_failure,
	mf_temp_failure,
	mf_timeout,

#define	mf_status_count (mf_smtp_temp_failure+1)
} mf_status;

#define mf_resolved(c) ((c) == mf_success || (c) == mf_not_found)

const char *mf_status_str(mf_status s);


enum smtp_timeout {
	smtp_timeout_connect,
	smtp_timeout_initial,
	smtp_timeout_helo,
	smtp_timeout_mail,
	smtp_timeout_rcpt,
	smtp_timeout_rset,
	smtp_timeout_quit
};

#define SMTP_NUM_TIMEOUT (smtp_timeout_quit+1)


#define MF_GETOPT_DEFAULT   0x00
/* Process options in order; don't permute */
#define MF_GETOPT_IN_ORDER  0x01
/* Don't parse configuration files */
#define MF_GETOPT_NO_CONFIG 0x02

void mf_getopt(struct mu_cli_setup *cli, int *pargc, char ***pargv, char **capa,
	       int flags);
void mailfromd_version(struct mu_parseopt *po, mu_stream_t stream);
int mf_vercmp(const char *a, const char *b, int *pres);
void mf_init_nls (void);
int parse_time_interval(const char *str, time_t *pint, const char **endp);

void dict_init(mu_assoc_t *dict);
char *dict_install(mu_assoc_t dict, const char *name, const char *value);
void dict_destroy(mu_assoc_t *dict);
char *dict_getsym(void *data, const char *str);


struct mf_privs {
	char *user;
	int allgroups;
	mu_list_t groups;
};

struct mf_gid_list;

struct mf_gid_list *mf_gid_list_alloc(void);
void mf_gid_list_free(struct mf_gid_list *gl);
struct mf_gid_list *mf_gid_list_dup(struct mf_gid_list *src);
void mf_gid_list_add(struct mf_gid_list *gl, gid_t gid);
void mf_gid_list_array(struct mf_gid_list *gl, size_t *gc, gid_t **gv);

int switch_to_privs (uid_t uid, gid_t gid, struct mf_gid_list *);
void get_user_groups (struct mf_gid_list *grouplist, const char *user);

void mf_priv_setup (struct mf_privs *);
void mf_epriv_setup (struct mf_privs *);


char **config_array_to_argv (mu_config_value_t *val);
char *config_array_to_string (mu_config_value_t *val);

int config_cb_timeout (struct timeval *pt, mu_config_value_t *val);
int config_cb_time_t(void *data, mu_config_value_t *arg);
int config_cb_ignore(void *data, mu_config_value_t *val);
int config_cb_lock_retry_count(void *data, mu_config_value_t *val);
int config_cb_lock_retry_timeout(void *data, mu_config_value_t *val);

void mf_proctitle_init (int argc, char *argv[], char *env[]);
void mf_proctitle_format (const char *fmt, ...);
int stderr_closed_p(void);
int mf_list_compare_string(const void *item, const void *value);


struct symtab;
struct syment {
	char *name;
	unsigned refcnt;
};

typedef int (*symtab_enumerator_t)(void *sym, void *data);

#define SYMTAB_COPY_KEY 0x1
#define SYMTAB_ICASE    0x2

const char * symtab_strerror(int rc);

int symtab_lookup_or_install(struct syment **ent,
			     struct symtab *st, const char *name,
			     int *install);
int symtab_lookup_or_install_entry(struct syment **elp, 
				   struct symtab *st, struct syment *ent,
				   int *install);
void symtab_clear(struct symtab *st);
struct symtab *symtab_create(size_t elsize, int flags,
			     void *(*alloc_fun)(size_t),
			     void (*free_fun)(void *));
void symtab_destroy(struct symtab **pst);
int symtab_remove(struct symtab *st, const char *name);
int symtab_replace(struct symtab *st, struct syment *ent,
		   struct syment **old_ent);
int symtab_enumerate(struct symtab *st, symtab_enumerator_t fun, void *data);


typedef int (*symtab_selfun)(const struct syment *ent, void *closure);
typedef int (*symtab_errfun)(int rc, struct symtab *tab, const char *name,
			     void *closure);
typedef int (*symtab_confun)(struct symtab *dst,
			     struct syment *dstent, struct syment *srcent,
			     void *closure);
typedef int (*symtab_cpyfun)(struct syment **pdst, struct syment *src,
			     size_t len, void *closure);

int symtab_import(struct symtab *dst, struct symtab *src,
		  symtab_selfun selfun, symtab_errfun errfun,
		  symtab_confun confun, symtab_cpyfun cpyfun,
		  void *closure);

size_t symtab_count_entries(struct symtab *st);


typedef struct transform *transform_t;

typedef int (*transform_append_t)(void *, const char *s, size_t len);
typedef char *(*transform_reduce_t)(void *);

const char *transform_error_string (void);
transform_t transform_compile(const char *expr, int cflags);
void transform_free(transform_t);
char *transform_string (transform_t tf, const char *input,
			void *slist,
			transform_append_t append,
			transform_reduce_t reduce);


void close_fds_above(int fd);
void close_fds_except(fd_set *exfd);

/* logger.c */
#ifdef DEFAULT_SYSLOG_ASYNC
# define DEFAULT_LOG_STREAM "syslog:async"
#else
# define DEFAULT_LOG_STREAM "syslog"
#endif

#define LOGF_STDERR 0x01 /* Logger uses stderr */

struct logger {
	char *name;
	int flags;
	void (*log_open)(void);
	void (*log_close)(void);
	void (*log_fdset)(fd_set *set);
	void (*log_text)(int, const char *);
};

int logger_flags(int mask);
int logger_select(const char *name);
void logger_open(void);
void logger_close(void);
void logger_fdset(fd_set *set);
void logger_text(int prio, const char *text);

#define vlogmsg mu_diag_voutput
#define logmsg mu_diag_output


/* strmwait.c */

struct timeout_ctl {
	time_t start;
	time_t timeout;
};

#define UPDATE_TTW(t) do {                                           \
        time_t now = time(NULL);                                     \
	time_t delta = now - (t).start;                              \
	if ((t).timeout > delta)                                     \
		(t).timeout -= delta;                                \
	else                                                         \
		(t).timeout = 0;                                     \
        (t).start = now;                                             \
} while (0)

void init_timeout_ctl(struct timeout_ctl *tctl, time_t timeout);
int mf_stream_wait(mu_stream_t stream, int flags, struct timeout_ctl *tctl);


/* ftimestr.c */
extern char *time_format_string;

size_t format_time_str(FILE *fp, time_t timestamp);


/* dns.c */
void dnsbase_init();
mf_status dns_to_mf_status(dns_status stat);
dns_status mf_to_dns_status(mf_status stat);
mf_status getmx(const char *host, struct mxbuf *mxbuf);
mf_status getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount);
mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf);
mf_status resolve_ipstr(const char *ipstr, char **phbuf);	
mf_status resolve_hostname(const char *host, char **pipbuf);	
	

/* server.c */

#define MF_SERVER_FOREGROUND 0x01
#define MF_SERVER_NORESTART  0x02

extern void mf_server_log_setup(void);

extern mode_t mf_server_umask;
extern char *mf_server_user;
extern struct mf_gid_list *mf_server_retain_groups;
extern char *mf_server_lint_option;

void mf_server_check_pidfile(const char *name);
void mf_server_save_cmdline(int argc, char **argv);
void mf_server_start(const char *program, const char *dir,
		     const char *pidfile, int flags);


/* namefixup.c */
void mf_namefixup_register(char **ptr, const char *initval);
void mf_file_name_ptr_fixup(char **ptr, char *dir, size_t dirlen);
void mf_namefixup_run(char *dir);
void mf_namefixup_free(void);

Return to:

Send suggestions and report system problems to the System administrator.