Init
This commit is contained in:
38
usr.etc/rpc.bootparamd/Makefile
Normal file
38
usr.etc/rpc.bootparamd/Makefile
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# @(#)Makefile 1.1 94/10/31 SMI
|
||||
#
|
||||
BINS= rpc.bootparamd
|
||||
OBJS= bootparam_svc.o bootparam_subr.o bootparam_lib.o
|
||||
SRCS= $(OBJS:.o=.c)
|
||||
LINTFLAGS= -bnuvx
|
||||
|
||||
CFLAGS = -O
|
||||
LIBS = -lrpcsvc
|
||||
|
||||
.KEEP_STATE:
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
$(BINS): $(OBJS)
|
||||
$(LINK.c) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
install: $(BINS)
|
||||
install -d $(DESTDIR)/usr/etc
|
||||
install -m 755 -o root $(BINS) $(DESTDIR)/usr/etc
|
||||
|
||||
clean:
|
||||
$(RM) $(BINS) $(OBJS)
|
||||
|
||||
tags: $(SRCS)
|
||||
ctags -tw $(SRCS)
|
||||
|
||||
lint: $(SRCS)
|
||||
$(LINT.c) $(SRCS)
|
||||
|
||||
ref: tags
|
||||
sed 's, /.*,,' tags | \
|
||||
awk ' { printf("%-26s%-16s%s\n", $$1, $$2, $$3) }' > $@
|
||||
|
||||
print: $(SRCS)
|
||||
r $? | $P
|
||||
touch $@
|
||||
355
usr.etc/rpc.bootparamd/bootparam_lib.c
Normal file
355
usr.etc/rpc.bootparamd/bootparam_lib.c
Normal file
@@ -0,0 +1,355 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)bootparam_lib.c 1.1 94/10/31 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Library routines of the bootparam server.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#define iseol(c) (c == '\0' || c == '\n' || c == '#')
|
||||
#define issep(c) (c == ' ' || c == '\t')
|
||||
|
||||
#define BOOTPARAMS "/etc/bootparams"
|
||||
#define LINESIZE 512
|
||||
#define NAMESIZE 256
|
||||
#define DOMAINSIZE 256
|
||||
|
||||
static char domain[DOMAINSIZE]; /* NIS domain name */
|
||||
|
||||
struct stat laststat;
|
||||
static char *bpbuf;
|
||||
|
||||
char *
|
||||
read_bootparams()
|
||||
{
|
||||
int fd;
|
||||
struct stat statb;
|
||||
|
||||
if (stat(BOOTPARAMS, &statb) < 0) {
|
||||
fprintf(stderr, "rpc.bootparamsd: can't stat %s\n", BOOTPARAMS);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (statb.st_mtime != laststat.st_mtime) {
|
||||
if ((fd = open(BOOTPARAMS, O_RDWR, 0)) < 0) {
|
||||
perror(BOOTPARAMS);
|
||||
return (NULL);
|
||||
}
|
||||
if (bpbuf) {
|
||||
free(bpbuf);
|
||||
}
|
||||
bpbuf = (char *)malloc(statb.st_size + 1);
|
||||
if (bpbuf == NULL) {
|
||||
fprintf("rpc.bootparamd: out of memory\n");
|
||||
return (NULL);
|
||||
}
|
||||
if (read(fd, bpbuf, statb.st_size) < 0) {
|
||||
perror(BOOTPARAMS);
|
||||
return (NULL);
|
||||
}
|
||||
bpbuf[statb.st_size] = '\0';
|
||||
laststat = statb;
|
||||
}
|
||||
return (bpbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* getline()
|
||||
* Read a line from a buffer.
|
||||
* Fill in line buffer, and update lpp, return number of chars.
|
||||
*/
|
||||
getline(line, maxlinelen, lpp)
|
||||
char *line;
|
||||
int maxlinelen;
|
||||
char **lpp;
|
||||
{
|
||||
int count;
|
||||
char *p;
|
||||
char *linestart;
|
||||
|
||||
p = *lpp;
|
||||
if (p == NULL || *p == '\0') {
|
||||
return (0);
|
||||
}
|
||||
count = 0;
|
||||
linestart = line;
|
||||
|
||||
while (iseol(*p)) {
|
||||
p++;
|
||||
}
|
||||
|
||||
while (*p) {
|
||||
if (*p == '\n') {
|
||||
if (count && p[-1] == '\\') {
|
||||
/*
|
||||
* Continuation line, back up one char
|
||||
* and get next line from buf.
|
||||
*/
|
||||
line--;
|
||||
p++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
*line++ = *p++;
|
||||
}
|
||||
*line = '\0';
|
||||
*lpp = p;
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* getname()
|
||||
* Get the next entry from the line.
|
||||
* You tell getname() which characters to ignore before storing them
|
||||
* into name, and which characters separate entries in a line.
|
||||
* The cookie is updated appropriately.
|
||||
* return:
|
||||
* 1: one entry parsed
|
||||
* 0: partial entry parsed, ran out of space in name
|
||||
* -1: no more entries in line
|
||||
*/
|
||||
int
|
||||
getname(name, namelen, linep)
|
||||
char *name;
|
||||
int namelen;
|
||||
char **linep;
|
||||
{
|
||||
char c;
|
||||
char *lp;
|
||||
char *np;
|
||||
int maxnamelen;
|
||||
|
||||
lp = *linep;
|
||||
do {
|
||||
c = *lp++;
|
||||
} while (issep(c) && !iseol(c));
|
||||
|
||||
if (iseol(c)) {
|
||||
*linep = lp - 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
np = name;
|
||||
while (! issep(c) && ! iseol(c) && np - name < namelen - 1) {
|
||||
*np++ = c;
|
||||
c = *lp++;
|
||||
}
|
||||
*np = '\0';
|
||||
lp--;
|
||||
*linep = lp;
|
||||
return (np - name);
|
||||
}
|
||||
|
||||
/*
|
||||
* getclntent reads the line buffer and returns a string of client entry
|
||||
* in NIS or the "/etc/bootparams" file. Called by getclntent.
|
||||
*/
|
||||
static int
|
||||
getvalue(lpp, clnt_entry)
|
||||
register char **lpp; /* function input */
|
||||
register char *clnt_entry; /* function output */
|
||||
{
|
||||
char name[NAMESIZE];
|
||||
int append = 0;
|
||||
|
||||
while (getname(name, sizeof(name), lpp) > 0) {
|
||||
if (!append) {
|
||||
strcpy(clnt_entry, name);
|
||||
append++;
|
||||
} else {
|
||||
strcat(clnt_entry, " ");
|
||||
strcat(clnt_entry, name);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* getfileent returns the client entry in the "/etc/bootparams"
|
||||
* file given the client name.
|
||||
*/
|
||||
int
|
||||
bp_getclntent(clnt_name, clnt_entry)
|
||||
register char *clnt_name; /* function input */
|
||||
register char *clnt_entry; /* function output */
|
||||
{
|
||||
FILE *fp;
|
||||
char line[LINESIZE];
|
||||
char name[NAMESIZE];
|
||||
char *lp;
|
||||
char *linep;
|
||||
char *val;
|
||||
int vallen;
|
||||
int reason;
|
||||
|
||||
reason = -1;
|
||||
lp = read_bootparams();
|
||||
while (reason && getline(line, sizeof(line), &lp)) {
|
||||
linep = line;
|
||||
val = NULL;
|
||||
|
||||
if (*linep == '+' && useyp()) {
|
||||
linep++;
|
||||
if (getname(name, sizeof(name), &linep)) {
|
||||
reason = yp_match(domain, name, clnt_name,
|
||||
strlen(clnt_name), &val, &vallen);
|
||||
} else {
|
||||
reason = yp_match(domain, "bootparams",
|
||||
clnt_name, strlen(clnt_name), &val,&vallen);
|
||||
}
|
||||
if (!reason) {
|
||||
linep = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reason || (getname(name, sizeof(name), &linep) > 0
|
||||
&& strcmp(name,clnt_name) == 0)) {
|
||||
reason = getvalue(&linep, clnt_entry);
|
||||
}
|
||||
|
||||
if (val) {
|
||||
free(val);
|
||||
}
|
||||
}
|
||||
return (reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the value string associated with clnt_key (key=value) in
|
||||
* the line buffer lpp. Update lpp.
|
||||
*/
|
||||
static int
|
||||
getkeyval(lpp, clnt_key, clnt_entry)
|
||||
register char **lpp; /* function input */
|
||||
register char *clnt_key; /* function input */
|
||||
register char *clnt_entry; /* function output */
|
||||
{
|
||||
char name[NAMESIZE];
|
||||
char *cp;
|
||||
|
||||
while (getname(name, sizeof(name), lpp) > 0) {
|
||||
if ((cp = (char *)index(name, '=')) == 0)
|
||||
return (-1);
|
||||
*cp++ = '\0';
|
||||
if (strcmp(name, clnt_key) == 0) {
|
||||
strcpy(clnt_entry, cp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (strcmp(clnt_key, "dump") == 0) {
|
||||
/*
|
||||
* This is a gross hack to handle the case where
|
||||
* no dump file exists in bootparams. The null
|
||||
* server and path names indicate this fact to the
|
||||
* client.
|
||||
*/
|
||||
strcpy(clnt_entry, ":");
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* getclntkey returns the client's server name and its pathname from either
|
||||
* the NIS or the "/etc/bootparams" file given the client name and
|
||||
* the key.
|
||||
*/
|
||||
int
|
||||
bp_getclntkey(clnt_name, clnt_key, clnt_entry)
|
||||
register char *clnt_name; /* function input */
|
||||
register char *clnt_key; /* function input */
|
||||
register char *clnt_entry; /* function output */
|
||||
{
|
||||
char line[LINESIZE];
|
||||
char name[NAMESIZE];
|
||||
char *lp;
|
||||
char *linep;
|
||||
char *val;
|
||||
int reason;
|
||||
int vallen;
|
||||
|
||||
reason = -1;
|
||||
lp = read_bootparams();
|
||||
while (reason && getline(line, sizeof(line), &lp)) {
|
||||
linep = line;
|
||||
val = NULL;
|
||||
|
||||
if (*linep == '+' && useyp()) {
|
||||
linep++;
|
||||
if (getname(name, sizeof(name), &linep)) {
|
||||
reason = yp_match(domain, name, clnt_name,
|
||||
strlen(clnt_name), &val, &vallen);
|
||||
} else {
|
||||
reason = yp_match(domain, "bootparams",
|
||||
clnt_name, strlen(clnt_name), &val,&vallen);
|
||||
}
|
||||
if (!reason) {
|
||||
linep = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reason || ( getname(name, sizeof(name), &linep) > 0
|
||||
&& strcmp(name,clnt_name) == 0) ) {
|
||||
reason = getkeyval(&linep, clnt_key, clnt_entry);
|
||||
}
|
||||
|
||||
if (val) {
|
||||
free(val);
|
||||
}
|
||||
}
|
||||
return (reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether or not to use the NIS service to do lookups.
|
||||
*/
|
||||
static int initted;
|
||||
static int usingyp;
|
||||
static int
|
||||
useyp()
|
||||
{
|
||||
if (!initted) {
|
||||
getdomainname(domain, sizeof(domain));
|
||||
usingyp = !yp_bind(domain);
|
||||
initted = 1;
|
||||
}
|
||||
return (usingyp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if a descriptor belongs to a socket or not
|
||||
*/
|
||||
issock(fd)
|
||||
int fd;
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* SunOS returns S_IFIFO for sockets, while 4.3 returns 0 and
|
||||
* does not even have an S_IFIFO mode. Since there is confusion
|
||||
* about what the mode is, we check for what it is not instead of
|
||||
* what it is.
|
||||
*/
|
||||
switch (st.st_mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
case S_IFREG:
|
||||
case S_IFLNK:
|
||||
case S_IFDIR:
|
||||
case S_IFBLK:
|
||||
return (0);
|
||||
default:
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
354
usr.etc/rpc.bootparamd/bootparam_subr.c
Normal file
354
usr.etc/rpc.bootparamd/bootparam_subr.c
Normal file
@@ -0,0 +1,354 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)bootparam_subr.c 1.1 94/10/31 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Subroutines that implement the bootparam services.
|
||||
*/
|
||||
|
||||
#include <rpcsvc/bootparam.h>
|
||||
#include <netdb.h>
|
||||
#include <nlist.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mbuf.h>
|
||||
#define KERNEL /* to get RTHASHSIZ */
|
||||
#include <net/route.h>
|
||||
#undef KERNEL
|
||||
#include <net/if.h> /* for structs ifnet and ifaddr */
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h> /* for struct in_ifaddr */
|
||||
|
||||
#define LINESIZE 1024
|
||||
|
||||
int debug = 0;
|
||||
|
||||
/*
|
||||
* Whoami turns a client address into a client name
|
||||
* and suggested route machine.
|
||||
*/
|
||||
bp_whoami_res *
|
||||
bootparamproc_whoami_1(argp)
|
||||
bp_whoami_arg *argp;
|
||||
{
|
||||
static bp_whoami_res res;
|
||||
struct in_addr clnt_addr;
|
||||
struct in_addr route_addr, get_route();
|
||||
struct hostent *hp;
|
||||
static char clnt_entry[LINESIZE];
|
||||
static char domain[32];
|
||||
|
||||
if (argp->client_address.address_type != IP_ADDR_TYPE) {
|
||||
if (debug) {
|
||||
fprintf(stderr,
|
||||
"Whoami failed: unknown address type %d\n",
|
||||
argp->client_address.address_type);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
bcopy ((char *) &argp->client_address.bp_address.ip_addr,
|
||||
(char *) &clnt_addr, sizeof (clnt_addr));
|
||||
hp = gethostbyaddr(&clnt_addr, sizeof clnt_addr, AF_INET);
|
||||
if (hp == NULL) {
|
||||
if (debug) {
|
||||
fprintf(stderr,
|
||||
"Whoami failed: gethostbyaddr for %s.\n",
|
||||
inet_ntoa (clnt_addr));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
if (bp_getclntent(hp->h_name, clnt_entry) != 0) {
|
||||
if (debug) {
|
||||
fprintf(stderr, "bp_getclntent failed.\n");
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
res.client_name = hp->h_name;
|
||||
getdomainname(domain, sizeof domain);
|
||||
res.domain_name = domain;
|
||||
res.router_address.address_type = IP_ADDR_TYPE;
|
||||
route_addr = get_route(clnt_addr);
|
||||
bcopy ((char *) &route_addr,
|
||||
(char *) &res.router_address.bp_address.ip_addr,
|
||||
sizeof (res.router_address.bp_address.ip_addr));
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr, "Whoami returning name = %s, router address = %s\n",
|
||||
res.client_name,
|
||||
inet_ntoa (res.router_address.bp_address.ip_addr));
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
struct nlist nl[] = {
|
||||
#define N_RTHOST 0
|
||||
{ "_rthost" },
|
||||
#define N_RTNET 1
|
||||
{ "_rtnet" },
|
||||
"",
|
||||
};
|
||||
|
||||
char *system = "/vmunix";
|
||||
char *kmemf = "/dev/kmem";
|
||||
int kmem;
|
||||
|
||||
/*
|
||||
* nlist the kernel once at program startup time.
|
||||
*/
|
||||
init_nlist()
|
||||
{
|
||||
if (nl[0].n_type == 0) {
|
||||
nlist(system, nl);
|
||||
if (nl[0].n_type == 0) {
|
||||
printf("no namelist for %s\n", system);
|
||||
exit(1);
|
||||
}
|
||||
kmem = open(kmemf, 0);
|
||||
if (kmem < 0) {
|
||||
printf("cannot open %s", kmemf);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_route paws through the kernel's routing table looking for a route
|
||||
* via a gateway that is on the same network and subnet as the client.
|
||||
* Any gateway will do because the selected gateway will return ICMP redirect
|
||||
* messages to the client if it can not route the traffic itself.
|
||||
*/
|
||||
|
||||
struct in_addr
|
||||
get_route(client_addr)
|
||||
struct in_addr client_addr;
|
||||
{
|
||||
off_t hostaddr, netaddr;
|
||||
struct mbuf mb;
|
||||
register struct rtentry *rt;
|
||||
register struct mbuf *m;
|
||||
struct netent *np;
|
||||
struct mbuf *routehash[RTHASHSIZ];
|
||||
int i, doinghost = 1;
|
||||
|
||||
hostaddr = nl[N_RTHOST].n_value;
|
||||
if (hostaddr == 0) {
|
||||
printf("rthost: symbol not in namelist\n");
|
||||
exit(1);
|
||||
}
|
||||
netaddr = nl[N_RTNET].n_value;
|
||||
if (netaddr == 0) {
|
||||
printf("rtnet: symbol not in namelist\n");
|
||||
exit(1);
|
||||
}
|
||||
if (lseek(kmem, (off_t) hostaddr, 0) == (off_t) -1) {
|
||||
perror ("lseek rthost");
|
||||
exit (1);
|
||||
}
|
||||
if (read(kmem, (char *) routehash, sizeof (routehash)) !=
|
||||
sizeof (routehash)) {
|
||||
fprintf (stderr, "read rthost in kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
again:
|
||||
for (i = 0; i < RTHASHSIZ; i++) {
|
||||
if (routehash[i] == 0)
|
||||
continue;
|
||||
for (m = routehash[i]; m; m = mb.m_next) {
|
||||
struct sockaddr_in *sin;
|
||||
struct ifnet ifnet;
|
||||
struct ifaddr *ifa;
|
||||
struct ifaddr ifaddr;
|
||||
struct in_ifaddr in_ifaddr;
|
||||
struct in_ifaddr *ia;
|
||||
|
||||
if (lseek(kmem, (off_t) m, 0) == (off_t) -1) {
|
||||
perror ("lseek routehash");
|
||||
exit (1);
|
||||
}
|
||||
if (read(kmem, (char *) &mb, sizeof (mb)) !=
|
||||
sizeof (mb)) {
|
||||
fprintf (stderr, "read routehash from kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
rt = mtod(&mb, struct rtentry *);
|
||||
|
||||
/*
|
||||
* reject routes that are down, routes that are not
|
||||
* to gateways, and routes that are not on the same
|
||||
* net as the client.
|
||||
*/
|
||||
if ((rt->rt_flags & (RTF_UP | RTF_GATEWAY)) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sin = (struct sockaddr_in *)&rt->rt_gateway;
|
||||
if (netof(client_addr.s_addr) !=
|
||||
netof(sin->sin_addr.s_addr))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* reject routes that are not on the same subnet
|
||||
* as the client.
|
||||
*/
|
||||
if (lseek (kmem, (off_t) rt->rt_ifp, 0) ==
|
||||
(off_t) -1) {
|
||||
perror ("lseek rt->rt_ifp");
|
||||
exit (1);
|
||||
}
|
||||
if (read (kmem, (char *) &ifnet,
|
||||
sizeof (struct ifnet)) !=
|
||||
sizeof (struct ifnet)) {
|
||||
fprintf (stderr, "read rt->rt_ifp from kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ifa = ifnet.if_addrlist;
|
||||
|
||||
while (ifa != (struct ifaddr *) 0) {
|
||||
if (lseek (kmem, (off_t) ifa, 0) ==
|
||||
(off_t) -1) {
|
||||
perror ("lseek ifaddr");
|
||||
exit (1);
|
||||
}
|
||||
if (read (kmem, (char *) &ifaddr,
|
||||
sizeof (struct ifaddr)) !=
|
||||
sizeof (struct ifaddr)) {
|
||||
printf ("read ifaddr from kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (ifaddr.ifa_addr.sa_family == AF_INET)
|
||||
break;
|
||||
|
||||
ifa = ifaddr.ifa_next;
|
||||
}
|
||||
|
||||
if (ifa == (struct ifaddr *) 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* read same ifaddr struct again, this time as an
|
||||
* in_ifaddr struct.
|
||||
*/
|
||||
if (lseek (kmem, (off_t) ifa, 0) == (off_t) -1) {
|
||||
perror ("lseek in_ifaddr");
|
||||
exit (1);
|
||||
}
|
||||
if (read (kmem, (char *) &in_ifaddr,
|
||||
sizeof (struct in_ifaddr)) !=
|
||||
sizeof (struct in_ifaddr)) {
|
||||
fprintf ("read in_ifaddr from kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if ((in_ifaddr.ia_subnetmask & sin->sin_addr.s_addr) !=
|
||||
(in_ifaddr.ia_subnetmask & client_addr.s_addr)) {
|
||||
if (debug)
|
||||
fprintf (stderr, "subnet mismatch. gateway = %s, client_addr = %s\n",
|
||||
inet_ntoa (sin->sin_addr.s_addr),
|
||||
inet_ntoa (client_addr));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* route passes all of our tests.
|
||||
*/
|
||||
return (sin->sin_addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (doinghost) {
|
||||
if (lseek(kmem, (off_t) netaddr, 0) == (off_t) -1) {
|
||||
perror ("lseek rtnet");
|
||||
exit (1);
|
||||
}
|
||||
if (read(kmem, (char *) routehash, sizeof (routehash)) !=
|
||||
sizeof (routehash)) {
|
||||
fprintf ("read rtnet in kmem failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
doinghost = 0;
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
printf("No route found for client %s.\n",
|
||||
inet_ntoa (client_addr));
|
||||
}
|
||||
|
||||
bzero ((char *) &client_addr, sizeof (client_addr));
|
||||
return (client_addr);
|
||||
}
|
||||
|
||||
netof(i)
|
||||
register int i;
|
||||
{
|
||||
if (IN_CLASSA(i))
|
||||
return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
|
||||
else if (IN_CLASSB(i))
|
||||
return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
|
||||
else
|
||||
return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Getfile gets the client name and the key and returns its server
|
||||
* and the pathname for that key.
|
||||
*/
|
||||
bp_getfile_res *
|
||||
bootparamproc_getfile_1(argp)
|
||||
bp_getfile_arg *argp;
|
||||
{
|
||||
static bp_getfile_res res;
|
||||
static char clnt_entry[LINESIZE];
|
||||
struct hostent *hp;
|
||||
char *cp;
|
||||
|
||||
if (bp_getclntkey(argp->client_name, argp->file_id, clnt_entry) != 0) {
|
||||
if (debug) {
|
||||
fprintf(stderr, "bp_getclntkey failed.\n");
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
if ((cp = (char *)index(clnt_entry, ':')) == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
*cp++ = '\0';
|
||||
res.server_name = clnt_entry;
|
||||
res.server_path = cp;
|
||||
if (*res.server_name == 0) {
|
||||
res.server_address.address_type = IP_ADDR_TYPE;
|
||||
bzero(&res.server_address.bp_address.ip_addr,
|
||||
sizeof(res.server_address.bp_address.ip_addr));
|
||||
} else {
|
||||
if ((hp = gethostbyname(res.server_name)) == NULL) {
|
||||
if (debug) {
|
||||
fprintf(stderr,
|
||||
"getfile_1: gethostbyname(%s) failed\n",
|
||||
res.server_name);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
res.server_address.address_type = IP_ADDR_TYPE;
|
||||
bcopy ((char *) hp->h_addr,
|
||||
(char *) &res.server_address.bp_address.ip_addr,
|
||||
sizeof (res.server_address.bp_address.ip_addr));
|
||||
}
|
||||
if (debug) {
|
||||
getf_printres(&res);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
getf_printres(res)
|
||||
bp_getfile_res *res;
|
||||
{
|
||||
fprintf(stderr, "getfile_1: file is \"%s\" %s \"%s\"\n",
|
||||
res->server_name,
|
||||
inet_ntoa (res->server_address.bp_address.ip_addr),
|
||||
res->server_path);
|
||||
}
|
||||
151
usr.etc/rpc.bootparamd/bootparam_svc.c
Normal file
151
usr.etc/rpc.bootparamd/bootparam_svc.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)bootparam_svc.c 1.1 94/10/31 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Main program of the bootparam server.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/bootparam.h>
|
||||
|
||||
extern int debug;
|
||||
|
||||
static void background();
|
||||
static void bootparamprog_1();
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
SVCXPRT *transp;
|
||||
|
||||
if (argc > 1) {
|
||||
if (strncmp(argv[1], "-d", 2) == 0) {
|
||||
debug++;
|
||||
fprintf(stderr, "In debug mode\n");
|
||||
} else {
|
||||
fprintf(stderr, "usage: %s [-d]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (! issock(0)) {
|
||||
/*
|
||||
* Started by user.
|
||||
*/
|
||||
if (!debug)
|
||||
background();
|
||||
|
||||
pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
|
||||
if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) {
|
||||
fprintf(stderr, "cannot create udp service.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (! svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS,
|
||||
bootparamprog_1, IPPROTO_UDP)) {
|
||||
fprintf(stderr, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp).\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Started by inetd.
|
||||
*/
|
||||
if ((transp = svcudp_create(0)) == NULL) {
|
||||
fprintf(stderr, "cannot create udp service.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS,
|
||||
bootparamprog_1, 0)) {
|
||||
fprintf(stderr, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp).\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start serving
|
||||
*/
|
||||
init_nlist(); /* nlist the kernel */
|
||||
svc_run();
|
||||
fprintf(stderr, "svc_run returned\n");
|
||||
exit(1);
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
background()
|
||||
{
|
||||
#ifndef DEBUG
|
||||
if (fork())
|
||||
exit(0);
|
||||
{ int s;
|
||||
for (s = 0; s < 10; s++)
|
||||
(void) close(s);
|
||||
}
|
||||
(void) open("/", O_RDONLY);
|
||||
(void) dup2(0, 1);
|
||||
(void) dup2(0, 2);
|
||||
#endif
|
||||
{ int tt = open("/dev/tty", O_RDWR);
|
||||
if (tt > 0) {
|
||||
ioctl(tt, TIOCNOTTY, 0);
|
||||
close(tt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bootparamprog_1(rqstp, transp)
|
||||
struct svc_req *rqstp;
|
||||
SVCXPRT *transp;
|
||||
{
|
||||
union {
|
||||
bp_whoami_arg bootparamproc_whoami_1_arg;
|
||||
bp_getfile_arg bootparamproc_getfile_1_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
bool_t (*xdr_argument)(), (*xdr_result)();
|
||||
char *(*local)();
|
||||
extern bp_whoami_res *bootparamproc_whoami_1();
|
||||
extern bp_getfile_res *bootparamproc_getfile_1();
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
case NULLPROC:
|
||||
svc_sendreply(transp, xdr_void, NULL);
|
||||
return;
|
||||
|
||||
case BOOTPARAMPROC_WHOAMI:
|
||||
xdr_argument = xdr_bp_whoami_arg;
|
||||
xdr_result = xdr_bp_whoami_res;
|
||||
local = (char *(*)()) bootparamproc_whoami_1;
|
||||
break;
|
||||
|
||||
case BOOTPARAMPROC_GETFILE:
|
||||
xdr_argument = xdr_bp_getfile_arg;
|
||||
xdr_result = xdr_bp_getfile_res;
|
||||
local = (char *(*)()) bootparamproc_getfile_1;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
bzero(&argument, sizeof(argument));
|
||||
if (! svc_getargs(transp, xdr_argument, &argument)) {
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
if ((result = (*local)(&argument)) != NULL) {
|
||||
if (! svc_sendreply(transp, xdr_result, result)) {
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
}
|
||||
if (! svc_freeargs(transp, xdr_argument, &argument)) {
|
||||
fprintf(stderr,"unable to free arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user