xref: /illumos-gate/usr/src/lib/libnsl/yp/dbm.c (revision 7c478bd9)
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 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved   */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
32*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of
33*7c478bd9Sstevel@tonic-gate  * California.
34*7c478bd9Sstevel@tonic-gate  */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #include <rpcsvc/dbm.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
40*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
42*7c478bd9Sstevel@tonic-gate #include <string.h>
43*7c478bd9Sstevel@tonic-gate #include <unistd.h>
44*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
45*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
46*7c478bd9Sstevel@tonic-gate #include <stdio.h>
47*7c478bd9Sstevel@tonic-gate #include <errno.h>
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate #if defined(sparc)
50*7c478bd9Sstevel@tonic-gate #define	_FSTAT	_fstat
51*7c478bd9Sstevel@tonic-gate extern int _fstat(int, struct stat *);
52*7c478bd9Sstevel@tonic-gate #else  /* !sparc */
53*7c478bd9Sstevel@tonic-gate #define	_FSTAT	fstat
54*7c478bd9Sstevel@tonic-gate #endif /* sparc */
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate void dbm_access(long);
58*7c478bd9Sstevel@tonic-gate void delitem(char *, int);
59*7c478bd9Sstevel@tonic-gate void chkblk(char *);
60*7c478bd9Sstevel@tonic-gate int  additem(char *, datum);
61*7c478bd9Sstevel@tonic-gate int  getbit(void);
62*7c478bd9Sstevel@tonic-gate int  setbit(void);
63*7c478bd9Sstevel@tonic-gate int  cmpdatum(datum, datum);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate int
66*7c478bd9Sstevel@tonic-gate dbminit(file)
67*7c478bd9Sstevel@tonic-gate 	char *file;
68*7c478bd9Sstevel@tonic-gate {
69*7c478bd9Sstevel@tonic-gate 	struct stat statb;
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbminit, 0);
72*7c478bd9Sstevel@tonic-gate 	dbrdonly = 0;
73*7c478bd9Sstevel@tonic-gate 	if (strlcpy(pagbuf, file, sizeof (pagbuf)) >= sizeof (pagbuf) ||
74*7c478bd9Sstevel@tonic-gate 	    strlcat(pagbuf, ".pag", sizeof (pagbuf)) >= sizeof (pagbuf)) {
75*7c478bd9Sstevel@tonic-gate 		/*
76*7c478bd9Sstevel@tonic-gate 		 * file.pag does not fit into pagbuf.
77*7c478bd9Sstevel@tonic-gate 		 * fails with ENAMETOOLONG.
78*7c478bd9Sstevel@tonic-gate 		 */
79*7c478bd9Sstevel@tonic-gate 		trace1(TR_dbminit, 1);
80*7c478bd9Sstevel@tonic-gate 		errno = ENAMETOOLONG;
81*7c478bd9Sstevel@tonic-gate 		return (-1);
82*7c478bd9Sstevel@tonic-gate 	}
83*7c478bd9Sstevel@tonic-gate 	pagf = open(pagbuf, 2);
84*7c478bd9Sstevel@tonic-gate 	if (pagf < 0) {
85*7c478bd9Sstevel@tonic-gate 		pagf = open(pagbuf, 0);
86*7c478bd9Sstevel@tonic-gate 		dbrdonly = 1;
87*7c478bd9Sstevel@tonic-gate 	}
88*7c478bd9Sstevel@tonic-gate 	/*
89*7c478bd9Sstevel@tonic-gate 	 * We know this won't overflow so it is safe to ignore the
90*7c478bd9Sstevel@tonic-gate 	 * return value; we use strl* to prevent false hits in
91*7c478bd9Sstevel@tonic-gate 	 * code sweeps.
92*7c478bd9Sstevel@tonic-gate 	 */
93*7c478bd9Sstevel@tonic-gate 	(void) strlcpy(pagbuf, file, sizeof (pagbuf));
94*7c478bd9Sstevel@tonic-gate 	(void) strlcat(pagbuf, ".dir", sizeof (pagbuf));
95*7c478bd9Sstevel@tonic-gate 	dirf = open(pagbuf, 2);
96*7c478bd9Sstevel@tonic-gate 	if (dirf < 0) {
97*7c478bd9Sstevel@tonic-gate 		dirf = open(pagbuf, 0);
98*7c478bd9Sstevel@tonic-gate 		dbrdonly = 1;
99*7c478bd9Sstevel@tonic-gate 	}
100*7c478bd9Sstevel@tonic-gate 	if (pagf < 0 || dirf < 0) {
101*7c478bd9Sstevel@tonic-gate 		trace1(TR_dbminit, 1);
102*7c478bd9Sstevel@tonic-gate 		return (-1);
103*7c478bd9Sstevel@tonic-gate 	}
104*7c478bd9Sstevel@tonic-gate 	_FSTAT(dirf, &statb);
105*7c478bd9Sstevel@tonic-gate 	maxbno = statb.st_size*BYTESIZ-1;
106*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbminit, 1);
107*7c478bd9Sstevel@tonic-gate 	return (0);
108*7c478bd9Sstevel@tonic-gate }
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate static long oldb1 = -1;
111*7c478bd9Sstevel@tonic-gate static long oldb2 = -1;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /* Avoid using cached data for subsequent accesses. */
114*7c478bd9Sstevel@tonic-gate int
115*7c478bd9Sstevel@tonic-gate dbmflush()
116*7c478bd9Sstevel@tonic-gate {
117*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbmflush, 0);
118*7c478bd9Sstevel@tonic-gate 	oldb1 = -1;
119*7c478bd9Sstevel@tonic-gate 	oldb2 = -1;
120*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbmflush, 1);
121*7c478bd9Sstevel@tonic-gate 	return (0);
122*7c478bd9Sstevel@tonic-gate }
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate /* Clean up after ourself. */
125*7c478bd9Sstevel@tonic-gate int
126*7c478bd9Sstevel@tonic-gate dbmclose()
127*7c478bd9Sstevel@tonic-gate {
128*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbmclose, 0);
129*7c478bd9Sstevel@tonic-gate 	(void) close(pagf);
130*7c478bd9Sstevel@tonic-gate 	(void) close(dirf);
131*7c478bd9Sstevel@tonic-gate 	bitno = 0;
132*7c478bd9Sstevel@tonic-gate 	maxbno = 0;
133*7c478bd9Sstevel@tonic-gate 	blkno = 0;
134*7c478bd9Sstevel@tonic-gate 	hmask = 0;
135*7c478bd9Sstevel@tonic-gate 	oldb1 = -1;
136*7c478bd9Sstevel@tonic-gate 	oldb2 = -1;
137*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbmclose, 1);
138*7c478bd9Sstevel@tonic-gate 	return (0);
139*7c478bd9Sstevel@tonic-gate }
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate long
142*7c478bd9Sstevel@tonic-gate forder(key)
143*7c478bd9Sstevel@tonic-gate 	datum key;
144*7c478bd9Sstevel@tonic-gate {
145*7c478bd9Sstevel@tonic-gate 	long hash;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	trace1(TR_forder, 0);
148*7c478bd9Sstevel@tonic-gate 	hash = calchash(key);
149*7c478bd9Sstevel@tonic-gate 	for (hmask = 0; ; hmask = (hmask<<1) + 1) {
150*7c478bd9Sstevel@tonic-gate 		blkno = hash & hmask;
151*7c478bd9Sstevel@tonic-gate 		bitno = blkno + hmask;
152*7c478bd9Sstevel@tonic-gate 		if (getbit() == 0)
153*7c478bd9Sstevel@tonic-gate 			break;
154*7c478bd9Sstevel@tonic-gate 	}
155*7c478bd9Sstevel@tonic-gate 	trace1(TR_forder, 1);
156*7c478bd9Sstevel@tonic-gate 	return (blkno);
157*7c478bd9Sstevel@tonic-gate }
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate datum
160*7c478bd9Sstevel@tonic-gate fetch(key)
161*7c478bd9Sstevel@tonic-gate 	datum key;
162*7c478bd9Sstevel@tonic-gate {
163*7c478bd9Sstevel@tonic-gate 	int i;
164*7c478bd9Sstevel@tonic-gate 	datum item;
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 	trace1(TR_fetch, 0);
167*7c478bd9Sstevel@tonic-gate 	dbm_access(calchash(key));
168*7c478bd9Sstevel@tonic-gate 	for (i = 0; ; i += 2) {
169*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
170*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL) {
171*7c478bd9Sstevel@tonic-gate 			trace1(TR_fetch, 1);
172*7c478bd9Sstevel@tonic-gate 			return (item);
173*7c478bd9Sstevel@tonic-gate 		}
174*7c478bd9Sstevel@tonic-gate 		if (cmpdatum(key, item) == 0) {
175*7c478bd9Sstevel@tonic-gate 			item = makdatum(pagbuf, i+1);
176*7c478bd9Sstevel@tonic-gate 			if (item.dptr == NULL)
177*7c478bd9Sstevel@tonic-gate 				(void) printf("items not in pairs\n");
178*7c478bd9Sstevel@tonic-gate 			trace1(TR_fetch, 1);
179*7c478bd9Sstevel@tonic-gate 			return (item);
180*7c478bd9Sstevel@tonic-gate 		}
181*7c478bd9Sstevel@tonic-gate 	}
182*7c478bd9Sstevel@tonic-gate }
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate int
185*7c478bd9Sstevel@tonic-gate delete(key)
186*7c478bd9Sstevel@tonic-gate 	datum key;
187*7c478bd9Sstevel@tonic-gate {
188*7c478bd9Sstevel@tonic-gate 	int i;
189*7c478bd9Sstevel@tonic-gate 	datum item;
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 	trace1(TR_delete, 0);
192*7c478bd9Sstevel@tonic-gate 	if (dbrdonly) {
193*7c478bd9Sstevel@tonic-gate 		trace1(TR_delete, 1);
194*7c478bd9Sstevel@tonic-gate 		return (-1);
195*7c478bd9Sstevel@tonic-gate 	}
196*7c478bd9Sstevel@tonic-gate 	dbm_access(calchash(key));
197*7c478bd9Sstevel@tonic-gate 	for (i = 0; ; i += 2) {
198*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
199*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL) {
200*7c478bd9Sstevel@tonic-gate 			trace1(TR_delete, 1);
201*7c478bd9Sstevel@tonic-gate 			return (-1);
202*7c478bd9Sstevel@tonic-gate 		}
203*7c478bd9Sstevel@tonic-gate 		if (cmpdatum(key, item) == 0) {
204*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
205*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
206*7c478bd9Sstevel@tonic-gate 			break;
207*7c478bd9Sstevel@tonic-gate 		}
208*7c478bd9Sstevel@tonic-gate 	}
209*7c478bd9Sstevel@tonic-gate 	(void) lseek(pagf, blkno*PBLKSIZ, 0);
210*7c478bd9Sstevel@tonic-gate 	(void) write(pagf, pagbuf, PBLKSIZ);
211*7c478bd9Sstevel@tonic-gate 	trace1(TR_delete, 1);
212*7c478bd9Sstevel@tonic-gate 	return (0);
213*7c478bd9Sstevel@tonic-gate }
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate int
216*7c478bd9Sstevel@tonic-gate store(key, dat)
217*7c478bd9Sstevel@tonic-gate 	datum key, dat;
218*7c478bd9Sstevel@tonic-gate {
219*7c478bd9Sstevel@tonic-gate 	int i;
220*7c478bd9Sstevel@tonic-gate 	datum item;
221*7c478bd9Sstevel@tonic-gate 	char ovfbuf[PBLKSIZ];
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 	trace1(TR_store, 0);
224*7c478bd9Sstevel@tonic-gate 	if (dbrdonly) {
225*7c478bd9Sstevel@tonic-gate 		trace1(TR_store, 1);
226*7c478bd9Sstevel@tonic-gate 		return (-1);
227*7c478bd9Sstevel@tonic-gate 	}
228*7c478bd9Sstevel@tonic-gate loop:
229*7c478bd9Sstevel@tonic-gate 	dbm_access(calchash(key));
230*7c478bd9Sstevel@tonic-gate 	for (i = 0; ; i += 2) {
231*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
232*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL)
233*7c478bd9Sstevel@tonic-gate 			break;
234*7c478bd9Sstevel@tonic-gate 		if (cmpdatum(key, item) == 0) {
235*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
236*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
237*7c478bd9Sstevel@tonic-gate 			break;
238*7c478bd9Sstevel@tonic-gate 		}
239*7c478bd9Sstevel@tonic-gate 	}
240*7c478bd9Sstevel@tonic-gate 	i = additem(pagbuf, key);
241*7c478bd9Sstevel@tonic-gate 	if (i < 0)
242*7c478bd9Sstevel@tonic-gate 		goto split;
243*7c478bd9Sstevel@tonic-gate 	if (additem(pagbuf, dat) < 0) {
244*7c478bd9Sstevel@tonic-gate 		delitem(pagbuf, i);
245*7c478bd9Sstevel@tonic-gate 		goto split;
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate 	(void) lseek(pagf, blkno*PBLKSIZ, 0);
248*7c478bd9Sstevel@tonic-gate 	(void) write(pagf, pagbuf, PBLKSIZ);
249*7c478bd9Sstevel@tonic-gate 	trace1(TR_store, 1);
250*7c478bd9Sstevel@tonic-gate 	return (0);
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate split:
253*7c478bd9Sstevel@tonic-gate 	if (key.dsize + dat.dsize + 3 * sizeof (short) >= PBLKSIZ) {
254*7c478bd9Sstevel@tonic-gate 		(void) printf("entry too big\n");
255*7c478bd9Sstevel@tonic-gate 		trace1(TR_store, 1);
256*7c478bd9Sstevel@tonic-gate 		return (-1);
257*7c478bd9Sstevel@tonic-gate 	}
258*7c478bd9Sstevel@tonic-gate 	(void) memset((char *)&ovfbuf, 0, PBLKSIZ);
259*7c478bd9Sstevel@tonic-gate 	for (i = 0; ; ) {
260*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
261*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL)
262*7c478bd9Sstevel@tonic-gate 			break;
263*7c478bd9Sstevel@tonic-gate 		if (calchash(item) & (hmask+1)) {
264*7c478bd9Sstevel@tonic-gate 			(void) additem(ovfbuf, item);
265*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
266*7c478bd9Sstevel@tonic-gate 			item = makdatum(pagbuf, i);
267*7c478bd9Sstevel@tonic-gate 			if (item.dptr == NULL) {
268*7c478bd9Sstevel@tonic-gate 				(void) printf("split not paired\n");
269*7c478bd9Sstevel@tonic-gate 				break;
270*7c478bd9Sstevel@tonic-gate 			}
271*7c478bd9Sstevel@tonic-gate 			(void) additem(ovfbuf, item);
272*7c478bd9Sstevel@tonic-gate 			delitem(pagbuf, i);
273*7c478bd9Sstevel@tonic-gate 			continue;
274*7c478bd9Sstevel@tonic-gate 		}
275*7c478bd9Sstevel@tonic-gate 		i += 2;
276*7c478bd9Sstevel@tonic-gate 	}
277*7c478bd9Sstevel@tonic-gate 	(void) lseek(pagf, blkno*PBLKSIZ, 0);
278*7c478bd9Sstevel@tonic-gate 	if (write(pagf, pagbuf, PBLKSIZ) < 0) {
279*7c478bd9Sstevel@tonic-gate 		trace1(TR_store, 1);
280*7c478bd9Sstevel@tonic-gate 		return (-1);
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 	(void) lseek(pagf, (blkno+hmask+1)*PBLKSIZ, 0);
283*7c478bd9Sstevel@tonic-gate 	if (write(pagf, ovfbuf, PBLKSIZ) < 0) {
284*7c478bd9Sstevel@tonic-gate 		trace1(TR_store, 1);
285*7c478bd9Sstevel@tonic-gate 		return (-1);
286*7c478bd9Sstevel@tonic-gate 	}
287*7c478bd9Sstevel@tonic-gate 	if (setbit() < 0) {
288*7c478bd9Sstevel@tonic-gate 		trace1(TR_store, 1);
289*7c478bd9Sstevel@tonic-gate 		return (-1);
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 	goto loop;
292*7c478bd9Sstevel@tonic-gate }
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate datum
295*7c478bd9Sstevel@tonic-gate firstkey()
296*7c478bd9Sstevel@tonic-gate {
297*7c478bd9Sstevel@tonic-gate 	datum dummy;
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate 	trace1(TR_firstkey, 0);
300*7c478bd9Sstevel@tonic-gate 	dummy = firsthash(0L);
301*7c478bd9Sstevel@tonic-gate 	trace1(TR_firstkey, 1);
302*7c478bd9Sstevel@tonic-gate 	return (dummy);
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate datum
306*7c478bd9Sstevel@tonic-gate nextkey(key)
307*7c478bd9Sstevel@tonic-gate 	datum key;
308*7c478bd9Sstevel@tonic-gate {
309*7c478bd9Sstevel@tonic-gate 	int i;
310*7c478bd9Sstevel@tonic-gate 	datum item, bitem;
311*7c478bd9Sstevel@tonic-gate 	long hash;
312*7c478bd9Sstevel@tonic-gate 	int f;
313*7c478bd9Sstevel@tonic-gate 	datum dummy;
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 	trace1(TR_nextkey, 0);
316*7c478bd9Sstevel@tonic-gate #ifdef lint
317*7c478bd9Sstevel@tonic-gate 	bitem.dptr = NULL;
318*7c478bd9Sstevel@tonic-gate 	bitem.dsize = 0;
319*7c478bd9Sstevel@tonic-gate #endif /* lint */
320*7c478bd9Sstevel@tonic-gate 	hash = calchash(key);
321*7c478bd9Sstevel@tonic-gate 	dbm_access(hash);
322*7c478bd9Sstevel@tonic-gate 	f = 1;
323*7c478bd9Sstevel@tonic-gate 	for (i = 0; ; i += 2) {
324*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
325*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL)
326*7c478bd9Sstevel@tonic-gate 			break;
327*7c478bd9Sstevel@tonic-gate 		if (cmpdatum(key, item) <= 0)
328*7c478bd9Sstevel@tonic-gate 			continue;
329*7c478bd9Sstevel@tonic-gate 		if (f || cmpdatum(bitem, item) < 0) {
330*7c478bd9Sstevel@tonic-gate 			bitem = item;
331*7c478bd9Sstevel@tonic-gate 			f = 0;
332*7c478bd9Sstevel@tonic-gate 		}
333*7c478bd9Sstevel@tonic-gate 	}
334*7c478bd9Sstevel@tonic-gate 	if (f == 0) {
335*7c478bd9Sstevel@tonic-gate 		trace1(TR_nextkey, 1);
336*7c478bd9Sstevel@tonic-gate 		return (bitem);
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 	hash = hashinc(hash);
339*7c478bd9Sstevel@tonic-gate 	if (hash == 0) {
340*7c478bd9Sstevel@tonic-gate 		trace1(TR_nextkey, 1);
341*7c478bd9Sstevel@tonic-gate 		return (item);
342*7c478bd9Sstevel@tonic-gate 	}
343*7c478bd9Sstevel@tonic-gate 	dummy = firsthash(hash);
344*7c478bd9Sstevel@tonic-gate 	trace1(TR_nextkey, 1);
345*7c478bd9Sstevel@tonic-gate 	return (dummy);
346*7c478bd9Sstevel@tonic-gate }
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate datum
349*7c478bd9Sstevel@tonic-gate firsthash(hash)
350*7c478bd9Sstevel@tonic-gate 	long hash;
351*7c478bd9Sstevel@tonic-gate {
352*7c478bd9Sstevel@tonic-gate 	int i;
353*7c478bd9Sstevel@tonic-gate 	datum item, bitem;
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 	trace2(TR_firsthash, 0, hash);
356*7c478bd9Sstevel@tonic-gate loop:
357*7c478bd9Sstevel@tonic-gate 	dbm_access(hash);
358*7c478bd9Sstevel@tonic-gate 	bitem = makdatum(pagbuf, 0);
359*7c478bd9Sstevel@tonic-gate 	for (i = 2; ; i += 2) {
360*7c478bd9Sstevel@tonic-gate 		item = makdatum(pagbuf, i);
361*7c478bd9Sstevel@tonic-gate 		if (item.dptr == NULL)
362*7c478bd9Sstevel@tonic-gate 			break;
363*7c478bd9Sstevel@tonic-gate 		if (cmpdatum(bitem, item) < 0)
364*7c478bd9Sstevel@tonic-gate 			bitem = item;
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 	if (bitem.dptr != NULL) {
367*7c478bd9Sstevel@tonic-gate 		trace1(TR_firsthash, 1);
368*7c478bd9Sstevel@tonic-gate 		return (bitem);
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate 	hash = hashinc(hash);
371*7c478bd9Sstevel@tonic-gate 	if (hash == 0) {
372*7c478bd9Sstevel@tonic-gate 		trace1(TR_firsthash, 1);
373*7c478bd9Sstevel@tonic-gate 		return (item);
374*7c478bd9Sstevel@tonic-gate 	}
375*7c478bd9Sstevel@tonic-gate 	goto loop;
376*7c478bd9Sstevel@tonic-gate }
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate void
379*7c478bd9Sstevel@tonic-gate dbm_access(hash)
380*7c478bd9Sstevel@tonic-gate 	long hash;
381*7c478bd9Sstevel@tonic-gate {
382*7c478bd9Sstevel@tonic-gate 	ssize_t readsize;
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 	trace2(TR_dbm_access, 0, hash);
385*7c478bd9Sstevel@tonic-gate 	for (hmask = 0; ; hmask = (hmask<<1) + 1) {
386*7c478bd9Sstevel@tonic-gate 		blkno = hash & hmask;
387*7c478bd9Sstevel@tonic-gate 		bitno = blkno + hmask;
388*7c478bd9Sstevel@tonic-gate 		if (getbit() == 0)
389*7c478bd9Sstevel@tonic-gate 			break;
390*7c478bd9Sstevel@tonic-gate 	}
391*7c478bd9Sstevel@tonic-gate 	if (blkno != oldb1) {
392*7c478bd9Sstevel@tonic-gate 		(void) lseek(pagf, blkno*PBLKSIZ, 0);
393*7c478bd9Sstevel@tonic-gate 		readsize = read(pagf, pagbuf, PBLKSIZ);
394*7c478bd9Sstevel@tonic-gate 		if (readsize != PBLKSIZ) {
395*7c478bd9Sstevel@tonic-gate 			if (readsize < 0) readsize = 0;
396*7c478bd9Sstevel@tonic-gate 			(void) memset((char *)(&pagbuf+readsize),
397*7c478bd9Sstevel@tonic-gate 			    0, PBLKSIZ-readsize);
398*7c478bd9Sstevel@tonic-gate 		}
399*7c478bd9Sstevel@tonic-gate 		chkblk(pagbuf);
400*7c478bd9Sstevel@tonic-gate 		oldb1 = blkno;
401*7c478bd9Sstevel@tonic-gate 	}
402*7c478bd9Sstevel@tonic-gate 	trace1(TR_dbm_access, 1);
403*7c478bd9Sstevel@tonic-gate }
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate int
406*7c478bd9Sstevel@tonic-gate getbit(void)
407*7c478bd9Sstevel@tonic-gate {
408*7c478bd9Sstevel@tonic-gate 	long bn;
409*7c478bd9Sstevel@tonic-gate 	ssize_t readsize;
410*7c478bd9Sstevel@tonic-gate 	long b, i, n;
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate 	trace1(TR_getbit, 0);
413*7c478bd9Sstevel@tonic-gate 	if (bitno > maxbno) {
414*7c478bd9Sstevel@tonic-gate 		trace1(TR_getbit, 1);
415*7c478bd9Sstevel@tonic-gate 		return (0);
416*7c478bd9Sstevel@tonic-gate 	}
417*7c478bd9Sstevel@tonic-gate 	n = bitno % BYTESIZ;
418*7c478bd9Sstevel@tonic-gate 	bn = bitno / BYTESIZ;
419*7c478bd9Sstevel@tonic-gate 	i = bn % DBLKSIZ;
420*7c478bd9Sstevel@tonic-gate 	b = bn / DBLKSIZ;
421*7c478bd9Sstevel@tonic-gate 	if (b != oldb2) {
422*7c478bd9Sstevel@tonic-gate 		(void) lseek(dirf, (long)b*DBLKSIZ, 0);
423*7c478bd9Sstevel@tonic-gate 		readsize = read(dirf, dirbuf, DBLKSIZ);
424*7c478bd9Sstevel@tonic-gate 		if (readsize != DBLKSIZ) {
425*7c478bd9Sstevel@tonic-gate 			if (readsize < 0) readsize = 0;
426*7c478bd9Sstevel@tonic-gate 			(void) memset((char *)(&dirbuf+readsize),
427*7c478bd9Sstevel@tonic-gate 			    0, DBLKSIZ-readsize);
428*7c478bd9Sstevel@tonic-gate 		}
429*7c478bd9Sstevel@tonic-gate 		oldb2 = b;
430*7c478bd9Sstevel@tonic-gate 	}
431*7c478bd9Sstevel@tonic-gate 	if (dirbuf[i] & (1<<n)) {
432*7c478bd9Sstevel@tonic-gate 		trace1(TR_getbit, 1);
433*7c478bd9Sstevel@tonic-gate 		return (1);
434*7c478bd9Sstevel@tonic-gate 	}
435*7c478bd9Sstevel@tonic-gate 	trace1(TR_getbit, 1);
436*7c478bd9Sstevel@tonic-gate 	return (0);
437*7c478bd9Sstevel@tonic-gate }
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate int
440*7c478bd9Sstevel@tonic-gate setbit(void)
441*7c478bd9Sstevel@tonic-gate {
442*7c478bd9Sstevel@tonic-gate 	long bn;
443*7c478bd9Sstevel@tonic-gate 	long i, n, b;
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	trace1(TR_setbit, 0);
446*7c478bd9Sstevel@tonic-gate 	if (dbrdonly) {
447*7c478bd9Sstevel@tonic-gate 		trace1(TR_setbit, 1);
448*7c478bd9Sstevel@tonic-gate 		return (-1);
449*7c478bd9Sstevel@tonic-gate 	}
450*7c478bd9Sstevel@tonic-gate 	if (bitno > maxbno) {
451*7c478bd9Sstevel@tonic-gate 		maxbno = bitno;
452*7c478bd9Sstevel@tonic-gate 		(void) getbit();
453*7c478bd9Sstevel@tonic-gate 	}
454*7c478bd9Sstevel@tonic-gate 	n = bitno % BYTESIZ;
455*7c478bd9Sstevel@tonic-gate 	bn = bitno / BYTESIZ;
456*7c478bd9Sstevel@tonic-gate 	i = bn % DBLKSIZ;
457*7c478bd9Sstevel@tonic-gate 	b = bn / DBLKSIZ;
458*7c478bd9Sstevel@tonic-gate 	dirbuf[i] |= 1<<n;
459*7c478bd9Sstevel@tonic-gate 	(void) lseek(dirf, (long)b*DBLKSIZ, 0);
460*7c478bd9Sstevel@tonic-gate 	if (write(dirf, dirbuf, DBLKSIZ) < 0) {
461*7c478bd9Sstevel@tonic-gate 		trace1(TR_setbit, 1);
462*7c478bd9Sstevel@tonic-gate 		return (-1);
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 	trace1(TR_setbit, 1);
465*7c478bd9Sstevel@tonic-gate 	return (0);
466*7c478bd9Sstevel@tonic-gate }
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate datum
469*7c478bd9Sstevel@tonic-gate makdatum(char buf[PBLKSIZ], int n)
470*7c478bd9Sstevel@tonic-gate {
471*7c478bd9Sstevel@tonic-gate 	short *sp;
472*7c478bd9Sstevel@tonic-gate 	int t;
473*7c478bd9Sstevel@tonic-gate 	datum item;
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 	trace1(TR_makdatum, 0);
476*7c478bd9Sstevel@tonic-gate 	sp = (short *)buf;
477*7c478bd9Sstevel@tonic-gate 	if (n < 0 || n >= sp[0])
478*7c478bd9Sstevel@tonic-gate 		goto null;
479*7c478bd9Sstevel@tonic-gate 	t = PBLKSIZ;
480*7c478bd9Sstevel@tonic-gate 	if (n > 0)
481*7c478bd9Sstevel@tonic-gate 		t = sp[n+1-1];
482*7c478bd9Sstevel@tonic-gate 	item.dptr = buf+sp[n+1];
483*7c478bd9Sstevel@tonic-gate 	item.dsize = t - sp[n+1];
484*7c478bd9Sstevel@tonic-gate 	trace1(TR_makdatum, 1);
485*7c478bd9Sstevel@tonic-gate 	return (item);
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate null:
488*7c478bd9Sstevel@tonic-gate 	item.dptr = NULL;
489*7c478bd9Sstevel@tonic-gate 	item.dsize = 0;
490*7c478bd9Sstevel@tonic-gate 	trace1(TR_makdatum, 1);
491*7c478bd9Sstevel@tonic-gate 	return (item);
492*7c478bd9Sstevel@tonic-gate }
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate int
495*7c478bd9Sstevel@tonic-gate cmpdatum(d1, d2)
496*7c478bd9Sstevel@tonic-gate 	datum d1, d2;
497*7c478bd9Sstevel@tonic-gate {
498*7c478bd9Sstevel@tonic-gate 	int n;
499*7c478bd9Sstevel@tonic-gate 	char *p1, *p2;
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	trace1(TR_cmpdatum, 0);
502*7c478bd9Sstevel@tonic-gate 	n = d1.dsize;
503*7c478bd9Sstevel@tonic-gate 	if (n != d2.dsize) {
504*7c478bd9Sstevel@tonic-gate 		trace1(TR_cmpdatum, 1);
505*7c478bd9Sstevel@tonic-gate 		return (n - d2.dsize);
506*7c478bd9Sstevel@tonic-gate 	}
507*7c478bd9Sstevel@tonic-gate 	if (n == 0) {
508*7c478bd9Sstevel@tonic-gate 		trace1(TR_cmpdatum, 1);
509*7c478bd9Sstevel@tonic-gate 		return (0);
510*7c478bd9Sstevel@tonic-gate 	}
511*7c478bd9Sstevel@tonic-gate 	p1 = d1.dptr;
512*7c478bd9Sstevel@tonic-gate 	p2 = d2.dptr;
513*7c478bd9Sstevel@tonic-gate 	do
514*7c478bd9Sstevel@tonic-gate 		if (*p1++ != *p2++) {
515*7c478bd9Sstevel@tonic-gate 			trace1(TR_cmpdatum, 1);
516*7c478bd9Sstevel@tonic-gate 			return (*--p1 - *--p2);
517*7c478bd9Sstevel@tonic-gate 		}
518*7c478bd9Sstevel@tonic-gate 	while (--n);
519*7c478bd9Sstevel@tonic-gate 	trace1(TR_cmpdatum, 1);
520*7c478bd9Sstevel@tonic-gate 	return (0);
521*7c478bd9Sstevel@tonic-gate }
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate int	hitab[16]
524*7c478bd9Sstevel@tonic-gate /*
525*7c478bd9Sstevel@tonic-gate  * ken's
526*7c478bd9Sstevel@tonic-gate  * {
527*7c478bd9Sstevel@tonic-gate  *	055, 043, 036, 054, 063, 014, 004, 005,
528*7c478bd9Sstevel@tonic-gate  *	010, 064, 077, 000, 035, 027, 025, 071,
529*7c478bd9Sstevel@tonic-gate  * };
530*7c478bd9Sstevel@tonic-gate  */
531*7c478bd9Sstevel@tonic-gate 	= {	61, 57, 53, 49, 45, 41, 37, 33,
532*7c478bd9Sstevel@tonic-gate 	29, 25, 21, 17, 13,  9,  5,  1,
533*7c478bd9Sstevel@tonic-gate };
534*7c478bd9Sstevel@tonic-gate long	hltab[64]
535*7c478bd9Sstevel@tonic-gate 	= {
536*7c478bd9Sstevel@tonic-gate 	06100151277L, 06106161736L, 06452611562L, 05001724107L,
537*7c478bd9Sstevel@tonic-gate 	02614772546L, 04120731531L, 04665262210L, 07347467531L,
538*7c478bd9Sstevel@tonic-gate 	06735253126L, 06042345173L, 03072226605L, 01464164730L,
539*7c478bd9Sstevel@tonic-gate 	03247435524L, 07652510057L, 01546775256L, 05714532133L,
540*7c478bd9Sstevel@tonic-gate 	06173260402L, 07517101630L, 02431460343L, 01743245566L,
541*7c478bd9Sstevel@tonic-gate 	00261675137L, 02433103631L, 03421772437L, 04447707466L,
542*7c478bd9Sstevel@tonic-gate 	04435620103L, 03757017115L, 03641531772L, 06767633246L,
543*7c478bd9Sstevel@tonic-gate 	02673230344L, 00260612216L, 04133454451L, 00615531516L,
544*7c478bd9Sstevel@tonic-gate 	06137717526L, 02574116560L, 02304023373L, 07061702261L,
545*7c478bd9Sstevel@tonic-gate 	05153031405L, 05322056705L, 07401116734L, 06552375715L,
546*7c478bd9Sstevel@tonic-gate 	06165233473L, 05311063631L, 01212221723L, 01052267235L,
547*7c478bd9Sstevel@tonic-gate 	06000615237L, 01075222665L, 06330216006L, 04402355630L,
548*7c478bd9Sstevel@tonic-gate 	01451177262L, 02000133436L, 06025467062L, 07121076461L,
549*7c478bd9Sstevel@tonic-gate 	03123433522L, 01010635225L, 01716177066L, 05161746527L,
550*7c478bd9Sstevel@tonic-gate 	01736635071L, 06243505026L, 03637211610L, 01756474365L,
551*7c478bd9Sstevel@tonic-gate 	04723077174L, 03642763134L, 05750130273L, 03655541561L,
552*7c478bd9Sstevel@tonic-gate };
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate long
555*7c478bd9Sstevel@tonic-gate hashinc(hash)
556*7c478bd9Sstevel@tonic-gate 	long hash;
557*7c478bd9Sstevel@tonic-gate {
558*7c478bd9Sstevel@tonic-gate 	long bit;
559*7c478bd9Sstevel@tonic-gate 
560*7c478bd9Sstevel@tonic-gate 	trace2(TR_hashinc, 0, hash);
561*7c478bd9Sstevel@tonic-gate 	hash &= hmask;
562*7c478bd9Sstevel@tonic-gate 	bit = hmask+1;
563*7c478bd9Sstevel@tonic-gate 	for (; ; ) {
564*7c478bd9Sstevel@tonic-gate 		bit >>= 1;
565*7c478bd9Sstevel@tonic-gate 		if (bit == 0) {
566*7c478bd9Sstevel@tonic-gate 			trace1(TR_hashinc, 1);
567*7c478bd9Sstevel@tonic-gate 			return (0L);
568*7c478bd9Sstevel@tonic-gate 		}
569*7c478bd9Sstevel@tonic-gate 		if ((hash&bit) == 0) {
570*7c478bd9Sstevel@tonic-gate 			trace1(TR_hashinc, 1);
571*7c478bd9Sstevel@tonic-gate 			return (hash|bit);
572*7c478bd9Sstevel@tonic-gate 		}
573*7c478bd9Sstevel@tonic-gate 		hash &= ~bit;
574*7c478bd9Sstevel@tonic-gate 	}
575*7c478bd9Sstevel@tonic-gate }
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate long
578*7c478bd9Sstevel@tonic-gate calchash(item)
579*7c478bd9Sstevel@tonic-gate 	datum item;
580*7c478bd9Sstevel@tonic-gate {
581*7c478bd9Sstevel@tonic-gate 	int i, j, f;
582*7c478bd9Sstevel@tonic-gate 	long hashl;
583*7c478bd9Sstevel@tonic-gate 	int hashi;
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate 	trace1(TR_calchash, 0);
586*7c478bd9Sstevel@tonic-gate 	hashl = 0;
587*7c478bd9Sstevel@tonic-gate 	hashi = 0;
588*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < item.dsize; i++) {
589*7c478bd9Sstevel@tonic-gate 		f = item.dptr[i];
590*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < BYTESIZ; j += 4) {
591*7c478bd9Sstevel@tonic-gate 			hashi += hitab[f&017];
592*7c478bd9Sstevel@tonic-gate 			hashl += hltab[hashi&63];
593*7c478bd9Sstevel@tonic-gate 			f >>= 4;
594*7c478bd9Sstevel@tonic-gate 		}
595*7c478bd9Sstevel@tonic-gate 	}
596*7c478bd9Sstevel@tonic-gate 	trace1(TR_calchash, 1);
597*7c478bd9Sstevel@tonic-gate 	return (hashl);
598*7c478bd9Sstevel@tonic-gate }
599*7c478bd9Sstevel@tonic-gate 
600*7c478bd9Sstevel@tonic-gate void
601*7c478bd9Sstevel@tonic-gate delitem(buf, n)
602*7c478bd9Sstevel@tonic-gate 	char buf[PBLKSIZ];
603*7c478bd9Sstevel@tonic-gate 	int n;
604*7c478bd9Sstevel@tonic-gate {
605*7c478bd9Sstevel@tonic-gate 	short *sp;
606*7c478bd9Sstevel@tonic-gate 	int i1, i2, i3;
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate 	trace1(TR_delitem, 0);
609*7c478bd9Sstevel@tonic-gate 	sp = (short *)buf;
610*7c478bd9Sstevel@tonic-gate 	if (n < 0 || n >= sp[0])
611*7c478bd9Sstevel@tonic-gate 		goto bad;
612*7c478bd9Sstevel@tonic-gate 	i1 = sp[n+1];
613*7c478bd9Sstevel@tonic-gate 	i2 = PBLKSIZ;
614*7c478bd9Sstevel@tonic-gate 	if (n > 0)
615*7c478bd9Sstevel@tonic-gate 		i2 = sp[n+1-1];
616*7c478bd9Sstevel@tonic-gate 	i3 = sp[sp[0]+1-1];
617*7c478bd9Sstevel@tonic-gate 	if (i2 > i1)
618*7c478bd9Sstevel@tonic-gate 	while (i1 > i3) {
619*7c478bd9Sstevel@tonic-gate 		i1--;
620*7c478bd9Sstevel@tonic-gate 		i2--;
621*7c478bd9Sstevel@tonic-gate 		buf[i2] = buf[i1];
622*7c478bd9Sstevel@tonic-gate 		buf[i1] = 0;
623*7c478bd9Sstevel@tonic-gate 	}
624*7c478bd9Sstevel@tonic-gate 	i2 -= i1;
625*7c478bd9Sstevel@tonic-gate 	for (i1 = n + 1; i1 < sp[0]; i1++)
626*7c478bd9Sstevel@tonic-gate 		sp[i1+1-1] = sp[i1+1] + i2;
627*7c478bd9Sstevel@tonic-gate 	sp[0]--;
628*7c478bd9Sstevel@tonic-gate 	sp[sp[0]+1] = 0;
629*7c478bd9Sstevel@tonic-gate 	trace1(TR_delitem, 1);
630*7c478bd9Sstevel@tonic-gate 	return;
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate bad:
633*7c478bd9Sstevel@tonic-gate 	(void) printf("bad delitem\n");
634*7c478bd9Sstevel@tonic-gate 	trace1(TR_delitem, 1);
635*7c478bd9Sstevel@tonic-gate 	abort();
636*7c478bd9Sstevel@tonic-gate }
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate int
639*7c478bd9Sstevel@tonic-gate additem(buf, item)
640*7c478bd9Sstevel@tonic-gate 	char buf[PBLKSIZ];
641*7c478bd9Sstevel@tonic-gate 	datum item;
642*7c478bd9Sstevel@tonic-gate {
643*7c478bd9Sstevel@tonic-gate 	short *sp;
644*7c478bd9Sstevel@tonic-gate 	int i1, i2;
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate 	trace1(TR_additem, 0);
647*7c478bd9Sstevel@tonic-gate 	sp = (short *)buf;
648*7c478bd9Sstevel@tonic-gate 	i1 = PBLKSIZ;
649*7c478bd9Sstevel@tonic-gate 	if (sp[0] > 0)
650*7c478bd9Sstevel@tonic-gate 		i1 = sp[sp[0]+1-1];
651*7c478bd9Sstevel@tonic-gate 	i1 -= item.dsize;
652*7c478bd9Sstevel@tonic-gate 	i2 = (sp[0]+2) * (int)sizeof (short);
653*7c478bd9Sstevel@tonic-gate 	if (i1 <= i2) {
654*7c478bd9Sstevel@tonic-gate 		trace1(TR_additem, 1);
655*7c478bd9Sstevel@tonic-gate 		return (-1);
656*7c478bd9Sstevel@tonic-gate 	}
657*7c478bd9Sstevel@tonic-gate 	sp[sp[0]+1] = (short)i1;
658*7c478bd9Sstevel@tonic-gate 	for (i2 = 0; i2 < item.dsize; i2++) {
659*7c478bd9Sstevel@tonic-gate 		buf[i1] = item.dptr[i2];
660*7c478bd9Sstevel@tonic-gate 		i1++;
661*7c478bd9Sstevel@tonic-gate 	}
662*7c478bd9Sstevel@tonic-gate 	sp[0]++;
663*7c478bd9Sstevel@tonic-gate 	trace1(TR_additem, 1);
664*7c478bd9Sstevel@tonic-gate 	return (sp[0]-1);
665*7c478bd9Sstevel@tonic-gate }
666*7c478bd9Sstevel@tonic-gate 
667*7c478bd9Sstevel@tonic-gate void
668*7c478bd9Sstevel@tonic-gate chkblk(buf)
669*7c478bd9Sstevel@tonic-gate 	char buf[PBLKSIZ];
670*7c478bd9Sstevel@tonic-gate {
671*7c478bd9Sstevel@tonic-gate 	short *sp;
672*7c478bd9Sstevel@tonic-gate 	int t, i;
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate 	trace1(TR_chkblk, 0);
675*7c478bd9Sstevel@tonic-gate 	sp = (short *)buf;
676*7c478bd9Sstevel@tonic-gate 	t = PBLKSIZ;
677*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < sp[0]; i++) {
678*7c478bd9Sstevel@tonic-gate 		if (sp[i+1] > t)
679*7c478bd9Sstevel@tonic-gate 			goto bad;
680*7c478bd9Sstevel@tonic-gate 		t = sp[i+1];
681*7c478bd9Sstevel@tonic-gate 	}
682*7c478bd9Sstevel@tonic-gate 	if (t < (sp[0]+1) * sizeof (short))
683*7c478bd9Sstevel@tonic-gate 		goto bad;
684*7c478bd9Sstevel@tonic-gate 	trace1(TR_chkblk, 1);
685*7c478bd9Sstevel@tonic-gate 	return;
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate bad:
688*7c478bd9Sstevel@tonic-gate 	(void) printf("bad block\n");
689*7c478bd9Sstevel@tonic-gate 	trace1(TR_chkblk, 1);
690*7c478bd9Sstevel@tonic-gate 	abort();
691*7c478bd9Sstevel@tonic-gate 	(void) memset((char *)&buf, 0, PBLKSIZ);
692*7c478bd9Sstevel@tonic-gate }
693