ypserv/ypserv-2.11-iface-binding3.patch

840 lines
21 KiB
Diff
Raw Normal View History

--- ypserv-2.11/ypserv/ypserv.8.in.iface 2003-01-17 22:57:35.000000000 +0100
+++ ypserv-2.11/ypserv/ypserv.8.in 2004-01-19 16:23:11.464352153 +0100
@@ -12,6 +12,9 @@
[
.B \-p port
]
+[
+.B \-i iface
+]
.LP
.SH DESCRIPTION
.IX "ypserv" "" "\fLypserv\fP \(em NIS server process"
@@ -59,12 +62,23 @@
reports only errors (access violations, dbm failures)
using the syslog(3) facility. In debug mode, the server does not
background itself and prints extra status messages to stderr for
-each request that it revceives.
+each request that it receives.
.B path
is an optionally parameter.
.B ypserv
is using this directory instead of @YPMAPDIR@
.TP
+.B "\-i" "--iface" "iface"
+Causes the server to only be available via interface
+.B iface
+Use this if you want ypserv to only provide service on a
+particular network interface.
+.B iface
+is a required parameter
+.B ypserv
+will be using that interface instead of all the available
+network interfaces.
+.TP
.B "\-p" "--port" port
.B ypserv
will bind itself to this port.
--- ypserv-2.11/ypserv/ypserv.c.iface 2003-11-24 11:26:53.000000000 +0100
+++ ypserv-2.11/ypserv/ypserv.c 2004-01-19 17:02:25.354924063 +0100
@@ -33,11 +33,15 @@
#include <getopt.h>
#endif
#include <sys/file.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
+#include <linux/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
2006-02-13 16:28:41 +00:00
#if defined(HAVE_RPC_SVC_SOC_H)
#include <rpc/svc_soc.h> /* for svcudp_create() */
#endif /* HAVE_RPC_SVC_SOC_H */
@@ -60,6 +64,8 @@
#define YPOLDVERS 1
#endif
+struct in_addr my_iface_num = {INADDR_ANY};
+
static char *path_ypdb = YPMAPDIR;
static void
@@ -92,7 +98,25 @@
bool_t retval;
xdrproc_t _xdr_argument, _xdr_result;
bool_t (*local) (char *, void *, struct svc_req *);
+ struct sockaddr_in *rqhost;
+ struct in_addr rqnetwork;
+ if (my_iface_num.s_addr != INADDR_ANY) {
+ /*
+ * If we are suppost only listen on one interface
+ * make this request comes from that inteface
+ * otherwise ignore it.
+ */
+ rqhost = svc_getcaller (rqstp->rq_xprt);
+ rqnetwork.s_addr = inet_netof(rqhost->sin_addr);
+ if (rqnetwork.s_addr != inet_netof(my_iface_num)) {
+ if (debug_flag) {
+ log_msg("Ignoring request from %s: wrong network\n",
+ inet_ntoa(rqhost->sin_addr));
+ }
+ return;
+ }
+ }
switch (rqstp->rq_proc)
{
case YPPROC_NULL:
@@ -242,6 +266,36 @@
}
#endif
+static void
+get_inet_for_iface (char *iface, uint32_t *iface_num)
+{
+ struct ifreq ifr;
+ struct in_addr inaddr;
+ int fd;
+
+ *iface_num = INADDR_ANY;
+
+ fd = socket (AF_INET, SOCK_DGRAM, 0);
+ if(fd < 0)
+ return;
+
+ memset(&ifr, '\0', sizeof(ifr));
+ strncpy (ifr.ifr_name, iface,
+ IFNAMSIZ > strlen (iface) ? strlen (iface) : IFNAMSIZ);
+
+ if (ioctl (fd, SIOCGIFADDR, &ifr) < 0)
+ {
+ log_msg("ifr_name error: %d\n", errno);
+ close (fd);
+ return;
+ }
+ memcpy(&inaddr, &ifr.ifr_netmask.sa_data[2], sizeof(struct in_addr));
+ *iface_num = inaddr.s_addr;
+
+ close (fd);
+}
+
+
/* Create a pidfile on startup */
static void
create_pidfile (void)
@@ -390,7 +444,7 @@
static void
Usage (int exitcode)
{
- fputs ("usage: ypserv [-d [path]] [-p port]\n", stderr);
+ fputs ("usage: ypserv [-d [path]] [-p port] [-i interface]\n", stderr);
fputs (" ypserv --version\n", stderr);
exit (exitcode);
@@ -401,6 +455,7 @@
{
SVCXPRT *transp;
int my_port = -1, my_socket, result;
+ char *my_iface = NULL;
struct sockaddr_in s_in;
openlog ("ypserv", LOG_PID, LOG_DAEMON);
@@ -413,12 +468,13 @@
{"version", no_argument, NULL, 'v'},
{"debug", no_argument, NULL, 'd'},
{"port", required_argument, NULL, 'p'},
+ {"iface", required_argument, NULL, 'i'},
{"usage", no_argument, NULL, 'u'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, '\0'}
};
- c = getopt_long (argc, argv, "vdp:buh", long_options, &option_index);
2004-10-14 19:13:51 +00:00
+ c = getopt_long (argc, argv, "vdp:i:buh", long_options, &option_index);
if (c == -1)
break;
switch (c)
@@ -435,6 +491,11 @@
if (debug_flag)
log_msg ("Using port %d\n", my_port);
break;
+ case 'i':
+ my_iface = optarg;
+ if (debug_flag)
+ log_msg ("Using interface %s\n", my_iface);
+ break;
case 'u':
case 'h':
Usage (0);
@@ -533,6 +594,11 @@
pmap_unset (YPPROG, YPVERS);
pmap_unset (YPPROG, YPOLDVERS);
+ if (my_iface)
+ {
+ get_inet_for_iface (my_iface, &my_iface_num.s_addr);
+ }
+
if (my_port >= 0)
{
my_socket = socket (AF_INET, SOCK_DGRAM, 0);
@@ -544,7 +610,7 @@
memset ((char *) &s_in, 0, sizeof (s_in));
s_in.sin_family = AF_INET;
- s_in.sin_addr.s_addr = htonl (INADDR_ANY);
+ s_in.sin_addr.s_addr = htonl (my_iface_num.s_addr);
s_in.sin_port = htons (my_port);
result = bind (my_socket, (struct sockaddr *) &s_in,
@@ -589,7 +655,7 @@
memset (&s_in, 0, sizeof (s_in));
s_in.sin_family = AF_INET;
- s_in.sin_addr.s_addr = htonl (INADDR_ANY);
+ s_in.sin_addr.s_addr = htonl (my_iface_num.s_addr);
s_in.sin_port = htons (my_port);
result = bind (my_socket, (struct sockaddr *) &s_in,
--- /dev/null 2003-09-15 15:40:47.000000000 +0200
+++ ypserv-2.11/ypserv/ypserv.c.iface_binding 2004-01-19 16:23:11.475350680 +0100
@@ -0,0 +1,635 @@
+/* Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Thorsten Kukuk
+ Author: Thorsten Kukuk <kukuk@suse.de>
+
+ The YP Server is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ The YP Server 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with the YP Server; see the file COPYING. If
+ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+ Cambridge, MA 02139, USA. */
+
+#define _GNU_SOURCE
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <signal.h>
+#include <getopt.h>
+#include <poll.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+#include "yp.h"
+#include "access.h"
+#include "log_msg.h"
+#include "ypserv_conf.h"
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifndef _PATH_VARRUN
+#define _PATH_VARRUN "/etc/"
+#endif
+#define _YPSERV_PIDFILE _PATH_VARRUN"ypserv.pid"
+
+#ifndef YPOLDVERS
+#define YPOLDVERS 1
+#endif
+
+volatile int children = 0;
+int forked = 0;
+
+static char *path_ypdb = YPMAPDIR;
+
+static void
+ypprog_2 (struct svc_req *rqstp, register SVCXPRT * transp)
+{
+ union {
+ domainname ypproc_domain_2_arg;
+ domainname ypproc_domain_nonack_2_arg;
+ ypreq_key ypproc_match_2_arg;
+ ypreq_nokey ypproc_first_2_arg;
+ ypreq_key ypproc_next_2_arg;
+ ypreq_xfr ypproc_xfr_2_arg;
+ ypreq_nokey ypproc_all_2_arg;
+ ypreq_nokey ypproc_master_2_arg;
+ ypreq_nokey ypproc_order_2_arg;
+ domainname ypproc_maplist_2_arg;
+ } argument;
+ union {
+ bool_t ypproc_domain_2_res;
+ bool_t ypproc_domain_nonack_2_res;
+ ypresp_val ypproc_match_2_res;
+ ypresp_key_val ypproc_first_2_res;
+ ypresp_key_val ypproc_next_2_res;
+ ypresp_xfr ypproc_xfr_2_res;
+ ypresp_all ypproc_all_2_res;
+ ypresp_master ypproc_master_2_res;
+ ypresp_order ypproc_order_2_res;
+ ypresp_maplist ypproc_maplist_2_res;
+ } result;
+ bool_t retval;
+ xdrproc_t _xdr_argument, _xdr_result;
+ bool_t (*local) (char *, void *, struct svc_req *);
+
+ switch (rqstp->rq_proc)
+ {
+ case YPPROC_NULL:
+ _xdr_argument = (xdrproc_t) xdr_void;
+ _xdr_result = (xdrproc_t) xdr_void;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_null_2_svc;
+ break;
+
+ case YPPROC_DOMAIN:
+ _xdr_argument = (xdrproc_t) xdr_domainname;
+ _xdr_result = (xdrproc_t) xdr_bool;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_domain_2_svc;
+ break;
+
+ case YPPROC_DOMAIN_NONACK:
+ _xdr_argument = (xdrproc_t) xdr_domainname;
+ _xdr_result = (xdrproc_t) xdr_bool;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *))
+ ypproc_domain_nonack_2_svc;
+ break;
+
+ case YPPROC_MATCH:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_key;
+ _xdr_result = (xdrproc_t) xdr_ypresp_val;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_match_2_svc;
+ break;
+
+ case YPPROC_FIRST:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+ _xdr_result = (xdrproc_t) xdr_ypresp_key_val;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_first_2_svc;
+ break;
+
+ case YPPROC_NEXT:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_key;
+ _xdr_result = (xdrproc_t) xdr_ypresp_key_val;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_next_2_svc;
+ break;
+
+ case YPPROC_XFR:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_xfr;
+ _xdr_result = (xdrproc_t) xdr_ypresp_xfr;
+ local = (bool_t (*)(char *, void *, struct svc_req *)) ypproc_xfr_2_svc;
+ break;
+
+ case YPPROC_CLEAR:
+ _xdr_argument = (xdrproc_t) xdr_void;
+ _xdr_result = (xdrproc_t) xdr_void;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_clear_2_svc;
+ break;
+
+ case YPPROC_ALL:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+ _xdr_result = (xdrproc_t) xdr_ypresp_all;
+ local = (bool_t (*)(char *, void *, struct svc_req *)) ypproc_all_2_svc;
+ break;
+
+ case YPPROC_MASTER:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+ _xdr_result = (xdrproc_t) xdr_ypresp_master;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_master_2_svc;
+ break;
+
+ case YPPROC_ORDER:
+ _xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+ _xdr_result = (xdrproc_t) xdr_ypresp_order;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_order_2_svc;
+ break;
+
+ case YPPROC_MAPLIST:
+ _xdr_argument = (xdrproc_t) xdr_domainname;
+ _xdr_result = (xdrproc_t) xdr_ypresp_maplist;
+ local =
+ (bool_t (*)(char *, void *, struct svc_req *)) ypproc_maplist_2_svc;
+ break;
+
+ default:
+ svcerr_noproc (transp);
+ return;
+ }
+
+ memset ((char *) &argument, 0, sizeof (argument));
+ if (!svc_getargs (transp, _xdr_argument, (caddr_t) &argument))
+ {
+ svcerr_decode (transp);
+ return;
+ }
+
+ retval = (bool_t) (*local) ((char *) &argument, (void *) &result, rqstp);
+ if (retval > 0 && !svc_sendreply (transp, _xdr_result, (char *) &result))
+ svcerr_systemerr (transp);
+
+ if (!svc_freeargs (transp, _xdr_argument, (caddr_t) &argument))
+ {
+ fprintf (stderr, "unable to free arguments");
+ exit (1);
+ }
+
+ if (!ypprog_2_freeresult (transp, _xdr_result, (caddr_t) &result))
+ fprintf (stderr, "unable to free results");
+
+ return;
+}
+
+static void
+ypserv_svc_run (void)
+{
+ int i;
+
+ for (;;)
+ {
+ struct pollfd *my_pollfd;
+
+ if (svc_max_pollfd == 0 && svc_pollfd == NULL)
+ return;
+
+ my_pollfd = malloc (sizeof (struct pollfd) * svc_max_pollfd);
+ for (i = 0; i < svc_max_pollfd; ++i)
+ {
+ my_pollfd[i].fd = svc_pollfd[i].fd;
+ my_pollfd[i].events = svc_pollfd[i].events;
+ my_pollfd[i].revents = 0;
+ }
+
+ switch (i = poll (my_pollfd, svc_max_pollfd, -1))
+ {
+ case -1:
+ free (my_pollfd);
+ if (errno == EINTR)
+ continue;
+ syslog (LOG_ERR, "svc_run: - poll failed: %m");
+ return;
+ case 0:
+ free (my_pollfd);
+ continue;
+ default:
+ svc_getreq_poll (my_pollfd, i);
+ free (my_pollfd);
+ if (forked)
+ _exit (0);
+ }
+ }
+}
+
+
+/* Create a pidfile on startup */
+static void
+create_pidfile (void)
+{
+ int fd, left, written, flags;
+ pid_t pid;
+ char pbuf[10], *ptr;
+ struct flock lock;
+
+ fd = open (_YPSERV_PIDFILE, O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0)
+ {
+ log_msg ("cannot create pidfile %s", _YPSERV_PIDFILE);
+ if (debug_flag)
+ log_msg ("\n");
+ }
+
+ /* Make sure file gets correctly closed when process finished. */
+ flags = fcntl (fd, F_GETFD, 0);
+ if (flags == -1)
+ {
+ /* Cannot get file flags. */
+ close (fd);
+ return;
+ }
+ flags |= FD_CLOEXEC; /* Close on exit. */
+ if (fcntl (fd, F_SETFD, flags) < 0)
+ {
+ /* Cannot set new flags. */
+ close (fd);
+ return;
+ }
+
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+
+ /* Is the pidfile locked by another ypserv ? */
+ if (fcntl (fd, F_GETLK, &lock) < 0)
+ {
+ log_msg ("fcntl error");
+ if (debug_flag)
+ log_msg ("\n");
+ }
+ if (lock.l_type == F_UNLCK)
+ pid = 0; /* false, not locked by another proc */
+ else
+ pid = lock.l_pid; /* true, return pid of lock owner */
+
+ if (0 != pid)
+ {
+ log_msg ("ypserv already running (pid %d) - exiting", pid);
+ if (debug_flag)
+ log_msg ("\n");
+ exit (1);
+ }
+
+ /* write lock */
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+ if (0 != fcntl (fd, F_SETLK, &lock))
+ log_msg ("cannot lock pidfile");
+ sprintf (pbuf, "%ld\n", (long) getpid ());
+ left = strlen (pbuf);
+ ptr = pbuf;
+ while (left > 0)
+ {
+ if ((written = write (fd, ptr, left)) <= 0)
+ return; /* error */
+ left -= written;
+ ptr += written;
+ }
+
+ return;
+}
+
+/* Clean up if we quit the program. */
+static void
+sig_quit (int sig __attribute__ ((unused)))
+{
+ pmap_unset (YPPROG, YPVERS);
+ pmap_unset (YPPROG, YPOLDVERS);
+ unlink (_YPSERV_PIDFILE);
+
+ exit (0);
+}
+
+/* Reload securenets and config file */
+static void
+sig_hup (int sig __attribute__ ((unused)))
+{
+ int old_cached_filehandles = cached_filehandles;
+
+ load_securenets ();
+ load_config ();
+ /* Don't allow to decrease the number of max. cached files with
+ SIGHUP. */
+ if (cached_filehandles < old_cached_filehandles)
+ cached_filehandles = old_cached_filehandles;
+}
+
+/* Clean up after child processes signal their termination. */
+static void
+sig_child (int sig)
+{
+ int st;
+ pid_t pid;
+
+ if (debug_flag)
+ log_msg ("sig_child: got signal %i", sig);
+
+
+ /* Clear all childs */
+ while ((pid = waitpid (-1, &st, WNOHANG)) > 0)
+ {
+ if (debug_flag)
+ log_msg ("pid=%d", pid);
+ --children;
+ }
+
+ if (children < 0)
+ log_msg ("children is lower 0 (%i)!", children);
+ else if (debug_flag)
+ log_msg ("children = %i", children);
+}
+
+
+static void
+Usage (int exitcode)
+{
+ fputs ("usage: ypserv [-d [path]] [-p port]\n", stderr);
+ fputs (" ypserv --version\n", stderr);
+
+ exit (exitcode);
+}
+
+int
+main (int argc, char **argv)
+{
+ SVCXPRT *transp;
+ int my_port = -1, my_socket, result;
+ struct sockaddr_in s_in;
+ struct sigaction sa;
+
+ openlog ("ypserv", LOG_PID, LOG_DAEMON);
+
+ while (1)
+ {
+ int c;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"version", no_argument, NULL, 'v'},
+ {"debug", no_argument, NULL, 'd'},
+ {"port", required_argument, NULL, 'p'},
+ {"usage", no_argument, NULL, 'u'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, '\0'}
+ };
+
+ c = getopt_long (argc, argv, "vdp:buh", long_options, &option_index);
+ if (c == -1)
+ break;
+ switch (c)
+ {
+ case 'v':
+ debug_flag = 1;
+ log_msg ("ypserv (%s) %s\n", PACKAGE, VERSION);
+ return 0;
+ case 'd':
+ ++debug_flag;
+ break;
+ case 'p':
+ my_port = atoi (optarg);
+ if (debug_flag)
+ log_msg ("Using port %d\n", my_port);
+ break;
+ case 'u':
+ case 'h':
+ Usage (0);
+ break;
+ default:
+ Usage (1);
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (debug_flag)
+ log_msg ("[ypserv (%s) %s]\n", PACKAGE, VERSION);
+ else
+ {
+ int i;
+
+ if ((i = fork ()) > 0)
+ exit (0);
+
+ if (i < 0)
+ {
+ log_msg ("Cannot fork: %s\n", strerror (errno));
+ exit (-1);
+ }
+
+ if (setsid () == -1)
+ {
+ log_msg ("Cannot setsid: %s\n", strerror (errno));
+ exit (-1);
+ }
+
+ if ((i = fork ()) > 0)
+ exit (0);
+
+ if (i < 0)
+ {
+ log_msg ("Cannot fork: %s\n", strerror (errno));
+ exit (-1);
+ }
+
+ for (i = 0; i < getdtablesize (); ++i)
+ close (i);
+ errno = 0;
+
+ umask (0);
+ i = open ("/dev/null", O_RDWR);
+ dup (i);
+ dup (i);
+ }
+
+ if (argc > 0 && debug_flag)
+ {
+ path_ypdb = argv[0];
+ log_msg ("Using database directory: %s\n", path_ypdb);
+ }
+
+ /* Change current directory to database location */
+ if (chdir (path_ypdb) < 0)
+ {
+ log_msg ("ypserv: chdir: %s", strerror (errno));
+ exit (1);
+ }
+
+ create_pidfile ();
+
+ load_securenets ();
+ load_config ();
+
+ /*
+ * Ignore SIGPIPEs. They can hurt us if someone does a ypcat
+ * and then hits CTRL-C before it terminates.
+ */
+ sigaction (SIGPIPE, NULL, &sa);
+ sa.sa_handler = SIG_IGN;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGPIPE, &sa, NULL);
+ /*
+ * If program quits, give ports free.
+ */
+ sigaction (SIGTERM, NULL, &sa);
+ sa.sa_handler = sig_quit;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGTERM, &sa, NULL);
+
+ sigaction (SIGINT, NULL, &sa);
+ sa.sa_handler = sig_quit;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGINT, &sa, NULL);
+
+ /*
+ * If we get a SIGHUP, reload the securenets and config file.
+ */
+ sigaction (SIGHUP, NULL, &sa);
+ sa.sa_handler = sig_hup;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGHUP, &sa, NULL);
+
+ /*
+ * On SIGCHLD wait for the child process, so it can give free all
+ * resources.
+ */
+ sigaction (SIGCHLD, NULL, &sa);
+ sa.sa_handler = sig_child;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGCHLD, &sa, NULL);
+
+ pmap_unset (YPPROG, YPVERS);
+ pmap_unset (YPPROG, YPOLDVERS);
+
+ if (my_port >= 0)
+ {
+ my_socket = socket (AF_INET, SOCK_DGRAM, 0);
+ if (my_socket < 0)
+ {
+ log_msg ("can not create UDP: %s", strerror (errno));
+ exit (1);
+ }
+
+ memset ((char *) &s_in, 0, sizeof (s_in));
+ s_in.sin_family = AF_INET;
+ s_in.sin_addr.s_addr = htonl (INADDR_ANY);
+ s_in.sin_port = htons (my_port);
+
+ result = bind (my_socket, (struct sockaddr *) &s_in,
+ sizeof (s_in));
+ if (result < 0)
+ {
+ log_msg ("ypserv: can not bind UDP: %s ", strerror (errno));
+ exit (1);
+ }
+ }
+ else
+ my_socket = RPC_ANYSOCK;
+
+ transp = svcudp_create (my_socket);
+ if (transp == NULL)
+ {
+ log_msg ("cannot create udp service.");
+ exit (1);
+ }
+
+ if (!svc_register (transp, YPPROG, YPVERS, ypprog_2, IPPROTO_UDP))
+ {
+ log_msg ("unable to register (YPPROG, YPVERS, udp).");
+ exit (1);
+ }
+
+ /* XXX ypprog_2 should be ypprog_1 */
+ if (!svc_register (transp, YPPROG, YPOLDVERS, ypprog_2, IPPROTO_UDP))
+ {
+ log_msg ("unable to register (YPPROG, YPOLDVERS, udp).");
+ exit (1);
+ }
+
+ if (my_port >= 0)
+ {
+ my_socket = socket (AF_INET, SOCK_STREAM, 0);
+ if (my_socket < 0)
+ {
+ log_msg ("ypserv: can not create TCP: %s", strerror (errno));
+ exit (1);
+ }
+
+ memset (&s_in, 0, sizeof (s_in));
+ s_in.sin_family = AF_INET;
+ s_in.sin_addr.s_addr = htonl (INADDR_ANY);
+ s_in.sin_port = htons (my_port);
+
+ result = bind (my_socket, (struct sockaddr *) &s_in,
+ sizeof (s_in));
+ if (result < 0)
+ {
+ log_msg ("ypserv: can not bind TCP ", strerror (errno));
+ exit (1);
+ }
+ }
+ else
+ my_socket = RPC_ANYSOCK;
+
+ transp = svctcp_create (my_socket, 0, 0);
+ if (transp == NULL)
+ {
+ log_msg ("ypserv: cannot create tcp service\n");
+ exit (1);
+ }
+
+ if (!svc_register (transp, YPPROG, YPVERS, ypprog_2, IPPROTO_TCP))
+ {
+ log_msg ("ypserv: unable to register (YPPROG, YPVERS, tcp)\n");
+ exit (1);
+ }
+
+ /* XXX ypprog_2 should be ypprog_1 */
+ if (!svc_register (transp, YPPROG, YPOLDVERS, ypprog_2, IPPROTO_TCP))
+ {
+ log_msg ("ypserv: unable to register (YPPROG, YPOLDVERS, tcp)\n");
+ exit (1);
+ }
+
+ ypserv_svc_run ();
+ log_msg ("svc_run returned");
+ unlink (_YPSERV_PIDFILE);
+ exit (1);
+ /* NOTREACHED */
+}