1
/* Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2005 Thorsten Kukuk
2
Author: Thorsten Kukuk <kukuk@suse.de>
4
The YP Server is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
version 2 as published by the Free Software Foundation.
8
The YP Server is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
General Public License for more details.
13
You should have received a copy of the GNU General Public
14
License along with the YP Server; see the file COPYING. If
15
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
16
Cambridge, MA 02139, USA. */
18
/* ypxfrd - ypxfrd main routines. */
36
#include <sys/syslog.h>
40
#include <sys/socket.h>
41
#include <sys/types.h>
44
#ifdef HAVE_RPC_SVC_SOC_H
45
#include <rpc/svc_soc.h>
46
#endif /* HAVE_RPC_SVC_SOC_H */
47
#include <rpc/pmap_clnt.h>
50
#endif /* HAVE_GETOPT_H */
53
#include "ypserv_conf.h"
62
extern void ypxfrd_freebsd_prog_1(struct svc_req *, SVCXPRT *);
68
#ifndef _RPCSVC_CLOSEDOWN
69
#define _RPCSVC_CLOSEDOWN 120
73
#define YPMAPDIR "/var/yp"
75
char *path_ypdb = YPMAPDIR;
80
** Needed, if we start rpc.ypxfrd from inetd
85
signal(sig, closedown);
86
if (_rpcsvcdirty == 0)
91
if (_rpcfdtype == SOCK_DGRAM)
94
size = _rpc_dtablesize();
96
for (i = 0, openfd = 0; i < size && openfd < 2; ++i)
97
if (FD_ISSET(i, &svc_fdset))
102
alarm(_RPCSVC_CLOSEDOWN);
105
/* Clean up after child processes signal their termination. */
107
sig_child (int sig UNUSED)
109
int save_errno = errno;
111
while (wait3 (NULL, WNOHANG, NULL) > 0)
116
/* Clean up if we quit the program. */
118
sig_quit (int sig UNUSED)
120
pmap_unset (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS);
125
** Reload securenets and config file
128
sig_hup (int sig UNUSED)
132
/* we don't wish to cache the file handles. */
133
cached_filehandles = 0;
139
fputs ("usage: rpc.ypxfrd [--debug] [-d path] [-p port]\n", stderr);
140
fputs (" rpc.ypxfrd --version\n", stderr);
146
main (int argc, char **argv)
148
SVCXPRT *main_transp;
151
struct sockaddr_in socket_address;
156
#else /* not __hpux */
157
socklen_t socket_size;
160
progname = strrchr (argv[0], '/');
161
if (progname == (char *) NULL)
166
openlog(progname, LOG_PID, LOG_DAEMON);
171
int option_index = 0;
172
static struct option long_options[] =
174
{"version", no_argument, NULL, '\255'},
175
{"debug", no_argument, NULL, '\254'},
176
{"port", required_argument, NULL, 'p'},
177
{"path", required_argument, NULL, 'd'},
178
{"dir", required_argument, NULL, 'd'},
179
{"usage", no_argument, NULL, 'u'},
180
{"help", no_argument, NULL, 'h'},
181
{NULL, 0, NULL, '\0'}
184
c=getopt_long(argc, argv, "p:d:uh",long_options, &option_index);
190
log_msg("rpc.ypxfrd (%s) %s\n", PACKAGE, VERSION);
198
log_msg("Using database directory: %s\n", path_ypdb);
201
my_port = atoi(optarg);
203
log_msg("Using port %d\n", my_port);
219
log_msg("[Welcome to the rpc.ypxfrd Daemon, version %s]\n", VERSION);
225
if ((i = fork()) > 0)
230
log_msg ("Cannot fork: %s\n", strerror (errno));
236
log_msg ("Cannot setsid: %s\n", strerror (errno));
240
if ((i = fork()) > 0)
245
log_msg ("Cannot fork: %s\n", strerror (errno));
249
for (i = 0; i < getdtablesize(); ++i)
254
i = open("/dev/null", O_RDWR);
259
/* Change current directory to database location */
260
if (chdir(path_ypdb) < 0)
262
log_msg("%s: chdir: %", argv[0], strerror(errno));
268
/* we don't wish to cache the file handles. */
269
cached_filehandles = 0;
272
* Ignore SIGPIPEs. They can hurt us if someone does a ypcat
273
* and then hits CTRL-C before it terminates.
275
sigaction(SIGPIPE, NULL, &sa);
276
sa.sa_handler = SIG_IGN;
277
#if !defined(sun) || (defined(sun) && defined(__svr4__))
278
sa.sa_flags |= SA_RESTART;
280
* The opposite to SA_ONESHOT, do not restore
281
* the signal action. This provides behavior
282
* compatible with BSD signal semantics.
285
sigemptyset(&sa.sa_mask);
286
sigaction(SIGPIPE, &sa, NULL);
288
* Clear up if child exists
290
sigaction(SIGCHLD, NULL, &sa);
291
#if !defined(sun) || (defined(sun) && defined(__svr4__))
292
sa.sa_flags |= SA_RESTART;
294
sa.sa_handler = sig_child;
295
sigemptyset(&sa.sa_mask);
296
sigaction(SIGCHLD, &sa, NULL);
298
* If program quits, give ports free.
300
sigaction(SIGTERM, NULL, &sa);
301
#if !defined(sun) || (defined(sun) && defined(__svr4__))
302
sa.sa_flags |= SA_RESTART;
304
sa.sa_handler = sig_quit;
305
sigemptyset(&sa.sa_mask);
306
sigaction(SIGTERM, &sa, NULL);
308
sigaction(SIGINT, NULL, &sa);
309
#if !defined(sun) || (defined(sun) && defined(__svr4__))
310
sa.sa_flags |= SA_RESTART;
312
sa.sa_handler = sig_quit;
313
sigemptyset(&sa.sa_mask);
314
sigaction(SIGINT, &sa, NULL);
317
* If we get a SIGHUP, reload the securenets and config file.
319
sigaction(SIGHUP, NULL, &sa);
320
#if !defined(sun) || (defined(sun) && defined(__svr4__))
321
sa.sa_flags |= SA_RESTART;
323
sa.sa_handler = sig_hup;
324
sigemptyset(&sa.sa_mask);
325
sigaction(SIGHUP, &sa, NULL);
327
pmap_unset(YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS);
329
socket_size = sizeof(socket_address);
331
if (getsockname(0, (struct sockaddr *)&socket_address, &socket_size) == 0)
334
int int_size = sizeof (int);
335
#else /* not __hpux */
336
socklen_t int_size = sizeof (int);
338
if (socket_address.sin_family != AF_INET)
340
if (getsockopt(0, SOL_SOCKET, SO_TYPE, (void*)&_rpcfdtype,
347
my_socket = RPC_ANYSOCK;
349
if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM))
351
if (_rpcfdtype == 0 && my_port > 0)
353
my_socket = socket (AF_INET, SOCK_DGRAM, 0);
356
log_msg("can not create UDP: %s",strerror(errno));
360
memset((char *) &socket_address, 0, sizeof(socket_address));
361
socket_address.sin_family = AF_INET;
362
socket_address.sin_addr.s_addr = htonl (INADDR_ANY);
363
socket_address.sin_port = htons (my_port);
365
result = bind (my_socket, (struct sockaddr *) &socket_address,
366
sizeof (socket_address));
369
log_msg("%s: can not bind UDP: %s ", progname,strerror(errno));
374
main_transp = svcudp_create(my_socket);
375
if (main_transp == NULL)
377
log_msg("cannot create udp service.");
380
if (!svc_register(main_transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS,
381
ypxfrd_freebsd_prog_1, IPPROTO_UDP))
383
log_msg("unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, udp).");
388
if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM))
390
if (_rpcfdtype == 0 && my_port >= 0)
392
my_socket = socket (AF_INET, SOCK_STREAM, 0);
395
log_msg ("%s: can not create TCP ",progname);
399
memset((char *) &socket_address, 0, sizeof(socket_address));
400
socket_address.sin_family = AF_INET;
401
socket_address.sin_addr.s_addr = htonl (INADDR_ANY);
402
socket_address.sin_port = htons (my_port);
404
result = bind (my_socket, (struct sockaddr *) &socket_address,
405
sizeof (socket_address));
408
log_msg("%s: can not bind TCP ",progname);
412
main_transp = svctcp_create(my_socket, 0, 0);
413
if (main_transp == NULL)
415
log_msg("%s: cannot create tcp service\n", progname);
418
if (!svc_register(main_transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS,
419
ypxfrd_freebsd_prog_1, IPPROTO_TCP))
421
log_msg("%s: unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, tcp)\n",
429
signal (SIGALRM, closedown);
430
alarm (_RPCSVC_CLOSEDOWN);
434
log_msg("svc_run returned");