aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-06-14 11:51:51 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-06-14 11:51:51 +0000
commitb74bc601f18b73fdd5a1ce106223975c2c669537 (patch)
tree9680324cb2ba5a71eef8042cf5d294a6e22a499f
parentea0eea5399a260d5170530cf3d7bbf90f303f8a9 (diff)
downloadmailfromd-b74bc601f18b73fdd5a1ce106223975c2c669537.tar.gz
mailfromd-b74bc601f18b73fdd5a1ce106223975c2c669537.tar.bz2
New option --source (#pragma source)
Adopt new MU namespace git-svn-id: file:///svnroot/mailfromd/branches/v_1_0@227 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--src/main.c123
1 files changed, 82 insertions, 41 deletions
diff --git a/src/main.c b/src/main.c
index e7c9b68a..7d06f8ab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -99,6 +99,8 @@ int force_remove; /* Remove local communication socket if it already
exists */
int foreground; /* Stay in foreground */
char *postmaster_email = "";
+unsigned long source_address = INADDR_ANY; /* Source address for TCP
+ connections */
char *pidfile = DEFAULT_PIDFILE;
char *user = DEFAULT_USER; /* Switch to this user privileges after
@@ -126,7 +128,7 @@ unsigned io_attempts = 3;
struct smtp_io_data; /* Declared later on */
struct message_data {
struct smtp_io_data *io;
- list_t hdr;
+ mu_list_t hdr;
};
#define MLFIPRIV(ctx) ((struct message_data*) smfi_getpriv(ctx))
@@ -165,8 +167,8 @@ priv_store_header_command(SMFICTX *ctx, struct header_node *node)
if (!md)
return 1;
if (!md->hdr)
- list_create(&md->hdr);
- list_append(md->hdr, node);
+ mu_list_create(&md->hdr);
+ mu_list_append(md->hdr, node);
return 0;
}
@@ -265,7 +267,7 @@ log_status(sfsistat status, SMFICTX *ctx)
/* Sendmail class file support */
-static list_t domain_list;
+static mu_list_t domain_list;
static int
compare_string(const void *item, const void *value)
@@ -290,8 +292,8 @@ read_domain_file(char *name)
}
if (!domain_list) {
- list_create(&domain_list);
- list_set_comparator(domain_list, compare_string);
+ mu_list_create(&domain_list);
+ mu_list_set_comparator(domain_list, compare_string);
}
while (p = fgets(buf, sizeof buf, fp)) {
@@ -308,7 +310,7 @@ read_domain_file(char *name)
if (*p == 0)
continue;
- list_append(domain_list, strdup(p));
+ mu_list_append(domain_list, strdup(p));
}
fclose(fp);
@@ -321,7 +323,7 @@ relayed_domain_p(char *name)
char *p = name;
while (p) {
- if (list_locate(domain_list, p, NULL) == 0) {
+ if (mu_list_locate(domain_list, p, NULL) == 0) {
debug2(10,"%s is in relayed domain %s",
name, p);
return 1;
@@ -340,7 +342,7 @@ host_in_relayed_domain_p(char *client)
{
char hbuf[NI_MAXHOST];
- if (list_is_empty(domain_list))
+ if (mu_list_is_empty(domain_list))
return 0;
if (resolve_ipstr(client, hbuf, sizeof(hbuf)))
@@ -355,7 +357,7 @@ host_in_relayed_domain_p(char *client)
struct smtp_io_data {
SMFICTX *ctx; /* Milter context */
- stream_t stream; /* I/O stream */
+ mu_stream_t stream; /* I/O stream */
size_t send_off; /* Send offset */
size_t recv_off; /* Receive offset */
struct obstack stk; /* Obstack for keeping commands/replies */
@@ -368,7 +370,7 @@ struct smtp_io_data {
};
int
-smtp_io_data_init(struct smtp_io_data *dat, SMFICTX *ctx, stream_t stream)
+smtp_io_data_init(struct smtp_io_data *dat, SMFICTX *ctx, mu_stream_t stream)
{
obstack_init(&dat->stk);
dat->send_off = dat->recv_off = 0;
@@ -385,8 +387,8 @@ void
smtp_io_data_destroy(struct smtp_io_data *dat)
{
if (dat) {
- stream_close (dat->stream);
- stream_destroy(&dat->stream, stream_get_owner(dat->stream));
+ 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);
@@ -394,7 +396,7 @@ smtp_io_data_destroy(struct smtp_io_data *dat)
}
int
-smtp_stream_wait(stream_t stream, int flags, int *attempt)
+smtp_stream_wait(mu_stream_t stream, int flags, int *attempt)
{
int rc;
int oflags = flags;
@@ -402,7 +404,7 @@ smtp_stream_wait(stream_t stream, int flags, int *attempt)
while (*attempt < io_attempts) {
tv.tv_sec = io_timeout;
tv.tv_usec = 0;
- rc = stream_wait(stream, &oflags, &tv);
+ rc = mu_stream_wait(stream, &oflags, &tv);
switch (rc) {
case 0:
if (flags & oflags)
@@ -436,11 +438,11 @@ smtp_send(struct smtp_io_data *dat, char *command)
transcript("SEND:", command);
do {
size_t nb;
- int rc = stream_write(dat->stream, command, len,
+ int 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");
+ mu_error("mu_stream_write: wrote 0 bytes");
return -1;
}
dat->send_off += nb;
@@ -457,11 +459,11 @@ smtp_send(struct smtp_io_data *dat, char *command)
}
continue;
} else {
- mu_error ("stream_write timed out");
+ mu_error ("mu_stream_write timed out");
return -1;
}
} else {
- mu_error ("stream_write: %s", mu_strerror (rc));
+ mu_error ("mu_stream_write: %s", mu_strerror (rc));
return -1;
}
} while (len > 0);
@@ -502,12 +504,12 @@ smtp_recvline(struct smtp_io_data *dat)
char *p;
if (dat->level == 0) {
- int rc = stream_read(dat->stream,
+ 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");
+ mu_error("mu_stream_read: read 0 bytes");
return -1;
}
dat->recv_off += dat->level;
@@ -585,20 +587,22 @@ mf_status
listens_on (const char *client_addr, int port)
{
unsigned count = 0;
- stream_t stream;
+ mu_stream_t stream;
int rc;
if (port == 0)
port = 25;
debug2(10, "client_addr = %s, port = %d", client_addr, port);
- rc = tcp_stream_create (&stream, client_addr, 25, MU_STREAM_NONBLOCK);
+ rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25,
+ source_address,
+ MU_STREAM_NONBLOCK);
if (rc) {
- debug1 (10, "tcp_stream_create: %s", mu_strerror (rc));
+ debug1 (10, "mu_tcp_stream_create_with_source_ip: %s", mu_strerror (rc));
return mf_failure;
}
- while ((rc = stream_open(stream))) {
+ while ((rc = mu_stream_open(stream))) {
if ((rc == EAGAIN || rc == EINPROGRESS)
&& count < io_attempts) {
rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
@@ -608,9 +612,9 @@ listens_on (const char *client_addr, int port)
}
break;
}
- stream_destroy(&stream, stream_get_owner(stream));
+ mu_stream_destroy(&stream, mu_stream_get_owner(stream));
- debug2 (10, "stream_open: %s, %u", mu_strerror(rc), count);
+ debug2 (10, "mu_stream_open: %s, %u", mu_strerror(rc), count);
return rc == 0 ? mf_success :
(rc == EAGAIN || rc == EINPROGRESS) ?
@@ -626,19 +630,21 @@ check_on_host(SMFICTX *ctx, char *email, char *client_addr,
char *ehlo, char *mailfrom)
{
int rc;
- stream_t stream;
+ mu_stream_t stream;
struct smtp_io_data io;
mf_status status = mf_success;
unsigned count = 0;
debug2(10, "email = %s, client_addr = %s", email, client_addr);
- rc = tcp_stream_create (&stream, client_addr, 25, MU_STREAM_NONBLOCK);
+ rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25,
+ source_address,
+ MU_STREAM_NONBLOCK);
if (rc) {
- mu_error ("tcp_stream_create: %s", mu_strerror (rc));
+ mu_error ("mu_tcp_stream_create_with_source_ip: %s", mu_strerror (rc));
return mf_temp_failure;
}
- while ((rc = stream_open(stream))) {
+ while ((rc = mu_stream_open(stream))) {
if ((rc == EAGAIN || rc == EINPROGRESS)
&& count < io_attempts) {
rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
@@ -646,8 +652,8 @@ check_on_host(SMFICTX *ctx, char *email, char *client_addr,
if (rc == 0)
continue;
}
- mu_error("stream_open: %s, %u", mu_strerror(rc), count);
- stream_destroy(&stream, stream_get_owner(stream));
+ mu_error("mu_stream_open: %s, %u", mu_strerror(rc), count);
+ mu_stream_destroy(&stream, mu_stream_get_owner(stream));
if (rc == EAGAIN || rc == EINPROGRESS)
return mf_temp_failure;
else
@@ -802,7 +808,7 @@ filter_cleanup(SMFICTX *ctx)
debug(100,"cleaning up");
if (md) {
smtp_io_data_destroy(md->io);
- list_destroy(&md->hdr);
+ mu_list_destroy(&md->hdr);
free(md);
smfi_setpriv(ctx, NULL);
}
@@ -854,7 +860,7 @@ mlfi_eom(SMFICTX *ctx)
if (md && md->hdr) {
debug(50,"executing header commands");
- list_do(md->hdr, run_header_command, ctx);
+ mu_list_do(md->hdr, run_header_command, ctx);
}
return SMFIS_CONTINUE;
}
@@ -1038,7 +1044,13 @@ load_relay_file(void *item, void *data)
void
set_relay(void *value)
{
- list_do(value, load_relay_file, NULL);
+ mu_list_do(value, load_relay_file, NULL);
+}
+
+void
+set_source(void *value)
+{
+ source_address = *(unsigned long*)value;
}
int
@@ -1102,8 +1114,30 @@ int
option_relay(char *opt, void **pval, char *newval)
{
if (!*pval)
- list_create((list_t*)pval);
- list_append(*pval, strdup(newval));
+ mu_list_create((mu_list_t*)pval);
+ mu_list_append(*pval, strdup(newval));
+ return 0;
+}
+
+int
+option_source(char *opt, void **pval, char *newval)
+{
+ unsigned long address = inet_addr (newval);
+ if (address == INADDR_NONE) {
+ struct hostent *phe = gethostbyname (newval);
+ if (!phe) {
+ mu_error("Cannot resolve `%s'", newval);
+ return 1;
+ }
+ address = *(((unsigned long **) phe->h_addr_list)[0]);
+ }
+
+ if (*pval == 0) {
+ *pval = malloc (sizeof address);
+ if (!*pval)
+ return 1;
+ }
+ *(unsigned long*)*pval = address;
return 0;
}
@@ -1128,6 +1162,7 @@ struct option_cache {
{ "retry", NULL, option_number, set_retry, 0 },
{ "timeout", NULL, option_time, set_timeout, 0 },
{ "relay", NULL, option_relay, set_relay, 1 },
+ { "source", NULL, option_source, set_source },
{ NULL }
};
@@ -1231,6 +1266,8 @@ static struct argp_option options[] = {
"Set pidfile name", GRP+1 },
{ "user", 'u', "NAME", 0,
"Switch to this user privileges after startup", GRP+1 },
+ { "source", 'S', "ADDRESS", 0,
+ "Set source address for TCP connections", GRP+1 },
#ifdef USE_DBM
{ "expire-interval", 'e', "NUMBER", 0,
"Set cache expiration interval to NUMBER seconds", GRP+1 },
@@ -1319,6 +1356,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
force_remove = 1;
break;
+ case 'S':
+ set_option("source", arg, 1);
+ break;
+
case 's':
log_to_stderr = 1;
break;
@@ -1632,7 +1673,7 @@ void
mailfromd_test(int argc, char **argv)
{
int i;
- list_t dict = NULL;
+ mu_list_t dict = NULL;
if (!argc)
return;
@@ -1685,10 +1726,10 @@ mailfromd_daemon()
if (!foreground) {
daemon(0, 0);
- daemon_create_pidfile(pidfile);
+ mu_daemon_create_pidfile(pidfile);
rc = smfi_main();
mu_error("OK. REMOVING PIDFILE");
- daemon_remove_pidfile();
+ mu_daemon_remove_pidfile();
} else
rc = smfi_main();
exit(rc);

Return to:

Send suggestions and report system problems to the System administrator.