aboutsummaryrefslogtreecommitdiff
path: root/gacopyz/gacopyz.h
blob: 9d5ed08a84d0102e4b557ec6bc8b48cf8ec37929 (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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
/* This file is part of gacopyz.
   Copyright (C) 2006-2011, 2015 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/>. */

#ifndef __gacopyz_h__
# define __gacopyz_h__

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>

#ifdef __cplusplus
extern "C" {
#endif

#define GACOPYZ_VERSION_MAJOR 2
#define GACOPYZ_VERSION_MINOR 0
	
/* Implementation version number */	
#define SMFI_VERSION      0x01000000

#define SM_LM_VRS_MAJOR(v)      (((v) & 0x7f000000) >> 24)
#define SM_LM_VRS_MINOR(v)      (((v) & 0x007fff00) >> 8)
#define SM_LM_VRS_PLVL(v)       ((v) & 0x0000007f)

#define GACOPYZ_SM_MKVER(maj,min,pat) \
	((((maj) & 0x7f)<<24) | (((min) & 0x7ffff) << 8) | ((pat) & 0x7f))
	
/* Milter protocol version */	
#define SMFI_PROT_VERSION 6

/* Minimal supported protocol version */
#define SMFI_PROT_VERSION_MIN 2
	
/* commands: don't use anything smaller than ' ' */
#define SMFIC_ABORT             'A'     /* Abort */
#define SMFIC_BODY              'B'     /* Body chunk */
#define SMFIC_CONNECT           'C'     /* Connection information */
#define SMFIC_MACRO             'D'     /* Define macro */
#define SMFIC_BODYEOB           'E'     /* final body chunk (End) */
#define SMFIC_HELO              'H'     /* HELO/EHLO */
#define SMFIC_HEADER            'L'     /* Header */
#define SMFIC_MAIL              'M'     /* MAIL from */
#define SMFIC_EOH               'N'     /* EOH */
#define SMFIC_OPTNEG            'O'     /* Option negotiation */
#define SMFIC_QUIT              'Q'     /* QUIT */
#define SMFIC_RCPT              'R'     /* RCPT to */
#define SMFIC_DATA              'T'     /* DATA (SMFI_VERSION > 3) */
#define SMFIC_UNKNOWN           'U'     /* Any unknown command */

/* actions (replies) */
#define SMFIR_ADDRCPT           '+'     /* add recipient */
#define SMFIR_DELRCPT           '-'     /* remove recipient */
#define SMFIR_ADDRCPT_PAR       '2'     /* add recipient */
#define SMFIR_SHUTDOWN          '4'     /* 421: shutdown (internal to MTA) */
#define SMFIR_ACCEPT            'a'     /* accept */
#define SMFIR_REPLBODY          'b'     /* replace body (chunk) */
#define SMFIR_CONTINUE          'c'     /* continue */
#define SMFIR_DISCARD           'd'     /* discard */
#define SMFIR_CHGFROM           'e'     /* change envelope sender (from) */
#define SMFIR_CONN_FAIL         'f'     /* cause a connection failure */
#define SMFIR_ADDHEADER         'h'     /* add header */
#define SMFIR_INSHEADER         'i'     /* insert header */
#if 0
#define SMFIR_SETSYMLIST        'l'     /* set list of macros (unused) */
#endif
#define SMFIR_CHGHEADER         'm'     /* change header */
#define SMFIR_PROGRESS          'p'     /* progress */
#define SMFIR_QUARANTINE        'q'     /* quarantine */
#define SMFIR_REJECT            'r'     /* reject */
#define SMFIR_SKIP              's'     /* skip */
#define SMFIR_TEMPFAIL          't'     /* tempfail */
#define SMFIR_REPLYCODE         'y'     /* reply code etc */

/* What the MTA can send/filter wants in protocol */
#define SMFIP_NOCONNECT 0x00000001L     /* MTA should not send connect info */
#define SMFIP_NOHELO    0x00000002L     /* MTA should not send HELO info */
#define SMFIP_NOMAIL    0x00000004L     /* MTA should not send MAIL info */
#define SMFIP_NORCPT    0x00000008L     /* MTA should not send RCPT info */
#define SMFIP_NOBODY    0x00000010L     /* MTA should not send body */
#define SMFIP_NOHDRS    0x00000020L     /* MTA should not send headers */
#define SMFIP_NOEOH     0x00000040L     /* MTA should not send EOH */
#define SMFIP_NR_HDR    0x00000080L     /* No reply for headers */
#define SMFIP_NOHREPL   SMFIP_NR_HDR    /* No reply for headers */
#define SMFIP_NOUNKNOWN 0x00000100L     /* MTA should not send unknown
                                           commands */
#define SMFIP_NODATA    0x00000200L     /* MTA should not send DATA */
#define SMFIP_SKIP      0x00000400L     /* MTA understands SMFIS_SKIP */
#define SMFIP_RCPT_REJ  0x00000800L     /* MTA should also send rejected
					   RCPTs */
#define SMFIP_NR_CONN   0x00001000L     /* No reply for connect */
#define SMFIP_NR_HELO   0x00002000L     /* No reply for HELO */
#define SMFIP_NR_MAIL   0x00004000L     /* No reply for MAIL */
#define SMFIP_NR_RCPT   0x00008000L     /* No reply for RCPT */
#define SMFIP_NR_DATA   0x00010000L     /* No reply for DATA */
#define SMFIP_NR_UNKN   0x00020000L     /* No reply for UNKN */
#define SMFIP_NR_EOH    0x00040000L     /* No reply for eoh */
#define SMFIP_NR_BODY   0x00080000L     /* No reply for body chunk */
#define SMFIP_HDR_LEADSPC 0x00100000L   /* header value leading space */
	
/* The protocol of V1 filter */
#define SMFI_V1_PROT    (SMFIP_NOCONNECT|SMFIP_NOHELO|SMFIP_NOMAIL|\
                         SMFIP_NORCPT|SMFIP_NOBODY|SMFIP_NOHDRS)
/* The protocol of V2 filter */	
#define SMFI_V2_PROT    (SMFI_V1_PROT|SMFIP_NOEOH)

/* All defined prot bits */	
#define SMFI_DEFAULT_PROT  0x001FFFFFL
	
/* Flags, defining milter capabilities */
#define SMFIF_NONE	0x00000000L	/* no flags */
#define SMFIF_ADDHDRS	0x00000001L	/* filter may add headers */
#define SMFIF_CHGBODY	0x00000002L	/* filter may replace body */
#define SMFIF_MODBODY	SMFIF_CHGBODY	/* backwards compatible */
#define SMFIF_ADDRCPT	0x00000004L	/* filter may add recipients */
#define SMFIF_DELRCPT	0x00000008L	/* filter may delete recipients */
#define SMFIF_CHGHDRS	0x00000010L	/* filter may change/delete headers */
#define SMFIF_QUARANTINE 0x00000020L	/* filter may quarantine envelope */
#define SMFIF_CHGFROM   0x00000040L     /* filter may change envelope "from" */
#define SMFIF_ADDRCPT_PAR 0x00000080L   /* add recipients incl. args */
	
#define SMFI_V1_ACTS (SMFIF_ADDHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT)
#define SMFI_V2_ACTS (SMFI_V1_ACTS|SMFIF_CHGHDRS|SMFIF_QUARANTINE)	
#define SMFI_V6_ACTS (SMFI_V2_ACTS|SMFIF_CHGFROM|SMFIF_ADDRCPT_PAR)
	
#define SMFI_DEFAULT_ACTS SMFI_V6_ACTS
	
/* Log levels */
#define SMI_LOG_PROTO	0
#define SMI_LOG_DEBUG   1
#define SMI_LOG_INFO    2
#define SMI_LOG_WARN    3
#define SMI_LOG_ERR     4
#define SMI_LOG_FATAL   5

#define SMI_LOG_MASK(n) (1<<(n))
#define SMI_LOG_UPTO(n) ((1 << ((n)+1))-1)  /* all levels through n */
#define SMI_LOG_FROM(n) (SMI_LOG_UPTO(SMI_LOG_FATAL) & \
			 ~((n) == 0 ? 0 : SMI_LOG_UPTO((n)-1)))
			 
