diff options
Diffstat (limited to 'src/bi_sa.m4')
-rw-r--r-- | src/bi_sa.m4 | 218 |
1 files changed, 177 insertions, 41 deletions
diff --git a/src/bi_sa.m4 b/src/bi_sa.m4 index 0ed7472b..8472bbe9 100644 --- a/src/bi_sa.m4 +++ b/src/bi_sa.m4 @@ -29,7 +29,127 @@ MF_VAR(clamav_virus_name, STRING); + +struct mf_stream { + eval_environ_t env; + mu_stream_t str; + time_t start; + time_t timeout; +}; + +typedef struct mf_stream *mf_stream_t; + +/* FIXME: duplicated in engine.c */ +#define UPDATE_TTW(t,start) do { \ + time_t delta = time(NULL) - start; \ + if (t > delta) \ + t -= delta; \ + else \ + t = 0; \ +} while (0) + +extern int smtp_stream_wait(mu_stream_t stream, int flags, time_t *timeout); +static void spamd_destroy(mf_stream_t *pstream); + +mf_stream_t +mf_stream_new (eval_environ_t env, mu_stream_t stream, time_t start, + time_t timeout) +{ + mf_stream_t pmfs = xmalloc (sizeof pmfs[0]); + pmfs->env = env; + pmfs->str = stream; + pmfs->start = start; + pmfs->timeout = timeout; + return pmfs; +} + +int +mf_stream_sequential_read(mf_stream_t stream, char *buf, size_t size) +{ + int rc; + eval_environ_t env = stream->env; + + if (stream->timeout == 0) { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_read: %s", + mu_strerror(ETIMEDOUT)); + } + + rc = smtp_stream_wait(stream->str, MU_STREAM_READY_RD, + &stream->timeout); + if (rc == 0) { + UPDATE_TTW(stream->timeout, stream->start); + rc = mu_stream_sequential_read(stream->str, buf, size, NULL); + } else { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_read: %s", + mu_strerror(ETIMEDOUT)); + } + + return rc; +} + +int +mf_stream_sequential_readline(mf_stream_t stream, char *buf, size_t size, + size_t *nbytes) +{ + int rc; + eval_environ_t env = stream->env; + + if (stream->timeout == 0) { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_readline: %s", + mu_strerror(ETIMEDOUT)); + } + rc = smtp_stream_wait(stream->str, MU_STREAM_READY_RD, + &stream->timeout); + if (rc == 0) { + UPDATE_TTW(stream->timeout, stream->start); + rc = mu_stream_sequential_readline(stream->str, buf, size, + nbytes); + } else { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_readline: %s", + mu_strerror(ETIMEDOUT)); + } + return rc; +} + +int +mf_stream_sequential_write(mf_stream_t stream, char *buf, size_t size) +{ + int rc; + eval_environ_t env = stream->env; + + if (stream->timeout == 0) { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_write: %s", + mu_strerror(ETIMEDOUT)); + } + + rc = smtp_stream_wait(stream->str, MU_STREAM_READY_WR, + &stream->timeout); + if (rc == 0) { + UPDATE_TTW(stream->timeout, stream->start); + rc = mu_stream_sequential_write(stream->str, buf, size); + } else { + spamd_destroy(&stream); + MF_THROW(mf_temp_failure, + "sa_sequential_write: %s", + mu_strerror(ETIMEDOUT)); + } + return rc; +} + + + static int -spamd_connect_tcp(eval_environ_t env, mu_stream_t *stream, - char *host, int port) +spamd_connect_tcp(eval_environ_t env, mf_stream_t *pmfs, + char *host, int port, time_t timeout) { - int rc = mu_tcp_stream_create(stream, host, port, 0); + mu_stream_t stream; + int rc = mu_tcp_stream_create(&stream, host, port, 0); MF_ASSERT(rc == 0, mf_failure, @@ -37,3 +157,3 @@ spamd_connect_tcp(eval_environ_t env, mu_stream_t *stream, mu_strerror(rc)); - rc = mu_stream_open(*stream); + rc = mu_stream_open(stream); MF_ASSERT(rc == 0, mf_failure, @@ -41,2 +161,3 @@ spamd_connect_tcp(eval_environ_t env, mu_stream_t *stream, mu_strerror(rc)); + *pmfs = mf_stream_new(env, stream, time(NULL), timeout); return rc; @@ -45,3 +166,4 @@ spamd_connect_tcp(eval_environ_t env, mu_stream_t *stream, static int -spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) +spamd_connect_socket(eval_environ_t env, mf_stream_t *pmfs, char *path, + time_t timeout) { @@ -50,2 +172,3 @@ spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) struct sockaddr_un addr; + mu_stream_t stream; @@ -65,3 +188,3 @@ spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) fp = fdopen(fd, "w+"); - rc = mu_stdio_stream_create(stream, fp, MU_STREAM_RDWR); + rc = mu_stdio_stream_create(&stream, fp, MU_STREAM_RDWR); if (rc) { @@ -73,5 +196,5 @@ spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) - rc = mu_stream_open(*stream); + rc = mu_stream_open(stream); if (rc) { - mu_stream_destroy (stream, mu_stream_get_owner (*stream)); + mu_stream_destroy(&stream, mu_stream_get_owner(stream)); fclose(fp); @@ -81,2 +204,5 @@ spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) } + + *pmfs = mf_stream_new(env, stream, time(NULL), timeout); + return rc; @@ -85,9 +211,9 @@ spamd_connect_socket(eval_environ_t env, mu_stream_t *stream, char *path) static void -spamd_shutdown(mu_stream_t stream, int isfile, int flag) +spamd_shutdown(mf_stream_t stream, int isfile, int flag) { int fd; - mu_transport_t trans; - mu_stream_flush(stream); - mu_stream_get_transport(stream, &trans); + + mu_stream_flush(stream->str); + mu_stream_get_transport(stream->str, &trans); if (isfile) @@ -100,6 +226,9 @@ spamd_shutdown(mu_stream_t stream, int isfile, int flag) static void -spamd_destroy(mu_stream_t *stream) +spamd_destroy(mf_stream_t *pstream) { - mu_stream_close(*stream); - mu_stream_destroy(stream, mu_stream_get_owner(*stream)); + mf_stream_t stream = *pstream; + mu_stream_close(stream->str); + mu_stream_destroy(&stream->str, mu_stream_get_owner(stream->str)); + free(stream); + *pstream = NULL; } @@ -107,3 +236,3 @@ spamd_destroy(mu_stream_t *stream) static void -spamd_send_command(mu_stream_t stream, const char *fmt, ...) +spamd_send_command(mf_stream_t stream, const char *fmt, ...) { @@ -116,4 +245,4 @@ spamd_send_command(mu_stream_t stream, const char *fmt, ...) va_end (ap); - mu_stream_sequential_write(stream, buf, n); - mu_stream_sequential_write(stream, "\r\n", 2); + mf_stream_sequential_write(stream, buf, n); + mf_stream_sequential_write(stream, "\r\n", 2); } @@ -121,3 +250,3 @@ spamd_send_command(mu_stream_t stream, const char *fmt, ...) static void -spamd_send_stream(mu_stream_t stream, mu_stream_t instr) +spamd_send_stream(mf_stream_t stream, mu_stream_t instr) { @@ -131,3 +260,3 @@ spamd_send_stream(mu_stream_t stream, mu_stream_t instr) debug3(80,"<< %*.*s", size, size, buf); - mu_stream_sequential_write (stream, buf, size); + mf_stream_sequential_write(stream, buf, size); } @@ -136,6 +265,6 @@ spamd_send_stream(mu_stream_t stream, mu_stream_t instr) static int -spamd_read_line(mu_stream_t stream, char *buffer, size_t size, size_t *pn) +spamd_read_line(mf_stream_t stream, char *buffer, size_t size, size_t *pn) { size_t n = 0; - int rc = mu_stream_sequential_readline(stream, buffer, size, &n); + int rc = mf_stream_sequential_readline(stream, buffer, size, &n); if (rc == 0) { @@ -189,7 +318,7 @@ decode_float(long *vn, char *str, int digits) static int -decode_boolean (char *str) +decode_boolean(char *str) { - if (strcasecmp (str, "true") == 0) + if (strcasecmp(str, "true") == 0) return 1; - else if (strcasecmp (str, "false") == 0) + else if (strcasecmp(str, "false") == 0) return 0; @@ -224,4 +353,5 @@ sigpipe_handler (int sig) -mu_stream_t -open_connection(eval_environ_t env, char *urlstr, int *isfile, char **phost) +mf_stream_t +open_connection(eval_environ_t env, char *urlstr, int *isfile, char **phost, + long timeout) { @@ -229,3 +359,3 @@ open_connection(eval_environ_t env, char *urlstr, int *isfile, char **phost) short port = 0; - mu_stream_t str = NULL; + mf_stream_t str = NULL; int rc; @@ -312,6 +442,6 @@ open_connection(eval_environ_t env, char *urlstr, int *isfile, char **phost) if (port == 0) { - rc = spamd_connect_socket(env, &str, path); + rc = spamd_connect_socket(env, &str, path, timeout); *isfile = 1; } else { - rc = spamd_connect_tcp(env, &str, path, port); + rc = spamd_connect_tcp(env, &str, path, port, timeout); *isfile = 0; @@ -334,3 +464,3 @@ MF_STATE(eom) MF_CAPTURE -MF_DEFUN(sa, NUMBER, STRING urlstr, NUMBER prec) +MF_DEFUN(sa, NUMBER, STRING urlstr, NUMBER prec, OPTIONAL, NUMBER timeout) { @@ -339,3 +469,3 @@ MF_DEFUN(sa, NUMBER, STRING urlstr, NUMBER prec) mu_stream_t mstr = env_get_stream(env); - mu_stream_t ostr; + mf_stream_t ostr; signal_handler_fn handler; @@ -349,3 +479,4 @@ MF_DEFUN(sa, NUMBER, STRING urlstr, NUMBER prec) - ostr = open_connection(env, urlstr, &isfile, NULL); + ostr = open_connection(env, urlstr, &isfile, NULL, + MF_OPTVAL(timeout, 7200)); mu_stream_size(mstr, &msize); @@ -416,6 +547,7 @@ MF_STATE(eom) MF_CAPTURE -MF_DEFUN(clamav, NUMBER, STRING urlstr) +MF_DEFUN(clamav, NUMBER, STRING urlstr, OPTIONAL, NUMBER timeout) { mu_stream_t mstr = env_get_stream(env); - mu_stream_t cstr, dstr; + mf_stream_t cstr, dstr; + mu_stream_t str; char buffer[512]; @@ -427,4 +559,5 @@ MF_DEFUN(clamav, NUMBER, STRING urlstr) int isfile; - - cstr = open_connection(env, urlstr, &isfile, &host); + + cstr = open_connection(env, urlstr, &isfile, &host, + MF_OPTVAL(timeout, 7200)); @@ -441,4 +574,4 @@ MF_DEFUN(clamav, NUMBER, STRING urlstr) host = strdup("127.0.0.1"); /* FIXME */ - - rc = mu_tcp_stream_create(&dstr, host, port, 0); + + rc = mu_tcp_stream_create(&str, host, port, 0); free(host); @@ -451,6 +584,6 @@ MF_DEFUN(clamav, NUMBER, STRING urlstr) - rc = mu_stream_open(dstr); + rc = mu_stream_open(str); if (rc) { spamd_destroy(&cstr); - mu_stream_destroy(&dstr, mu_stream_get_owner(dstr)); + mu_stream_destroy(&str, mu_stream_get_owner(str)); MF_THROW(mf_failure, @@ -461,4 +594,7 @@ MF_DEFUN(clamav, NUMBER, STRING urlstr) handler = set_signal_handler(SIGPIPE, sigpipe_handler); + dstr = mf_stream_new (env, str, cstr->start, cstr->timeout); spamd_send_stream(dstr, mstr); spamd_shutdown(dstr, 0, SHUT_WR); + spamd_destroy(&dstr); + set_signal_handler(SIGPIPE, handler); |