diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-03-08 23:32:04 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-03-08 23:32:04 +0000 |
commit | f340b89d4722df3bce8a5bef92ab3b5f76241868 (patch) | |
tree | 5b105c54d0feba10adcc885152803f8ad601095a /gacopyz | |
parent | dc86c84d43e819bcdfd5b2b69a9db486f56b4e16 (diff) | |
download | mailfromd-f340b89d4722df3bce8a5bef92ab3b5f76241868.tar.gz mailfromd-f340b89d4722df3bce8a5bef92ab3b5f76241868.tar.bz2 |
Implement mail from and rcpt to
git-svn-id: file:///svnroot/mailfromd/trunk@1282 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'gacopyz')
-rw-r--r-- | gacopyz/gacopyz.h | 24 | ||||
-rw-r--r-- | gacopyz/gacopyz_priv.h | 12 | ||||
-rw-r--r-- | gacopyz/io.c | 8 | ||||
-rw-r--r-- | gacopyz/log.c | 15 | ||||
-rw-r--r-- | gacopyz/server.c | 439 |
5 files changed, 443 insertions, 55 deletions
diff --git a/gacopyz/gacopyz.h b/gacopyz/gacopyz.h index 251810bd..5d46f5cb 100644 --- a/gacopyz/gacopyz.h +++ b/gacopyz/gacopyz.h @@ -292,17 +292,17 @@ void *gacopyz_getpriv (SMFICTX *ctx); /* Logging (extensions) */ #define GACOPYZ_VBUFSIZE 69 -size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], char *buf, +size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf, size_t size); void gacopyz_log(gacopyz_conn_t conn, int level, char *fmt, ...); void gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...); void gacopyz_logmsg(int level, char *fmt, ...); -void _gacopyz_logdump(int logmask, int level, char *pfx, char *buf, +void _gacopyz_logdump(int logmask, int level, const char *pfx, const char *buf, size_t size); -void gacopyz_logdump(gacopyz_conn_t conn, int level, char *pfx, - char *buf, size_t size); -void gacopyz_io_logdump(gacopyz_iod_t iod, int level, char *pfx, - char *buf, size_t size); +void gacopyz_logdump(gacopyz_conn_t conn, int level, const char *pfx, + const char *buf, size_t size); +void gacopyz_io_logdump(gacopyz_iod_t iod, int level, 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); @@ -317,6 +317,9 @@ int gacopyz_srv_find_macro (gacopyz_srv_t srv, const char *name, const char **pval); int gacopyz_srv_define_macro (gacopyz_srv_t srv, const char *name, const char *value); +int gacopyz_srv_define_macro0 (gacopyz_srv_t srv, + const char *name, const char *value, + int overwrite); int gacopyz_srv_del_macro (gacopyz_srv_t srv, const char *name); int gacopyz_srv_clear_macros (gacopyz_srv_t srv); int gacopyz_srv_iterate_macros (gacopyz_srv_t srv, @@ -340,11 +343,18 @@ 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); int gacopyz_srv_set_source(gacopyz_srv_t srv, unsigned long addr); int gacopyz_srv_set_version(gacopyz_srv_t srv, int version); int gacopyz_srv_set_protocol(gacopyz_srv_t srv, int proto); int gacopyz_srv_set_actions(gacopyz_srv_t srv, int acts); -int gacopyz_srv_set_timeout(gacopyz_srv_t srv, time_t t); + +int 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); + +void gacopyz_srv_reply (gacopyz_srv_t srv, char **msg, size_t *size); #ifdef __cplusplus } diff --git a/gacopyz/gacopyz_priv.h b/gacopyz/gacopyz_priv.h index 19d72468..54bc4fcf 100644 --- a/gacopyz/gacopyz_priv.h +++ b/gacopyz/gacopyz_priv.h @@ -72,15 +72,21 @@ typedef unsigned long gacopyz_uint32_t; void (*__gacopyz_log_printer)(int, char *, va_list); +#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 + struct gacopyz_iod { int sd; - struct timeval timeout; + struct timeval timeout[GACOPYZ_TO_COUNT]; int logmask; }; int _gacopyz_read (gacopyz_iod_t iod, char *buf, size_t size); -int _gacopyz_write(gacopyz_iod_t iod, char *buf, size_t size); +int _gacopyz_write(gacopyz_iod_t iod, const char *buf, size_t size); int gacopyz_send_command(gacopyz_iod_t iod, - int cmd, void *data, size_t size); + int cmd, const void *data, size_t size); int gacopyz_read_command(gacopyz_iod_t iod, unsigned char *cmd, size_t *pcount, char **pbuf, size_t *psize); diff --git a/gacopyz/io.c b/gacopyz/io.c index 29cdb390..d258800c 100644 --- a/gacopyz/io.c +++ b/gacopyz/io.c @@ -34,7 +34,7 @@ _gacopyz_read (gacopyz_iod_t iod, char *buf, size_t size) FD_SET(iod->sd, &rset); FD_SET(iod->sd, &xset); - to = iod->timeout; + to = iod->timeout[GACOPYZ_TO_READ]; res = select(iod->sd + 1, &rset, NULL, &xset, &to); if (res == 0) { @@ -84,7 +84,7 @@ _gacopyz_read (gacopyz_iod_t iod, char *buf, size_t size) } int -_gacopyz_write(gacopyz_iod_t iod, char *buf, size_t size) +_gacopyz_write(gacopyz_iod_t iod, const char *buf, size_t size) { int rc = MI_SUCCESS; @@ -99,7 +99,7 @@ _gacopyz_write(gacopyz_iod_t iod, char *buf, size_t size) FD_SET(iod->sd, &wset); FD_SET(iod->sd, &xset); - to = iod->timeout; + to = iod->timeout[GACOPYZ_TO_READ]; res = select(iod->sd + 1, NULL, &wset, &xset, &to); if (res == 0) { @@ -157,7 +157,7 @@ union header { }; int -gacopyz_send_command(gacopyz_iod_t iod, int cmd, void *data, size_t size) +gacopyz_send_command(gacopyz_iod_t iod, int cmd, const void *data, size_t size) { int rc; union header header; diff --git a/gacopyz/log.c b/gacopyz/log.c index 43eae63e..05144568 100644 --- a/gacopyz/log.c +++ b/gacopyz/log.c @@ -95,7 +95,7 @@ gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...) } size_t -gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], char *buf, size_t size) +gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf, size_t size) { char *p = vbuf; char *q = vbuf + 51; @@ -105,7 +105,7 @@ gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], char *buf, size_t size) for (i = 0; i < 16; i++) { unsigned c; if (j < size) { - c = *(unsigned char*)buf++; + c = *(const unsigned char*)buf++; j++; } else c = 0; @@ -124,7 +124,8 @@ gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], char *buf, size_t size) } void -_gacopyz_logdump(int logmask, int level, char *pfx, char *buf, size_t size) +_gacopyz_logdump(int logmask, int level, const char *pfx, + const char *buf, size_t size) { if (logmask & SMI_LOG_MASK(level)) { char vbuf[GACOPYZ_VBUFSIZE]; @@ -139,15 +140,15 @@ _gacopyz_logdump(int logmask, int level, char *pfx, char *buf, size_t size) } void -gacopyz_logdump(gacopyz_conn_t conn, int level, char *pfx, - char *buf, size_t size) +gacopyz_logdump(gacopyz_conn_t conn, int level, const char *pfx, + const char *buf, size_t size) { return _gacopyz_logdump(conn->logmask, level, pfx, buf, size); } void -gacopyz_io_logdump(gacopyz_iod_t iod, int level, char *pfx, - char *buf, size_t size) +gacopyz_io_logdump(gacopyz_iod_t iod, int level, const char *pfx, + const char *buf, size_t size) { return _gacopyz_logdump(iod->logmask, level, pfx, buf, size); } diff --git a/gacopyz/server.c b/gacopyz/server.c index 944952a3..0b6c2aaa 100644 --- a/gacopyz/server.c +++ b/gacopyz/server.c @@ -25,9 +25,14 @@ struct gacopyz_macro_def { }; enum gacopyz_srv_state { - srv_init, - srv_connected, - srv_ready + srv_init, /* Initialized but not connected */ + srv_connected, /* Initialized and connected to the client */ + srv_ready, /* Ready for processing requests */ + srv_msgproc, /* Processing a message */ + srv_done, /* Finished processing a message */ + srv_closed, /* Finished and closed */ + srv_disabled, /* Disabled for any further requests */ + srv_error, /* Some error ocurred */ }; struct gacopyz_srv { @@ -38,32 +43,41 @@ struct gacopyz_srv { size_t ndefs; size_t maxdefs; gacopyz_uint32_t source_addr; + int onerror; + int version; int acts; int proto; char *buf; size_t bufsize; + + char *resp_ptr; + size_t resp_size; }; static struct gacopyz_macro_def * -find_def(gacopyz_srv_t srv, const char *name) +find_def(gacopyz_srv_t srv, const char *name, size_t len) { size_t i; for (i = 0; i < srv->ndefs; i++) - if (strcmp(srv->def[i].name, name) == 0) + if (strncmp(srv->def[i].name, name, len) == 0) return &srv->def[i]; return NULL; } static int -add_def(gacopyz_srv_t srv, const char *name, const char *value) +add_def(gacopyz_srv_t srv, const char *name, size_t len, + const char *value, int overwrite) { struct gacopyz_macro_def *def; - if (def = find_def(srv, name)) - free(def->value); - else { + if (def = find_def(srv, name, len)) { + if (overwrite) + free(def->value); + else + return MI_SUCCESS; + } else { if (srv->ndefs == srv->maxdefs) { size_t maxdefs = srv->maxdefs + 64; def = realloc(srv->def, @@ -74,19 +88,23 @@ add_def(gacopyz_srv_t srv, const char *name, const char *value) srv->def = def; } def = srv->def + srv->ndefs++; - def->name = strdup(name); + def->name = malloc(len + 1); + if (!def->name) + return MI_FAILURE; + memcpy(def->name, name, len); + def->name[len] = 0; } def->value = strdup(value); - if (!def->name || !def->value) + if (!def->value) /* FIXME: Remove this entry from srv->dev */ return MI_FAILURE; return MI_SUCCESS; } void -del_def(gacopyz_srv_t srv, const char *name) +del_def(gacopyz_srv_t srv, const char *name, size_t len) { - struct gacopyz_macro_def *def = find_def(srv, name); + struct gacopyz_macro_def *def = find_def(srv, name, len); size_t n; if (!def) @@ -98,17 +116,97 @@ del_def(gacopyz_srv_t srv, const char *name) memmove(def, def + 1, sizeof(srv->def[0]) *(srv->ndefs - (def - srv->def))); } + +static int +srv_ensure_space(gacopyz_srv_t srv, size_t size) +{ + if (size > srv->bufsize) { + char *p = realloc(srv->buf, size); + if (!p) { + gacopyz_io_log(&srv->iod, + SMI_LOG_FATAL, + "Not enough memory"); + return 1; + } + srv->buf = p; + srv->bufsize = size; + } + return 0; +} + +size_t +macro_size(gacopyz_srv_t srv) +{ + size_t i; + size_t size = 0; + struct gacopyz_macro_def *def; + + for (i = 0, def = srv->def; i < srv->ndefs; i++, def++) { + size_t len = strlen(def->name); + size += len; + if (len > 1 && def->name[0] != '{') + size += 2; /* for {} */ + size += 1 + strlen (def->value) + 1; + } + return size; +} + +int +srv_format_macros(gacopyz_srv_t srv, unsigned char cmd, size_t *psize) +{ + size_t i; + char *p; + size_t size = macro_size(srv) + 2; + struct gacopyz_macro_def *def; + + if (srv_ensure_space(srv, size)) + return MI_FAILURE; + + p = srv->buf; + *p++ = cmd; + for (i = 0, def = srv->def; i < srv->ndefs; i++, def++) { + size_t len = strlen(def->name); + if (len > 1 && def->name[0] != '{') { + *p++ = '{'; + memcpy(p, def->name, len); + p += len; + *p++ = '}'; + *p++ = 0; + } else { + len++; + memcpy(p, def->name, len); + p += len; + } + len = strlen(def->value) + 1; + memcpy(p, def->value, len); + p += len; + } + *p = 0; + *psize = size; + return MI_SUCCESS; +} + +#define GETNAMELEN(name, len) \ + len = strlen(name); \ + if (name[0] == '{' && name[len-1] == '}') { \ + name++; \ + len -= 2; \ + } + + int gacopyz_srv_find_macro(gacopyz_srv_t srv, const char *name, const char **pval) { struct gacopyz_macro_def *def; - + size_t len; + if (!srv) return MI_FAILURE; - - def = find_def(srv, name); + + GETNAMELEN(name, len); + def = find_def(srv, name, len); if (def) { *pval = def->value; return MI_SUCCESS; @@ -117,20 +215,35 @@ gacopyz_srv_find_macro(gacopyz_srv_t srv, const char *name, const char **pval) } int -gacopyz_srv_define_macro(gacopyz_srv_t srv, - const char *name, const char *value) +gacopyz_srv_define_macro0(gacopyz_srv_t srv, + const char *name, const char *value, + int overwrite) { + size_t len; + if (!srv) return MI_FAILURE; - return add_def(srv, name, value); + + GETNAMELEN(name, len); + + return add_def(srv, name, len, value, overwrite); +} + +int +gacopyz_srv_define_macro(gacopyz_srv_t srv, + const char *name, const char *value) +{ + return gacopyz_srv_define_macro0(srv, name, value, 1); } int gacopyz_srv_del_macro(gacopyz_srv_t srv, const char *name) { + size_t len; if (!srv) return MI_FAILURE; - del_def(srv, name); + GETNAMELEN(name, len); + del_def(srv, name, len); return MI_SUCCESS; } @@ -181,15 +294,20 @@ gacopyz_srv_count_macros(gacopyz_srv_t srv, size_t *count) int gacopyz_srv_create(gacopyz_srv_t *p, unsigned logmask) { + int i; gacopyz_srv_t srv = calloc(1, sizeof(*srv)); if (!srv) return MI_FAILURE; srv->iod.sd = -1; srv->iod.logmask = logmask; - srv->iod.timeout.tv_usec = 0; - srv->iod.timeout.tv_sec = 5; + /* FIXME Set default timeouts */ + for (i = 0; i < GACOPYZ_TO_COUNT; i++) { + srv->iod.timeout[i].tv_usec = 0; + srv->iod.timeout[i].tv_sec = 5; + } srv->state = srv_init; srv->source_addr = INADDR_ANY; + srv->onerror = SMFIR_TEMPFAIL; srv->version = SMFI_VERSION; srv->proto = SMFI_V2_PROT; srv->acts = SMFI_V2_ACTS; @@ -198,15 +316,49 @@ gacopyz_srv_create(gacopyz_srv_t *p, unsigned logmask) } int -gacopyz_srv_set_timeout(gacopyz_srv_t srv, time_t t) +gacopyz_srv_onerror(gacopyz_srv_t srv, int code) +{ + if (!srv) + return MI_FAILURE; + switch (code) { + case SMFIR_CONTINUE: + case SMFIR_DISCARD: + case SMFIR_REJECT: + case SMFIR_TEMPFAIL: + case SMFIR_SHUTDOWN: + srv->onerror = code; + return MI_SUCCESS; + } + return MI_FAILURE; +} + +int +gacopyz_srv_set_all_timeouts(gacopyz_srv_t srv, struct timeval *tvp) { if (!srv) return MI_FAILURE; - srv->iod.timeout.tv_usec = 0; - srv->iod.timeout.tv_sec = t; + memcpy(srv->iod.timeout, tvp, sizeof srv->iod.timeout); return MI_SUCCESS; } - + +int +gacopyz_srv_set_timeout(gacopyz_srv_t srv, unsigned n, struct timeval *tvp) +{ + if (!srv || n >= GACOPYZ_TO_COUNT) + return MI_FAILURE; + srv->iod.timeout[n] = *tvp; + return MI_SUCCESS; +} + +int +gacopyz_srv_set_timeout_sec(gacopyz_srv_t srv, unsigned n, time_t t) +{ + struct timeval tv; + tv.tv_usec = 0; + tv.tv_sec = t; + return gacopyz_srv_set_timeout(srv, n, &tv); +} + int gacopyz_srv_set_source(gacopyz_srv_t srv, unsigned long addr) { @@ -521,44 +673,261 @@ gacopyz_srv_negotiate(gacopyz_srv_t srv) return MI_SUCCESS; } +static struct command_assoc { + unsigned char cmd; + int pflag; + const char *action; + const char *code; +} command_tab[] = { + { SMFIC_CONNECT, SMFIP_NOCONNECT, "connect", "554" }, + { SMFIC_HELO, SMFIP_NOHELO, "helo", "550" }, + { SMFIC_MAIL, SMFIP_NOMAIL, "mail", "550 5.7.1" }, + { SMFIC_RCPT, SMFIP_NORCPT, "rcpt", "550 5.7.1" }, + { SMFIC_HEADER, SMFIP_NOHDRS, "header", "550 5.7.1" }, + { SMFIC_BODY, SMFIP_NOBODY, "body", "554 5.7.1" }, + { SMFIC_EOH, SMFIP_NOEOH, "eoh", "550 5.7.1" }, + { SMFIC_UNKNOWN, SMFIP_NOUNKNOWN, "unknown", "550 5.7.1" }, + { SMFIC_DATA, SMFIP_NODATA, "data", "550 5.7.1" }, + { 0, 0, "default", "550 5.7.1" } +}; + +static struct command_assoc * +find_cmd_assoc(unsigned char cmd) +{ + struct command_assoc *cp; + for (cp = command_tab; cp->cmd; cp++) + if (cp->cmd == cmd) + break; + return cp; +} + +#define is_rfc822_reject_code(s) \ + (((s)[0] == '4' || (s)[0] == '5') \ + && isascii((s)[1]) && isdigit((s)[1]) \ + && isascii((s)[2]) && isdigit((s)[2])) + +#define DEFREPLY "Command rejected" + +static void +verify_reply(gacopyz_srv_t srv, size_t size, const char *reject_code) +{ + if (size < 3 || !is_rfc822_reject_code(srv->buf)) { + if (srv_ensure_space(srv, + strlen(reject_code) + 1 + + sizeof(DEFREPLY))) + abort(); + strcpy(srv->buf, reject_code); + strcat(srv->buf, " "); + strcat(srv->buf, DEFREPLY); + } +} + +int +gacopyz_srv_send_macros(gacopyz_srv_t srv, unsigned char cmd) +{ + size_t size; + if (srv_format_macros(srv, cmd, &size)) + return MI_FAILURE; + if (gacopyz_send_command(&srv->iod, SMFIC_MACRO, + srv->buf, size)) + return MI_FAILURE; + return MI_SUCCESS; +} + +int +gacopyz_srv_send_command(gacopyz_srv_t srv, unsigned char cmd, + const void *data, size_t datasize) +{ + unsigned char rcmd; + size_t size; + struct command_assoc *cp; + + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "gacopyz_srv_send_command: size=%lu, cmd=%c", + datasize, cmd); + + cp = find_cmd_assoc(cmd); + + srv->resp_ptr = NULL; + srv->resp_size = 0; + if (cp->pflag && (srv->proto & cp->pflag)) + return SMFIR_CONTINUE; + + if (gacopyz_srv_send_macros(srv, cmd)) + return srv->onerror; + + if (gacopyz_send_command(&srv->iod, cmd, data, datasize)) + return srv->onerror; + + if (cmd == SMFIC_HEADER && (srv->proto & SMFIP_NOHREPL)) + return SMFIR_CONTINUE; + + if (gacopyz_read_command(&srv->iod, &rcmd, &size, + &srv->buf, &srv->bufsize)) + return srv->onerror; + + switch (rcmd) { + case SMFIR_REPLYCODE: + verify_reply(srv, size, cp->code); + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, reject=%s", + cp->action, srv->buf); + srv->resp_ptr = srv->buf; + srv->resp_size = size; + break; + + case SMFIR_REJECT: + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, reject", + cp->action); + break; + + case SMFIR_DISCARD: + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, discard", + cp->action); + srv->state = srv_disabled; + break; + + case SMFIR_TEMPFAIL: + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, tempfail", + cp->action); + break; + + case SMFIR_ACCEPT: + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, accept", + cp->action); + srv->state = srv_disabled; + break; + + case SMFIR_CONTINUE: + gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG, + "action=%s, continue", + cp->action); + break; + + default: + gacopyz_io_log(&srv->iod, SMI_LOG_ERR, + "action=%s, bogus response=%c", + cp->action, rcmd); + /*FIXME: Change to error state */ + srv->state = srv_error; + rcmd = srv->onerror; + break; + } + + return rcmd; +} + +#define not_implemented(srv) ( \ + gacopyz_io_log(&srv->iod, SMI_LOG_FATAL, \ + "%s:%d: %s not implemented!!!", \ + __FILE__, __LINE__, __FUNCTION__), \ + MI_FAILURE \ +) + +void +gacopyz_srv_reply (gacopyz_srv_t srv, char **msg, size_t *size) +{ + *msg = srv->resp_ptr; + *size = srv->resp_size; +} + int gacopyz_srv_abort(gacopyz_srv_t srv) { + return not_implemented(srv); } int -gacopyz_srv_helo(gacopyz_srv_t p, const char *domain) +gacopyz_srv_helo(gacopyz_srv_t srv, const char *domain) { + return gacopyz_srv_send_command(srv, SMFIC_HELO, + domain, strlen(domain) + 1); } +static int +format_argv(gacopyz_srv_t srv, char **argv, char **buf, size_t *psize) +{ + size_t len; + char **ap; + char *p; + + for (len = 1, ap = argv; *ap; ap++) + len += strlen(*ap) + 1; + + *buf = malloc(len); + if (!*buf) { + gacopyz_io_log(&srv->iod, + SMI_LOG_FATAL, + "Not enough memory"); + return 1; + } + + for (p = *buf, ap = argv; *ap; ap++) { + size_t len = strlen(*ap) + 1; + memcpy(p, *ap, len); + p += len; + } + *p = 0; + *psize = len; + return 0; +} + int -gacopyz_srv_envfrom(gacopyz_srv_t p, char **argv) +gacopyz_srv_envfrom(gacopyz_srv_t srv, char **argv) { + int rc; + size_t size; + char *buf; + if (!srv) + return MI_FAILURE; + if (format_argv(srv, argv, &buf, &size)) + return MI_FAILURE; + rc = gacopyz_srv_send_command(srv, SMFIC_MAIL, buf, size); + free (buf); + return rc; } int -gacopyz_srv_envrcpt(gacopyz_srv_t p, char **argv) +gacopyz_srv_envrcpt(gacopyz_srv_t srv, char **argv) { + int rc; + size_t size; + char *buf; + if (!srv) + return MI_FAILURE; + if (format_argv(srv, argv, &buf, &size)) + return MI_FAILURE; + rc = gacopyz_srv_send_command(srv, SMFIC_RCPT, buf, size); + free (buf); + return rc; } int -gacopyz_srv_header(gacopyz_srv_t p, char *name, char *value) +gacopyz_srv_header(gacopyz_srv_t srv, char *name, char *value) { + return not_implemented(srv); } int -gacopyz_srv_eoh(gacopyz_srv_t p) +gacopyz_srv_eoh(gacopyz_srv_t srv) { + return not_implemented(srv); } int -gacopyz_srv_body(gacopyz_srv_t p, unsigned char *str, size_t size) +gacopyz_srv_body(gacopyz_srv_t srv, unsigned char *str, size_t size) { + return not_implemented(srv); } int -gacopyz_srv_eom(gacopyz_srv_t p) +gacopyz_srv_eom(gacopyz_srv_t srv) { + return not_implemented(srv); } int @@ -566,10 +935,12 @@ gacopyz_srv_close(gacopyz_srv_t srv) { close (srv->iod.sd); srv->state = srv_init; + return MI_SUCCESS; } int -gacopyz_srv_data(gacopyz_srv_t p) +gacopyz_srv_data(gacopyz_srv_t srv) { + return not_implemented(srv); } |