#define SMI_DEFAULT_LOG_MASK SMI_LOG_MASK(SMI_LOG_INFO)   \
                             | SMI_LOG_MASK(SMI_LOG_WARN) \
                 	     | SMI_LOG_MASK(SMI_LOG_ERR)  \
		             | SMI_LOG_MASK(SMI_LOG_FATAL)

/* address families */
#define SMFIA_UNKNOWN 'U'     /* unknown */
#define SMFIA_UNIX    'L'     /* unix/local */
#define SMFIA_INET    '4'     /* inet */
#define SMFIA_INET6   '6'     /* inet6 */

/* Function return codes */
#define MI_SUCCESS	0
#define MI_FAILURE	(-1)

/* Data types */
typedef struct smfi_str SMFICTX;
typedef struct smfi_str *SMFICTX_PTR;
typedef struct gacopyz_conn *gacopyz_conn_t;
typedef struct gacopyz_iod *gacopyz_iod_t;
	
/* Return type for the callbacks */
typedef enum {
	SMFIS_CONTINUE,
	SMFIS_REJECT,
	SMFIS_DISCARD,
	SMFIS_ACCEPT,
	SMFIS_TEMPFAIL,
	SMFIS_NOREPLY = 7,
	SMFIS_SKIP = 8,
	SMFIS_ALL_OPTS = 10
} sfsistat;
	
