xref: /titanic_50/usr/src/cmd/ypcmd/ypxfrd_server.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
30*7c478bd9Sstevel@tonic-gate #include <signal.h>
31*7c478bd9Sstevel@tonic-gate #include <string.h>
32*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
33*7c478bd9Sstevel@tonic-gate #include <unistd.h>
34*7c478bd9Sstevel@tonic-gate #include <ndbm.h>
35*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
36*7c478bd9Sstevel@tonic-gate #include <rpc/svc.h>
37*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
39*7c478bd9Sstevel@tonic-gate #include <syslog.h>
40*7c478bd9Sstevel@tonic-gate #include "ypxfrd.h"
41*7c478bd9Sstevel@tonic-gate #include "ypsym.h"
42*7c478bd9Sstevel@tonic-gate #include "ypdefs.h"
43*7c478bd9Sstevel@tonic-gate /*
44*7c478bd9Sstevel@tonic-gate  * Because this code hacks into DBM underneath its API it can't use the N2L
45*7c478bd9Sstevel@tonic-gate  * shim in it's normal way. It thus includes shim.h instead of shim_hooks.h
46*7c478bd9Sstevel@tonic-gate  * and has knowledge of shim internals. While copying the DBM files it does
47*7c478bd9Sstevel@tonic-gate  * not lock them. This reflects the behavior of the pre N2L code.
48*7c478bd9Sstevel@tonic-gate  */
49*7c478bd9Sstevel@tonic-gate #include "shim.h"
50*7c478bd9Sstevel@tonic-gate #include "yptol.h"
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate #if (defined(vax) || defined(i386))
53*7c478bd9Sstevel@tonic-gate #define	DOSWAB 1
54*7c478bd9Sstevel@tonic-gate #endif
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate USE_YP_SECURE
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /* per connection stuff */
59*7c478bd9Sstevel@tonic-gate struct mycon {
60*7c478bd9Sstevel@tonic-gate 	map_ctrl *map;
61*7c478bd9Sstevel@tonic-gate 	int	lblk;
62*7c478bd9Sstevel@tonic-gate 	int	firstd;
63*7c478bd9Sstevel@tonic-gate 	datum	key;
64*7c478bd9Sstevel@tonic-gate };
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate bool_t xdr_myfyl(XDR *xdrs, struct mycon *objp);
67*7c478bd9Sstevel@tonic-gate bool_t xdr_pages(XDR *xdrs, struct mycon *m);
68*7c478bd9Sstevel@tonic-gate bool_t xdr_dirs(XDR *xdrs, struct mycon *m);
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate int mygetdir(char *block, int *no, struct mycon *m);
71*7c478bd9Sstevel@tonic-gate int mygetpage(char *block, int *pageno, struct mycon *m);
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate datum mydbm_topkey(DBM *db, datum okey);
74*7c478bd9Sstevel@tonic-gate datum dbm_do_nextkey();
75*7c478bd9Sstevel@tonic-gate datum shim_dbm_do_nextkey();
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate extern void get_secure_nets(char *);
78*7c478bd9Sstevel@tonic-gate extern int check_secure_net_ti(struct netbuf *, char *);
79*7c478bd9Sstevel@tonic-gate extern int _main(int, char **);
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate int
82*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
83*7c478bd9Sstevel@tonic-gate {
84*7c478bd9Sstevel@tonic-gate 	int connmaxrec = RPC_MAXDATASIZE;
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	/* load up the securenet file */
87*7c478bd9Sstevel@tonic-gate 	get_secure_nets(argv[0]);
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	/*
90*7c478bd9Sstevel@tonic-gate 	 * Set non-blocking mode and maximum record size for
91*7c478bd9Sstevel@tonic-gate 	 * connection oriented RPC transports.
92*7c478bd9Sstevel@tonic-gate 	 */
93*7c478bd9Sstevel@tonic-gate 	if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &connmaxrec)) {
94*7c478bd9Sstevel@tonic-gate 		syslog(LOG_INFO|LOG_DAEMON,
95*7c478bd9Sstevel@tonic-gate 			"unable to set maximum RPC record size");
96*7c478bd9Sstevel@tonic-gate 	}
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 	/* Initialize file locking etc. */
99*7c478bd9Sstevel@tonic-gate 	if (!init_lock_system(TRUE))
100*7c478bd9Sstevel@tonic-gate 		/* An detailed error will already have been logged */
101*7c478bd9Sstevel@tonic-gate 		exit(-1);
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	return (_main(argc, argv));
104*7c478bd9Sstevel@tonic-gate }
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * In yptol mode we may start a cache update thread within a child process.
108*7c478bd9Sstevel@tonic-gate  * It is thus important that child processes do not exit, killing any such
109*7c478bd9Sstevel@tonic-gate  * threads, before the thread has completed. They must thus call this version
110*7c478bd9Sstevel@tonic-gate  * of the exit() function.
111*7c478bd9Sstevel@tonic-gate  */
112*7c478bd9Sstevel@tonic-gate void
113*7c478bd9Sstevel@tonic-gate yptol_exit(int status)
114*7c478bd9Sstevel@tonic-gate {
115*7c478bd9Sstevel@tonic-gate 	if (yptol_mode) {
116*7c478bd9Sstevel@tonic-gate 		thr_join(0, NULL, NULL);
117*7c478bd9Sstevel@tonic-gate 	}
118*7c478bd9Sstevel@tonic-gate 	exit(status);
119*7c478bd9Sstevel@tonic-gate }
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate dbmfyl *
122*7c478bd9Sstevel@tonic-gate getdbm_1_svc(hosereq *argp, struct svc_req *rqstp)
123*7c478bd9Sstevel@tonic-gate {
124*7c478bd9Sstevel@tonic-gate 	static dbmfyl  result;
125*7c478bd9Sstevel@tonic-gate 	char path[MAXNAMLEN + 1];
126*7c478bd9Sstevel@tonic-gate 	SVCXPRT *xprt;
127*7c478bd9Sstevel@tonic-gate 	int pid;
128*7c478bd9Sstevel@tonic-gate 	int res;
129*7c478bd9Sstevel@tonic-gate 	struct mycon m;
130*7c478bd9Sstevel@tonic-gate 	char *ypname = "ypxfrd";
131*7c478bd9Sstevel@tonic-gate 	struct netbuf *nbuf;
132*7c478bd9Sstevel@tonic-gate 	sa_family_t af;
133*7c478bd9Sstevel@tonic-gate 	in_port_t port;
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	xprt = rqstp->rq_xprt;
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	signal(SIGPIPE, SIG_IGN);
138*7c478bd9Sstevel@tonic-gate 	signal(SIGCHLD, SIG_IGN);
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 	/*
141*7c478bd9Sstevel@tonic-gate 	 * Build up path name. If we are working in N2L mode also conv
142*7c478bd9Sstevel@tonic-gate 	 * to the new N2L style mapname.
143*7c478bd9Sstevel@tonic-gate 	 *
144*7c478bd9Sstevel@tonic-gate 	 * Do not allow any path as a domain name or map name.
145*7c478bd9Sstevel@tonic-gate 	 */
146*7c478bd9Sstevel@tonic-gate 	if ((strchr(argp->domain, '/') != NULL) ||
147*7c478bd9Sstevel@tonic-gate 		(strchr(argp->map, '/') != NULL) ||
148*7c478bd9Sstevel@tonic-gate 		(!ypmkfilename(argp->domain, argp->map, (char *)&path))) {
149*7c478bd9Sstevel@tonic-gate 		res = GETDBM_ERROR;
150*7c478bd9Sstevel@tonic-gate 		if (!svc_sendreply(rqstp->rq_xprt, xdr_answer,
151*7c478bd9Sstevel@tonic-gate 					(caddr_t)&res)) {
152*7c478bd9Sstevel@tonic-gate 			svcerr_systemerr(rqstp->rq_xprt);
153*7c478bd9Sstevel@tonic-gate 		}
154*7c478bd9Sstevel@tonic-gate 		return (NULL);
155*7c478bd9Sstevel@tonic-gate 	}
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 	pid = fork1();
158*7c478bd9Sstevel@tonic-gate 	if (pid < 0) {
159*7c478bd9Sstevel@tonic-gate 		perror("fork");
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 		res = GETDBM_ERROR;
162*7c478bd9Sstevel@tonic-gate 		if (!svc_sendreply(rqstp->rq_xprt, xdr_answer,
163*7c478bd9Sstevel@tonic-gate 					(caddr_t)&res)) {
164*7c478bd9Sstevel@tonic-gate 			svcerr_systemerr(rqstp->rq_xprt);
165*7c478bd9Sstevel@tonic-gate 		}
166*7c478bd9Sstevel@tonic-gate 		return (NULL);
167*7c478bd9Sstevel@tonic-gate 	}
168*7c478bd9Sstevel@tonic-gate 	if (pid != 0)
169*7c478bd9Sstevel@tonic-gate 		return (NULL);
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 	m.map = (map_ctrl *)shim_dbm_open(path, 0, 0);
172*7c478bd9Sstevel@tonic-gate 	if (m.map == NULL) {
173*7c478bd9Sstevel@tonic-gate 		perror(path);
174*7c478bd9Sstevel@tonic-gate 		res = GETDBM_ERROR;
175*7c478bd9Sstevel@tonic-gate 		if (!svc_sendreply(rqstp->rq_xprt, xdr_answer,
176*7c478bd9Sstevel@tonic-gate 					(caddr_t)&res)) {
177*7c478bd9Sstevel@tonic-gate 		    svcerr_systemerr(rqstp->rq_xprt);
178*7c478bd9Sstevel@tonic-gate 		}
179*7c478bd9Sstevel@tonic-gate 		yptol_exit(0);
180*7c478bd9Sstevel@tonic-gate 		return (NULL);
181*7c478bd9Sstevel@tonic-gate 	}
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate 	/* Do the security thing */
184*7c478bd9Sstevel@tonic-gate 	if ((nbuf = svc_getrpccaller(xprt)) == 0) {
185*7c478bd9Sstevel@tonic-gate 		res = GETDBM_ERROR;
186*7c478bd9Sstevel@tonic-gate 		if (!svc_sendreply(xprt, xdr_answer, (caddr_t)&res)) {
187*7c478bd9Sstevel@tonic-gate 			svcerr_systemerr(xprt);
188*7c478bd9Sstevel@tonic-gate 		}
189*7c478bd9Sstevel@tonic-gate 		shim_dbm_close((DBM *)m.map);
190*7c478bd9Sstevel@tonic-gate 		yptol_exit(0);
191*7c478bd9Sstevel@tonic-gate 		return (NULL);
192*7c478bd9Sstevel@tonic-gate 	}
193*7c478bd9Sstevel@tonic-gate 	if (!check_secure_net_ti(nbuf, ypname)) {
194*7c478bd9Sstevel@tonic-gate 		res = GETDBM_ERROR;
195*7c478bd9Sstevel@tonic-gate 		if (!svc_sendreply(xprt, xdr_answer, (caddr_t)&res)) {
196*7c478bd9Sstevel@tonic-gate 			svcerr_systemerr(xprt);
197*7c478bd9Sstevel@tonic-gate 		}
198*7c478bd9Sstevel@tonic-gate 		shim_dbm_close((DBM *)m.map);
199*7c478bd9Sstevel@tonic-gate 		yptol_exit(1);
200*7c478bd9Sstevel@tonic-gate 		return (NULL);
201*7c478bd9Sstevel@tonic-gate 	}
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 	af = ((struct sockaddr_storage *)nbuf->buf)->ss_family;
204*7c478bd9Sstevel@tonic-gate 	port = (af == AF_INET6) ?
205*7c478bd9Sstevel@tonic-gate 		((struct sockaddr_in6 *)nbuf->buf)->sin6_port :
206*7c478bd9Sstevel@tonic-gate 		((struct sockaddr_in  *)nbuf->buf)->sin_port;
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	if ((af == AF_INET || af == AF_INET6) &&
209*7c478bd9Sstevel@tonic-gate 		(ntohs(port) > IPPORT_RESERVED)) {
210*7c478bd9Sstevel@tonic-gate 		datum key, val;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
213*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
214*7c478bd9Sstevel@tonic-gate 		val = shim_dbm_fetch((DBM *)m.map, key);
215*7c478bd9Sstevel@tonic-gate 		if (val.dptr != NULL) {
216*7c478bd9Sstevel@tonic-gate 			res = GETDBM_ERROR;
217*7c478bd9Sstevel@tonic-gate 			if (!svc_sendreply(xprt, xdr_answer, (caddr_t)&res)) {
218*7c478bd9Sstevel@tonic-gate 				svcerr_systemerr(xprt);
219*7c478bd9Sstevel@tonic-gate 			}
220*7c478bd9Sstevel@tonic-gate 			shim_dbm_close((DBM *)m.map);
221*7c478bd9Sstevel@tonic-gate 			yptol_exit(1);
222*7c478bd9Sstevel@tonic-gate 			return (NULL);
223*7c478bd9Sstevel@tonic-gate 		}
224*7c478bd9Sstevel@tonic-gate 	}
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 	/* OK, we're through */
227*7c478bd9Sstevel@tonic-gate 	m.key = shim_dbm_firstkey((DBM *)m.map);
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	m.lblk = -1;
230*7c478bd9Sstevel@tonic-gate 	m.firstd = 0;
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	if (!svc_sendreply(rqstp->rq_xprt, xdr_myfyl, (caddr_t)&m)) {
233*7c478bd9Sstevel@tonic-gate 		svcerr_systemerr(rqstp->rq_xprt);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 	shim_dbm_close((DBM *)m.map);
236*7c478bd9Sstevel@tonic-gate 	yptol_exit(0);
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	return (&result);
239*7c478bd9Sstevel@tonic-gate }
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate bool_t
242*7c478bd9Sstevel@tonic-gate xdr_myfyl(XDR *xdrs, struct mycon *objp)
243*7c478bd9Sstevel@tonic-gate {
244*7c478bd9Sstevel@tonic-gate 	int	ans = OK;
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate 	if (!xdr_answer(xdrs, (answer *) &ans))
247*7c478bd9Sstevel@tonic-gate 		return (FALSE);
248*7c478bd9Sstevel@tonic-gate 	if (!xdr_pages(xdrs, objp))
249*7c478bd9Sstevel@tonic-gate 		return (FALSE);
250*7c478bd9Sstevel@tonic-gate 	if (!xdr_dirs(xdrs, objp))
251*7c478bd9Sstevel@tonic-gate 		return (FALSE);
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 	return (TRUE);
254*7c478bd9Sstevel@tonic-gate }
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate bool_t
257*7c478bd9Sstevel@tonic-gate xdr_pages(XDR *xdrs, struct mycon *m)
258*7c478bd9Sstevel@tonic-gate {
259*7c478bd9Sstevel@tonic-gate 	static	struct pag res;
260*7c478bd9Sstevel@tonic-gate 	bool_t	false = FALSE;
261*7c478bd9Sstevel@tonic-gate 	bool_t	true = TRUE;
262*7c478bd9Sstevel@tonic-gate #ifdef DOSWAB
263*7c478bd9Sstevel@tonic-gate 	short	*s;
264*7c478bd9Sstevel@tonic-gate 	int	i;
265*7c478bd9Sstevel@tonic-gate 	int	cnt;
266*7c478bd9Sstevel@tonic-gate #endif
267*7c478bd9Sstevel@tonic-gate 	res.status = mygetpage(res.pag_u.ok.blkdat, &(res.pag_u.ok.blkno), m);
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate #ifdef DOSWAB
270*7c478bd9Sstevel@tonic-gate 	s = (short *)res.pag_u.ok.blkdat;
271*7c478bd9Sstevel@tonic-gate 	cnt = s[0];
272*7c478bd9Sstevel@tonic-gate 	for (i = 0; i <= cnt; i++)
273*7c478bd9Sstevel@tonic-gate 		s[i] = ntohs(s[i]);
274*7c478bd9Sstevel@tonic-gate #endif
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	if (!xdr_pag(xdrs, &res))
277*7c478bd9Sstevel@tonic-gate 		return (FALSE);
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	while (res.status == OK) {
280*7c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true))
281*7c478bd9Sstevel@tonic-gate 			return (FALSE);
282*7c478bd9Sstevel@tonic-gate 		res.status = mygetpage(res.pag_u.ok.blkdat,
283*7c478bd9Sstevel@tonic-gate 					&(res.pag_u.ok.blkno), m);
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate #ifdef DOSWAB
286*7c478bd9Sstevel@tonic-gate 		s = (short *)res.pag_u.ok.blkdat;
287*7c478bd9Sstevel@tonic-gate 		cnt = s[0];
288*7c478bd9Sstevel@tonic-gate 		for (i = 0; i <= cnt; i++)
289*7c478bd9Sstevel@tonic-gate 			s[i] = ntohs(s[i]);
290*7c478bd9Sstevel@tonic-gate #endif
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 		if (!xdr_pag(xdrs, &res))
293*7c478bd9Sstevel@tonic-gate 			return (FALSE);
294*7c478bd9Sstevel@tonic-gate 	}
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	return (xdr_bool(xdrs, &false));
297*7c478bd9Sstevel@tonic-gate }
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate int
300*7c478bd9Sstevel@tonic-gate mygetdir(char *block, int *no, struct mycon *m)
301*7c478bd9Sstevel@tonic-gate {
302*7c478bd9Sstevel@tonic-gate 	int	status;
303*7c478bd9Sstevel@tonic-gate 	int	len;
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	if (m->firstd == 0) {
306*7c478bd9Sstevel@tonic-gate 		lseek(m->map->entries->dbm_dirf, 0, 0);
307*7c478bd9Sstevel@tonic-gate 		m->firstd = 1;
308*7c478bd9Sstevel@tonic-gate 	} else
309*7c478bd9Sstevel@tonic-gate 		m->firstd++;
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 	len = read(m->map->entries->dbm_dirf, block, DBLKSIZ);
312*7c478bd9Sstevel@tonic-gate 	*no = (m->firstd) - 1;
313*7c478bd9Sstevel@tonic-gate 	status = OK;
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 	/*
316*7c478bd9Sstevel@tonic-gate 	 * printf("dir block %d\n", (m->firstd) - 1);
317*7c478bd9Sstevel@tonic-gate 	 */
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 	if (len < 0) {
320*7c478bd9Sstevel@tonic-gate 		perror("read directory");
321*7c478bd9Sstevel@tonic-gate 		status = GETDBM_ERROR;
322*7c478bd9Sstevel@tonic-gate 	} else if (len == 0) {
323*7c478bd9Sstevel@tonic-gate 		status = GETDBM_EOF;
324*7c478bd9Sstevel@tonic-gate 		/*
325*7c478bd9Sstevel@tonic-gate 		 * printf("dir EOF\n");
326*7c478bd9Sstevel@tonic-gate 		 */
327*7c478bd9Sstevel@tonic-gate 	}
328*7c478bd9Sstevel@tonic-gate 	return (status);
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate bool_t
332*7c478bd9Sstevel@tonic-gate xdr_dirs(XDR *xdrs, struct mycon *m)
333*7c478bd9Sstevel@tonic-gate {
334*7c478bd9Sstevel@tonic-gate 	static	struct dir res;
335*7c478bd9Sstevel@tonic-gate 	bool_t	false = FALSE;
336*7c478bd9Sstevel@tonic-gate 	bool_t	true = TRUE;
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 	res.status = mygetdir(res.dir_u.ok.blkdat, &(res.dir_u.ok.blkno), m);
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 	if (!xdr_dir(xdrs, &res))
341*7c478bd9Sstevel@tonic-gate 		return (FALSE);
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 	while (res.status == OK) {
344*7c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true))
345*7c478bd9Sstevel@tonic-gate 			return (FALSE);
346*7c478bd9Sstevel@tonic-gate 		res.status = mygetdir(res.dir_u.ok.blkdat,
347*7c478bd9Sstevel@tonic-gate 					&(res.dir_u.ok.blkno), m);
348*7c478bd9Sstevel@tonic-gate 		if (!xdr_dir(xdrs, &res))
349*7c478bd9Sstevel@tonic-gate 			return (FALSE);
350*7c478bd9Sstevel@tonic-gate 	}
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 	return (xdr_bool(xdrs, &false));
353*7c478bd9Sstevel@tonic-gate }
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate int
356*7c478bd9Sstevel@tonic-gate mygetpage(char *block, int *pageno, struct mycon *m)
357*7c478bd9Sstevel@tonic-gate {
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 	for (; m->key.dptr;
360*7c478bd9Sstevel@tonic-gate 			m->key = shim_dbm_do_nextkey((DBM *)m->map, m->key)) {
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 		if (m->map->entries->dbm_pagbno != m->lblk) {
363*7c478bd9Sstevel@tonic-gate 			/*
364*7c478bd9Sstevel@tonic-gate 			 * printf("block=%d lblk=%d\n",
365*7c478bd9Sstevel@tonic-gate 			 *		m->map->entries->dbm_pagbno,
366*7c478bd9Sstevel@tonic-gate 			 * 		m->lblk);
367*7c478bd9Sstevel@tonic-gate 			 */
368*7c478bd9Sstevel@tonic-gate 			m->lblk = m->map->entries->dbm_pagbno;
369*7c478bd9Sstevel@tonic-gate 			*pageno = m->lblk;
370*7c478bd9Sstevel@tonic-gate 			memmove(block, m->map->entries->dbm_pagbuf, PBLKSIZ);
371*7c478bd9Sstevel@tonic-gate 			/* advance key on first  try	*/
372*7c478bd9Sstevel@tonic-gate 			m->key = mydbm_topkey(m->map->entries, m->key);
373*7c478bd9Sstevel@tonic-gate 			m->key = shim_dbm_do_nextkey((DBM *)m->map, m->key);
374*7c478bd9Sstevel@tonic-gate 			return (OK);
375*7c478bd9Sstevel@tonic-gate 		}
376*7c478bd9Sstevel@tonic-gate 	}
377*7c478bd9Sstevel@tonic-gate 	/*
378*7c478bd9Sstevel@tonic-gate 	 * printf("EOF\n");
379*7c478bd9Sstevel@tonic-gate 	 */
380*7c478bd9Sstevel@tonic-gate 	return (GETDBM_EOF);
381*7c478bd9Sstevel@tonic-gate }
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate datum
384*7c478bd9Sstevel@tonic-gate mydbm_topkey(DBM *db, datum okey)
385*7c478bd9Sstevel@tonic-gate {
386*7c478bd9Sstevel@tonic-gate 	datum		ans;
387*7c478bd9Sstevel@tonic-gate 	datum		tmp;
388*7c478bd9Sstevel@tonic-gate 	register char	*buf;
389*7c478bd9Sstevel@tonic-gate 	int		n;
390*7c478bd9Sstevel@tonic-gate 	register short	*sp;
391*7c478bd9Sstevel@tonic-gate 	register	t;
392*7c478bd9Sstevel@tonic-gate 	datum		item;
393*7c478bd9Sstevel@tonic-gate 	register	m;
394*7c478bd9Sstevel@tonic-gate 	register char	*p1, *p2;
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 	buf = db->dbm_pagbuf;
397*7c478bd9Sstevel@tonic-gate 	sp = (short *)buf;
398*7c478bd9Sstevel@tonic-gate 	/* find the maximum key in cmpdatum order */
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 	if ((unsigned)0 >= sp[0]) {
401*7c478bd9Sstevel@tonic-gate 		return (okey);
402*7c478bd9Sstevel@tonic-gate 	} else {
403*7c478bd9Sstevel@tonic-gate 		ans.dptr = buf + sp[1];
404*7c478bd9Sstevel@tonic-gate 		ans.dsize = PBLKSIZ - sp[1];
405*7c478bd9Sstevel@tonic-gate 	}
406*7c478bd9Sstevel@tonic-gate 	for (n = 2; ; n += 2) {
407*7c478bd9Sstevel@tonic-gate 		if ((unsigned)n >= sp[0]) {
408*7c478bd9Sstevel@tonic-gate 			if (ans.dptr == NULL) {
409*7c478bd9Sstevel@tonic-gate 				return (okey);
410*7c478bd9Sstevel@tonic-gate 			} else {
411*7c478bd9Sstevel@tonic-gate 				return (ans);
412*7c478bd9Sstevel@tonic-gate 			}
413*7c478bd9Sstevel@tonic-gate 		} else {
414*7c478bd9Sstevel@tonic-gate 			t = PBLKSIZ;
415*7c478bd9Sstevel@tonic-gate 			if (n > 0)
416*7c478bd9Sstevel@tonic-gate 				t = sp[n];
417*7c478bd9Sstevel@tonic-gate 			tmp.dptr = buf + sp[n + 1];
418*7c478bd9Sstevel@tonic-gate 			tmp.dsize = t - sp[n + 1];
419*7c478bd9Sstevel@tonic-gate 		}
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate 		m = tmp.dsize;
422*7c478bd9Sstevel@tonic-gate 		if (m != ans.dsize) {
423*7c478bd9Sstevel@tonic-gate 			if ((m - ans.dsize) < 0)
424*7c478bd9Sstevel@tonic-gate 				ans = tmp;
425*7c478bd9Sstevel@tonic-gate 		} else if (m == 0) {
426*7c478bd9Sstevel@tonic-gate 		} else {
427*7c478bd9Sstevel@tonic-gate 			p1 = tmp.dptr;
428*7c478bd9Sstevel@tonic-gate 			p2 = ans.dptr;
429*7c478bd9Sstevel@tonic-gate 			do
430*7c478bd9Sstevel@tonic-gate 				if (*p1++ != *p2++) {
431*7c478bd9Sstevel@tonic-gate 					if ((*--p1 - *--p2) < 0)
432*7c478bd9Sstevel@tonic-gate 						ans = tmp;
433*7c478bd9Sstevel@tonic-gate 				break;
434*7c478bd9Sstevel@tonic-gate 				}
435*7c478bd9Sstevel@tonic-gate 			while (--m);
436*7c478bd9Sstevel@tonic-gate 		}
437*7c478bd9Sstevel@tonic-gate 	}
438*7c478bd9Sstevel@tonic-gate }
439