diff options
author | peter <peter@FreeBSD.org> | 1996-02-17 15:14:59 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-02-17 15:14:59 +0000 |
commit | e6ac6d91b7e1f994da1f3d7d6e3b1b285c37066e (patch) | |
tree | 78f5d156646b83bd1cb711d861c4be8729e6bfd0 /sbin/rpc.statd/statd.c | |
parent | 2db8f15200d98fabce4687490a205d742173c5be (diff) | |
download | FreeBSD-src-e6ac6d91b7e1f994da1f3d7d6e3b1b285c37066e.zip FreeBSD-src-e6ac6d91b7e1f994da1f3d7d6e3b1b285c37066e.tar.gz |
Import Jan 15 version of Andrew Gordon <andrew.gordon@net-tel.co.uk>'s
rpc.statd.
This is apparently fully functional and complete.
Diffstat (limited to 'sbin/rpc.statd/statd.c')
-rw-r--r-- | sbin/rpc.statd/statd.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/sbin/rpc.statd/statd.c b/sbin/rpc.statd/statd.c new file mode 100644 index 0000000..0aaa363 --- /dev/null +++ b/sbin/rpc.statd/statd.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 1995 + * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the FreeBSD project + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + + +/* main() function for status monitor daemon. Some of the code in this */ +/* file was generated by running rpcgen /usr/include/rpcsvc/sm_inter.x */ +/* The actual program logic is in the file procs.c */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <syslog.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include "statd.h" + +#ifndef lint +static char rcsid[] = "$id: $"; +#endif /* not lint */ + +int debug = 0; /* Controls syslog() calls for debug messages */ + +static void sm_prog_1(); +static void handle_sigchld(); + +main(int argc, char **argv) +{ + SVCXPRT *transp; + struct sigaction sa; + + if (argc > 1) + { + if (strcmp(argv[1], "-d")) + { + fprintf(stderr, "Usage: rpc.statd [-d]\n"); + exit(1); + } + debug = 1; + } + + (void)pmap_unset(SM_PROG, SM_VERS); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) + { + fprintf(stderr, "cannot create udp service.\n"); + exit(1); + } + if (!svc_register(transp, SM_PROG, SM_VERS, sm_prog_1, IPPROTO_UDP)) + { + fprintf(stderr, "unable to register (SM_PROG, SM_VERS, udp).\n"); + exit(1); + } + + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL) + { + fprintf(stderr, "cannot create tcp service.\n"); + exit(1); + } + if (!svc_register(transp, SM_PROG, SM_VERS, sm_prog_1, IPPROTO_TCP)) { + fprintf(stderr, "unable to register (SM_PROG, SM_VERS, tcp).\n"); + exit(1); + } + init_file("/var/db/statd.status"); + + /* Note that it is NOT sensible to run this program from inetd - the */ + /* protocol assumes that it will run immediately at boot time. */ + daemon(0, 0); + openlog("rpc.statd", 0, LOG_DAEMON); + if (debug) syslog(LOG_INFO, "Starting - debug enabled"); + else syslog(LOG_INFO, "Starting"); + + /* Install signal handler to collect exit status of child processes */ + sa.sa_handler = handle_sigchld; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGCHLD); + sa.sa_flags = SA_RESTART; + sigaction(SIGCHLD, &sa, NULL); + + /* Initialisation now complete - start operating */ + notify_hosts(); /* Forks a process (if necessary) to do the */ + /* SM_NOTIFY calls, which may be slow. */ + + svc_run(); /* Should never return */ + exit(1); +} + + +/* handle_sigchld ---------------------------------------------------------- */ +/* + Purpose: Catch SIGCHLD and collect process status + Retruns: Nothing. + Notes: No special action required, other than to collect the + process status and hence allow the child to die: + we only use child processes for asynchronous transmission + of SM_NOTIFY to other systems, so it is normal for the + children to exit when they have done their work. +*/ + +static void handle_sigchld(int sig, int code, struct sigcontext *scp) +{ + int pid, status; + pid = wait4(-1, &status, WNOHANG, (struct rusage*)0); + if (!pid) syslog(LOG_ERR, "Phantom SIGCHLD??"); + else if (status == 0) + { + if (debug) syslog(LOG_DEBUG, "Child %d exited OK", pid); + } + else syslog(LOG_ERR, "Child %d failed with status %d", pid, + WEXITSTATUS(status)); +} + + +/* sm_prog1 ---------------------------------------------------------------- */ +/* + Purpose: Handle one RPC request + Returns: Nothing + Notes: Called from RPC libraray on receipt of a request. + Code for this function was auto-generated by rpcgen. +*/ + +static void +sm_prog_1(struct svc_req *rqstp, SVCXPRT *transp) +{ + union + { + struct sm_name sm_stat_1_arg; + struct mon sm_mon_1_arg; + struct mon_id sm_unmon_1_arg; + struct my_id sm_unmon_all_1_arg; + struct stat_chge sm_notify_1_arg; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) + { + case NULLPROC: + (void)svc_sendreply(transp, xdr_void, (char *)NULL); + return; + + case SM_STAT: + xdr_argument = xdr_sm_name; + xdr_result = xdr_sm_stat_res; + local = (char *(*)()) sm_stat_1; + break; + + case SM_MON: + xdr_argument = xdr_mon; + xdr_result = xdr_sm_stat_res; + local = (char *(*)()) sm_mon_1; + break; + + case SM_UNMON: + xdr_argument = xdr_mon_id; + xdr_result = xdr_sm_stat; + local = (char *(*)()) sm_unmon_1; + break; + + case SM_UNMON_ALL: + xdr_argument = xdr_my_id; + xdr_result = xdr_sm_stat; + local = (char *(*)()) sm_unmon_all_1; + break; + + case SM_SIMU_CRASH: + xdr_argument = xdr_void; + xdr_result = xdr_void; + local = (char *(*)()) sm_simu_crash_1; + break; + + case SM_NOTIFY: + xdr_argument = xdr_stat_chge; + xdr_result = xdr_void; + local = (char *(*)()) sm_notify_1; + break; + + default: + svcerr_noproc(transp); + return; + } + + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) + { + svcerr_decode(transp); + return; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) + { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) + { + syslog(LOG_ERR, "unable to free arguments"); + exit(1); + } +} + |