typedef union {
	struct sockaddr sa;
	struct sockaddr_in sin;
	struct sockaddr_un sunix;
#ifdef GACOPYZ_IPV6
	struct sockaddr_in6 sin6;
#endif
} milter_sockaddr_t;

enum gacopyz_stage {
	gacopyz_stage_conn,	
	gacopyz_stage_helo,	
	gacopyz_stage_mail,	
	gacopyz_stage_rcpt,	
	gacopyz_stage_data,
	gacopyz_stage_eom,
	gacopyz_stage_eoh,
	
	gacopyz_stage_max,
	gacopyz_stage_none = gacopyz_stage_max
};

#define SMFIM_CONNECT   gacopyz_stage_conn  
#define SMFIM_HELO      gacopyz_stage_helo  
#define SMFIM_ENVFROM   gacopyz_stage_mail  
#define SMFIM_ENVRCPT   gacopyz_stage_rcpt  
#define SMFIM_DATA      gacopyz_stage_data  
#define SMFIM_EOM       gacopyz_stage_eom   
#define SMFIM_EOH       gacopyz_stage_eoh   
	
#define _SOCK_ADDR milter_sockaddr_t	
#define smfiDesc gacopyz_milter_descr

typedef struct gacopyz_milter_descr gacopyz_milter_descr_t;
	
struct gacopyz_milter_descr
{
        char          *xxfi_name;     /* filter name */
        int           xxfi_version;   /* version code */
        unsigned long xxfi_flags;     /* flags */
	  /* Filters: */
          /* connection info */
        sfsistat    (*xxfi_connect) (SMFICTX *, char *, milter_sockaddr_t *);
          /* SMTP HELO command */
        sfsistat    (*xxfi_helo) (SMFICTX *, char *);
          /* envelope sender */
        sfsistat    (*xxfi_envfrom) (SMFICTX *, char **);
          /* envelope recipient */
        sfsistat    (*xxfi_envrcpt) (SMFICTX *, char **);
          /* header */
        sfsistat    (*xxfi_header) (SMFICTX *, char *, char *);
          /* end of header */
        sfsistat    (*xxfi_eoh) (SMFICTX *);
          /* body block */
        sfsistat    (*xxfi_body) (SMFICTX *, unsigned char *, size_t);
          /* end of message */
        sfsistat     (*xxfi_eom) (SMFICTX *);
          /* message aborted */
        sfsistat     (*xxfi_abort) (SMFICTX *);
          /* connection cleanup */
        sfsistat     (*xxfi_close) (SMFICTX *);
          /* any unrecognized or unimplemented command (SMFI_VERSION > 2) */
        sfsistat     (*xxfi_unknown) (SMFICTX *, char *);
          /* SMTP DATA command (SMFI_VERSION > 3) */
        sfsistat     (*xxfi_data) (SMFICTX *);
	  /* Milter negotiation (SMFI_VERSION > 3) */
	sfsistat     (*xxfi_negotiate) (SMFICTX *,
					unsigned long, unsigned long,
		                        unsigned long, unsigned long,
		                        unsigned long *, unsigned long *,
		                        unsigned long *, unsigned long *);
		
