summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2000-12-16 18:06:09 +0000
committerume <ume@FreeBSD.org>2000-12-16 18:06:09 +0000
commitbd199e398300ffe7763db31037bf1a6d19b2d407 (patch)
tree3a4830f8c7df7ed9495f11908a846633c967ffaa /usr.sbin
parent5b8ad91da1233aca24afce2d8c4fe1d0966b3c50 (diff)
downloadFreeBSD-src-bd199e398300ffe7763db31037bf1a6d19b2d407.zip
FreeBSD-src-bd199e398300ffe7763db31037bf1a6d19b2d407.tar.gz
IPv6 support for lpr.
Reviewed by: freebsd-current (no objection) Obtained from: KAME
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/lpr/Makefile.inc1
-rw-r--r--usr.sbin/lpr/common_source/lp.h5
-rw-r--r--usr.sbin/lpr/common_source/net.c186
-rw-r--r--usr.sbin/lpr/lpd/lpd.88
-rw-r--r--usr.sbin/lpr/lpd/lpd.c245
5 files changed, 303 insertions, 142 deletions
diff --git a/usr.sbin/lpr/Makefile.inc b/usr.sbin/lpr/Makefile.inc
index 141373e..9d01167 100644
--- a/usr.sbin/lpr/Makefile.inc
+++ b/usr.sbin/lpr/Makefile.inc
@@ -1,5 +1,6 @@
# $FreeBSD$
+CFLAGS+=-DINET6
CWARNFLAGS= -Wall -Wnested-externs -Wmissing-prototypes -Wno-unused -Wredundant-decls -Wstrict-prototypes
.if exists(${.OBJDIR}/../common_source)
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 4e4e4b6..309a770 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -36,6 +36,7 @@
#include <sys/queue.h>
#include <time.h>
+#include <netdb.h>
/*
* All this information used to be in global static variables shared
@@ -156,14 +157,14 @@ extern char *name; /* program name */
/* host machine name */
extern char host[MAXHOSTNAMELEN];
extern char *from; /* client's machine name */
-#define MAXIPSTRLEN 32 /* maxlen of an IP-address as a string */
-extern char from_ip[MAXIPSTRLEN]; /* client machine's IP address */
+extern char from_ip[NI_MAXHOST]; /* client machine's IP address */
extern int requ[]; /* job number of spool entries */
extern int requests; /* # of spool requests */
extern char *user[]; /* users to process */
extern int users; /* # of users in user array */
extern char *person; /* name of person doing lprm */
+extern u_char family; /* address family */
/*
* Structure used for building a sorted list of control files.
diff --git a/usr.sbin/lpr/common_source/net.c b/usr.sbin/lpr/common_source/net.c
index 4cfabfa..2f30d85 100644
--- a/usr.sbin/lpr/common_source/net.c
+++ b/usr.sbin/lpr/common_source/net.c
@@ -67,7 +67,13 @@ static const char rcsid[] =
char host[MAXHOSTNAMELEN]; /* host machine name */
char *from = host; /* client's machine name */
-char from_ip[MAXIPSTRLEN] = ""; /* client machine's IP address */
+char from_ip[NI_MAXHOST] = ""; /* client machine's IP address */
+
+#ifdef INET6
+u_char family = PF_UNSPEC;
+#else
+u_char family = PF_INET;
+#endif
extern uid_t uid, euid;
@@ -79,46 +85,52 @@ extern uid_t uid, euid;
int
getport(const struct printer *pp, const char *rhost, int rport)
{
- struct hostent *hp;
- struct servent *sp;
- struct sockaddr_in sin;
+ struct addrinfo hints, *res, *ai;
int s, timo = 1, lport = IPPORT_RESERVED - 1;
- int err;
+ int err, refused = 0;
/*
* Get the host address and port number to connect to.
*/
if (rhost == NULL)
fatal(pp, "no remote host to connect to");
- bzero((char *)&sin, sizeof(sin));
- sin.sin_len = sizeof sin;
- sin.sin_family = AF_INET;
- if (inet_aton(rhost, &sin.sin_addr) == 0) {
- hp = gethostbyname2(rhost, AF_INET);
- if (hp == NULL)
- fatal(pp, "cannot resolve %s: %s", rhost,
- hstrerror(h_errno));
- /* XXX - should deal with more addresses */
- sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0];
- }
- if (rport == 0) {
- sp = getservbyname("printer", "tcp");
- if (sp == NULL)
- fatal(pp, "printer/tcp: unknown service");
- sin.sin_port = sp->s_port;
- } else
- sin.sin_port = htons(rport);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ err = getaddrinfo(rhost, (rport == 0 ? "printer" : NULL),
+ &hints, &res);
+ if (err)
+ fatal(pp, "%s\n", gai_strerror(err));
+ if (rport != 0)
+ ((struct sockaddr_in *) res->ai_addr)->sin_port = htons(rport);
/*
* Try connecting to the server.
*/
+ ai = res;
retry:
seteuid(euid);
- s = rresvport(&lport);
+ s = rresvport_af(&lport, ai->ai_family);
seteuid(uid);
- if (s < 0)
+ if (s < 0) {
+ if (errno != EAGAIN) {
+ if (ai->ai_next) {
+ ai = ai->ai_next;
+ goto retry;
+ }
+ if (refused && timo <= 16) {
+ sleep(timo);
+ timo *= 2;
+ refused = 0;
+ ai = res;
+ goto retry;
+ }
+ }
+ freeaddrinfo(res);
return(-1);
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ }
+ if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
err = errno;
(void) close(s);
errno = err;
@@ -128,16 +140,28 @@ retry:
* rresvport should guarantee that the chosen port will
* never result in an EADDRINUSE).
*/
- if (errno == EADDRINUSE)
+ if (errno == EADDRINUSE) {
goto retry;
+ }
- if (errno == ECONNREFUSED && timo <= 16) {
+ if (errno == ECONNREFUSED)
+ refused++;
+
+ if (ai->ai_next != NULL) {
+ ai = ai->ai_next;
+ goto retry;
+ }
+ if (refused && timo <= 16) {
sleep(timo);
timo *= 2;
+ refused = 0;
+ ai = res;
goto retry;
}
+ freeaddrinfo(res);
return(-1);
}
+ freeaddrinfo(res);
return(s);
}
@@ -155,10 +179,10 @@ char *
checkremote(struct printer *pp)
{
char name[MAXHOSTNAMELEN];
- register struct hostent *hp;
+ struct addrinfo hints, *local_res, *remote_res, *lr, *rr;
char *err;
- struct in_addr *localaddrs;
- int i, j, nlocaladdrs, ncommonaddrs;
+ int ncommonaddrs, error;
+ char h1[NI_MAXHOST], h2[NI_MAXHOST];
if (!pp->rp_matches_local) { /* Remote printer doesn't match local */
pp->remote = 1;
@@ -166,57 +190,63 @@ checkremote(struct printer *pp)
}
pp->remote = 0; /* assume printer is local */
- if (pp->remote_host != NULL) {
- /* get the addresses of the local host */
- gethostname(name, sizeof(name));
- name[sizeof(name) - 1] = '\0';
- hp = gethostbyname2(name, AF_INET);
- if (hp == (struct hostent *) NULL) {
- asprintf(&err, "unable to get official name "
- "for local machine %s: %s",
- name, hstrerror(h_errno));
- return err;
- }
- for (i = 0; hp->h_addr_list[i]; i++)
- ;
- nlocaladdrs = i;
- localaddrs = malloc(i * sizeof(struct in_addr));
- if (localaddrs == 0) {
- asprintf(&err, "malloc %lu bytes failed",
- (u_long)i * sizeof(struct in_addr));
- return err;
- }
- for (i = 0; hp->h_addr_list[i]; i++)
- localaddrs[i] = *(struct in_addr *)hp->h_addr_list[i];
+ if (pp->remote_host == NULL)
+ return NULL;
- /* get the official name of RM */
- hp = gethostbyname2(pp->remote_host, AF_INET);
- if (hp == (struct hostent *) NULL) {
- asprintf(&err, "unable to get address list for "
- "remote machine %s: %s",
- pp->remote_host, hstrerror(h_errno));
- free(localaddrs);
- return err;
- }
+ /* get the addresses of the local host */
+ gethostname(name, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
- ncommonaddrs = 0;
- for (i = 0; i < nlocaladdrs; i++) {
- for (j = 0; hp->h_addr_list[j]; j++) {
- char *them = hp->h_addr_list[j];
- if (localaddrs[i].s_addr ==
- (*(struct in_addr *)them).s_addr)
- ncommonaddrs++;
- }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ if ((error = getaddrinfo(name, NULL, &hints, &local_res)) != 0) {
+ asprintf(&err, "unable to get official name "
+ "for local machine %s: %s",
+ name, gai_strerror(error));
+ return err;
+ }
+
+ /* get the official name of RM */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ if ((error = getaddrinfo(pp->remote_host, NULL,
+ &hints, &remote_res)) != 0) {
+ asprintf(&err, "unable to get address list for "
+ "remote machine %s: %s",
+ pp->remote_host, gai_strerror(error));
+ freeaddrinfo(local_res);
+ return err;
+ }
+
+ ncommonaddrs = 0;
+ for (lr = local_res; lr; lr = lr->ai_next) {
+ h1[0] = '\0';
+ if (getnameinfo(lr->ai_addr, lr->ai_addrlen, h1, sizeof(h1),
+ NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) != 0)
+ continue;
+ for (rr = remote_res; rr; rr = rr->ai_next) {
+ h2[0] = '\0';
+ if (getnameinfo(rr->ai_addr, rr->ai_addrlen,
+ h2, sizeof(h2), NULL, 0,
+ NI_NUMERICHOST | NI_WITHSCOPEID) != 0)
+ continue;
+ if (strcmp(h1, h2) == 0)
+ ncommonaddrs++;
}
-
- /*
- * if the two hosts do not share at least one IP address
- * then the printer must be remote.
- */
- if (ncommonaddrs == 0)
- pp->remote = 1;
- free(localaddrs);
}
+
+ /*
+ * if the two hosts do not share at least one IP address
+ * then the printer must be remote.
+ */
+ if (ncommonaddrs == 0)
+ pp->remote = 1;
+ freeaddrinfo(local_res);
+ freeaddrinfo(remote_res);
return NULL;
}
diff --git a/usr.sbin/lpr/lpd/lpd.8 b/usr.sbin/lpr/lpd/lpd.8
index 48e2af3..0c48f7c 100644
--- a/usr.sbin/lpr/lpd/lpd.8
+++ b/usr.sbin/lpr/lpd/lpd.8
@@ -40,7 +40,7 @@
.Nd line printer spooler daemon
.Sh SYNOPSIS
.Nm
-.Op Fl dlp
+.Op Fl dlp46
.Op Ar port#
.Sh DESCRIPTION
.Nm Lpd
@@ -81,6 +81,12 @@ The
flag causes
.Nm
not to open an Internet listening socket.
+.It Fl 4
+Inet only.
+.It Fl 6
+Inet6 only.
+.It Fl 46
+Inet and inet6 (default).
.It Ar "port#"
The Internet port number used to rendezvous
with other processes is normally obtained with
diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c
index ea505ae..a890826 100644
--- a/usr.sbin/lpr/lpd/lpd.c
+++ b/usr.sbin/lpr/lpd/lpd.c
@@ -112,12 +112,14 @@ static void reapchild __P((int));
static void mcleanup __P((int));
static void doit __P((void));
static void startup __P((void));
-static void chkhost __P((struct sockaddr_in *));
+static void chkhost __P((struct sockaddr *));
static int ckqueue __P((struct printer *));
static void usage __P((void));
-/* From rcmd.c: */
-int __ivaliduser __P((FILE *, u_long, const char *,
- const char *));
+static int *socksetup __P((int, int));
+
+/* XXX from libc/net/rcmd.c */
+extern int __ivaliduser_sa __P((FILE *, struct sockaddr *, socklen_t,
+ const char *, const char *));
uid_t uid, euid;
@@ -126,13 +128,14 @@ main(argc, argv)
int argc;
char **argv;
{
- int errs, f, funix, finet, fromlen, i, socket_debug;
+ int errs, f, funix, *finet, fromlen, i, options, socket_debug;
fd_set defreadfds;
struct sockaddr_un un, fromunix;
- struct sockaddr_in sin, frominet;
+ struct sockaddr_storage frominet;
int lfd;
sigset_t omask, nmask;
struct servent *sp, serv;
+ int inet_flag = 0, inet6_flag = 0;
euid = geteuid(); /* these shouldn't be different */
uid = getuid();
@@ -145,7 +148,7 @@ main(argc, argv)
errx(EX_NOPERM,"must run as root");
errs = 0;
- while ((i = getopt(argc, argv, "dlp")) != -1)
+ while ((i = getopt(argc, argv, "dlp46")) != -1)
switch (i) {
case 'd':
socket_debug++;
@@ -156,9 +159,19 @@ main(argc, argv)
case 'p':
pflag++;
break;
+ case '4':
+ family = PF_INET;
+ inet_flag++;
+ break;
+ case '6':
+ family = PF_INET6;
+ inet6_flag++;
+ break;
default:
errs++;
}
+ if (inet_flag && inet6_flag)
+ family = PF_UNSPEC;
argc -= optind;
argv += optind;
if (errs)
@@ -283,32 +296,17 @@ main(argc, argv)
FD_ZERO(&defreadfds);
FD_SET(funix, &defreadfds);
listen(funix, 5);
- finet = -1;
if (pflag == 0) {
- finet = socket(AF_INET, SOCK_STREAM, 0);
- if (finet >= 0) {
- i = 1;
- if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &i,
- sizeof i) < 0) {
- syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
- mcleanup(0);
- }
- if (socket_debug &&
- setsockopt(finet, SOL_SOCKET, SO_DEBUG,
- &socket_debug, sizeof(socket_debug)) < 0) {
- syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
- mcleanup(0);
- }
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = sp->s_port;
- if (bind(finet, (struct sockaddr *)&sin,
- sizeof(sin)) < 0) {
- syslog(LOG_ERR, "bind: %m");
- mcleanup(0);
- }
- FD_SET(finet, &defreadfds);
- listen(finet, 5);
+ options = SO_REUSEADDR;
+ if (socket_debug)
+ options |= SO_DEBUG;
+ finet = socksetup(family, options);
+ } else
+ finet = NULL; /* pretend we couldn't open TCP socket. */
+ if (finet) {
+ for (i = 1; i <= *finet; i++) {
+ FD_SET(finet[i], &defreadfds);
+ listen(finet[i], 5);
}
}
/*
@@ -322,7 +320,7 @@ main(argc, argv)
* XXX - should be redone for multi-protocol
*/
for (;;) {
- int domain, nfds, s;
+ int domain = -1, nfds, s = -1;
fd_set readfds;
FD_COPY(&defreadfds, &readfds);
@@ -338,14 +336,15 @@ main(argc, argv)
domain = AF_UNIX, fromlen = sizeof(fromunix);
s = accept(funix,
(struct sockaddr *)&fromunix, &fromlen);
- } else if (pflag == 0) /* if (FD_ISSET(finet, &readfds)) */ {
- domain = AF_INET, fromlen = sizeof(frominet);
- s = accept(finet,
- (struct sockaddr *)&frominet, &fromlen);
- if (frominet.sin_port == htons(20)) {
- close(s);
- continue;
- }
+ } else {
+ for (i = 1; i <= *finet; i++)
+ if (FD_ISSET(finet[i], &readfds)) {
+ domain = AF_INET;
+ fromlen = sizeof(frominet);
+ s = accept(finet[i],
+ (struct sockaddr *)&frominet,
+ &fromlen);
+ }
}
if (s < 0) {
if (errno != EINTR)
@@ -359,14 +358,16 @@ main(argc, argv)
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
(void) close(funix);
- if (pflag == 0) {
- (void) close(finet);
+ if (pflag == 0 && finet) {
+ for (i = 1; i <= *finet; i++)
+ (void)close(finet[i]);
}
dup2(s, 1);
(void) close(s);
if (domain == AF_INET) {
+ /* for both AF_INET and AF_INET6 */
from_remote = 1;
- chkhost(&frominet);
+ chkhost((struct sockaddr *)&frominet);
} else
from_remote = 0;
doit();
@@ -606,35 +607,75 @@ ckqueue(pp)
*/
static void
chkhost(f)
- struct sockaddr_in *f;
+ struct sockaddr *f;
{
- register struct hostent *hp;
+ struct addrinfo hints, *res, *r;
register FILE *hostf;
int first = 1;
int good = 0;
+ char host[NI_MAXHOST], ip[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+ int error, addrlen;
+ caddr_t addr;
+
+ error = getnameinfo(f, f->sa_len, NULL, 0, serv, sizeof(serv),
+ NI_NUMERICSERV);
+ if (error || atoi(serv) >= IPPORT_RESERVED)
+ fatal(0, "Malformed from address");
/* Need real hostname for temporary filenames */
- hp = gethostbyaddr((char *)&f->sin_addr,
- sizeof(struct in_addr), f->sin_family);
- if (hp == NULL)
- fatal(0, "Host name for your address (%s) unknown",
- inet_ntoa(f->sin_addr));
+ error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0,
+ NI_NAMEREQD);
+ if (error) {
+ error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0,
+ NI_NUMERICHOST | NI_WITHSCOPEID);
+ if (error)
+ fatal(0, "Host name for your address unknown");
+ else
+ fatal(0, "Host name for your address (%s) unknown",
+ host);
+ }
- (void) strncpy(fromb, hp->h_name, sizeof(fromb) - 1);
+ (void)strncpy(fromb, host, sizeof(fromb) - 1);
fromb[sizeof(fromb) - 1] = '\0';
from = fromb;
- strncpy(from_ip, inet_ntoa(f->sin_addr), MAXIPSTRLEN);
+
+ /* Need address in stringform for comparison (no DNS lookup here) */
+ error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0,
+ NI_NUMERICHOST | NI_WITHSCOPEID);
+ if (error)
+ fatal(0, "Cannot print address");
+ strncpy(from_ip, host, NI_MAXHOST);
from_ip[sizeof(from_ip) - 1] = '\0';
+ /* Reject numeric addresses */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+ if (getaddrinfo(fromb, NULL, &hints, &res) == 0) {
+ freeaddrinfo(res);
+ fatal(0, "reverse lookup results in non-FQDN %s", fromb);
+ }
+
/* Check for spoof, ala rlogind */
- hp = gethostbyname(fromb);
- if (!hp)
- fatal(0, "hostname for your address (%s) unknown", from_ip);
- for (; good == 0 && hp->h_addr_list[0] != NULL; hp->h_addr_list++) {
- if (!bcmp(hp->h_addr_list[0], (caddr_t)&f->sin_addr,
- sizeof(f->sin_addr)))
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ error = getaddrinfo(fromb, NULL, &hints, &res);
+ if (error) {
+ fatal(0, "hostname for your address (%s) unknown: %s", from_ip,
+ gai_strerror(error));
+ }
+ good = 0;
+ for (r = res; good == 0 && r; r = r->ai_next) {
+ error = getnameinfo(r->ai_addr, r->ai_addrlen, ip, sizeof(ip),
+ NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID);
+ if (!error && !strcmp(from_ip, ip))
good = 1;
}
+ if (res)
+ freeaddrinfo(res);
if (good == 0)
fatal(0, "address for your hostname (%s) not matched",
from_ip);
@@ -642,8 +683,7 @@ chkhost(f)
hostf = fopen(_PATH_HOSTSEQUIV, "r");
again:
if (hostf) {
- if (__ivaliduser(hostf, f->sin_addr.s_addr,
- DUMMY, DUMMY) == 0) {
+ if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) {
(void) fclose(hostf);
return;
}
@@ -664,3 +704,86 @@ usage()
fprintf(stderr, "usage: lpd [-dlp] [port#]\n");
exit(EX_USAGE);
}
+
+/* setup server socket for specified address family */
+/* if af is PF_UNSPEC more than one socket may be returned */
+/* the returned list is dynamically allocated, so caller needs to free it */
+static int *
+socksetup(af, options)
+ int af, options;
+{
+ struct addrinfo hints, *res, *r;
+ int error, maxs, *s, *socks;
+ const int on = 1;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(NULL, "printer", &hints, &res);
+ if (error) {
+ syslog(LOG_ERR, "%s", gai_strerror(error));
+ mcleanup(0);
+ }
+
+ /* Count max number of sockets we may open */
+ for (maxs = 0, r = res; r; r = r->ai_next, maxs++)
+ ;
+ socks = malloc((maxs + 1) * sizeof(int));
+ if (!socks) {
+ syslog(LOG_ERR, "couldn't allocate memory for sockets");
+ mcleanup(0);
+ }
+
+ *socks = 0; /* num of sockets counter at start of array */
+ s = socks + 1;
+ for (r = res; r; r = r->ai_next) {
+ *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+ if (*s < 0) {
+ syslog(LOG_DEBUG, "socket(): %m");
+ continue;
+ }
+ if (options & SO_REUSEADDR)
+ if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, &on,
+ sizeof(on)) < 0) {
+ syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
+ close(*s);
+ continue;
+ }
+ if (options & SO_DEBUG)
+ if (setsockopt(*s, SOL_SOCKET, SO_DEBUG,
+ &on, sizeof(on)) < 0) {
+ syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
+ close(*s);
+ continue;
+ }
+#ifdef IPV6_BINDV6ONLY
+ if (r->ai_family == AF_INET6) {
+ if (setsockopt(*s, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+ &on, sizeof(on)) < 0) {
+ syslog(LOG_ERR,
+ "setsockopt (IPV6_BINDV6ONLY): %m");
+ close(*s);
+ continue;
+ }
+ }
+#endif
+ if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
+ syslog(LOG_DEBUG, "bind(): %m");
+ close(*s);
+ continue;
+ }
+ (*socks)++;
+ s++;
+ }
+
+ if (res)
+ freeaddrinfo(res);
+
+ if (*socks == 0) {
+ syslog(LOG_ERR, "Couldn't bind to any socket");
+ free(socks);
+ mcleanup(0);
+ }
+ return(socks);
+}
OpenPOWER on IntegriCloud