aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-10-21 11:20:33 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-10-21 11:20:33 +0000
commit44e921546471416e57574f9c00a8014864b60276 (patch)
tree0d7a87b42dba95fbbf7b491ea883dc2f1bd7edb6
parent53cdaa581361a885bd7ab087b691b5c68cdc837c (diff)
downloadmailfromd-44e921546471416e57574f9c00a8014864b60276.tar.gz
mailfromd-44e921546471416e57574f9c00a8014864b60276.tar.bz2
* src/engine.c: Fix timeout calculations
(struct timeout_ctl): New data type (UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl. All callers updated. (init_timeout_ctl): New function. git-svn-id: file:///svnroot/mailfromd/trunk@1517 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog8
-rw-r--r--src/engine.c79
2 files changed, 54 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index ee51e4c7..c50cbd64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,20 @@
+2007-10-21 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * src/engine.c: Fix timeout calculations
+ (struct timeout_ctl): New data type
+ (UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl.
+ All callers updated.
+ (init_timeout_ctl): New function.
+
2007-10-12 Sergey Poznyakoff <gray@gnu.org.ua>
* src/mtasim.c (_def_read): Return 0 if zero bytes were read
(get_input_line): Fix counting of input bytes.
(smtp): Fix checking for returns from process_data_reply.
* gacopyz/server.c (srv_format_macros): Do not add trailing zero
to the packet.
2007-10-10 Sergey Poznyakoff <gray@gnu.org.ua>
* src/mailfromd.h [!ENABLE_NLS] (bindtextdomain): Fix definition.
* src/cache.c (cache_get2): Fix misplaced variable definition.
diff --git a/src/engine.c b/src/engine.c
index 1801fdec..bb3fa18c 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -296,99 +296,112 @@ void
smtp_io_data_destroy(struct smtp_io_data *dat)
{
if (dat) {
mu_stream_close (dat->stream);
mu_stream_destroy(&dat->stream,
mu_stream_get_owner(dat->stream));
obstack_free(&dat->stk, NULL);
if (dat->ctx)
priv_set_io(dat->ctx, NULL);
}
}
-#define UPDATE_TTW(t,start) do { \
- time_t delta = time(NULL) - start; \
- if (t > delta) \
- t -= delta; \
+struct timeout_ctl {
+ time_t start;
+ time_t timeout;
+};
+
+static void
+init_timeout_ctl(struct timeout_ctl *tctl, time_t timeout)
+{
+ tctl->start = time(NULL);
+ tctl->timeout = 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 = 0; \
+ (t).timeout = 0; \
+ (t).start = now; \
} while (0)
int
-smtp_stream_wait(mu_stream_t stream, int flags, time_t *timeout)
+smtp_stream_wait(mu_stream_t stream, int flags, struct timeout_ctl *tctl)
{
int rc;
int oflags = flags;
struct timeval tv;
- time_t start = time(NULL);
- while (*timeout) {
- tv.tv_sec = *timeout;
+ while (tctl->timeout) {
+ tv.tv_sec = tctl->timeout;
tv.tv_usec = 0;
rc = mu_stream_wait(stream, &oflags, &tv);
/* Correct the timeout */
- UPDATE_TTW(*timeout, start);
+ UPDATE_TTW(*tctl);
switch (rc) {
case 0:
if (flags & oflags)
return 0;
/* FALLTHROUGH */
case EAGAIN:
case EINPROGRESS:
continue;
default:
return rc;
}
}
return ETIMEDOUT;
}
int
-smtp_wait(struct smtp_io_data *dat, int flags, time_t *timeout)
+smtp_wait(struct smtp_io_data *dat, int flags, struct timeout_ctl *tctl)
{
- return smtp_stream_wait(dat->stream, flags, timeout);
+ return smtp_stream_wait(dat->stream, flags, tctl);
}
int
smtp_send(struct smtp_io_data *dat, char *command)
{
size_t len = strlen(command);
- time_t timeout = io_timeout;
- time_t start = time(NULL);
+ struct timeout_ctl tctl;
+
+ init_timeout_ctl (&tctl, io_timeout);
dat->reply = NULL; /* Clear reply for logging purposes */
transcript(dat, "SEND:", command);
do {
size_t nb;
int rc;
- UPDATE_TTW(timeout, start);
+ UPDATE_TTW(tctl);
rc = mu_stream_write(dat->stream, command, len,
dat->send_off, &nb);
if (rc == 0) {
if (nb == 0) {
mu_error(_("stream_write: wrote 0 bytes"));
return -1;
}
dat->send_off += nb;
len -= nb;
command += nb;
} else if (rc == EAGAIN) {
- rc = smtp_wait(dat, MU_STREAM_READY_WR,
- &timeout);
+ rc = smtp_wait(dat, MU_STREAM_READY_WR, &tctl);
if (rc) {
mu_error(_("smtp_wait failed: %s"),
mu_strerror(rc));
return -1;
}
continue;
} else {
mu_error("mu_stream_write: %s",
mu_strerror (rc));
return -1;
}
} while (len > 0);
@@ -415,45 +428,44 @@ smtp_send3(struct smtp_io_data *dat, char *command, char *arg1, char *arg2)
obstack_grow(&dat->stk, arg1, strlen(arg1));
obstack_grow(&dat->stk, arg2, strlen(arg2));
obstack_grow(&dat->stk, "\r\n", 2);
obstack_1grow(&dat->stk, 0);
dat->command = obstack_finish(&dat->stk);
return smtp_send(dat, dat->command);
}
int
smtp_recvline(struct smtp_io_data *dat, time_t timeout)
{
- time_t start = time(NULL);
-
+ struct timeout_ctl tctl;
+ init_timeout_ctl(&tctl, timeout);
for (;;) {
char *p;
- UPDATE_TTW(timeout, start);
-
+ UPDATE_TTW(tctl);
+
if (dat->level == 0) {
int rc = mu_stream_read(dat->stream,
dat->buf, sizeof dat->buf,
dat->recv_off, &dat->level);
if (rc == 0) {
if (dat->level == 0) {
mu_error(_("stream_read: read 0 bytes"));
return -1;
}
dat->recv_off += dat->level;
} else if (rc == EAGAIN) {
rc = smtp_wait(dat,
- MU_STREAM_READY_RD,
- &timeout);
+ MU_STREAM_READY_RD, &tctl);
if (rc) {
mu_error(_("smtp_wait failed: %s"),
mu_strerror(rc));
return -1;
}
continue;
} else {
mu_error("mu_stream_read: %s",
mu_strerror (rc));
return -1;
}
}
@@ -554,48 +566,48 @@ reset(struct smtp_io_data *io)
/* Verify whether EMAIL address is served by host CLIENT_ADDR. */
mf_status
check_on_host(eval_environ_t env, char *email, char *client_addr,
char *ehlo, char *mailfrom)
{
int rc;
mu_stream_t stream;
struct smtp_io_data io;
mf_status status = mf_success;
int count = 0;
SMFICTX *ctx = env_get_context(env);
- time_t timeout, start = time(NULL);
+ struct timeout_ctl tctl;
debug2(10, "email = %s, client_addr = %s", email, client_addr);
set_last_poll_result(env, client_addr, "", "");
rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25,
source_address,
MU_STREAM_NONBLOCK);
if (rc) {
mu_error(_("%sCannot connect to `%s': %s"),
mailfromd_msgid(ctx), client_addr,
mu_strerror (rc));
return mf_temp_failure;
}
-
- timeout = connect_timeout;
+
+ init_timeout_ctl(&tctl, connect_timeout);
while ((rc = mu_stream_open(stream))) {
if ((rc == EAGAIN || rc == EINPROGRESS)
- && timeout) {
+ && tctl.timeout) {
rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
- &timeout);
+ &tctl);
if (rc == 0) {
- UPDATE_TTW(timeout, start);
+ UPDATE_TTW(tctl);
continue;
}
}
mu_error("%sstream_open: %s, %d",
mailfromd_msgid(ctx), mu_strerror(rc), count);
mu_stream_destroy(&stream, mu_stream_get_owner(stream));
return mf_temp_failure;
}
debug(100,"stream opened");
if (smtp_io_data_init(&io, ctx, stream))
status = mf_temp_failure;
@@ -818,45 +830,46 @@ method_standard(eval_environ_t env, char *email, char *ehlo, char *mailfrom)
set_last_poll_result(env, "", "", "");
set_cache_used(env, 1);
}
return rc;
}
mf_status
listens_on (const char *client_addr, int port)
{
unsigned count = 0;
mu_stream_t stream;
int rc;
- time_t timeout = connect_timeout, start = time(NULL);
+ struct timeout_ctl tctl;
if (port == 0)
port = 25;
debug2(10, "client_addr = %s, port = %d", client_addr, port);
rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, port,
source_address,
MU_STREAM_NONBLOCK);
if (rc) {
debug1 (10, "mu_tcp_stream_create_with_source_ip: %s",
mu_strerror (rc));
return mf_failure;
}
+ init_timeout_ctl(&tctl, connect_timeout);
while ((rc = mu_stream_open(stream))) {
- if ((rc == EAGAIN || rc == EINPROGRESS) && timeout) {
+ if ((rc == EAGAIN || rc == EINPROGRESS) && tctl.timeout) {
rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
- &timeout);
+ &tctl);
if (rc == 0) {
- UPDATE_TTW(timeout, start);
+ UPDATE_TTW(tctl);
continue;
}
}
break;
}
mu_stream_destroy(&stream, mu_stream_get_owner(stream));
debug3 (10, "mu_stream_open(%s): %s, %u", client_addr, mu_strerror(rc),
count);
return rc == 0 ? mf_success :
(rc == EAGAIN || rc == EINPROGRESS) ?

Return to:

Send suggestions and report system problems to the System administrator.