summaryrefslogtreecommitdiff
path: root/libmailutils/sockaddr
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-11-01 10:56:08 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2017-11-01 10:56:08 +0200
commit4e7bcdbae346a26c1addf266a23c1f6cdc74533f (patch)
tree30f6721129f8a7688814b9dc88727e810770fbda /libmailutils/sockaddr
parenta5e929972db1342beec4b8f577399f2d8d9a76c2 (diff)
downloadmailutils-4e7bcdbae346a26c1addf266a23c1f6cdc74533f.tar.gz
mailutils-4e7bcdbae346a26c1addf266a23c1f6cdc74533f.tar.bz2
Improve socket and SMTP client API
Split formatting functions into two distinct families. Functions prefixed with mu_sys_sockadrr deal with struct sockaddr, wherease those starting with mu_sockaddr deal with struct mu_sockaddr. Introduce special format for SMTP EHLO. When sending EHLO to the remote party, use IP address in square brackets if hostname is empty. * libmailutils/sockaddr/Makefile.am (libsockaddr_la_SOURCES): Add fromsock.c * libmailutils/sockaddr/fromsock.c: New function. * libmailutils/sockaddr/str.c (mu_sockaddr_format): Rewrite. (mu_sys_sockaddr_format,mu_sys_sockaddr_to_astr): New functions. * include/mailutils/debug.h (mu_sockaddr_to_astr): Remove prototype. * include/mailutils/sockaddr.h (mu_sockaddr_format): New enum. (mu_sockaddr_format): change signature. (mu_sys_sockaddr_format,mu_sys_sockaddr_to_astr): New prototypes. (mu_sockaddr_from_socket): New prototype. * include/mailutils/stream.h (MU_IOCTL_TCPSTREAM): New ioctl family; (MU_IOCTL_TCP_GETSOCKNAME): New ioctl opcode. * comsat/comsat.c: Use mu_sys_sockaddr_ interface to handle struct sockaddr. * lib/tcpwrap.c: Likewise. * libmailutils/server/ipsrv.c: Likewise. * libmailutils/server/msrv.c: Likewise. * libmailutils/stream/tcp.c (_tcp_ioctl): Handle MU_IOCTL_TCPSTREAM. * libproto/mailer/smtp_ehlo.c (mu_smtp_ehlo): If hostname is empty, use IP address in square brackets.
Diffstat (limited to 'libmailutils/sockaddr')
-rw-r--r--libmailutils/sockaddr/Makefile.am1
-rw-r--r--libmailutils/sockaddr/fromsock.c38
-rw-r--r--libmailutils/sockaddr/str.c85
3 files changed, 105 insertions, 19 deletions
diff --git a/libmailutils/sockaddr/Makefile.am b/libmailutils/sockaddr/Makefile.am
index 961696815..4c98100a3 100644
--- a/libmailutils/sockaddr/Makefile.am
+++ b/libmailutils/sockaddr/Makefile.am
@@ -22,6 +22,7 @@ libsockaddr_la_SOURCES = \
create.c\
free.c\
fromnode.c\
+ fromsock.c\
insert.c\
ipaddr.c\
str.c\
diff --git a/libmailutils/sockaddr/fromsock.c b/libmailutils/sockaddr/fromsock.c
new file mode 100644
index 000000000..5d3f79a34
--- /dev/null
+++ b/libmailutils/sockaddr/fromsock.c
@@ -0,0 +1,38 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <mailutils/sockaddr.h>
+#include <mailutils/errno.h>
+#include <mailutils/error.h>
+
+int
+mu_sockaddr_from_socket (struct mu_sockaddr **retval, int fd)
+{
+ int rc;
+ struct sockaddr addr;
+ socklen_t len = sizeof (addr);
+ rc = getsockname (fd, &addr, &len);
+ if (rc)
+ return rc;
+ return mu_sockaddr_create (retval, &addr, len);
+}
diff --git a/libmailutils/sockaddr/str.c b/libmailutils/sockaddr/str.c
index dd6e865f8..d78c329be 100644
--- a/libmailutils/sockaddr/str.c
+++ b/libmailutils/sockaddr/str.c
@@ -38,7 +38,9 @@ static char *default_sockaddr_text = "[not enogh memory]";
"" : (sa)->sun_path)
int
-mu_sockaddr_format (char **pbuf, const struct sockaddr *sa, socklen_t salen)
+mu_sys_sockaddr_format (char **pbuf,
+ enum mu_sockaddr_format fmt,
+ const struct sockaddr *sa, socklen_t salen)
{
int rc = MU_ERR_FAILURE;
@@ -54,23 +56,51 @@ mu_sockaddr_format (char **pbuf, const struct sockaddr *sa, socklen_t salen)
host, sizeof (host), srv, sizeof (srv),
NI_NUMERICHOST|NI_NUMERICSERV) == 0)
{
- if (sa->sa_family == AF_INET6)
- rc = mu_asprintf (pbuf, "inet6://[%s]:%s", host, srv);
- else
- rc = mu_asprintf (pbuf, "inet://%s:%s", host, srv);
+ switch (fmt)
+ {
+ case mu_sockaddr_format_default:
+ if (sa->sa_family == AF_INET6)
+ rc = mu_asprintf (pbuf, "inet6://[%s]:%s", host, srv);
+ else
+ rc = mu_asprintf (pbuf, "inet://%s:%s", host, srv);
+ break;
+
+ case mu_sockaddr_format_ehlo:
+ rc = mu_asprintf (pbuf, "[%s]", host);
+ break;
+ }
}
else
- rc = mu_asprintf (pbuf, "%s://[getnameinfo failed]",
- sa->sa_family == AF_INET ?
- "inet" : "inet6");
+ {
+ switch (fmt)
+ {
+ case mu_sockaddr_format_default:
+ rc = mu_asprintf (pbuf, "%s://[getnameinfo failed]",
+ sa->sa_family == AF_INET ?
+ "inet" : "inet6");
+ break;
+
+ case mu_sockaddr_format_ehlo:
+ return MU_ERR_FAILURE;
+ }
+ }
break;
}
#else
case AF_INET:
{
struct sockaddr_in *s_in = (struct sockaddr_in *)sa;
- rc = mu_asprintf (pbuf, "inet://%s:%hu",
- inet_ntoa (s_in->sin_addr), s_in->sin_port);
+ switch (fmt)
+ {
+ case mu_sockaddr_format_default:
+ rc = mu_asprintf (pbuf, "inet://%s:%hu",
+ inet_ntoa (s_in->sin_addr), s_in->sin_port);
+ break;
+
+ case mu_sockaddr_format_ehlo:
+ rc = mu_asprintf (pbuf, "[%s]", inet_ntoa (s_in->sin_addr));
+ break;
+ }
break;
}
#endif
@@ -78,10 +108,19 @@ mu_sockaddr_format (char **pbuf, const struct sockaddr *sa, socklen_t salen)
case AF_UNIX:
{
struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
- if (S_UN_NAME (s_un, salen)[0] == 0)
- rc = mu_asprintf (pbuf, "unix://[anonymous socket]");
- else
- rc = mu_asprintf (pbuf, "unix://%s", s_un->sun_path);
+
+ switch (fmt)
+ {
+ case mu_sockaddr_format_default:
+ if (S_UN_NAME (s_un, salen)[0] == 0)
+ rc = mu_asprintf (pbuf, "unix://[anonymous socket]");
+ else
+ rc = mu_asprintf (pbuf, "unix://%s", s_un->sun_path);
+ break;
+
+ case mu_sockaddr_format_ehlo:
+ rc = mu_asprintf (pbuf, "localhost");
+ }
break;
}
@@ -92,19 +131,27 @@ mu_sockaddr_format (char **pbuf, const struct sockaddr *sa, socklen_t salen)
}
char *
-mu_sockaddr_to_astr (const struct sockaddr *sa, int salen)
+mu_sys_sockaddr_to_astr (const struct sockaddr *sa, int salen)
{
char *buf = NULL;
- mu_sockaddr_format (&buf, sa, salen);
+ mu_sys_sockaddr_format (&buf, mu_sockaddr_format_default, sa, salen);
return buf;
}
+int
+mu_sockaddr_format (struct mu_sockaddr *sa, char **pbuf,
+ enum mu_sockaddr_format fmt)
+{
+ return mu_sys_sockaddr_format (pbuf, fmt, sa->addr, sa->addrlen);
+}
+
const char *
mu_sockaddr_str (struct mu_sockaddr *sa)
{
- if (!sa->str && mu_sockaddr_format (&sa->str, sa->addr, sa->addrlen))
- return default_sockaddr_text;
- return sa->str;
+ if (!sa->str
+ && mu_sockaddr_format (sa, &sa->str, mu_sockaddr_format_default))
+ return default_sockaddr_text;
+ return sa->str;
}

Return to:

Send suggestions and report system problems to the System administrator.