1 /* This file is part of gacopyz. 2 Copyright (C) 2006-2021 Sergey Poznyakoff 3 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 3, or (at your option) 7 any later version. 8 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. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifndef __gacopyz_h__ 18 # define __gacopyz_h__ 19 20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <sys/types.h> 23 #include <sys/time.h> 24 #include <netinet/in.h> 25 #include <sys/un.h> 26 #include <sys/stat.h> 27 #include <sys/wait.h> 28 #include <netdb.h> 29 #include <arpa/inet.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <errno.h> 33 #include <syslog.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <stdarg.h> 37 #include <string.h> 38 #include <signal.h> 39 #include <ctype.h> 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 #define GACOPYZ_VERSION_MAJOR 2 46 #define GACOPYZ_VERSION_MINOR 0 47 48 /* Implementation version number */ 49 #define SMFI_VERSION 0x01000000 50 51 #define SM_LM_VRS_MAJOR(v) (((v) & 0x7f000000) >> 24) 52 #define SM_LM_VRS_MINOR(v) (((v) & 0x007fff00) >> 8) 53 #define SM_LM_VRS_PLVL(v) ((v) & 0x0000007f) 54 55 #define GACOPYZ_SM_MKVER(maj,min,pat) \ 56 ((((maj) & 0x7f)<<24) | (((min) & 0x7ffff) << 8) | ((pat) & 0x7f)) 57 58 /* Milter protocol version */ 59 #define SMFI_PROT_VERSION 6 60 61 /* Minimal supported protocol version */ 62 #define SMFI_PROT_VERSION_MIN 2 63 64 /* commands: don't use anything smaller than ' ' */ 65 #define SMFIC_ABORT 'A' /* Abort */ 66 #define SMFIC_BODY 'B' /* Body chunk */ 67 #define SMFIC_CONNECT 'C' /* Connection information */ 68 #define SMFIC_MACRO 'D' /* Define macro */ 69 #define SMFIC_BODYEOB 'E' /* final body chunk (End) */ 70 #define SMFIC_HELO 'H' /* HELO/EHLO */ 71 #define SMFIC_HEADER 'L' /* Header */ 72 #define SMFIC_MAIL 'M' /* MAIL from */ 73 #define SMFIC_EOH 'N' /* EOH */ 74 #define SMFIC_OPTNEG 'O' /* Option negotiation */ 75 #define SMFIC_QUIT 'Q' /* QUIT */ 76 #define SMFIC_RCPT 'R' /* RCPT to */ 77 #define SMFIC_DATA 'T' /* DATA (SMFI_VERSION > 3) */ 78 #define SMFIC_UNKNOWN 'U' /* Any unknown command */ 79 80 /* actions (replies) */ 81 #define SMFIR_ADDRCPT '+' /* add recipient */ 82 #define SMFIR_DELRCPT '-' /* remove recipient */ 83 #define SMFIR_ADDRCPT_PAR '2' /* add recipient */ 84 #define SMFIR_SHUTDOWN '4' /* 421: shutdown (internal to MTA) */ 85 #define SMFIR_ACCEPT 'a' /* accept */ 86 #define SMFIR_REPLBODY 'b' /* replace body (chunk) */ 87 #define SMFIR_CONTINUE 'c' /* continue */ 88 #define SMFIR_DISCARD 'd' /* discard */ 89 #define SMFIR_CHGFROM 'e' /* change envelope sender (from) */ 90 #define SMFIR_CONN_FAIL 'f' /* cause a connection failure */ 91 #define SMFIR_ADDHEADER 'h' /* add header */ 92 #define SMFIR_INSHEADER 'i' /* insert header */ 93 #if 0 94 #define SMFIR_SETSYMLIST 'l' /* set list of macros (unused) */ 95 #endif 96 #define SMFIR_CHGHEADER 'm' /* change header */ 97 #define SMFIR_PROGRESS 'p' /* progress */ 98 #define SMFIR_QUARANTINE 'q' /* quarantine */ 99 #define SMFIR_REJECT 'r' /* reject */ 100 #define SMFIR_SKIP 's' /* skip */ 101 #define SMFIR_TEMPFAIL 't' /* tempfail */ 102 #define SMFIR_REPLYCODE 'y' /* reply code etc */ 103 104 /* What the MTA can send/filter wants in protocol */ 105 #define SMFIP_NOCONNECT 0x00000001L /* MTA should not send connect info */ 106 #define SMFIP_NOHELO 0x00000002L /* MTA should not send HELO info */ 107 #define SMFIP_NOMAIL 0x00000004L /* MTA should not send MAIL info */ 108 #define SMFIP_NORCPT 0x00000008L /* MTA should not send RCPT info */ 109 #define SMFIP_NOBODY 0x00000010L /* MTA should not send body */ 110 #define SMFIP_NOHDRS 0x00000020L /* MTA should not send headers */ 111 #define SMFIP_NOEOH 0x00000040L /* MTA should not send EOH */ 112 #define SMFIP_NR_HDR 0x00000080L /* No reply for headers */ 113 #define SMFIP_NOHREPL SMFIP_NR_HDR /* No reply for headers */ 114 #define SMFIP_NOUNKNOWN 0x00000100L /* MTA should not send unknown 115 commands */ 116 #define SMFIP_NODATA 0x00000200L /* MTA should not send DATA */ 117 #define SMFIP_SKIP 0x00000400L /* MTA understands SMFIS_SKIP */ 118 #define SMFIP_RCPT_REJ 0x00000800L /* MTA should also send rejected 119 RCPTs */ 120 #define SMFIP_NR_CONN 0x00001000L /* No reply for connect */ 121 #define SMFIP_NR_HELO 0x00002000L /* No reply for HELO */ 122 #define SMFIP_NR_MAIL 0x00004000L /* No reply for MAIL */ 123 #define SMFIP_NR_RCPT 0x00008000L /* No reply for RCPT */ 124 #define SMFIP_NR_DATA 0x00010000L /* No reply for DATA */ 125 #define SMFIP_NR_UNKN 0x00020000L /* No reply for UNKN */ 126 #define SMFIP_NR_EOH 0x00040000L /* No reply for eoh */ 127 #define SMFIP_NR_BODY 0x00080000L /* No reply for body chunk */ 128 #define SMFIP_HDR_LEADSPC 0x00100000L /* header value leading space */ 129 130 /* The protocol of V1 filter */ 131 #define SMFI_V1_PROT (SMFIP_NOCONNECT|SMFIP_NOHELO|SMFIP_NOMAIL|\ 132 SMFIP_NORCPT|SMFIP_NOBODY|SMFIP_NOHDRS) 133 /* The protocol of V2 filter */ 134 #define SMFI_V2_PROT (SMFI_V1_PROT|SMFIP_NOEOH) 135 136 /* All defined prot bits */ 137 #define SMFI_DEFAULT_PROT 0x001FFFFFL 138 139 /* Flags, defining milter capabilities */ 140 #define SMFIF_NONE 0x00000000L /* no flags */ 141 #define SMFIF_ADDHDRS 0x00000001L /* filter may add headers */ 142 #define SMFIF_CHGBODY 0x00000002L /* filter may replace body */ 143 #define SMFIF_MODBODY SMFIF_CHGBODY /* backwards compatible */ 144 #define SMFIF_ADDRCPT 0x00000004L /* filter may add recipients */ 145 #define SMFIF_DELRCPT 0x00000008L /* filter may delete recipients */ 146 #define SMFIF_CHGHDRS 0x00000010L /* filter may change/delete headers */ 147 #define SMFIF_QUARANTINE 0x00000020L /* filter may quarantine envelope */ 148 #define SMFIF_CHGFROM 0x00000040L /* filter may change envelope "from" */ 149 #define SMFIF_ADDRCPT_PAR 0x00000080L /* add recipients incl. args */ 150 151 #define SMFI_V1_ACTS (SMFIF_ADDHDRS|SMFIF_CHGBODY|SMFIF_ADDRCPT|SMFIF_DELRCPT) 152 #define SMFI_V2_ACTS (SMFI_V1_ACTS|SMFIF_CHGHDRS|SMFIF_QUARANTINE) 153 #define SMFI_V6_ACTS (SMFI_V2_ACTS|SMFIF_CHGFROM|SMFIF_ADDRCPT_PAR) 154 155 #define SMFI_DEFAULT_ACTS SMFI_V6_ACTS 156 157 /* Log levels */ 158 #define SMI_LOG_PROTO 0 159 #define SMI_LOG_DEBUG 1 160 #define SMI_LOG_INFO 2 161 #define SMI_LOG_WARN 3 162 #define SMI_LOG_ERR 4 163 #define SMI_LOG_FATAL 5 164 165 #define SMI_LOG_MASK(n) (1<<(n)) 166 #define SMI_LOG_UPTO(n) ((1 << ((n)+1))-1) /* all levels through n */ 167 #define SMI_LOG_FROM(n) (SMI_LOG_UPTO(SMI_LOG_FATAL) & \ 168 ~((n) == 0 ? 0 : SMI_LOG_UPTO((n)-1))) 169 170 #define SMI_DEFAULT_LOG_MASK SMI_LOG_MASK(SMI_LOG_INFO) \ 171 | SMI_LOG_MASK(SMI_LOG_WARN) \ 172 | SMI_LOG_MASK(SMI_LOG_ERR) \ 173 | SMI_LOG_MASK(SMI_LOG_FATAL) 174 175 /* address families */ 176 #define SMFIA_UNKNOWN 'U' /* unknown */ 177 #define SMFIA_UNIX 'L' /* unix/local */ 178 #define SMFIA_INET '4' /* inet */ 179 #define SMFIA_INET6 '6' /* inet6 */ 180 181 /* Function return codes */ 182 #define MI_SUCCESS 0 183 #define MI_FAILURE (-1) 184 185 /* Data types */ 186 typedef struct smfi_str SMFICTX; 187 typedef struct smfi_str *SMFICTX_PTR; 188 typedef struct gacopyz_conn *gacopyz_conn_t; 189 typedef struct gacopyz_iod *gacopyz_iod_t; 190 191 /* Return type for the callbacks */ 192 typedef enum { 193 SMFIS_CONTINUE, 194 SMFIS_REJECT, 195 SMFIS_DISCARD, 196 SMFIS_ACCEPT, 197 SMFIS_TEMPFAIL, 198 SMFIS_NOREPLY = 7, 199 SMFIS_SKIP = 8, 200 SMFIS_ALL_OPTS = 10 201 } sfsistat; 202 203 typedef union { 204 struct sockaddr sa; 205 struct sockaddr_in sin; 206 struct sockaddr_un sunix; 207 #ifdef GACOPYZ_IPV6 208 struct sockaddr_in6 sin6; 209 #endif 210 } milter_sockaddr_t; 211 212 enum gacopyz_stage { 213 gacopyz_stage_conn, 214 gacopyz_stage_helo, 215 gacopyz_stage_mail, 216 gacopyz_stage_rcpt, 217 gacopyz_stage_data, 218 gacopyz_stage_eom, 219 gacopyz_stage_eoh, 220 221 gacopyz_stage_max, 222 gacopyz_stage_none = gacopyz_stage_max 223 }; 224 225 #define SMFIM_CONNECT gacopyz_stage_conn 226 #define SMFIM_HELO gacopyz_stage_helo 227 #define SMFIM_ENVFROM gacopyz_stage_mail 228 #define SMFIM_ENVRCPT gacopyz_stage_rcpt 229 #define SMFIM_DATA gacopyz_stage_data 230 #define SMFIM_EOM gacopyz_stage_eom 231 #define SMFIM_EOH gacopyz_stage_eoh 232 233 #define _SOCK_ADDR milter_sockaddr_t 234 #define smfiDesc gacopyz_milter_descr 235 236 typedef struct gacopyz_milter_descr gacopyz_milter_descr_t; 237 238 struct gacopyz_milter_descr 239 { 240 char *xxfi_name; /* filter name */ 241 int xxfi_version; /* version code */ 242 unsigned long xxfi_flags; /* flags */ 243 /* Filters: */ 244 /* connection info */ 245 sfsistat (*xxfi_connect) (SMFICTX *, char *, milter_sockaddr_t *); 246 /* SMTP HELO command */ 247 sfsistat (*xxfi_helo) (SMFICTX *, char *); 248 /* envelope sender */ 249 sfsistat (*xxfi_envfrom) (SMFICTX *, char **); 250 /* envelope recipient */ 251 sfsistat (*xxfi_envrcpt) (SMFICTX *, char **); 252 /* header */ 253 sfsistat (*xxfi_header) (SMFICTX *, char *, char *); 254 /* end of header */ 255 sfsistat (*xxfi_eoh) (SMFICTX *); 256 /* body block */ 257 sfsistat (*xxfi_body) (SMFICTX *, unsigned char *, size_t); 258 /* end of message */ 259 sfsistat (*xxfi_eom) (SMFICTX *); 260 /* message aborted */ 261 sfsistat (*xxfi_abort) (SMFICTX *); 262 /* connection cleanup */ 263 sfsistat (*xxfi_close) (SMFICTX *); 264 /* any unrecognized or unimplemented command (SMFI_VERSION > 2) */ 265 sfsistat (*xxfi_unknown) (SMFICTX *, char *); 266 /* SMTP DATA command (SMFI_VERSION > 3) */ 267 sfsistat (*xxfi_data) (SMFICTX *); 268 /* Milter negotiation (SMFI_VERSION > 3) */ 269 sfsistat (*xxfi_negotiate) (SMFICTX *, 270 unsigned long, unsigned long, 271 unsigned long, unsigned long, 272 unsigned long *, unsigned long *, 273 unsigned long *, unsigned long *); 274 275 /* Extensions: */ 276 277 int (*xxfi_start) (); /* Child start callback */ 278 int (*xxfi_finish) (); /* Child finish callback */ 279 int (*xxfi_idle) (gacopyz_conn_t); /* Idle handler */ 280 int (*xxfi_accept) (gacopyz_conn_t, int, const milter_sockaddr_t *, 281 int salen); 282 283 int logmask; 284 struct timeval ctx_timeout; 285 }; 286 287 /* Standard API calls */ 288 extern int smfi_version (unsigned int *, unsigned int *, unsigned int *); 289 extern int smfi_opensocket (int); 290 extern int smfi_register (struct smfiDesc); 291 extern int smfi_main (void); 292 extern int smfi_setbacklog (int); 293 extern int smfi_setdbg (int); 294 extern int smfi_settimeout (time_t); 295 extern int smfi_setconn (char *); 296 extern int smfi_stop (void); 297 298 #define smfi_getsymval(ctx,s) ((char*) gacopyz_getsymval(ctx, (char*)s)) 299 300 int smfi_addheader (SMFICTX *, char *, char *); 301 int smfi_chgheader (SMFICTX *, char *, int, char *); 302 int smfi_insheader (SMFICTX *, int, char *, char *); 303 int smfi_addrcpt (SMFICTX *, char *); 304 int smfi_delrcpt (SMFICTX *, char *); 305 int smfi_progress (SMFICTX *); 306 int smfi_replacebody (SMFICTX *, unsigned char *, int); 307 int smfi_quarantine (SMFICTX *ctx, char *reason); 308 int smfi_addrcpt_par(SMFICTX *ctx, char *rcpt, char *args); 309 int smfi_chgfrom(SMFICTX *ctx, char *from, char *args); 310 #define smfi_setpriv gacopyz_setpriv 311 #define smfi_getpriv gacopyz_getpriv 312 size_t smfi_setmaxdatasize (size_t); 313 int smfi_setsymlist(SMFICTX *ctx, int stage, char *macros); 314 315 /* Replies: */ 316 extern int smfi_setreply (SMFICTX *, char *, char *, char *); 317 int smfi_setmlreply (SMFICTX *, const char *, const char *, ...); 318 319 /* Extensions */ 320 extern int smfi_set_foreground(int val); 321 extern int smfi_setlogmask(int logmask); 322 323 /* New API calls: */ 324 int gacopyz_init(gacopyz_conn_t *pconn, struct smfiDesc *desc); 325 void gacopyz_free(gacopyz_conn_t conn); 326 const char *gacopyz_safe_header_value(const char *input, char **poutput); 327 328 int gacopyz_set_logmask(gacopyz_conn_t conn, int mask); 329 int gacopyz_get_logmask(gacopyz_conn_t conn, int *mask); 330 int gacopyz_set_foreground(gacopyz_conn_t conn, int fg); 331 int gacopyz_set_master_timeout(gacopyz_conn_t conn, struct timeval *timeout); 332 int gacopyz_get_master_timeout(gacopyz_conn_t conn, struct timeval *timeout); 333 int gacopyz_set_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout); 334 int gacopyz_get_ctx_timeout(gacopyz_conn_t conn, struct timeval *timeout); 335 int gacopyz_stop(gacopyz_conn_t conn); 336 337 int gacopyz_open(gacopyz_conn_t conn, const char *cstr, 338 int backlog, int rmsocket); 339 340 int gacopyz_parse_connection(const char *cstr, 341 char **pproto, char **pport, char **ppath); 342 343 int gacopyz_connect(gacopyz_conn_t *, struct smfiDesc *, const char *, 344 int backlog, int rmsocket); 345 int gacopyz_get_fd(gacopyz_conn_t); 346 347 int gacopyz_run(gacopyz_conn_t); 348 int gacopyz_context_loop(int fd, struct smfiDesc const *desc, 349 milter_sockaddr_t *addr, socklen_t addrlen, 350 void *calldata); 351 352 int gacopyz_register_child(gacopyz_conn_t conn, pid_t pid); 353 void gacopyz_cleanup_children(gacopyz_conn_t conn); 354 void gacopyz_cleanup_conn(gacopyz_conn_t conn); 355 void gacopyz_setup_signals(void); 356 357 const char *gacopyz_getsymval (SMFICTX *, const char *); 358 359 int gacopyz_setreply(SMFICTX *ctx, const char *rcode, const char *xcode, 360 const char *message); 361 int gacopyz_setmlreply_v(SMFICTX *ctx, const char *rcode, const char *xcode, 362 ...); 363 int gacopyz_setmlreply_va(SMFICTX *ctx, const char *rcode, const char *xcode, 364 va_list ap); 365 int _gacopyz_setmlreply_va(SMFICTX *ctx, size_t max, const char *rcode, 366 const char *xcode, va_list ap); 367 368 int gacopyz_add_header(SMFICTX *ctx, const char *headerf, 369 const char *headerv); 370 371 int gacopyz_insert_header(SMFICTX *ctx, int index, const char *headerf, 372 const char *headerv); 373 int gacopyz_change_header(SMFICTX *ctx, int index, const char *headerf, 374 const char *headerv); 375 int gacopyz_add_rcpt(SMFICTX *ctx, const char *rcpt); 376 int gacopyz_del_rcpt(SMFICTX *ctx, const char *rcpt); 377 int gacopyz_replace_body(SMFICTX *ctx, const unsigned char *bodyp, 378 size_t bodylen); 379 int gacopyz_replace_body_fn(SMFICTX *ctx, 380 void *bodyp, 381 ssize_t (*cpf)(char*,void*,size_t)); 382 int gacopyz_replace_body_fd(SMFICTX *ctx, int fd); 383 int gacopyz_progress(SMFICTX *ctx); 384 int gacopyz_quarantine(SMFICTX *ctx, const char *reason); 385 int gacopyz_add_rcpt_par(SMFICTX *ctx, const char *rcpt, const char *args); 386 int gacopyz_chgfrom(SMFICTX *ctx, const char *from, const char *args); 387 388 int gacopyz_setsymlist(SMFICTX *ctx, enum gacopyz_stage ind, 389 const char *macros); 390 391 int gacopyz_setpriv (SMFICTX *ctx, void *data); 392 void *gacopyz_getpriv (SMFICTX *ctx); 393 void *gacopyz_getclosure(SMFICTX *ctx); 394 395 int gacopyz_client_sockname(SMFICTX *ctx, 396 milter_sockaddr_t *name, socklen_t *namelen); 397 int gacopyz_server_sockname(SMFICTX *ctx, 398 milter_sockaddr_t *name, socklen_t *namelen); 399 400 /* Logging (extensions) */ 401 extern const char *gacopyz_stage_name[gacopyz_stage_max]; 402 403 #define GACOPYZ_VBUFSIZE 69 404 size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf, 405 size_t size); 406 void gacopyz_log(int level, char *fmt, ...); 407 void gacopyz_logdump(int level, const char *pfx, 408 const char *buf, size_t size); 409 void gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...); 410 void gacopyz_io_logdump(gacopyz_iod_t iod, const char *pfx, 411 const char *buf, size_t size); 412 void gacopyz_set_logger(void (*)(int, char *, va_list)); 413 414 void gacopyz_stderr_log_printer(int level, char *fmt, va_list ap); 415 void gacopyz_syslog_log_printer(int level, char *fmt, va_list ap); 416 int gacopyz_string_to_log_level(const char *str); 417 const char *gacopyz_log_level_to_string(int level); 418 419 420 /* Server */ 421 typedef struct gacopyz_srv *gacopyz_srv_t; 422 423 enum gacopyz_flag_op { 424 gacopyz_flag_rpl, 425 gacopyz_flag_set, 426 gacopyz_flag_clr 427 }; 428 429 #define GACOPYZ_SRV_DISABLED 0x0001 430 431 int gacopyz_srv_create(gacopyz_srv_t *p, const char *name, 432 const char *portspec, unsigned logmask); 433 int gacopyz_srv_create_X(gacopyz_srv_t *p, const char *spec, unsigned logmask); 434 435 void gacopyz_srv_destroy(gacopyz_srv_t *p); 436 int gacopyz_srv_find_macro (gacopyz_srv_t srv, const char *name, 437 const char **pval); 438 void gacopyz_srv_define_macro (gacopyz_srv_t srv, 439 const char *name, const char *value); 440 void gacopyz_srv_del_macro (gacopyz_srv_t srv, const char *name); 441 void gacopyz_srv_clear_macros (gacopyz_srv_t srv); 442 void gacopyz_srv_clear_macros_pred(gacopyz_srv_t srv, 443 int (*pred) (const char*, void*), 444 void *data); 445 446 void gacopyz_srv_iterate_macros (gacopyz_srv_t srv, 447 int (*func) (const char *name, 448 const char *value, 449 void *data), 450 void *data); 451 void gacopyz_srv_count_macros (gacopyz_srv_t srv, size_t *count); 452 453 const char **gacopyz_srv_get_required_macros(gacopyz_srv_t srv, 454 enum gacopyz_stage stage); 455 const char *gacopyz_srv_get_id(gacopyz_srv_t srv); 456 const char *gacopyz_srv_get_portspec(gacopyz_srv_t srv); 457 458 int gacopyz_srv_flags(gacopyz_srv_t srv, int flags, enum gacopyz_flag_op op); 459 int gacopyz_srv_get_flags(gacopyz_srv_t srv); 460 461 int gacopyz_srv_get_logmask(gacopyz_srv_t srv); 462 int gacopyz_srv_get_fd(gacopyz_srv_t srv); 463 int gacopyz_srv_get_onerr(gacopyz_srv_t srv); 464 465 int gacopyz_srv_open(gacopyz_srv_t srv); 466 int gacopyz_srv_init(gacopyz_srv_t srv); 467 int gacopyz_srv_negotiate(gacopyz_srv_t srv); 468 int gacopyz_srv_abort(gacopyz_srv_t srv); 469 int gacopyz_srv_quit(gacopyz_srv_t srv); 470 471 int gacopyz_srv_connect(gacopyz_srv_t srv, const char *hostname, 472 struct sockaddr *sa); 473 int gacopyz_srv_helo (gacopyz_srv_t p, const char *domain); 474 int gacopyz_srv_envfrom (gacopyz_srv_t p, char **argv); 475 int gacopyz_srv_envrcpt (gacopyz_srv_t p, char **argv); 476 int gacopyz_srv_header (gacopyz_srv_t p, char *name, char *value); 477 int gacopyz_srv_eoh (gacopyz_srv_t p); 478 int gacopyz_srv_body (gacopyz_srv_t p, unsigned char *str, size_t size); 479 480 int gacopyz_srv_eom (gacopyz_srv_t p, unsigned char *str, size_t size); 481 int gacopyz_srv_abort (gacopyz_srv_t p); 482 int gacopyz_srv_close (gacopyz_srv_t p); 483 int gacopyz_srv_data (gacopyz_srv_t p); 484 485 int gacopyz_srv_onerror(gacopyz_srv_t srv, int code); 486 void gacopyz_srv_set_logmask(gacopyz_srv_t srv, int logmask); 487 void gacopyz_srv_set_memerror(gacopyz_srv_t srv, 488 void (*memerror)(gacopyz_srv_t, const char *, 489 unsigned int)); 490 void gacopyz_srv_set_callback(gacopyz_srv_t srv, 491 int (*cb) (gacopyz_srv_t, int, int, void *)); 492 void gacopyz_srv_set_callback_data(gacopyz_srv_t, void *); 493 494 int gacopyz_srv_set_source(gacopyz_srv_t srv, struct sockaddr *sa, 495 socklen_t len); 496 int gacopyz_srv_set_version(gacopyz_srv_t srv, unsigned long version); 497 int gacopyz_srv_set_protocol(gacopyz_srv_t srv, unsigned long proto); 498 int gacopyz_srv_set_actions(gacopyz_srv_t srv, unsigned long acts); 499 500 #define GACOPYZ_WRITE_TIMEOUT 10 501 #define GACOPYZ_READ_TIMEOUT 10 502 #define GACOPYZ_EOM_TIMEOUT 300 503 #define GACOPYZ_CONNECT_TIMEOUT 300 504 505 #define GACOPYZ_TO_WRITE 0 /* Timeout for sending information */ 506 #define GACOPYZ_TO_READ 1 /* Timeout waiting for a response */ 507 #define GACOPYZ_TO_EOM 2 /* Timeout for ACK/NAK to EOM */ 508 #define GACOPYZ_TO_CONNECT 3 /* Timeout for connect() */ 509 #define GACOPYZ_TO_COUNT 4 510 511 void gacopyz_srv_set_all_timeouts(gacopyz_srv_t srv, struct timeval *tvp); 512 int gacopyz_srv_set_timeout(gacopyz_srv_t srv, unsigned n, 513 struct timeval *tvp); 514 int gacopyz_srv_set_timeout_sec(gacopyz_srv_t srv, unsigned n, time_t t); 515 516 int gacopyz_srv_reply(gacopyz_srv_t srv, char **msg, size_t *size); 517 void gacopyz_srv_reply_raw(gacopyz_srv_t srv, char **msg, size_t *size); 518 519 #ifdef __cplusplus 520 } 521 #endif 522 523 #endif /* __gacopyz_h__ */ 524