	/* Extensions: */

	int (*xxfi_start) ();  /* Child start callback */
	int (*xxfi_finish) (); /* Child finish callback */
	int (*xxfi_idle) (gacopyz_conn_t); /* Idle handler */
	int (*xxfi_accept) (gacopyz_conn_t, int, const milter_sockaddr_t *,
			    int salen);
	
	int logmask;
	struct timeval ctx_timeout;
};

/* Standard API calls */
extern int smfi_version (unsigned int *, unsigned int *, unsigned int *);
extern int smfi_opensocket (int);
extern int smfi_register (struct smfiDesc);
extern int smfi_main (void);
extern int smfi_setbacklog (int);
extern int smfi_setdbg (int);
extern int smfi_settimeout (time_t);
extern int smfi_setconn (char *);
extern int smfi_stop (void);
	
#define smfi_getsymval(ctx,s) ((char*) gacopyz_getsymval(ctx, (char*)s))

int smfi_addheader (SMFICTX *, char *, char *);
int smfi_chgheader (SMFICTX *, char *, int, char *);
int smfi_insheader (SMFICTX *, int, char *, char *);
int smfi_addrcpt (SMFICTX *, char *);
int smfi_delrcpt (SMFICTX *, char *);
int smfi_progress (SMFICTX *);
int smfi_replacebody (SMFICTX *, unsigned char *, int);
int smfi_quarantine (SMFICTX *ctx, char *reason);
int smfi_addrcpt_par(SMFICTX *ctx, char *rcpt, char *args);
int smfi_chgfrom(SMFICTX *ctx, char *from, char *args);
#define smfi_setpriv gacopyz_setpriv
#define smfi_getpriv gacopyz_getpriv
size_t smfi_setmaxdatasize (size_t); 
int smfi_setsymlist(SMFICTX *ctx, int stage, char *macros);
	
/* Replies: */
extern int smfi_setreply (SMFICTX *, char *, char *, char *);
int smfi_setmlreply (SMFICTX *, const char *, const char *, ...);

/* Extensions */	
extern int smfi_set_foreground(int val);
extern int smfi_setlogmask(int logmask);

/* New API calls: */
int gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc);
void gacopyz_free(gacopyz_conn_t conn);
const char *gacopyz_safe_header_value(const char *input, char **poutput);

int gacopyz_set_logmask(gacopyz_conn_t conn, int mask);
int gacopyz_get_logmask(gacopyz_conn_t conn, int *mask);
int gacopyz_set_foreground(gacopyz_conn_t conn, int fg);
int gacopyz_set_master_timeout(gacopyz_conn_t conn, struct timeval *timeout);
int gacopyz_get_master_timeout(gacopyz_conn_t conn, struct timeval *timeout);
int gacopyz_set_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout);
int gacopyz_get_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout);
int gacopyz_stop(gacopyz_conn_t conn);
	
int gacopyz_open(gacopyz_conn_t conn, const char *cstr,
		  int backlog, int rmsocket);
	
int gacopyz_parse_connection(const char *cstr,
			     char **pproto, char **pport, char **ppath);

int gacopyz_connect(gacopyz_conn_t *, struct smfiDesc *, const char *,
		    int backlog, int rmsocket);
int gacopyz_get_fd(gacopyz_conn_t);
	
int gacopyz_run(gacopyz_conn_t);	
int gacopyz_context_loop(int fd, struct smfiDesc const *desc,
			 milter_sockaddr_t *addr, socklen_t addrlen,
			 void *calldata);

int gacopyz_register_child(gacopyz_conn_t conn, pid_t pid);
void gacopyz_cleanup_children(gacopyz_conn_t conn);
void gacopyz_cleanup_conn(gacopyz_conn_t conn);
void gacopyz_setup_signals(void);

const char *gacopyz_getsymval (SMFICTX *, const char *);	

int gacopyz_setreply(SMFICTX *ctx, const char *rcode, const char *xcode,
		      const char *message);
int gacopyz_setmlreply_v(SMFICTX *ctx, const char *rcode, const char *xcode,
			  ...);
