ypxfrd_main.c revision 62989
116125Swpaul/* 216125Swpaul * Copyright (c) 1995, 1996 316125Swpaul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 416125Swpaul * 516125Swpaul * Redistribution and use in source and binary forms, with or without 616125Swpaul * modification, are permitted provided that the following conditions 716125Swpaul * are met: 816125Swpaul * 1. Redistributions of source code must retain the above copyright 916125Swpaul * notice, this list of conditions and the following disclaimer. 1016125Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1116125Swpaul * notice, this list of conditions and the following disclaimer in the 1216125Swpaul * documentation and/or other materials provided with the distribution. 1316125Swpaul * 3. All advertising materials mentioning features or use of this software 1416125Swpaul * must display the following acknowledgement: 1516125Swpaul * This product includes software developed by Bill Paul. 1616125Swpaul * 4. Neither the name of the author nor the names of any co-contributors 1716125Swpaul * may be used to endorse or promote products derived from this software 1816125Swpaul * without specific prior written permission. 1916125Swpaul * 2016125Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2116125Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2216125Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2316125Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 2416125Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2516125Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2616125Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2716125Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2816125Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2916125Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3016125Swpaul * SUCH DAMAGE. 3116125Swpaul */ 3216125Swpaul 3330378Scharnier#ifndef lint 3430378Scharnierstatic const char rcsid[] = 3550479Speter "$FreeBSD: head/usr.sbin/rpc.ypxfrd/ypxfrd_main.c 62989 2000-07-12 00:50:49Z kris $"; 3630378Scharnier#endif /* not lint */ 3730378Scharnier 3816125Swpaul#include "ypxfrd.h" 3930378Scharnier#include <err.h> 4030378Scharnier#include <fcntl.h> 4116125Swpaul#include <stdio.h> 4216125Swpaul#include <stdlib.h> /* getenv, exit */ 4323716Speter#include <unistd.h> 4416125Swpaul#include <rpc/pmap_clnt.h> /* for pmap_unset */ 4516125Swpaul#include <string.h> /* strcmp */ 4616125Swpaul#include <signal.h> 4716125Swpaul#include <sys/ttycom.h> /* TIOCNOTTY */ 4816125Swpaul#ifdef __cplusplus 4916125Swpaul#include <sysent.h> /* getdtablesize, open */ 5016125Swpaul#endif /* __cplusplus */ 5116125Swpaul#include <memory.h> 5216125Swpaul#include <sys/socket.h> 5316125Swpaul#include <netinet/in.h> 5416125Swpaul#include <syslog.h> 5516125Swpaul#include "ypxfrd_extern.h" 5616125Swpaul#include <sys/wait.h> 5716125Swpaul#include <errno.h> 5816125Swpaul 5916125Swpaul#ifndef SIG_PF 6016125Swpaul#define SIG_PF void(*)(int) 6116125Swpaul#endif 6216125Swpaul 6316125Swpaul#ifdef DEBUG 6416125Swpaul#define RPC_SVC_FG 6516125Swpaul#endif 6616125Swpaul 6716125Swpaul#define _RPCSVC_CLOSEDOWN 120 6816125Swpaulint _rpcpmstart; /* Started by a port monitor ? */ 6916125Swpaulstatic int _rpcfdtype; 7016125Swpaul /* Whether Stream or Datagram ? */ 7116125Swpaul /* States a server can be in wrt request */ 7216125Swpaul 7316125Swpaul#define _IDLE 0 7416125Swpaul#define _SERVED 1 7516125Swpaul#define _SERVING 2 7616125Swpaul 7716125Swpaulextern int _rpcsvcstate; /* Set when a request is serviced */ 7816125Swpaul 7916125Swpaulchar *progname = "rpc.ypxfrd"; 8016125Swpaulchar *yp_dir = "/var/yp/"; 8116125Swpaul 8216125Swpaulstatic 8316125Swpaulvoid _msgout(char* msg) 8416125Swpaul{ 8516125Swpaul#ifdef RPC_SVC_FG 8616125Swpaul if (_rpcpmstart) 8762989Skris syslog(LOG_ERR, "%s", msg); 8816125Swpaul else 8930378Scharnier warnx("%s", msg); 9016125Swpaul#else 9162989Skris syslog(LOG_ERR, "%s", msg); 9216125Swpaul#endif 9316125Swpaul} 9416125Swpaul 9516125Swpaulstatic void 9616125Swpaulclosedown(int sig) 9716125Swpaul{ 9816125Swpaul if (_rpcsvcstate == _IDLE) { 9916125Swpaul extern fd_set svc_fdset; 10016125Swpaul static int size; 10116125Swpaul int i, openfd; 10216125Swpaul 10316125Swpaul if (_rpcfdtype == SOCK_DGRAM) 10416125Swpaul exit(0); 10516125Swpaul if (size == 0) { 10616125Swpaul size = getdtablesize(); 10716125Swpaul } 10816125Swpaul for (i = 0, openfd = 0; i < size && openfd < 2; i++) 10916125Swpaul if (FD_ISSET(i, &svc_fdset)) 11016125Swpaul openfd++; 11116125Swpaul if (openfd <= 1) 11216125Swpaul exit(0); 11316125Swpaul } 11416125Swpaul if (_rpcsvcstate == _SERVED) 11516125Swpaul _rpcsvcstate = _IDLE; 11616125Swpaul 11716125Swpaul (void) signal(SIGALRM, (SIG_PF) closedown); 11816125Swpaul (void) alarm(_RPCSVC_CLOSEDOWN/2); 11916125Swpaul} 12016125Swpaul 12116125Swpaul 12216125Swpaulstatic void 12316125Swpaulypxfrd_svc_run() 12416125Swpaul{ 12516125Swpaul#ifdef FD_SETSIZE 12616125Swpaul fd_set readfds; 12716125Swpaul#else 12816125Swpaul int readfds; 12916125Swpaul#endif /* def FD_SETSIZE */ 13016125Swpaul extern int forked; 13116125Swpaul int pid; 13216125Swpaul int fd_setsize = _rpc_dtablesize(); 13316125Swpaul 13416125Swpaul /* Establish the identity of the parent ypserv process. */ 13516125Swpaul pid = getpid(); 13616125Swpaul 13716125Swpaul for (;;) { 13816125Swpaul#ifdef FD_SETSIZE 13916125Swpaul readfds = svc_fdset; 14016125Swpaul#else 14116125Swpaul readfds = svc_fds; 14216125Swpaul#endif /* def FD_SETSIZE */ 14316125Swpaul switch (select(fd_setsize, &readfds, NULL, NULL, 14416125Swpaul (struct timeval *)0)) { 14516125Swpaul case -1: 14616125Swpaul if (errno == EINTR) { 14716125Swpaul continue; 14816125Swpaul } 14930378Scharnier warn("svc_run: - select failed"); 15016125Swpaul return; 15116125Swpaul case 0: 15216125Swpaul continue; 15316125Swpaul default: 15416125Swpaul svc_getreqset(&readfds); 15516125Swpaul if (forked && pid != getpid()) 15616125Swpaul exit(0); 15716125Swpaul } 15816125Swpaul } 15916125Swpaul} 16016125Swpaul 16116125Swpaulstatic void reaper(sig) 16216125Swpaul int sig; 16316125Swpaul{ 16436642Swpaul int status; 16536642Swpaul int saved_errno; 16616125Swpaul 16736642Swpaul saved_errno = errno; 16836642Swpaul 16916125Swpaul if (sig == SIGHUP) { 17016125Swpaul load_securenets(); 17136642Swpaul errno = saved_errno; 17216125Swpaul return; 17316125Swpaul } 17416125Swpaul 17516125Swpaul if (sig == SIGCHLD) { 17616125Swpaul while (wait3(&status, WNOHANG, NULL) > 0) 17716125Swpaul children--; 17816125Swpaul } else { 17916125Swpaul (void) pmap_unset(YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS); 18016125Swpaul exit(0); 18116125Swpaul } 18236642Swpaul 18336642Swpaul errno = saved_errno; 18436642Swpaul return; 18516125Swpaul} 18616125Swpaul 18716125Swpaulvoid usage() 18816125Swpaul{ 18930378Scharnier fprintf(stderr, "usage: rpc.ypxfrd [-p path]\n"); 19016125Swpaul exit(0); 19116125Swpaul} 19216125Swpaul 19330378Scharnierint 19416125Swpaulmain(argc, argv) 19516125Swpaul int argc; 19616125Swpaul char *argv[]; 19716125Swpaul{ 19830378Scharnier register SVCXPRT *transp = NULL; 19916125Swpaul int sock; 20030378Scharnier int proto = 0; 20116125Swpaul struct sockaddr_in saddr; 20216125Swpaul int asize = sizeof (saddr); 20316125Swpaul int ch; 20416125Swpaul 20524428Simp while ((ch = getopt(argc, argv, "p:h")) != -1) { 20616125Swpaul switch(ch) { 20716125Swpaul case 'p': 20816125Swpaul yp_dir = optarg; 20916125Swpaul break; 21016125Swpaul default: 21116125Swpaul usage(); 21216125Swpaul break; 21316125Swpaul } 21416125Swpaul } 21516125Swpaul 21616125Swpaul load_securenets(); 21716125Swpaul 21816125Swpaul if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) { 21916125Swpaul int ssize = sizeof (int); 22016125Swpaul 22116125Swpaul if (saddr.sin_family != AF_INET) 22216125Swpaul exit(1); 22316125Swpaul if (getsockopt(0, SOL_SOCKET, SO_TYPE, 22416125Swpaul (char *)&_rpcfdtype, &ssize) == -1) 22516125Swpaul exit(1); 22616125Swpaul sock = 0; 22716125Swpaul _rpcpmstart = 1; 22816125Swpaul proto = 0; 22916125Swpaul openlog("rpc.ypxfrd", LOG_PID, LOG_DAEMON); 23016125Swpaul } else { 23116125Swpaul#ifndef RPC_SVC_FG 23216125Swpaul int size; 23316125Swpaul int pid, i; 23416125Swpaul 23516125Swpaul pid = fork(); 23630378Scharnier if (pid < 0) 23730378Scharnier err(1, "fork"); 23816125Swpaul if (pid) 23916125Swpaul exit(0); 24016125Swpaul size = getdtablesize(); 24116125Swpaul for (i = 0; i < size; i++) 24216125Swpaul (void) close(i); 24316125Swpaul i = open("/dev/console", 2); 24416125Swpaul (void) dup2(i, 1); 24516125Swpaul (void) dup2(i, 2); 24616125Swpaul i = open("/dev/tty", 2); 24716125Swpaul if (i >= 0) { 24816125Swpaul (void) ioctl(i, TIOCNOTTY, (char *)NULL); 24916125Swpaul (void) close(i); 25016125Swpaul } 25116125Swpaul openlog("rpc.ypxfrd", LOG_PID, LOG_DAEMON); 25216125Swpaul#endif 25316125Swpaul sock = RPC_ANYSOCK; 25416125Swpaul (void) pmap_unset(YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS); 25516125Swpaul } 25616125Swpaul 25716125Swpaul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) { 25816125Swpaul transp = svcudp_create(sock); 25916125Swpaul if (transp == NULL) { 26016125Swpaul _msgout("cannot create udp service."); 26116125Swpaul exit(1); 26216125Swpaul } 26316125Swpaul if (!_rpcpmstart) 26416125Swpaul proto = IPPROTO_UDP; 26516125Swpaul if (!svc_register(transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, ypxfrd_freebsd_prog_1, proto)) { 26616125Swpaul _msgout("unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, udp)."); 26716125Swpaul exit(1); 26816125Swpaul } 26916125Swpaul } 27016125Swpaul 27116125Swpaul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { 27216125Swpaul transp = svctcp_create(sock, 0, 0); 27316125Swpaul if (transp == NULL) { 27416125Swpaul _msgout("cannot create tcp service."); 27516125Swpaul exit(1); 27616125Swpaul } 27716125Swpaul if (!_rpcpmstart) 27816125Swpaul proto = IPPROTO_TCP; 27916125Swpaul if (!svc_register(transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, ypxfrd_freebsd_prog_1, proto)) { 28016125Swpaul _msgout("unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, tcp)."); 28116125Swpaul exit(1); 28216125Swpaul } 28316125Swpaul } 28416125Swpaul 28516125Swpaul if (transp == (SVCXPRT *)NULL) { 28616125Swpaul _msgout("could not create a handle"); 28716125Swpaul exit(1); 28816125Swpaul } 28916125Swpaul if (_rpcpmstart) { 29016125Swpaul (void) signal(SIGALRM, (SIG_PF) closedown); 29116125Swpaul (void) alarm(_RPCSVC_CLOSEDOWN/2); 29216125Swpaul } 29316125Swpaul 29416125Swpaul (void) signal(SIGPIPE, SIG_IGN); 29516125Swpaul (void) signal(SIGCHLD, (SIG_PF) reaper); 29616125Swpaul (void) signal(SIGTERM, (SIG_PF) reaper); 29716125Swpaul (void) signal(SIGINT, (SIG_PF) reaper); 29816125Swpaul (void) signal(SIGHUP, (SIG_PF) reaper); 29916125Swpaul 30016125Swpaul ypxfrd_svc_run(); 30116125Swpaul _msgout("svc_run returned"); 30216125Swpaul exit(1); 30316125Swpaul /* NOTREACHED */ 30416125Swpaul} 305