ypupdated_main.c revision 90298
126236Swpaul/* 226236Swpaul * Copyright (c) 1995, 1996 326236Swpaul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 426236Swpaul * 526236Swpaul * Redistribution and use in source and binary forms, with or without 626236Swpaul * modification, are permitted provided that the following conditions 726236Swpaul * are met: 826236Swpaul * 1. Redistributions of source code must retain the above copyright 926236Swpaul * notice, this list of conditions and the following disclaimer. 1026236Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1126236Swpaul * notice, this list of conditions and the following disclaimer in the 1226236Swpaul * documentation and/or other materials provided with the distribution. 1326236Swpaul * 3. All advertising materials mentioning features or use of this software 1426236Swpaul * must display the following acknowledgement: 1526236Swpaul * This product includes software developed by Bill Paul. 1626236Swpaul * 4. Neither the name of the author nor the names of any co-contributors 1726236Swpaul * may be used to endorse or promote products derived from this software 1826236Swpaul * without specific prior written permission. 1926236Swpaul * 2026236Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2126236Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2226236Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2326236Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 2426236Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2526236Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2626236Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2726236Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2826236Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2926236Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3026236Swpaul * SUCH DAMAGE. 3126236Swpaul */ 3226236Swpaul 3330378Scharnier#ifndef lint 3430378Scharnierstatic const char rcsid[] = 3550479Speter "$FreeBSD: head/usr.sbin/rpc.ypupdated/ypupdated_main.c 90298 2002-02-06 15:26:07Z des $"; 3630378Scharnier#endif /* not lint */ 3730378Scharnier 3826236Swpaul#include "ypupdate_prot.h" 3926236Swpaul#include <stdio.h> 4026236Swpaul#include <stdlib.h> /* getenv, exit */ 4126236Swpaul#include <rpc/pmap_clnt.h> /* for pmap_unset */ 4226236Swpaul#include <string.h> /* strcmp */ 4326236Swpaul#include <signal.h> 4426236Swpaul#ifdef __cplusplus 4526236Swpaul#include <sysent.h> /* getdtablesize, open */ 4626236Swpaul#endif /* __cplusplus */ 4726236Swpaul#include <memory.h> 4826236Swpaul#include <sys/socket.h> 4926236Swpaul#include <netinet/in.h> 5026236Swpaul#include <syslog.h> 5126236Swpaul#include <sys/wait.h> 5226236Swpaul#include <errno.h> 5326236Swpaul#include <err.h> 5426236Swpaul#include <stdlib.h> 5526236Swpaul#include <unistd.h> 5626236Swpaul#include "ypupdated_extern.h" 5726236Swpaul#include "yp_extern.h" 5826236Swpaul 5926236Swpaul#ifndef SIG_PF 6026236Swpaul#define SIG_PF void(*)(int) 6126236Swpaul#endif 6226236Swpaul 6326236Swpaul#ifdef DEBUG 6426236Swpaul#define RPC_SVC_FG 6526236Swpaul#endif 6626236Swpaul 6726236Swpaul#define _RPCSVC_CLOSEDOWN 120 6826236Swpaulint _rpcpmstart; /* Started by a port monitor ? */ 6926236Swpaulstatic int _rpcfdtype; 7026236Swpaul /* Whether Stream or Datagram ? */ 7126236Swpaul /* States a server can be in wrt request */ 7226236Swpaul 7326236Swpaul#define _IDLE 0 7426236Swpaul#define _SERVED 1 7526236Swpaul#define _SERVING 2 7626236Swpaul 7726236Swpaulextern int _rpcsvcstate; /* Set when a request is serviced */ 7826236Swpaul 7926236Swpaulchar *progname = "rpc.ypupdated"; 8026236Swpaulchar *yp_dir = "/var/yp/"; 8126236Swpaul 8290298Sdesstatic void 8390298Sdes_msgout(char* msg) 8426236Swpaul{ 8526236Swpaul#ifdef RPC_SVC_FG 8626236Swpaul if (_rpcpmstart) 8762989Skris syslog(LOG_ERR, "%s", msg); 8826236Swpaul else 8930378Scharnier warnx("%s", msg); 9026236Swpaul#else 9162989Skris syslog(LOG_ERR, "%s", msg); 9226236Swpaul#endif 9326236Swpaul} 9426236Swpaul 9526236Swpaulstatic void 9626236Swpaulclosedown(int sig) 9726236Swpaul{ 9826236Swpaul if (_rpcsvcstate == _IDLE) { 9926236Swpaul extern fd_set svc_fdset; 10026236Swpaul static int size; 10126236Swpaul int i, openfd; 10226236Swpaul 10326236Swpaul if (_rpcfdtype == SOCK_DGRAM) 10426236Swpaul exit(0); 10526236Swpaul if (size == 0) { 10626236Swpaul size = getdtablesize(); 10726236Swpaul } 10826236Swpaul for (i = 0, openfd = 0; i < size && openfd < 2; i++) 10926236Swpaul if (FD_ISSET(i, &svc_fdset)) 11026236Swpaul openfd++; 11126236Swpaul if (openfd <= 1) 11226236Swpaul exit(0); 11326236Swpaul } 11426236Swpaul if (_rpcsvcstate == _SERVED) 11526236Swpaul _rpcsvcstate = _IDLE; 11626236Swpaul 11726236Swpaul (void) signal(SIGALRM, (SIG_PF) closedown); 11826236Swpaul (void) alarm(_RPCSVC_CLOSEDOWN/2); 11926236Swpaul} 12026236Swpaul 12126236Swpaulstatic void 12290298Sdesypupdated_svc_run(void) 12326236Swpaul{ 12426236Swpaul#ifdef FD_SETSIZE 12526236Swpaul fd_set readfds; 12626236Swpaul#else 12726236Swpaul int readfds; 12826236Swpaul#endif /* def FD_SETSIZE */ 12926236Swpaul extern int forked; 13026236Swpaul int pid; 13126236Swpaul int fd_setsize = _rpc_dtablesize(); 13226236Swpaul 13326236Swpaul /* Establish the identity of the parent ypupdated process. */ 13426236Swpaul pid = getpid(); 13526236Swpaul 13626236Swpaul for (;;) { 13726236Swpaul#ifdef FD_SETSIZE 13826236Swpaul readfds = svc_fdset; 13926236Swpaul#else 14026236Swpaul readfds = svc_fds; 14126236Swpaul#endif /* def FD_SETSIZE */ 14226236Swpaul switch (select(fd_setsize, &readfds, NULL, NULL, 14326236Swpaul (struct timeval *)0)) { 14426236Swpaul case -1: 14526236Swpaul if (errno == EINTR) { 14626236Swpaul continue; 14726236Swpaul } 14830378Scharnier warn("svc_run: - select failed"); 14926236Swpaul return; 15026236Swpaul case 0: 15126236Swpaul continue; 15226236Swpaul default: 15326236Swpaul svc_getreqset(&readfds); 15426236Swpaul if (forked && pid != getpid()) 15526236Swpaul exit(0); 15626236Swpaul } 15726236Swpaul } 15826236Swpaul} 15926236Swpaul 16090298Sdesstatic void 16190298Sdesreaper(int sig) 16226236Swpaul{ 16326236Swpaul int status; 16426236Swpaul 16526236Swpaul if (sig == SIGHUP) { 16626236Swpaul#ifdef foo 16726236Swpaul load_securenets(); 16826236Swpaul#endif 16926236Swpaul return; 17026236Swpaul } 17126236Swpaul 17226236Swpaul if (sig == SIGCHLD) { 17326236Swpaul while (wait3(&status, WNOHANG, NULL) > 0) 17426236Swpaul children--; 17526236Swpaul } else { 17626236Swpaul (void) pmap_unset(YPU_PROG, YPU_VERS); 17726236Swpaul exit(0); 17826236Swpaul } 17926236Swpaul} 18026236Swpaul 18190298Sdesvoid 18290298Sdesusage(void) 18326236Swpaul{ 18430378Scharnier fprintf(stderr, "rpc.ypupdatedd [-p path]\n"); 18526236Swpaul exit(0); 18626236Swpaul} 18726236Swpaul 18830378Scharnierint 18990298Sdesmain(int argc, char *argv[]) 19026236Swpaul{ 19126236Swpaul register SVCXPRT *transp = NULL; 19226236Swpaul int sock; 19326236Swpaul int proto = 0; 19426236Swpaul struct sockaddr_in saddr; 19526236Swpaul int asize = sizeof (saddr); 19626236Swpaul int ch; 19726236Swpaul 19847442Simp while ((ch = getopt(argc, argv, "p:h")) != -1) { 19990297Sdes switch (ch) { 20026236Swpaul case 'p': 20126236Swpaul yp_dir = optarg; 20226236Swpaul break; 20326236Swpaul default: 20426236Swpaul usage(); 20526236Swpaul break; 20626236Swpaul } 20726236Swpaul } 20826236Swpaul#ifdef foo 20926236Swpaul load_securenets(); 21026236Swpaul#endif 21126236Swpaul 21226236Swpaul if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) { 21326236Swpaul yp_error("failed to register AUTH_DES flavor"); 21426236Swpaul exit(1); 21526236Swpaul } 21626236Swpaul 21726236Swpaul if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) { 21826236Swpaul int ssize = sizeof (int); 21926236Swpaul 22026236Swpaul if (saddr.sin_family != AF_INET) 22126236Swpaul exit(1); 22226236Swpaul if (getsockopt(0, SOL_SOCKET, SO_TYPE, 22326236Swpaul (char *)&_rpcfdtype, &ssize) == -1) 22426236Swpaul exit(1); 22526236Swpaul sock = 0; 22626236Swpaul _rpcpmstart = 1; 22726236Swpaul proto = 0; 22826236Swpaul openlog("rpc.ypupdatedd", LOG_PID, LOG_DAEMON); 22926236Swpaul } else { 23026236Swpaul#ifndef RPC_SVC_FG 23126236Swpaul if (daemon(0,0)) { 23226236Swpaul err(1, "cannot fork"); 23326236Swpaul } 23426236Swpaul openlog("rpc.ypupdated", LOG_PID, LOG_DAEMON); 23526236Swpaul#endif 23626236Swpaul sock = RPC_ANYSOCK; 23726236Swpaul (void) pmap_unset(YPU_PROG, YPU_VERS); 23826236Swpaul } 23926236Swpaul 24026236Swpaul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) { 24126236Swpaul transp = svcudp_create(sock); 24226236Swpaul if (transp == NULL) { 24326236Swpaul _msgout("cannot create udp service."); 24426236Swpaul exit(1); 24526236Swpaul } 24626236Swpaul if (!_rpcpmstart) 24726236Swpaul proto = IPPROTO_UDP; 24826236Swpaul if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { 24926236Swpaul _msgout("unable to register (YPU_PROG, YPU_VERS, udp)."); 25026236Swpaul exit(1); 25126236Swpaul } 25226236Swpaul } 25326236Swpaul 25426236Swpaul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { 25526236Swpaul transp = svctcp_create(sock, 0, 0); 25626236Swpaul if (transp == NULL) { 25726236Swpaul _msgout("cannot create tcp service."); 25826236Swpaul exit(1); 25926236Swpaul } 26026236Swpaul if (!_rpcpmstart) 26126236Swpaul proto = IPPROTO_TCP; 26226236Swpaul if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { 26326236Swpaul _msgout("unable to register (YPU_PROG, YPU_VERS, tcp)."); 26426236Swpaul exit(1); 26526236Swpaul } 26626236Swpaul } 26726236Swpaul 26826236Swpaul if (transp == (SVCXPRT *)NULL) { 26926236Swpaul _msgout("could not create a handle"); 27026236Swpaul exit(1); 27126236Swpaul } 27226236Swpaul if (_rpcpmstart) { 27326236Swpaul (void) signal(SIGALRM, (SIG_PF) closedown); 27426236Swpaul (void) alarm(_RPCSVC_CLOSEDOWN/2); 27526236Swpaul } 27626236Swpaul 27726236Swpaul (void) signal(SIGPIPE, SIG_IGN); 27826236Swpaul (void) signal(SIGCHLD, (SIG_PF) reaper); 27926236Swpaul (void) signal(SIGTERM, (SIG_PF) reaper); 28026236Swpaul (void) signal(SIGINT, (SIG_PF) reaper); 28126236Swpaul (void) signal(SIGHUP, (SIG_PF) reaper); 28226236Swpaul 28326236Swpaul ypupdated_svc_run(); 28426236Swpaul _msgout("svc_run returned"); 28526236Swpaul exit(1); 28626236Swpaul /* NOTREACHED */ 28726236Swpaul} 288