int gacopyz_setmlreply_va(SMFICTX *ctx, const char *rcode, const char *xcode,
			   va_list ap);
int _gacopyz_setmlreply_va(SMFICTX *ctx, size_t max, const char *rcode,
			    const char *xcode, va_list ap);

int gacopyz_add_header(SMFICTX *ctx, const char *headerf,
			const char *headerv);

int gacopyz_insert_header(SMFICTX *ctx, int index, const char *headerf,
			   const char *headerv);
int gacopyz_change_header(SMFICTX *ctx, int index, const char *headerf,
			   const char *headerv);
int gacopyz_add_rcpt(SMFICTX *ctx, const char *rcpt);
int gacopyz_del_rcpt(SMFICTX *ctx, const char *rcpt);
int gacopyz_replace_body(SMFICTX *ctx, const unsigned char *bodyp,
			 size_t bodylen);
int gacopyz_replace_body_fn(SMFICTX *ctx,
			    void *bodyp, 
			    ssize_t (*cpf)(char*,void*,size_t));
int gacopyz_replace_body_fd(SMFICTX *ctx, int fd);	
int gacopyz_progress(SMFICTX *ctx);
int gacopyz_quarantine(SMFICTX *ctx, const char *reason);
int gacopyz_add_rcpt_par(SMFICTX *ctx, const char *rcpt, const char *args);
int gacopyz_chgfrom(SMFICTX *ctx, const char *from, const char *args);

int gacopyz_setsymlist(SMFICTX *ctx, enum gacopyz_stage ind,
		       const char *macros);
	
int gacopyz_setpriv (SMFICTX *ctx, void *data);
void *gacopyz_getpriv (SMFICTX *ctx);
void *gacopyz_getclosure(SMFICTX *ctx);

int gacopyz_client_sockname(SMFICTX *ctx,
			    milter_sockaddr_t *name, socklen_t *namelen);
int gacopyz_server_sockname(SMFICTX *ctx,
			    milter_sockaddr_t *name, socklen_t *namelen);
	
/* Logging (extensions) */
extern const char *gacopyz_stage_name[gacopyz_stage_max];
	
#define GACOPYZ_VBUFSIZE 69
size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf,
			   size_t size);
void gacopyz_log(int level, char *fmt, ...);
void gacopyz_logdump(int level, const char *pfx,
		     const char *buf, size_t size);
void gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...);
void gacopyz_io_logdump(gacopyz_iod_t iod, const char *pfx,
			const char *buf, size_t size);
void gacopyz_set_logger(void (*)(int, char *, va_list));

void gacopyz_stderr_log_printer(int level, char *fmt, va_list ap);
void gacopyz_syslog_log_printer(int level, char *fmt, va_list ap);
int gacopyz_string_to_log_level(const char *str);
const char *gacopyz_log_level_to_string(int level);
	
	
/* Server */
typedef struct gacopyz_srv *gacopyz_srv_t;

enum gacopyz_flag_op {
	gacopyz_flag_rpl,
	gacopyz_flag_set,
	gacopyz_flag_clr
};

#define GACOPYZ_SRV_DISABLED 0x0001
	
int gacopyz_srv_create(gacopyz_srv_t *p, const char *name,
		       const char *portspec, unsigned logmask);
int gacopyz_srv_create_X(gacopyz_srv_t *p, const char *spec, unsigned logmask);
	
void gacopyz_srv_destroy(gacopyz_srv_t *p);	
int gacopyz_srv_find_macro (gacopyz_srv_t srv, const char *name,
			    const char **pval);
void gacopyz_srv_define_macro (gacopyz_srv_t srv,
			      const char *name, const char *value);
void gacopyz_srv_del_macro (gacopyz_srv_t srv, const char *name);
void gacopyz_srv_clear_macros (gacopyz_srv_t srv);
void gacopyz_srv_clear_macros_pred(gacopyz_srv_t srv,
				   int (*pred) (const char*, void*),
				   void *data);

void gacopyz_srv_iterate_macros (gacopyz_srv_t srv,
				 int (*func) (const char *name,
					      const char *value,
					      void *data),
				 void *data);
void gacopyz_srv_count_macros (gacopyz_srv_t srv, size_t *count);
	
