resolv.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1993-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <signal.h>
#include <string.h>
#include <sys/resource.h>
#include <errno.h>
#include <sys/systeminfo.h>
#include <netconfig.h>
#include <netdir.h>
#include "resolv_common.h"
#include "nis_proc.h"
#define YPDNSVERS 2L
#define RESOLV_EXEC_PATH "/usr/sbin/rpc.nisd_resolv"
#define RESOLV_EXEC_ERR "can't exec /usr/sbin/rpc.nisd_resolv: %s\n"
/*
* Need to protect against inadvertently starting more than one rpc.nis_resolv.
* Thus, apply this lock before checking if rpc.nisd_resolv is running,
* and hold it until setup_resolv() (if called) has completed.
*/
extern int verbose;
void
int *fwding;
int *child;
char *tp_type;
long prognum; /* use transient if this not set */
{
char *tp;
char name[257];
void *h;
if (!*fwding)
return;
/* try the specified netid (default ticots), then any loopback */
return;
}
/*
* Startup the resolv server: use transient prognum if prognum
* isn't set. Using transient means we create mapping then
* pass child the fd to use for service.
*/
endnetconfig(h);
return;
}
case -1: /* error */
endnetconfig(h);
return;
case 0: /* child */
/*
* if using transient we must maintain fd across
*
* if using transient we'll just do svc_tli_create
* in child on our bound fd.
*/
"-F", /* forground */
NULL);
/*
* vfork(2) says the forked child should call _exit(),
* not exit(), if exec() fails.
*/
_exit(1);
default: /* parent */
/* close fd, free xprt, but leave mapping */
/* let it crank up before we create client */
sleep(4);
}
endnetconfig(h);
return;
}
endnetconfig(h);
return;
}
endnetconfig(h);
/* ping for comfort */
clnt_destroy (*client);
return;
}
if (verbose)
}
int
long *prognum;
char *fd_str;
char *prog_str;
long vers;
char *tp_type;
{
int fd;
/* If prognum specified, use it instead of transient hassel. */
if (*prognum) {
return (TRUE);
}
/*
* Transient hassel:
* - parent must create mapping since someone else could
* steal the transient prognum before child created it
* - pass the child the fd to use for service
* - close the fd (after exec), free xprt, leave mapping intact
*/
/* tp_type is legit: users choice or a loopback netid */
return (FALSE);
return (FALSE);
}
start++;
return (TRUE);
}
int
char *netid;
void **handle;
{
return (FALSE);
/* XXX Shouldn't this be strcmp() == 0 ? */
return (TRUE);
}
if (save) {
return (TRUE);
} else {
return (FALSE);
}
}
int
int *fwding;
int *pid;
char *tp;
char *map;
{
struct ypfwdreq_key4 fwd_req4;
struct ypfwdreq_key6 fwd_req6;
char *cp;
int i;
struct sockaddr_in *sin4;
struct sockaddr_in6 *sin6;
int savepid;
if (!*fwding)
return (FALSE);
/* default status is YP_NOKEY */
return (FALSE);
}
/*
* In order to tell if we have an IPv4 or IPv6 caller address,
* we must know that nb->buf is a (sockaddr_in *) or a
* (sockaddr_in6 *). Hence, we might as well dispense with the
* conversion to uaddr and parsing of same that this section
* of the code previously involved itself in.
*/
if (nb != 0)
sizeof (in6));
} else {
return (FALSE);
}
/* Restart resolver if it died. (possible overkill) */
/*
* Since we may end up restarting rpc.nisd_resolv, acquire the
* lock.
*/
"Restarting resolv server: old one (pid %d) died.\n", *pid);
clnt_destroy (*client);
if (!*fwding) {
"can't restart resolver: ending resolv service.\n");
return (FALSE);
}
}
/*
* Save pid of rpc.nisd_resolv, so that we can tell if another
* thread performed a restart while we weren't holding the lock.
*/
/* may need to up timeout */
} else {
}
return (TRUE);
else { /* Over kill error recovery */
/*
* If the pid of rpc.nisd_resolv has changed, another thread
* has already attempted a restart, and there's little point
* in our doing the same. Just repeat the clnt_call().
*/
/*
* make one attempt to restart service before turning
* off
*/
"Restarting resolv server: old one not responding.\n");
clnt_destroy (*client);
0l /* transient p# */);
if (!*fwding) {
"resolv_req(setup_resolv)");
"can't restart resolver: ending resolv service.\n");
return (FALSE);
}
}
} else {
}
return (TRUE);
else {
/* no more restarts */
clnt_destroy (*client);
"restarted resolver not responding: ending resolv service.\n");
return (FALSE);
}
}
}