lockd.c revision 173281
174462Salfred/* $NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $ */ 274462Salfred/* $FreeBSD: head/usr.sbin/rpc.lockd/lockd.c 173281 2007-11-02 14:51:53Z matteo $ */ 374462Salfred 414123Speter/* 514123Speter * Copyright (c) 1995 614123Speter * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved. 714123Speter * 814123Speter * Redistribution and use in source and binary forms, with or without 914123Speter * modification, are permitted provided that the following conditions 1014123Speter * are met: 1114123Speter * 1. Redistributions of source code must retain the above copyright 1214123Speter * notice, this list of conditions and the following disclaimer. 1314123Speter * 2. Redistributions in binary form must reproduce the above copyright 1414123Speter * notice, this list of conditions and the following disclaimer in the 1514123Speter * documentation and/or other materials provided with the distribution. 1614123Speter * 3. All advertising materials mentioning features or use of this software 1714123Speter * must display the following acknowledgement: 1814123Speter * This product includes software developed for the FreeBSD project 1914123Speter * 4. Neither the name of the author nor the names of any co-contributors 2014123Speter * may be used to endorse or promote products derived from this software 2114123Speter * without specific prior written permission. 2214123Speter * 2314123Speter * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND 2414123Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2514123Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2614123Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2714123Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2814123Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2914123Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3014123Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3114123Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3214123Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3314123Speter * SUCH DAMAGE. 3414123Speter * 3514123Speter */ 3614123Speter 3774462Salfred#include <sys/cdefs.h> 3830376Scharnier#ifndef lint 3974462Salfred__RCSID("$NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $"); 4074462Salfred#endif 4114123Speter 4274462Salfred/* 4374462Salfred * main() function for NFS lock daemon. Most of the code in this 4474462Salfred * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x. 4574462Salfred * 4674462Salfred * The actual program logic is in the file lock_proc.c 4774462Salfred */ 4814123Speter 4974462Salfred#include <sys/types.h> 5074462Salfred#include <sys/socket.h> 5174462Salfred 52173281Smatteo#include <netinet/in.h> 53173281Smatteo#include <arpa/inet.h> 54173281Smatteo 5530376Scharnier#include <err.h> 5674462Salfred#include <stdio.h> 5730376Scharnier#include <stdlib.h> 5874462Salfred#include <errno.h> 5974462Salfred#include <syslog.h> 6074462Salfred#include <signal.h> 6130376Scharnier#include <string.h> 6274462Salfred#include <unistd.h> 6374462Salfred#include <libutil.h> 6474462Salfred#include <netconfig.h> 65173281Smatteo#include <netdb.h> 6674462Salfred 6730376Scharnier#include <rpc/rpc.h> 68109363Smbr#include <rpc/rpc_com.h> 6974462Salfred#include <rpcsvc/sm_inter.h> 7074462Salfred 7114123Speter#include "lockd.h" 7274462Salfred#include <rpcsvc/nlm_prot.h> 7314123Speter 7474462Salfredint debug_level = 0; /* 0 = no debugging syslog() calls */ 7574462Salfredint _rpcsvcdirty = 0; 7614123Speter 7774462Salfredint grace_expired; 7875631Salfredint nsm_state; 7975631Salfredpid_t client_pid; 8075631Salfredstruct mon mon_host; 81173281Smatteochar **hosts, *svcport_str = NULL; 82173281Smatteoint nhosts = 0; 83173281Smatteoint xcreated = 0; 8414123Speter 85173281Smatteovoid create_service(struct netconfig *nconf); 8675631Salfredvoid init_nsm(void); 8792909Salfredvoid nlm_prog_0(struct svc_req *, SVCXPRT *); 8892909Salfredvoid nlm_prog_1(struct svc_req *, SVCXPRT *); 8992909Salfredvoid nlm_prog_3(struct svc_req *, SVCXPRT *); 9092909Salfredvoid nlm_prog_4(struct svc_req *, SVCXPRT *); 91173281Smatteovoid out_of_mem(void); 9292909Salfredvoid usage(void); 9374462Salfred 9492909Salfredvoid sigalarm_handler(void); 9574462Salfred 9630376Scharnierint 97173281Smatteomain(int argc, char **argv) 9814123Speter{ 99173281Smatteo int ch, i, s; 100173281Smatteo void *nc_handle; 101173281Smatteo char *endptr, **hosts_bak; 10287096Salfred struct sigaction sigalarm; 10374462Salfred int grace_period = 30; 10474462Salfred struct netconfig *nconf; 105173281Smatteo int have_v6 = 1; 106109363Smbr int maxrec = RPC_MAXDATASIZE; 107168324Smatteo in_port_t svcport = 0; 10814123Speter 109173281Smatteo while ((ch = getopt(argc, argv, "d:g:h:p:")) != (-1)) { 11074462Salfred switch (ch) { 11174462Salfred case 'd': 11274462Salfred debug_level = atoi(optarg); 11374462Salfred if (!debug_level) { 11474462Salfred usage(); 11574462Salfred /* NOTREACHED */ 11674462Salfred } 11774462Salfred break; 11874462Salfred case 'g': 11974462Salfred grace_period = atoi(optarg); 12074462Salfred if (!grace_period) { 12174462Salfred usage(); 12274462Salfred /* NOTREACHED */ 12374462Salfred } 12474462Salfred break; 125173281Smatteo case 'h': 126173281Smatteo ++nhosts; 127173281Smatteo hosts_bak = hosts; 128173281Smatteo hosts_bak = realloc(hosts, nhosts * sizeof(char *)); 129173281Smatteo if (hosts_bak == NULL) { 130173281Smatteo if (hosts != NULL) { 131173281Smatteo for (i = 0; i < nhosts; i++) 132173281Smatteo free(hosts[i]); 133173281Smatteo free(hosts); 134173281Smatteo out_of_mem(); 135173281Smatteo } 136173281Smatteo } 137173281Smatteo hosts = hosts_bak; 138173281Smatteo hosts[nhosts - 1] = strdup(optarg); 139173281Smatteo if (hosts[nhosts - 1] == NULL) { 140173281Smatteo for (i = 0; i < (nhosts - 1); i++) 141173281Smatteo free(hosts[i]); 142173281Smatteo free(hosts); 143173281Smatteo out_of_mem(); 144173281Smatteo } 145173281Smatteo break; 146168324Smatteo case 'p': 147168324Smatteo endptr = NULL; 148168324Smatteo svcport = (in_port_t)strtoul(optarg, &endptr, 10); 149168324Smatteo if (endptr == NULL || *endptr != '\0' || 150168324Smatteo svcport == 0 || svcport >= IPPORT_MAX) 151168324Smatteo usage(); 152173281Smatteo svcport_str = strdup(optarg); 153168324Smatteo break; 15474462Salfred default: 15574462Salfred case '?': 15674462Salfred usage(); 15774462Salfred /* NOTREACHED */ 15874462Salfred } 15974462Salfred } 16074462Salfred if (geteuid()) { /* This command allowed only to root */ 16174462Salfred fprintf(stderr, "Sorry. You are not superuser\n"); 16274462Salfred exit(1); 16374462Salfred } 16414123Speter 16574462Salfred (void)rpcb_unset(NLM_PROG, NLM_SM, NULL); 16674462Salfred (void)rpcb_unset(NLM_PROG, NLM_VERS, NULL); 16774462Salfred (void)rpcb_unset(NLM_PROG, NLM_VERSX, NULL); 16874462Salfred (void)rpcb_unset(NLM_PROG, NLM_VERS4, NULL); 16914123Speter 17074462Salfred /* 17174462Salfred * Check if IPv6 support is present. 17274462Salfred */ 17374462Salfred s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 17474462Salfred if (s < 0) 175173281Smatteo have_v6 = 0; 176173281Smatteo else 17774462Salfred close(s); 17814123Speter 179173281Smatteo rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); 180168324Smatteo 181173281Smatteo /* 182173281Smatteo * If no hosts were specified, add a wildcard entry to bind to 183173281Smatteo * INADDR_ANY. Otherwise make sure 127.0.0.1 and ::1 are added to the 184173281Smatteo * list. 185173281Smatteo */ 186173281Smatteo if (nhosts == 0) { 187173281Smatteo hosts = malloc(sizeof(char**)); 188173281Smatteo if (hosts == NULL) 189173281Smatteo out_of_mem(); 190168324Smatteo 191173281Smatteo hosts[0] = "*"; 192173281Smatteo nhosts = 1; 193173281Smatteo } else { 194173281Smatteo hosts_bak = hosts; 195173281Smatteo if (have_v6) { 196173281Smatteo hosts_bak = realloc(hosts, (nhosts + 2) * 197173281Smatteo sizeof(char *)); 198173281Smatteo if (hosts_bak == NULL) { 199173281Smatteo for (i = 0; i < nhosts; i++) 200173281Smatteo free(hosts[i]); 201173281Smatteo free(hosts); 202173281Smatteo out_of_mem(); 203173281Smatteo } else 204173281Smatteo hosts = hosts_bak; 205109363Smbr 206173281Smatteo nhosts += 2; 207173281Smatteo hosts[nhosts - 2] = "::1"; 208173281Smatteo } else { 209173281Smatteo hosts_bak = realloc(hosts, (nhosts + 1) * sizeof(char *)); 210173281Smatteo if (hosts_bak == NULL) { 211173281Smatteo for (i = 0; i < nhosts; i++) 212173281Smatteo free(hosts[i]); 21314123Speter 214173281Smatteo free(hosts); 215173281Smatteo out_of_mem(); 216173281Smatteo } else { 217173281Smatteo nhosts += 1; 218173281Smatteo hosts = hosts_bak; 219168324Smatteo } 220168324Smatteo } 221173281Smatteo hosts[nhosts - 1] = "127.0.0.1"; 222173281Smatteo } 223168324Smatteo 224173281Smatteo nc_handle = setnetconfig(); 225173281Smatteo while ((nconf = getnetconfig(nc_handle))) { 226173281Smatteo /* We want to listen only on udp6, tcp6, udp, tcp transports */ 227173281Smatteo if (nconf->nc_flag & NC_VISIBLE) { 228173281Smatteo /* Skip if there's no IPv6 support */ 229173281Smatteo if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 230173281Smatteo /* DO NOTHING */ 231173281Smatteo } else { 232173281Smatteo create_service(nconf); 233173281Smatteo } 23474462Salfred } 23574462Salfred } 236173281Smatteo endnetconfig(nc_handle); 23714123Speter 23874462Salfred /* 23974462Salfred * Note that it is NOT sensible to run this program from inetd - the 24074462Salfred * protocol assumes that it will run immediately at boot time. 24174462Salfred */ 242132254Smr if (daemon(0, debug_level > 0)) { 24374462Salfred err(1, "cannot fork"); 24474462Salfred /* NOTREACHED */ 24574462Salfred } 24674462Salfred 24774462Salfred openlog("rpc.lockd", 0, LOG_DAEMON); 24874462Salfred if (debug_level) 24974462Salfred syslog(LOG_INFO, "Starting, debug level %d", debug_level); 25074462Salfred else 25174462Salfred syslog(LOG_INFO, "Starting"); 25274462Salfred 25386319Salfred sigalarm.sa_handler = (sig_t) sigalarm_handler; 25474462Salfred sigemptyset(&sigalarm.sa_mask); 25574462Salfred sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */ 25674462Salfred sigalarm.sa_flags |= SA_RESTART; 25774462Salfred if (sigaction(SIGALRM, &sigalarm, NULL) != 0) { 25874462Salfred syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s", 25974462Salfred strerror(errno)); 26074462Salfred exit(1); 26174462Salfred } 26274462Salfred grace_expired = 0; 263161552Sthomas alarm(grace_period); 26474462Salfred 26575631Salfred init_nsm(); 26675631Salfred 26775631Salfred client_pid = client_request(); 26875631Salfred 26974462Salfred svc_run(); /* Should never return */ 27074462Salfred exit(1); 27114123Speter} 27230376Scharnier 273173281Smatteo/* 274173281Smatteo * This routine creates and binds sockets on the appropriate 275173281Smatteo * addresses. It gets called one time for each transport and 276173281Smatteo * registrates the service with rpcbind on that trasport. 277173281Smatteo */ 27874462Salfredvoid 279173281Smatteocreate_service(struct netconfig *nconf) 280173281Smatteo{ 281173281Smatteo struct addrinfo hints, *res = NULL; 282173281Smatteo struct sockaddr_in *sin; 283173281Smatteo struct sockaddr_in6 *sin6; 284173281Smatteo struct __rpc_sockinfo si; 285173281Smatteo struct netbuf servaddr; 286173281Smatteo SVCXPRT *transp = NULL; 287173281Smatteo int aicode; 288173281Smatteo int fd; 289173281Smatteo int nhostsbak; 290173281Smatteo int r; 291173281Smatteo int registered = 0; 292173281Smatteo u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 293173281Smatteo 294173281Smatteo if ((nconf->nc_semantics != NC_TPI_CLTS) && 295173281Smatteo (nconf->nc_semantics != NC_TPI_COTS) && 296173281Smatteo (nconf->nc_semantics != NC_TPI_COTS_ORD)) 297173281Smatteo return; /* not my type */ 298173281Smatteo 299173281Smatteo /* 300173281Smatteo * XXX - using RPC library internal functions. 301173281Smatteo */ 302173281Smatteo if (!__rpc_nconf2sockinfo(nconf, &si)) { 303173281Smatteo syslog(LOG_ERR, "cannot get information for %s", 304173281Smatteo nconf->nc_netid); 305173281Smatteo return; 306173281Smatteo } 307173281Smatteo 308173281Smatteo /* Get rpc.statd's address on this transport */ 309173281Smatteo memset(&hints, 0, sizeof hints); 310173281Smatteo hints.ai_flags = AI_PASSIVE; 311173281Smatteo hints.ai_family = si.si_af; 312173281Smatteo hints.ai_socktype = si.si_socktype; 313173281Smatteo hints.ai_protocol = si.si_proto; 314173281Smatteo 315173281Smatteo /* 316173281Smatteo * Bind to specific IPs if asked to 317173281Smatteo */ 318173281Smatteo nhostsbak = nhosts; 319173281Smatteo while (nhostsbak > 0) { 320173281Smatteo --nhostsbak; 321173281Smatteo 322173281Smatteo /* 323173281Smatteo * XXX - using RPC library internal functions. 324173281Smatteo */ 325173281Smatteo if ((fd = __rpc_nconf2fd(nconf)) < 0) { 326173281Smatteo syslog(LOG_ERR, "cannot create socket for %s", 327173281Smatteo nconf->nc_netid); 328173281Smatteo continue; 329173281Smatteo } 330173281Smatteo 331173281Smatteo switch (hints.ai_family) { 332173281Smatteo case AF_INET: 333173281Smatteo if (inet_pton(AF_INET, hosts[nhostsbak], 334173281Smatteo host_addr) == 1) { 335173281Smatteo hints.ai_flags &= AI_NUMERICHOST; 336173281Smatteo } else { 337173281Smatteo /* 338173281Smatteo * Skip if we have an AF_INET6 address. 339173281Smatteo */ 340173281Smatteo if (inet_pton(AF_INET6, hosts[nhostsbak], 341173281Smatteo host_addr) == 1) { 342173281Smatteo close(fd); 343173281Smatteo continue; 344173281Smatteo } 345173281Smatteo } 346173281Smatteo break; 347173281Smatteo case AF_INET6: 348173281Smatteo if (inet_pton(AF_INET6, hosts[nhostsbak], 349173281Smatteo host_addr) == 1) { 350173281Smatteo hints.ai_flags &= AI_NUMERICHOST; 351173281Smatteo } else { 352173281Smatteo /* 353173281Smatteo * Skip if we have an AF_INET address. 354173281Smatteo */ 355173281Smatteo if (inet_pton(AF_INET, hosts[nhostsbak], 356173281Smatteo host_addr) == 1) { 357173281Smatteo close(fd); 358173281Smatteo continue; 359173281Smatteo } 360173281Smatteo } 361173281Smatteo break; 362173281Smatteo default: 363173281Smatteo break; 364173281Smatteo } 365173281Smatteo 366173281Smatteo /* 367173281Smatteo * If no hosts were specified, just bind to INADDR_ANY 368173281Smatteo */ 369173281Smatteo if (strcmp("*", hosts[nhostsbak]) == 0) { 370173281Smatteo if (svcport_str == NULL) { 371173281Smatteo res = malloc(sizeof(struct addrinfo)); 372173281Smatteo if (res == NULL) 373173281Smatteo out_of_mem(); 374173281Smatteo res->ai_flags = hints.ai_flags; 375173281Smatteo res->ai_family = hints.ai_family; 376173281Smatteo res->ai_protocol = hints.ai_protocol; 377173281Smatteo switch (res->ai_family) { 378173281Smatteo case AF_INET: 379173281Smatteo sin = malloc(sizeof(struct sockaddr_in)); 380173281Smatteo if (sin == NULL) 381173281Smatteo out_of_mem(); 382173281Smatteo sin->sin_family = AF_INET; 383173281Smatteo sin->sin_port = htons(0); 384173281Smatteo sin->sin_addr.s_addr = htonl(INADDR_ANY); 385173281Smatteo res->ai_addr = (struct sockaddr*) sin; 386173281Smatteo res->ai_addrlen = (socklen_t) 387173281Smatteo sizeof(res->ai_addr); 388173281Smatteo break; 389173281Smatteo case AF_INET6: 390173281Smatteo sin6 = malloc(sizeof(struct sockaddr_in6)); 391173281Smatteo if (res->ai_addr == NULL) 392173281Smatteo out_of_mem(); 393173281Smatteo sin6->sin6_family = AF_INET6; 394173281Smatteo sin6->sin6_port = htons(0); 395173281Smatteo sin6->sin6_addr = in6addr_any; 396173281Smatteo res->ai_addr = (struct sockaddr*) sin6; 397173281Smatteo res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 398173281Smatteo break; 399173281Smatteo default: 400173281Smatteo break; 401173281Smatteo } 402173281Smatteo } else { 403173281Smatteo if ((aicode = getaddrinfo(NULL, svcport_str, 404173281Smatteo &hints, &res)) != 0) { 405173281Smatteo syslog(LOG_ERR, 406173281Smatteo "cannot get local address for %s: %s", 407173281Smatteo nconf->nc_netid, 408173281Smatteo gai_strerror(aicode)); 409173281Smatteo continue; 410173281Smatteo } 411173281Smatteo } 412173281Smatteo } else { 413173281Smatteo if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 414173281Smatteo &hints, &res)) != 0) { 415173281Smatteo syslog(LOG_ERR, 416173281Smatteo "cannot get local address for %s: %s", 417173281Smatteo nconf->nc_netid, gai_strerror(aicode)); 418173281Smatteo continue; 419173281Smatteo } 420173281Smatteo } 421173281Smatteo 422173281Smatteo r = bindresvport_sa(fd, res->ai_addr); 423173281Smatteo if (r != 0) { 424173281Smatteo syslog(LOG_ERR, "bindresvport_sa: %m"); 425173281Smatteo exit(1); 426173281Smatteo } 427173281Smatteo 428173281Smatteo transp = svc_tli_create(fd, nconf, NULL, 429173281Smatteo RPC_MAXDATASIZE, RPC_MAXDATASIZE); 430173281Smatteo 431173281Smatteo if (transp != (SVCXPRT *) NULL) { 432173281Smatteo if (!svc_reg(transp, NLM_PROG, NLM_SM, nlm_prog_0, 433173281Smatteo NULL)) 434173281Smatteo syslog(LOG_ERR, 435173281Smatteo "can't register %s NLM_PROG, NLM_SM service", 436173281Smatteo nconf->nc_netid); 437173281Smatteo 438173281Smatteo if (!svc_reg(transp, NLM_PROG, NLM_VERS, nlm_prog_1, 439173281Smatteo NULL)) 440173281Smatteo syslog(LOG_ERR, 441173281Smatteo "can't register %s NLM_PROG, NLM_VERS service", 442173281Smatteo nconf->nc_netid); 443173281Smatteo 444173281Smatteo if (!svc_reg(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, 445173281Smatteo NULL)) 446173281Smatteo syslog(LOG_ERR, 447173281Smatteo "can't register %s NLM_PROG, NLM_VERSX service", 448173281Smatteo nconf->nc_netid); 449173281Smatteo 450173281Smatteo if (!svc_reg(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, 451173281Smatteo NULL)) 452173281Smatteo syslog(LOG_ERR, 453173281Smatteo "can't register %s NLM_PROG, NLM_VERS4 service", 454173281Smatteo nconf->nc_netid); 455173281Smatteo 456173281Smatteo } else 457173281Smatteo syslog(LOG_WARNING, "can't create %s services", 458173281Smatteo nconf->nc_netid); 459173281Smatteo 460173281Smatteo if (registered == 0) { 461173281Smatteo registered = 1; 462173281Smatteo memset(&hints, 0, sizeof hints); 463173281Smatteo hints.ai_flags = AI_PASSIVE; 464173281Smatteo hints.ai_family = si.si_af; 465173281Smatteo hints.ai_socktype = si.si_socktype; 466173281Smatteo hints.ai_protocol = si.si_proto; 467173281Smatteo 468173281Smatteo if (svcport_str == NULL) { 469173281Smatteo svcport_str = malloc(NI_MAXSERV * sizeof(char)); 470173281Smatteo if (svcport_str == NULL) 471173281Smatteo out_of_mem(); 472173281Smatteo 473173281Smatteo if (getnameinfo(res->ai_addr, 474173281Smatteo res->ai_addr->sa_len, NULL, NI_MAXHOST, 475173281Smatteo svcport_str, NI_MAXSERV * sizeof(char), 476173281Smatteo NI_NUMERICHOST | NI_NUMERICSERV)) 477173281Smatteo errx(1, "Cannot get port number"); 478173281Smatteo } 479173281Smatteo 480173281Smatteo if((aicode = getaddrinfo(NULL, svcport_str, &hints, 481173281Smatteo &res)) != 0) { 482173281Smatteo syslog(LOG_ERR, "cannot get local address: %s", 483173281Smatteo gai_strerror(aicode)); 484173281Smatteo exit(1); 485173281Smatteo } 486173281Smatteo 487173281Smatteo servaddr.buf = malloc(res->ai_addrlen); 488173281Smatteo memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen); 489173281Smatteo servaddr.len = res->ai_addrlen; 490173281Smatteo 491173281Smatteo rpcb_set(NLM_PROG, NLM_SM, nconf, &servaddr); 492173281Smatteo rpcb_set(NLM_PROG, NLM_VERS, nconf, &servaddr); 493173281Smatteo rpcb_set(NLM_PROG, NLM_VERSX, nconf, &servaddr); 494173281Smatteo rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr); 495173281Smatteo 496173281Smatteo xcreated++; 497173281Smatteo freeaddrinfo(res); 498173281Smatteo } 499173281Smatteo } /* end while */ 500173281Smatteo} 501173281Smatteo 502173281Smatteovoid 50386319Salfredsigalarm_handler(void) 50474462Salfred{ 50586319Salfred 50674462Salfred grace_expired = 1; 50774462Salfred} 50874462Salfred 50974462Salfredvoid 51030376Scharnierusage() 51130376Scharnier{ 512168324Smatteo errx(1, "usage: rpc.lockd [-d <debuglevel>]" 513173281Smatteo " [-g <grace period>] [-h <bindip>] [-p <port>]"); 51430376Scharnier} 51575631Salfred 51675631Salfred/* 51775631Salfred * init_nsm -- 51875631Salfred * Reset the NSM state-of-the-world and acquire its state. 51975631Salfred */ 52075631Salfredvoid 52175631Salfredinit_nsm(void) 52275631Salfred{ 52375631Salfred enum clnt_stat ret; 52475631Salfred my_id id; 52575631Salfred sm_stat stat; 52692978Salfred char name[] = "NFS NLM"; 52792978Salfred char localhost[] = "localhost"; 52875631Salfred 52975631Salfred /* 53075631Salfred * !!! 53175631Salfred * The my_id structure isn't used by the SM_UNMON_ALL call, as far 53275631Salfred * as I know. Leave it empty for now. 53375631Salfred */ 53475631Salfred memset(&id, 0, sizeof(id)); 53592978Salfred id.my_name = name; 53675631Salfred 53775631Salfred /* 53875631Salfred * !!! 53975631Salfred * The statd program must already be registered when lockd runs. 54075631Salfred */ 54175631Salfred do { 54275631Salfred ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, 543121558Speter (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat); 54475631Salfred if (ret == RPC_PROGUNAVAIL) { 545113971Sghelmer syslog(LOG_WARNING, "%lu %s", SM_PROG, 546113971Sghelmer clnt_sperrno(ret)); 54775631Salfred sleep(2); 54875631Salfred continue; 54975631Salfred } 55075631Salfred break; 55175631Salfred } while (0); 55275631Salfred 55375631Salfred if (ret != 0) { 554113971Sghelmer syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); 555113971Sghelmer exit(1); 55675631Salfred } 55775631Salfred 55875631Salfred nsm_state = stat.state; 55975631Salfred 56075631Salfred /* setup constant data for SM_MON calls */ 56192978Salfred mon_host.mon_id.my_id.my_name = localhost; 56275631Salfred mon_host.mon_id.my_id.my_prog = NLM_PROG; 56375631Salfred mon_host.mon_id.my_id.my_vers = NLM_SM; 56475631Salfred mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY; /* bsdi addition */ 56575631Salfred} 566173281Smatteo 567173281Smatteo/* 568173281Smatteo * Out of memory, fatal 569173281Smatteo */ 570173281Smatteovoid out_of_mem() 571173281Smatteo{ 572173281Smatteo syslog(LOG_ERR, "out of memory"); 573173281Smatteo exit(2); 574173281Smatteo} 575