const char **gacopyz_srv_get_required_macros(gacopyz_srv_t srv,
					     enum gacopyz_stage stage);
const char *gacopyz_srv_get_id(gacopyz_srv_t srv);
const char *gacopyz_srv_get_portspec(gacopyz_srv_t srv);

int gacopyz_srv_flags(gacopyz_srv_t srv, int flags, enum gacopyz_flag_op op);
int gacopyz_srv_get_flags(gacopyz_srv_t srv);

int gacopyz_srv_get_logmask(gacopyz_srv_t srv);
int gacopyz_srv_get_fd(gacopyz_srv_t srv);	
int gacopyz_srv_get_onerr(gacopyz_srv_t srv);
  
int gacopyz_srv_open(gacopyz_srv_t srv);
int gacopyz_srv_init(gacopyz_srv_t srv);
int gacopyz_srv_negotiate(gacopyz_srv_t srv);
int gacopyz_srv_abort(gacopyz_srv_t srv);
int gacopyz_srv_quit(gacopyz_srv_t srv);

int gacopyz_srv_connect(gacopyz_srv_t srv, const char *hostname,
			struct sockaddr *sa);
int gacopyz_srv_helo (gacopyz_srv_t p, const char *domain);
int gacopyz_srv_envfrom (gacopyz_srv_t p, char **argv);
int gacopyz_srv_envrcpt (gacopyz_srv_t p, char **argv);
int gacopyz_srv_header (gacopyz_srv_t p, char *name, char *value);
int gacopyz_srv_eoh (gacopyz_srv_t p);
int gacopyz_srv_body (gacopyz_srv_t p, unsigned char *str, size_t size);

int gacopyz_srv_eom (gacopyz_srv_t p, unsigned char *str, size_t size);
int gacopyz_srv_abort (gacopyz_srv_t p);
int gacopyz_srv_close (gacopyz_srv_t p);
int gacopyz_srv_data (gacopyz_srv_t p);

int gacopyz_srv_onerror(gacopyz_srv_t srv, int code);
void gacopyz_srv_set_logmask(gacopyz_srv_t srv, int logmask);
void gacopyz_srv_set_memerror(gacopyz_srv_t srv,
			      void (*memerror)(gacopyz_srv_t, const char *,
					       unsigned int));
void gacopyz_srv_set_callback(gacopyz_srv_t srv,
			      int (*cb) (gacopyz_srv_t, int, int, void *));
void gacopyz_srv_set_callback_data(gacopyz_srv_t, void *);

int gacopyz_srv_set_source(gacopyz_srv_t srv, struct sockaddr *sa,
			   socklen_t len);
int gacopyz_srv_set_version(gacopyz_srv_t srv, unsigned long version);
int gacopyz_srv_set_protocol(gacopyz_srv_t srv, unsigned long proto);
int gacopyz_srv_set_actions(gacopyz_srv_t srv, unsigned long acts);

#define GACOPYZ_WRITE_TIMEOUT 10
#define GACOPYZ_READ_TIMEOUT 10
#define GACOPYZ_EOM_TIMEOUT 300
#define GACOPYZ_CONNECT_TIMEOUT 300	
	
#define GACOPYZ_TO_WRITE    0    /* Timeout for sending information */
#define GACOPYZ_TO_READ     1    /* Timeout waiting for a response */
#define GACOPYZ_TO_EOM      2    /* Timeout for ACK/NAK to EOM */
#define GACOPYZ_TO_CONNECT  3    /* Timeout for connect() */
#define GACOPYZ_TO_COUNT    4

void gacopyz_srv_set_all_timeouts(gacopyz_srv_t srv, struct timeval *tvp);
int gacopyz_srv_set_timeout(gacopyz_srv_t srv, unsigned n,
			    struct timeval *tvp);
int gacopyz_srv_set_timeout_sec(gacopyz_srv_t srv, unsigned n, time_t t);
	
int gacopyz_srv_reply(gacopyz_srv_t srv, char **msg, size_t *size);
void gacopyz_srv_reply_raw(gacopyz_srv_t srv, char **msg, size_t *size);
	
#ifdef __cplusplus
}
#endif

#endif /* __gacopyz_h__ */

Return to:

Send suggestions and report system problems to the System administrator.