xref: /csrg-svn/old/libndbm/ndbm.c (revision 15646)
1*15646Sralph #ifndef lint
2*15646Sralph static char sccsid[] = "@(#)ndbm.c	4.1 (Berkeley) 12/02/83";
3*15646Sralph #endif
4*15646Sralph 
5*15646Sralph #include <sys/types.h>
6*15646Sralph #include <sys/stat.h>
7*15646Sralph #include <sys/file.h>
8*15646Sralph #include <errno.h>
9*15646Sralph #include <ndbm.h>
10*15646Sralph 
11*15646Sralph #define NULL    (char *)0
12*15646Sralph #define BYTESIZ 8
13*15646Sralph 
14*15646Sralph static  datum firsthash();
15*15646Sralph static  dbm_access();
16*15646Sralph static  getbit();
17*15646Sralph static  setbit();
18*15646Sralph static  datum makdatum();
19*15646Sralph static  cmpdatum();
20*15646Sralph static  long hashinc();
21*15646Sralph static  long dcalchash();
22*15646Sralph static  delitem();
23*15646Sralph static  additem();
24*15646Sralph static  chkblk();
25*15646Sralph extern  int errno;
26*15646Sralph 
27*15646Sralph DBM *
28*15646Sralph ndbmopen(file, flags, mode)
29*15646Sralph 	char *file;
30*15646Sralph 	int flags, mode;
31*15646Sralph {
32*15646Sralph 	struct stat statb;
33*15646Sralph 	register DBM *db;
34*15646Sralph 
35*15646Sralph 	if ((db = (DBM *)malloc(sizeof *db)) == 0) {
36*15646Sralph 		errno = ENOMEM;
37*15646Sralph 		return ((DBM *)0);
38*15646Sralph 	}
39*15646Sralph 	if ((flags & 03) == O_WRONLY)
40*15646Sralph 		flags = (flags & ~03) | O_RDWR;
41*15646Sralph 	db->db_flags = 0;
42*15646Sralph 	strcpy(db->db_pagbuf, file);
43*15646Sralph 	strcat(db->db_pagbuf, ".pag");
44*15646Sralph 	db->db_pagf = open(db->db_pagbuf, flags, mode);
45*15646Sralph 	if (db->db_pagf < 0)
46*15646Sralph 		goto bad;
47*15646Sralph 	strcpy(db->db_pagbuf, file);
48*15646Sralph 	strcat(db->db_pagbuf, ".dir");
49*15646Sralph 	db->db_dirf = open(db->db_pagbuf, flags, mode);
50*15646Sralph 	if (db->db_dirf < 0)
51*15646Sralph 		goto bad1;
52*15646Sralph 	fstat(db->db_dirf, &statb);
53*15646Sralph 	db->db_maxbno = statb.st_size*BYTESIZ-1;
54*15646Sralph 	db->db_pagbno = db->db_dirbno = -1;
55*15646Sralph 	return (db);
56*15646Sralph bad1:
57*15646Sralph 	(void) close(db->db_pagf);
58*15646Sralph bad:
59*15646Sralph 	free((char *)db);
60*15646Sralph 	return ((DBM *)0);
61*15646Sralph }
62*15646Sralph 
63*15646Sralph void
64*15646Sralph ndbmclose(db)
65*15646Sralph 	DBM *db;
66*15646Sralph {
67*15646Sralph 
68*15646Sralph 	(void) close(db->db_dirf);
69*15646Sralph 	(void) close(db->db_pagf);
70*15646Sralph 	free((char *)db);
71*15646Sralph }
72*15646Sralph 
73*15646Sralph long
74*15646Sralph dbmforder(db, key)
75*15646Sralph 	register DBM *db;
76*15646Sralph 	datum key;
77*15646Sralph {
78*15646Sralph 	long hash;
79*15646Sralph 
80*15646Sralph 	hash = dcalchash(key);
81*15646Sralph 	for (db->db_hmask=0;; db->db_hmask=(db->db_hmask<<1)+1) {
82*15646Sralph 		db->db_blkno = hash & db->db_hmask;
83*15646Sralph 		db->db_bitno = db->db_blkno + db->db_hmask;
84*15646Sralph 		if (getbit(db) == 0)
85*15646Sralph 			break;
86*15646Sralph 	}
87*15646Sralph 	return (db->db_blkno);
88*15646Sralph }
89*15646Sralph 
90*15646Sralph datum
91*15646Sralph dbmfetch(db, key)
92*15646Sralph 	register DBM *db;
93*15646Sralph 	datum key;
94*15646Sralph {
95*15646Sralph 	register i;
96*15646Sralph 	datum item;
97*15646Sralph 
98*15646Sralph 	dbm_access(db, dcalchash(key));
99*15646Sralph 	for (i=0;; i+=2) {
100*15646Sralph 		item = makdatum(db->db_pagbuf, i);
101*15646Sralph 		if (item.dptr == NULL)
102*15646Sralph 			return (item);
103*15646Sralph 		if (cmpdatum(key, item) == 0) {
104*15646Sralph 			item = makdatum(db->db_pagbuf, i+1);
105*15646Sralph 			if (item.dptr == NULL)
106*15646Sralph 				printf("items not in pairs\n");
107*15646Sralph 			return (item);
108*15646Sralph 		}
109*15646Sralph 	}
110*15646Sralph }
111*15646Sralph 
112*15646Sralph dbmdelete(db, key)
113*15646Sralph 	register DBM *db;
114*15646Sralph 	datum key;
115*15646Sralph {
116*15646Sralph 	register i;
117*15646Sralph 	datum item;
118*15646Sralph 
119*15646Sralph 	if (dbrdonly(db)) {
120*15646Sralph 		errno = EPERM;
121*15646Sralph 		return (-1);
122*15646Sralph 	}
123*15646Sralph 	dbm_access(db, dcalchash(key));
124*15646Sralph 	for (i=0;; i+=2) {
125*15646Sralph 		item = makdatum(db->db_pagbuf, i);
126*15646Sralph 		if (item.dptr == NULL)
127*15646Sralph 			return (-1);
128*15646Sralph 		if (cmpdatum(key, item) == 0) {
129*15646Sralph 			delitem(db->db_pagbuf, i);
130*15646Sralph 			delitem(db->db_pagbuf, i);
131*15646Sralph 			break;
132*15646Sralph 		}
133*15646Sralph 	}
134*15646Sralph 	(void) lseek(db->db_pagf, db->db_blkno*PBLKSIZ, L_SET);
135*15646Sralph 	(void) write(db->db_pagf, db->db_pagbuf, PBLKSIZ);
136*15646Sralph 	db->db_pagbno = db->db_blkno;
137*15646Sralph 	return (0);
138*15646Sralph }
139*15646Sralph 
140*15646Sralph dbmstore(db, key, dat)
141*15646Sralph 	register DBM *db;
142*15646Sralph 	datum key, dat;
143*15646Sralph {
144*15646Sralph 	register i;
145*15646Sralph 	datum item;
146*15646Sralph 	char ovfbuf[PBLKSIZ];
147*15646Sralph 
148*15646Sralph 	if (dbrdonly(db)) {
149*15646Sralph 		errno = EPERM;
150*15646Sralph 		return (-1);
151*15646Sralph 	}
152*15646Sralph loop:
153*15646Sralph 	dbm_access(db, dcalchash(key));
154*15646Sralph 	for (i=0;; i+=2) {
155*15646Sralph 		item = makdatum(db->db_pagbuf, i);
156*15646Sralph 		if (item.dptr == NULL)
157*15646Sralph 			break;
158*15646Sralph 		if (cmpdatum(key, item) == 0) {
159*15646Sralph 			return(0);
160*15646Sralph /*
161*15646Sralph 			delitem(db->db_pagbuf, i);
162*15646Sralph 			delitem(db->db_pagbuf, i);
163*15646Sralph 			break;
164*15646Sralph */
165*15646Sralph 		}
166*15646Sralph 	}
167*15646Sralph 	i = additem(db->db_pagbuf, key);
168*15646Sralph 	if (i < 0)
169*15646Sralph 		goto split;
170*15646Sralph 	if (additem(db->db_pagbuf, dat) < 0) {
171*15646Sralph 		delitem(db->db_pagbuf, i);
172*15646Sralph 		goto split;
173*15646Sralph 	}
174*15646Sralph 	(void) lseek(db->db_pagf, db->db_blkno*PBLKSIZ, L_SET);
175*15646Sralph 	(void) write(db->db_pagf, db->db_pagbuf, PBLKSIZ);
176*15646Sralph 	db->db_pagbno = db->db_blkno;
177*15646Sralph 	return (0);
178*15646Sralph 
179*15646Sralph split:
180*15646Sralph 	if (key.dsize+dat.dsize+2*sizeof(short) >= PBLKSIZ) {
181*15646Sralph 		errno = ENOSPC;
182*15646Sralph 		return (-1);
183*15646Sralph 	}
184*15646Sralph 	bzero(ovfbuf, PBLKSIZ);
185*15646Sralph 	for (i=0;;) {
186*15646Sralph 		item = makdatum(db->db_pagbuf, i);
187*15646Sralph 		if (item.dptr == NULL)
188*15646Sralph 			break;
189*15646Sralph 		if (dcalchash(item) & (db->db_hmask+1)) {
190*15646Sralph 			additem(ovfbuf, item);
191*15646Sralph 			delitem(db->db_pagbuf, i);
192*15646Sralph 			item = makdatum(db->db_pagbuf, i);
193*15646Sralph 			if (item.dptr == NULL) {
194*15646Sralph 				printf("ndbm: split not paired\n");
195*15646Sralph 				break;
196*15646Sralph 			}
197*15646Sralph 			additem(ovfbuf, item);
198*15646Sralph 			delitem(db->db_pagbuf, i);
199*15646Sralph 			continue;
200*15646Sralph 		}
201*15646Sralph 		i += 2;
202*15646Sralph 	}
203*15646Sralph 	(void) lseek(db->db_pagf, db->db_blkno*PBLKSIZ, L_SET);
204*15646Sralph 	(void) write(db->db_pagf, db->db_pagbuf, PBLKSIZ);
205*15646Sralph 	db->db_pagbno = db->db_blkno;
206*15646Sralph 	(void) lseek(db->db_pagf, (db->db_blkno+db->db_hmask+1)*PBLKSIZ, L_SET);
207*15646Sralph 	(void) write(db->db_pagf, ovfbuf, PBLKSIZ);
208*15646Sralph 	setbit(db);
209*15646Sralph 	goto loop;
210*15646Sralph }
211*15646Sralph 
212*15646Sralph datum
213*15646Sralph dbmfirstkey(db)
214*15646Sralph 	DBM *db;
215*15646Sralph {
216*15646Sralph 
217*15646Sralph 	return (firsthash(db, 0L));
218*15646Sralph }
219*15646Sralph 
220*15646Sralph datum
221*15646Sralph dbmnextkey(db, key)
222*15646Sralph 	register DBM *db;
223*15646Sralph 	datum key;
224*15646Sralph {
225*15646Sralph 	register i;
226*15646Sralph 	datum item, bitem;
227*15646Sralph 	long hash;
228*15646Sralph 	int f;
229*15646Sralph 
230*15646Sralph 	hash = dcalchash(key);
231*15646Sralph 	dbm_access(db, hash);
232*15646Sralph 	f = 1;
233*15646Sralph 	for (i=0;; i+=2) {
234*15646Sralph 		item = makdatum(db->db_pagbuf, i);
235*15646Sralph 		if (item.dptr == NULL)
236*15646Sralph 			break;
237*15646Sralph 		if (cmpdatum(key, item) <= 0)
238*15646Sralph 			continue;
239*15646Sralph 		if (f || cmpdatum(bitem, item) < 0) {
240*15646Sralph 			bitem = item;
241*15646Sralph 			f = 0;
242*15646Sralph 		}
243*15646Sralph 	}
244*15646Sralph 	if (f == 0)
245*15646Sralph 		return (bitem);
246*15646Sralph 	hash = hashinc(db, hash);
247*15646Sralph 	if (hash == 0)
248*15646Sralph 		return (item);
249*15646Sralph 	return (firsthash(db, hash));
250*15646Sralph }
251*15646Sralph 
252*15646Sralph static datum
253*15646Sralph firsthash(db, hash)
254*15646Sralph 	register DBM *db;
255*15646Sralph 	long hash;
256*15646Sralph {
257*15646Sralph 	register i;
258*15646Sralph 	datum item, bitem;
259*15646Sralph 
260*15646Sralph loop:
261*15646Sralph 	dbm_access(db, hash);
262*15646Sralph 	bitem = makdatum(db->db_pagbuf, 0);
263*15646Sralph 	for (i=2;; i+=2) {
264*15646Sralph 		item = makdatum(db->db_pagbuf, i);
265*15646Sralph 		if (item.dptr == NULL)
266*15646Sralph 			break;
267*15646Sralph 		if (cmpdatum(bitem, item) < 0)
268*15646Sralph 			bitem = item;
269*15646Sralph 	}
270*15646Sralph 	if (bitem.dptr != NULL)
271*15646Sralph 		return (bitem);
272*15646Sralph 	hash = hashinc(db, hash);
273*15646Sralph 	if (hash == 0)
274*15646Sralph 		return (item);
275*15646Sralph 	goto loop;
276*15646Sralph }
277*15646Sralph 
278*15646Sralph static
279*15646Sralph dbm_access(db, hash)
280*15646Sralph 	register DBM *db;
281*15646Sralph 	long hash;
282*15646Sralph {
283*15646Sralph 
284*15646Sralph 	for (db->db_hmask=0;; db->db_hmask=(db->db_hmask<<1)+1) {
285*15646Sralph 		db->db_blkno = hash & db->db_hmask;
286*15646Sralph 		db->db_bitno = db->db_blkno + db->db_hmask;
287*15646Sralph 		if (getbit(db) == 0)
288*15646Sralph 			break;
289*15646Sralph 	}
290*15646Sralph 	if (db->db_blkno != db->db_pagbno) {
291*15646Sralph 		bzero(db->db_pagbuf, PBLKSIZ);
292*15646Sralph 		(void) lseek(db->db_pagf, db->db_blkno*PBLKSIZ, L_SET);
293*15646Sralph 		(void) read(db->db_pagf, db->db_pagbuf, PBLKSIZ);
294*15646Sralph 		chkblk(db->db_pagbuf);
295*15646Sralph 		db->db_pagbno = db->db_blkno;
296*15646Sralph 	}
297*15646Sralph }
298*15646Sralph 
299*15646Sralph static
300*15646Sralph getbit(db)
301*15646Sralph 	register DBM *db;
302*15646Sralph {
303*15646Sralph 	long bn;
304*15646Sralph 	register b, i, n;
305*15646Sralph 
306*15646Sralph 
307*15646Sralph 	if (db->db_bitno > db->db_maxbno)
308*15646Sralph 		return (0);
309*15646Sralph 	n = db->db_bitno % BYTESIZ;
310*15646Sralph 	bn = db->db_bitno / BYTESIZ;
311*15646Sralph 	i = bn % DBLKSIZ;
312*15646Sralph 	b = bn / DBLKSIZ;
313*15646Sralph 	if (b != db->db_dirbno) {
314*15646Sralph 		bzero(db->db_dirbuf, DBLKSIZ);
315*15646Sralph 		(void) lseek(db->db_dirf, (long)b*DBLKSIZ, L_SET);
316*15646Sralph 		(void) read(db->db_dirf, db->db_dirbuf, DBLKSIZ);
317*15646Sralph 		db->db_dirbno = b;
318*15646Sralph 	}
319*15646Sralph 	if (db->db_dirbuf[i] & (1<<n))
320*15646Sralph 		return (1);
321*15646Sralph 	return (0);
322*15646Sralph }
323*15646Sralph 
324*15646Sralph static
325*15646Sralph setbit(db)
326*15646Sralph 	register DBM *db;
327*15646Sralph {
328*15646Sralph 	long bn;
329*15646Sralph 	register i, n, b;
330*15646Sralph 
331*15646Sralph 	if (dbrdonly(db)) {
332*15646Sralph 		errno = EPERM;
333*15646Sralph 		return (-1);
334*15646Sralph 	}
335*15646Sralph 	if (db->db_bitno > db->db_maxbno) {
336*15646Sralph 		db->db_maxbno = db->db_bitno;
337*15646Sralph 		getbit(db);
338*15646Sralph 	}
339*15646Sralph 	n = db->db_bitno % BYTESIZ;
340*15646Sralph 	bn = db->db_bitno / BYTESIZ;
341*15646Sralph 	i = bn % DBLKSIZ;
342*15646Sralph 	b = bn / DBLKSIZ;
343*15646Sralph 	db->db_dirbuf[i] |= 1<<n;
344*15646Sralph 	(void) lseek(db->db_dirf, (long)b*DBLKSIZ, L_SET);
345*15646Sralph 	(void) write(db->db_dirf, db->db_dirbuf, DBLKSIZ);
346*15646Sralph 	db->db_dirbno = b;
347*15646Sralph }
348*15646Sralph 
349*15646Sralph static datum
350*15646Sralph makdatum(buf, n)
351*15646Sralph 	char buf[PBLKSIZ];
352*15646Sralph {
353*15646Sralph 	register short *sp;
354*15646Sralph 	register t;
355*15646Sralph 	datum item;
356*15646Sralph 
357*15646Sralph 	sp = (short *)buf;
358*15646Sralph 	if (n < 0 || n >= sp[0])
359*15646Sralph 		goto null;
360*15646Sralph 	t = PBLKSIZ;
361*15646Sralph 	if (n > 0)
362*15646Sralph 		t = sp[n+1-1];
363*15646Sralph 	item.dptr = buf+sp[n+1];
364*15646Sralph 	item.dsize = t - sp[n+1];
365*15646Sralph 	return (item);
366*15646Sralph 
367*15646Sralph null:
368*15646Sralph 	item.dptr = NULL;
369*15646Sralph 	item.dsize = 0;
370*15646Sralph 	return (item);
371*15646Sralph }
372*15646Sralph 
373*15646Sralph static
374*15646Sralph cmpdatum(d1, d2)
375*15646Sralph 	datum d1, d2;
376*15646Sralph {
377*15646Sralph 	register n;
378*15646Sralph 	register char *p1, *p2;
379*15646Sralph 
380*15646Sralph 	n = d1.dsize;
381*15646Sralph 	if (n != d2.dsize)
382*15646Sralph 		return (n - d2.dsize);
383*15646Sralph 	if (n == 0)
384*15646Sralph 		return (0);
385*15646Sralph 	p1 = d1.dptr;
386*15646Sralph 	p2 = d2.dptr;
387*15646Sralph 	do
388*15646Sralph 		if (*p1++ != *p2++)
389*15646Sralph 			return (*--p1 - *--p2);
390*15646Sralph 	while (--n);
391*15646Sralph 	return (0);
392*15646Sralph }
393*15646Sralph 
394*15646Sralph static  int hitab[16]
395*15646Sralph /* ken's
396*15646Sralph {
397*15646Sralph 	055,043,036,054,063,014,004,005,
398*15646Sralph 	010,064,077,000,035,027,025,071,
399*15646Sralph };
400*15646Sralph */
401*15646Sralph  = {    61, 57, 53, 49, 45, 41, 37, 33,
402*15646Sralph 	29, 25, 21, 17, 13,  9,  5,  1,
403*15646Sralph };
404*15646Sralph static  long hltab[64]
405*15646Sralph  = {
406*15646Sralph 	06100151277L,06106161736L,06452611562L,05001724107L,
407*15646Sralph 	02614772546L,04120731531L,04665262210L,07347467531L,
408*15646Sralph 	06735253126L,06042345173L,03072226605L,01464164730L,
409*15646Sralph 	03247435524L,07652510057L,01546775256L,05714532133L,
410*15646Sralph 	06173260402L,07517101630L,02431460343L,01743245566L,
411*15646Sralph 	00261675137L,02433103631L,03421772437L,04447707466L,
412*15646Sralph 	04435620103L,03757017115L,03641531772L,06767633246L,
413*15646Sralph 	02673230344L,00260612216L,04133454451L,00615531516L,
414*15646Sralph 	06137717526L,02574116560L,02304023373L,07061702261L,
415*15646Sralph 	05153031405L,05322056705L,07401116734L,06552375715L,
416*15646Sralph 	06165233473L,05311063631L,01212221723L,01052267235L,
417*15646Sralph 	06000615237L,01075222665L,06330216006L,04402355630L,
418*15646Sralph 	01451177262L,02000133436L,06025467062L,07121076461L,
419*15646Sralph 	03123433522L,01010635225L,01716177066L,05161746527L,
420*15646Sralph 	01736635071L,06243505026L,03637211610L,01756474365L,
421*15646Sralph 	04723077174L,03642763134L,05750130273L,03655541561L,
422*15646Sralph };
423*15646Sralph 
424*15646Sralph static long
425*15646Sralph hashinc(db, hash)
426*15646Sralph 	register DBM *db;
427*15646Sralph 	long hash;
428*15646Sralph {
429*15646Sralph 	long bit;
430*15646Sralph 
431*15646Sralph 	hash &= db->db_hmask;
432*15646Sralph 	bit = db->db_hmask+1;
433*15646Sralph 	for (;;) {
434*15646Sralph 		bit >>= 1;
435*15646Sralph 		if (bit == 0)
436*15646Sralph 			return (0L);
437*15646Sralph 		if ((hash&bit) == 0)
438*15646Sralph 			return (hash|bit);
439*15646Sralph 		hash &= ~bit;
440*15646Sralph 	}
441*15646Sralph }
442*15646Sralph 
443*15646Sralph static long
444*15646Sralph dcalchash(item)
445*15646Sralph 	datum item;
446*15646Sralph {
447*15646Sralph 	register i, j, f;
448*15646Sralph 	long hashl;
449*15646Sralph 	int hashi;
450*15646Sralph 
451*15646Sralph 	hashl = 0;
452*15646Sralph 	hashi = 0;
453*15646Sralph 	for (i=0; i<item.dsize; i++) {
454*15646Sralph 		f = item.dptr[i];
455*15646Sralph 		for (j=0; j<BYTESIZ; j+=4) {
456*15646Sralph 			hashi += hitab[f&017];
457*15646Sralph 			hashl += hltab[hashi&63];
458*15646Sralph 			f >>= 4;
459*15646Sralph 		}
460*15646Sralph 	}
461*15646Sralph 	return (hashl);
462*15646Sralph }
463*15646Sralph 
464*15646Sralph static
465*15646Sralph delitem(buf, n)
466*15646Sralph 	char buf[PBLKSIZ];
467*15646Sralph {
468*15646Sralph 	register short *sp;
469*15646Sralph 	register i1, i2, i3;
470*15646Sralph 
471*15646Sralph 	sp = (short *)buf;
472*15646Sralph 	if (n < 0 || n >= sp[0])
473*15646Sralph 		goto bad;
474*15646Sralph 	i1 = sp[n+1];
475*15646Sralph 	i2 = PBLKSIZ;
476*15646Sralph 	if (n > 0)
477*15646Sralph 		i2 = sp[n+1-1];
478*15646Sralph 	i3 = sp[sp[0]+1-1];
479*15646Sralph 	if (i2 > i1)
480*15646Sralph 	while (i1 > i3) {
481*15646Sralph 		i1--;
482*15646Sralph 		i2--;
483*15646Sralph 		buf[i2] = buf[i1];
484*15646Sralph 		buf[i1] = 0;
485*15646Sralph 	}
486*15646Sralph 	i2 -= i1;
487*15646Sralph 	for (i1=n+1; i1<sp[0]; i1++)
488*15646Sralph 		sp[i1+1-1] = sp[i1+1] + i2;
489*15646Sralph 	sp[0]--;
490*15646Sralph 	sp[sp[0]+1] = 0;
491*15646Sralph 	return;
492*15646Sralph 
493*15646Sralph bad:
494*15646Sralph 	printf("ndbm: bad delitem\n");
495*15646Sralph 	abort();
496*15646Sralph }
497*15646Sralph 
498*15646Sralph static
499*15646Sralph additem(buf, item)
500*15646Sralph 	char buf[PBLKSIZ];
501*15646Sralph 	datum item;
502*15646Sralph {
503*15646Sralph 	register short *sp;
504*15646Sralph 	register i1, i2;
505*15646Sralph 
506*15646Sralph 	sp = (short *)buf;
507*15646Sralph 	i1 = PBLKSIZ;
508*15646Sralph 	if (sp[0] > 0)
509*15646Sralph 		i1 = sp[sp[0]+1-1];
510*15646Sralph 	i1 -= item.dsize;
511*15646Sralph 	i2 = (sp[0]+2) * sizeof(short);
512*15646Sralph 	if (i1 <= i2)
513*15646Sralph 		return (-1);
514*15646Sralph 	sp[sp[0]+1] = i1;
515*15646Sralph 	for (i2=0; i2<item.dsize; i2++) {
516*15646Sralph 		buf[i1] = item.dptr[i2];
517*15646Sralph 		i1++;
518*15646Sralph 	}
519*15646Sralph 	sp[0]++;
520*15646Sralph 	return (sp[0]-1);
521*15646Sralph }
522*15646Sralph 
523*15646Sralph static
524*15646Sralph chkblk(buf)
525*15646Sralph 	char buf[PBLKSIZ];
526*15646Sralph {
527*15646Sralph 	register short *sp;
528*15646Sralph 	register t, i;
529*15646Sralph 
530*15646Sralph 	sp = (short *)buf;
531*15646Sralph 	t = PBLKSIZ;
532*15646Sralph 	for (i=0; i<sp[0]; i++) {
533*15646Sralph 		if (sp[i+1] > t)
534*15646Sralph 			goto bad;
535*15646Sralph 		t = sp[i+1];
536*15646Sralph 	}
537*15646Sralph 	if (t < (sp[0]+1)*sizeof(short))
538*15646Sralph 		goto bad;
539*15646Sralph 	return;
540*15646Sralph 
541*15646Sralph bad:
542*15646Sralph 	printf("ndbm: bad block\n");
543*15646Sralph 	abort();
544*15646Sralph 	bzero(buf, PBLKSIZ);
545*15646Sralph }
546