xref: /csrg-svn/old/libndbm/ndbm.c (revision 17023)
115646Sralph #ifndef lint
2*17023Sralph static char sccsid[] = "@(#)ndbm.c	4.3 (Berkeley) 08/28/84";
315646Sralph #endif
415646Sralph 
515646Sralph #include <sys/types.h>
615646Sralph #include <sys/stat.h>
715646Sralph #include <sys/file.h>
8*17023Sralph #include <stdio.h>
915646Sralph #include <errno.h>
1015646Sralph #include <ndbm.h>
1115646Sralph 
1215646Sralph #define BYTESIZ 8
1315646Sralph 
1415646Sralph static  datum firsthash();
1515646Sralph static  datum makdatum();
1615646Sralph static  long hashinc();
1715646Sralph static  long dcalchash();
1815646Sralph extern  int errno;
1915646Sralph 
2015646Sralph DBM *
21*17023Sralph dbm_open(file, flags, mode)
2215646Sralph 	char *file;
2315646Sralph 	int flags, mode;
2415646Sralph {
2515646Sralph 	struct stat statb;
2615646Sralph 	register DBM *db;
2715646Sralph 
2815646Sralph 	if ((db = (DBM *)malloc(sizeof *db)) == 0) {
2915646Sralph 		errno = ENOMEM;
3015646Sralph 		return ((DBM *)0);
3115646Sralph 	}
32*17023Sralph 	db->dbm_flags = (flags & 03) == O_RDONLY ? _DBM_RDONLY : 0;
3315646Sralph 	if ((flags & 03) == O_WRONLY)
3415646Sralph 		flags = (flags & ~03) | O_RDWR;
35*17023Sralph 	strcpy(db->dbm_pagbuf, file);
36*17023Sralph 	strcat(db->dbm_pagbuf, ".pag");
37*17023Sralph 	db->dbm_pagf = open(db->dbm_pagbuf, flags, mode);
38*17023Sralph 	if (db->dbm_pagf < 0)
3915646Sralph 		goto bad;
40*17023Sralph 	strcpy(db->dbm_pagbuf, file);
41*17023Sralph 	strcat(db->dbm_pagbuf, ".dir");
42*17023Sralph 	db->dbm_dirf = open(db->dbm_pagbuf, flags, mode);
43*17023Sralph 	if (db->dbm_dirf < 0)
4415646Sralph 		goto bad1;
45*17023Sralph 	fstat(db->dbm_dirf, &statb);
46*17023Sralph 	db->dbm_maxbno = statb.st_size*BYTESIZ-1;
47*17023Sralph 	db->dbm_pagbno = db->dbm_dirbno = -1;
4815646Sralph 	return (db);
4915646Sralph bad1:
50*17023Sralph 	(void) close(db->dbm_pagf);
5115646Sralph bad:
5215646Sralph 	free((char *)db);
5315646Sralph 	return ((DBM *)0);
5415646Sralph }
5515646Sralph 
5615646Sralph void
57*17023Sralph dbm_close(db)
5815646Sralph 	DBM *db;
5915646Sralph {
6015646Sralph 
61*17023Sralph 	(void) close(db->dbm_dirf);
62*17023Sralph 	(void) close(db->dbm_pagf);
6315646Sralph 	free((char *)db);
6415646Sralph }
6515646Sralph 
6615646Sralph long
67*17023Sralph dbm_forder(db, key)
6815646Sralph 	register DBM *db;
6915646Sralph 	datum key;
7015646Sralph {
7115646Sralph 	long hash;
7215646Sralph 
7315646Sralph 	hash = dcalchash(key);
74*17023Sralph 	for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1) {
75*17023Sralph 		db->dbm_blkno = hash & db->dbm_hmask;
76*17023Sralph 		db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
7715646Sralph 		if (getbit(db) == 0)
7815646Sralph 			break;
7915646Sralph 	}
80*17023Sralph 	return (db->dbm_blkno);
8115646Sralph }
8215646Sralph 
8315646Sralph datum
84*17023Sralph dbm_fetch(db, key)
8515646Sralph 	register DBM *db;
8615646Sralph 	datum key;
8715646Sralph {
8815646Sralph 	register i;
8915646Sralph 	datum item;
9015646Sralph 
91*17023Sralph 	if (dbm_error(db))
92*17023Sralph 		goto err;
9315646Sralph 	dbm_access(db, dcalchash(key));
94*17023Sralph 	if (dbm_error(db))
95*17023Sralph 		goto err;
9615646Sralph 	for (i=0;; i+=2) {
97*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
9815646Sralph 		if (item.dptr == NULL)
9915646Sralph 			return (item);
10015646Sralph 		if (cmpdatum(key, item) == 0) {
101*17023Sralph 			item = makdatum(db->dbm_pagbuf, i+1);
10215646Sralph 			if (item.dptr == NULL)
103*17023Sralph 				fprintf(stderr, "dbm: items not in pairs\n");
10415646Sralph 			return (item);
10515646Sralph 		}
10615646Sralph 	}
107*17023Sralph err:
108*17023Sralph 	item.dptr = NULL;
109*17023Sralph 	item.dsize = 0;
110*17023Sralph 	return (item);
11115646Sralph }
11215646Sralph 
113*17023Sralph dbm_delete(db, key)
11415646Sralph 	register DBM *db;
11515646Sralph 	datum key;
11615646Sralph {
11715646Sralph 	register i;
11815646Sralph 	datum item;
11915646Sralph 
120*17023Sralph 	if (dbm_error(db))
121*17023Sralph 		return (-1);
122*17023Sralph 	if (dbm_rdonly(db)) {
12315646Sralph 		errno = EPERM;
12415646Sralph 		return (-1);
12515646Sralph 	}
12615646Sralph 	dbm_access(db, dcalchash(key));
127*17023Sralph 	if (dbm_error(db))
128*17023Sralph 		return (-1);
12915646Sralph 	for (i=0;; i+=2) {
130*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
13115646Sralph 		if (item.dptr == NULL)
13215646Sralph 			return (-1);
13315646Sralph 		if (cmpdatum(key, item) == 0) {
134*17023Sralph 			if (!delitem(db->dbm_pagbuf, i) ||
135*17023Sralph 			    !delitem(db->dbm_pagbuf, i))
136*17023Sralph 				db->dbm_flags |= _DBM_IOERR;
13715646Sralph 			break;
13815646Sralph 		}
13915646Sralph 	}
140*17023Sralph 	db->dbm_pagbno = db->dbm_blkno;
141*17023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
142*17023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
143*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
144*17023Sralph 		return (-1);
145*17023Sralph 	}
14615646Sralph 	return (0);
14715646Sralph }
14815646Sralph 
149*17023Sralph dbm_store(db, key, dat, replace)
15015646Sralph 	register DBM *db;
15115646Sralph 	datum key, dat;
15215749Sralph 	int replace;
15315646Sralph {
15415646Sralph 	register i;
15515646Sralph 	datum item;
15615646Sralph 	char ovfbuf[PBLKSIZ];
15715646Sralph 
158*17023Sralph 	if (dbm_error(db))
159*17023Sralph 		return (-1);
160*17023Sralph 	if (dbm_rdonly(db)) {
16115646Sralph 		errno = EPERM;
16215646Sralph 		return (-1);
16315646Sralph 	}
16415646Sralph loop:
16515646Sralph 	dbm_access(db, dcalchash(key));
166*17023Sralph 	if (dbm_error(db))
167*17023Sralph 		return (-1);
16815646Sralph 	for (i=0;; i+=2) {
169*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
17015646Sralph 		if (item.dptr == NULL)
17115646Sralph 			break;
17215646Sralph 		if (cmpdatum(key, item) == 0) {
17315749Sralph 			if (!replace)
17415749Sralph 				return (1);
175*17023Sralph 			if (!delitem(db->dbm_pagbuf, i) ||
176*17023Sralph 			    !delitem(db->dbm_pagbuf, i)) {
177*17023Sralph 				db->dbm_flags |= _DBM_IOERR;
178*17023Sralph 				return (-1);
179*17023Sralph 			}
18015646Sralph 		}
18115646Sralph 	}
182*17023Sralph 	if (!additem(db->dbm_pagbuf, key))
18315646Sralph 		goto split;
184*17023Sralph 	if (!additem(db->dbm_pagbuf, dat)) {
185*17023Sralph 		/* special case of delitem() expanded inline here */
186*17023Sralph 		((short *) db->dbm_pagbuf)[0]--;
18715646Sralph 		goto split;
18815646Sralph 	}
189*17023Sralph 	db->dbm_pagbno = db->dbm_blkno;
190*17023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
191*17023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
192*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
193*17023Sralph 		return (-1);
194*17023Sralph 	}
19515646Sralph 	return (0);
19615646Sralph 
19715646Sralph split:
19815646Sralph 	if (key.dsize+dat.dsize+2*sizeof(short) >= PBLKSIZ) {
199*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
20015646Sralph 		errno = ENOSPC;
20115646Sralph 		return (-1);
20215646Sralph 	}
20315646Sralph 	bzero(ovfbuf, PBLKSIZ);
20415646Sralph 	for (i=0;;) {
205*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
20615646Sralph 		if (item.dptr == NULL)
20715646Sralph 			break;
208*17023Sralph 		if (dcalchash(item) & (db->dbm_hmask+1)) {
209*17023Sralph 			if (!additem(ovfbuf, item) ||
210*17023Sralph 			    !delitem(db->dbm_pagbuf, i)) {
211*17023Sralph 				db->dbm_flags |= _DBM_IOERR;
212*17023Sralph 				return (-1);
213*17023Sralph 			}
214*17023Sralph 			item = makdatum(db->dbm_pagbuf, i);
21515646Sralph 			if (item.dptr == NULL) {
216*17023Sralph 				fprintf(stderr, "ndbm: split not paired\n");
217*17023Sralph 				db->dbm_flags |= _DBM_IOERR;
21815646Sralph 				break;
21915646Sralph 			}
220*17023Sralph 			if (!additem(ovfbuf, item) ||
221*17023Sralph 			    !delitem(db->dbm_pagbuf, i)) {
222*17023Sralph 				db->dbm_flags |= _DBM_IOERR;
223*17023Sralph 				return (-1);
224*17023Sralph 			}
22515646Sralph 			continue;
22615646Sralph 		}
22715646Sralph 		i += 2;
22815646Sralph 	}
229*17023Sralph 	db->dbm_pagbno = db->dbm_blkno;
230*17023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
231*17023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
232*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
233*17023Sralph 		return (-1);
234*17023Sralph 	}
235*17023Sralph 	(void) lseek(db->dbm_pagf, (db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ, L_SET);
236*17023Sralph 	if (write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ) {
237*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
238*17023Sralph 		return (-1);
239*17023Sralph 	}
24015646Sralph 	setbit(db);
24115646Sralph 	goto loop;
24215646Sralph }
24315646Sralph 
24415646Sralph datum
245*17023Sralph dbm_firstkey(db)
24615646Sralph 	DBM *db;
24715646Sralph {
24815646Sralph 
24915646Sralph 	return (firsthash(db, 0L));
25015646Sralph }
25115646Sralph 
25215646Sralph datum
253*17023Sralph dbm_nextkey(db, key)
25415646Sralph 	register DBM *db;
25515646Sralph 	datum key;
25615646Sralph {
25715646Sralph 	register i;
25815646Sralph 	datum item, bitem;
25915646Sralph 	long hash;
26015646Sralph 	int f;
26115646Sralph 
262*17023Sralph 	if (dbm_error(db))
263*17023Sralph 		goto err;
264*17023Sralph 	dbm_access(db, hash = dcalchash(key));
265*17023Sralph 	if (dbm_error(db))
266*17023Sralph 		goto err;
26715646Sralph 	f = 1;
26815646Sralph 	for (i=0;; i+=2) {
269*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
27015646Sralph 		if (item.dptr == NULL)
27115646Sralph 			break;
27215646Sralph 		if (cmpdatum(key, item) <= 0)
27315646Sralph 			continue;
27415646Sralph 		if (f || cmpdatum(bitem, item) < 0) {
27515646Sralph 			bitem = item;
27615646Sralph 			f = 0;
27715646Sralph 		}
27815646Sralph 	}
27915646Sralph 	if (f == 0)
28015646Sralph 		return (bitem);
28115646Sralph 	hash = hashinc(db, hash);
28215646Sralph 	if (hash == 0)
28315646Sralph 		return (item);
28415646Sralph 	return (firsthash(db, hash));
285*17023Sralph err:
286*17023Sralph 	item.dptr = NULL;
287*17023Sralph 	item.dsize = 0;
288*17023Sralph 	return (item);
28915646Sralph }
29015646Sralph 
29115646Sralph static datum
29215646Sralph firsthash(db, hash)
29315646Sralph 	register DBM *db;
29415646Sralph 	long hash;
29515646Sralph {
29615646Sralph 	register i;
29715646Sralph 	datum item, bitem;
29815646Sralph 
29915646Sralph loop:
30015646Sralph 	dbm_access(db, hash);
301*17023Sralph 	if (dbm_error(db)) {
302*17023Sralph 		item.dptr = NULL;
303*17023Sralph 		return (item);
304*17023Sralph 	}
305*17023Sralph 	bitem = makdatum(db->dbm_pagbuf, 0);
30615646Sralph 	for (i=2;; i+=2) {
307*17023Sralph 		item = makdatum(db->dbm_pagbuf, i);
30815646Sralph 		if (item.dptr == NULL)
30915646Sralph 			break;
31015646Sralph 		if (cmpdatum(bitem, item) < 0)
31115646Sralph 			bitem = item;
31215646Sralph 	}
31315646Sralph 	if (bitem.dptr != NULL)
31415646Sralph 		return (bitem);
31515646Sralph 	hash = hashinc(db, hash);
31615646Sralph 	if (hash == 0)
31715646Sralph 		return (item);
31815646Sralph 	goto loop;
31915646Sralph }
32015646Sralph 
32115646Sralph static
32215646Sralph dbm_access(db, hash)
32315646Sralph 	register DBM *db;
32415646Sralph 	long hash;
32515646Sralph {
32615646Sralph 
327*17023Sralph 	for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1) {
328*17023Sralph 		db->dbm_blkno = hash & db->dbm_hmask;
329*17023Sralph 		db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
33015646Sralph 		if (getbit(db) == 0)
33115646Sralph 			break;
33215646Sralph 	}
333*17023Sralph 	if (db->dbm_blkno != db->dbm_pagbno) {
334*17023Sralph 		db->dbm_pagbno = db->dbm_blkno;
335*17023Sralph 		(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
336*17023Sralph 		if (read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
337*17023Sralph 			bzero(db->dbm_pagbuf, PBLKSIZ);
338*17023Sralph 		else if (chkblk(db->dbm_pagbuf) < 0)
339*17023Sralph 			db->dbm_flags |= _DBM_IOERR;
34015646Sralph 	}
34115646Sralph }
34215646Sralph 
34315646Sralph static
34415646Sralph getbit(db)
34515646Sralph 	register DBM *db;
34615646Sralph {
34715646Sralph 	long bn;
34815646Sralph 	register b, i, n;
34915646Sralph 
35015646Sralph 
351*17023Sralph 	if (db->dbm_bitno > db->dbm_maxbno)
35215646Sralph 		return (0);
353*17023Sralph 	n = db->dbm_bitno % BYTESIZ;
354*17023Sralph 	bn = db->dbm_bitno / BYTESIZ;
35515646Sralph 	i = bn % DBLKSIZ;
35615646Sralph 	b = bn / DBLKSIZ;
357*17023Sralph 	if (b != db->dbm_dirbno) {
358*17023Sralph 		db->dbm_dirbno = b;
359*17023Sralph 		(void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
360*17023Sralph 		if (read(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
361*17023Sralph 			bzero(db->dbm_dirbuf, DBLKSIZ);
36215646Sralph 	}
363*17023Sralph 	if (db->dbm_dirbuf[i] & (1<<n))
36415646Sralph 		return (1);
36515646Sralph 	return (0);
36615646Sralph }
36715646Sralph 
36815646Sralph static
36915646Sralph setbit(db)
37015646Sralph 	register DBM *db;
37115646Sralph {
37215646Sralph 	long bn;
37315646Sralph 	register i, n, b;
37415646Sralph 
375*17023Sralph 	if (dbm_rdonly(db)) {
37615646Sralph 		errno = EPERM;
37715646Sralph 		return (-1);
37815646Sralph 	}
379*17023Sralph 	if (db->dbm_bitno > db->dbm_maxbno) {
380*17023Sralph 		db->dbm_maxbno = db->dbm_bitno;
38115646Sralph 		getbit(db);
38215646Sralph 	}
383*17023Sralph 	n = db->dbm_bitno % BYTESIZ;
384*17023Sralph 	bn = db->dbm_bitno / BYTESIZ;
38515646Sralph 	i = bn % DBLKSIZ;
38615646Sralph 	b = bn / DBLKSIZ;
387*17023Sralph 	db->dbm_dirbuf[i] |= 1<<n;
388*17023Sralph 	db->dbm_dirbno = b;
389*17023Sralph 	(void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
390*17023Sralph 	if (write(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ) {
391*17023Sralph 		db->dbm_flags |= _DBM_IOERR;
392*17023Sralph 		return (-1);
393*17023Sralph 	}
394*17023Sralph 	return (0);
39515646Sralph }
39615646Sralph 
39715646Sralph static datum
39815646Sralph makdatum(buf, n)
39915646Sralph 	char buf[PBLKSIZ];
40015646Sralph {
40115646Sralph 	register short *sp;
40215646Sralph 	register t;
40315646Sralph 	datum item;
40415646Sralph 
40515646Sralph 	sp = (short *)buf;
406*17023Sralph 	if (n < 0 || n >= sp[0]) {
407*17023Sralph 		item.dptr = NULL;
408*17023Sralph 		item.dsize = 0;
409*17023Sralph 		return (item);
410*17023Sralph 	}
41115646Sralph 	t = PBLKSIZ;
41215646Sralph 	if (n > 0)
413*17023Sralph 		t = sp[n];
41415646Sralph 	item.dptr = buf+sp[n+1];
41515646Sralph 	item.dsize = t - sp[n+1];
41615646Sralph 	return (item);
41715646Sralph }
41815646Sralph 
41915646Sralph static
42015646Sralph cmpdatum(d1, d2)
42115646Sralph 	datum d1, d2;
42215646Sralph {
423*17023Sralph 	register int n;
42415646Sralph 	register char *p1, *p2;
42515646Sralph 
42615646Sralph 	n = d1.dsize;
42715646Sralph 	if (n != d2.dsize)
42815646Sralph 		return (n - d2.dsize);
42915646Sralph 	if (n == 0)
43015646Sralph 		return (0);
43115646Sralph 	p1 = d1.dptr;
43215646Sralph 	p2 = d2.dptr;
43315646Sralph 	do
43415646Sralph 		if (*p1++ != *p2++)
43515646Sralph 			return (*--p1 - *--p2);
43615646Sralph 	while (--n);
43715646Sralph 	return (0);
43815646Sralph }
43915646Sralph 
44015646Sralph static  int hitab[16]
44115646Sralph /* ken's
44215646Sralph {
44315646Sralph 	055,043,036,054,063,014,004,005,
44415646Sralph 	010,064,077,000,035,027,025,071,
44515646Sralph };
44615646Sralph */
44715646Sralph  = {    61, 57, 53, 49, 45, 41, 37, 33,
44815646Sralph 	29, 25, 21, 17, 13,  9,  5,  1,
44915646Sralph };
45015646Sralph static  long hltab[64]
45115646Sralph  = {
45215646Sralph 	06100151277L,06106161736L,06452611562L,05001724107L,
45315646Sralph 	02614772546L,04120731531L,04665262210L,07347467531L,
45415646Sralph 	06735253126L,06042345173L,03072226605L,01464164730L,
45515646Sralph 	03247435524L,07652510057L,01546775256L,05714532133L,
45615646Sralph 	06173260402L,07517101630L,02431460343L,01743245566L,
45715646Sralph 	00261675137L,02433103631L,03421772437L,04447707466L,
45815646Sralph 	04435620103L,03757017115L,03641531772L,06767633246L,
45915646Sralph 	02673230344L,00260612216L,04133454451L,00615531516L,
46015646Sralph 	06137717526L,02574116560L,02304023373L,07061702261L,
46115646Sralph 	05153031405L,05322056705L,07401116734L,06552375715L,
46215646Sralph 	06165233473L,05311063631L,01212221723L,01052267235L,
46315646Sralph 	06000615237L,01075222665L,06330216006L,04402355630L,
46415646Sralph 	01451177262L,02000133436L,06025467062L,07121076461L,
46515646Sralph 	03123433522L,01010635225L,01716177066L,05161746527L,
46615646Sralph 	01736635071L,06243505026L,03637211610L,01756474365L,
46715646Sralph 	04723077174L,03642763134L,05750130273L,03655541561L,
46815646Sralph };
46915646Sralph 
47015646Sralph static long
47115646Sralph hashinc(db, hash)
47215646Sralph 	register DBM *db;
47315646Sralph 	long hash;
47415646Sralph {
47515646Sralph 	long bit;
47615646Sralph 
477*17023Sralph 	hash &= db->dbm_hmask;
478*17023Sralph 	bit = db->dbm_hmask+1;
47915646Sralph 	for (;;) {
48015646Sralph 		bit >>= 1;
48115646Sralph 		if (bit == 0)
48215646Sralph 			return (0L);
483*17023Sralph 		if ((hash & bit) == 0)
484*17023Sralph 			return (hash | bit);
48515646Sralph 		hash &= ~bit;
48615646Sralph 	}
48715646Sralph }
48815646Sralph 
48915646Sralph static long
49015646Sralph dcalchash(item)
49115646Sralph 	datum item;
49215646Sralph {
493*17023Sralph 	register int s, c, j;
494*17023Sralph 	register char *cp;
495*17023Sralph 	register long hashl;
496*17023Sralph 	register int hashi;
49715646Sralph 
49815646Sralph 	hashl = 0;
49915646Sralph 	hashi = 0;
500*17023Sralph 	for (cp = item.dptr, s=item.dsize; --s >= 0; ) {
501*17023Sralph 		c = *cp++;
50215646Sralph 		for (j=0; j<BYTESIZ; j+=4) {
503*17023Sralph 			hashi += hitab[c&017];
50415646Sralph 			hashl += hltab[hashi&63];
505*17023Sralph 			c >>= 4;
50615646Sralph 		}
50715646Sralph 	}
50815646Sralph 	return (hashl);
50915646Sralph }
51015646Sralph 
51115646Sralph static
51215646Sralph delitem(buf, n)
51315646Sralph 	char buf[PBLKSIZ];
51415646Sralph {
515*17023Sralph 	register short *sp, *sp1;
516*17023Sralph 	register i1, i2;
51715646Sralph 
51815646Sralph 	sp = (short *)buf;
519*17023Sralph 	i2 = sp[0];
520*17023Sralph 	if (n < 0 || n >= i2)
521*17023Sralph 		return (0);
522*17023Sralph 	if (n == i2-1) {
523*17023Sralph 		sp[0]--;
524*17023Sralph 		return (1);
525*17023Sralph 	}
526*17023Sralph 	i1 = PBLKSIZ;
52715646Sralph 	if (n > 0)
528*17023Sralph 		i1 = sp[n];
529*17023Sralph 	i1 -= sp[n+1];
530*17023Sralph 	if (i1 > 0) {
531*17023Sralph 		i2 = sp[i2];
532*17023Sralph 		bcopy(&buf[i2], &buf[i2 + i1], sp[n+1] - i2);
53315646Sralph 	}
534*17023Sralph 	for (sp1 = sp + sp[0]--, sp += n+1; sp < sp1; sp++)
535*17023Sralph 		sp[0] = sp[1] + i1;
536*17023Sralph 	return (1);
53715646Sralph }
53815646Sralph 
53915646Sralph static
54015646Sralph additem(buf, item)
54115646Sralph 	char buf[PBLKSIZ];
54215646Sralph 	datum item;
54315646Sralph {
54415646Sralph 	register short *sp;
54515646Sralph 	register i1, i2;
54615646Sralph 
54715646Sralph 	sp = (short *)buf;
54815646Sralph 	i1 = PBLKSIZ;
549*17023Sralph 	i2 = sp[0];
550*17023Sralph 	if (i2 > 0)
551*17023Sralph 		i1 = sp[i2];
55215646Sralph 	i1 -= item.dsize;
553*17023Sralph 	i2 = (i2+2) * sizeof(short);
55415646Sralph 	if (i1 <= i2)
555*17023Sralph 		return (0);
556*17023Sralph 	sp[++sp[0]] = i1;
557*17023Sralph 	bcopy(item.dptr, &buf[i1], item.dsize);
558*17023Sralph 	return (1);
55915646Sralph }
56015646Sralph 
56115646Sralph static
56215646Sralph chkblk(buf)
56315646Sralph 	char buf[PBLKSIZ];
56415646Sralph {
56515646Sralph 	register short *sp;
56615646Sralph 	register t, i;
56715646Sralph 
56815646Sralph 	sp = (short *)buf;
56915646Sralph 	t = PBLKSIZ;
57015646Sralph 	for (i=0; i<sp[0]; i++) {
57115646Sralph 		if (sp[i+1] > t)
572*17023Sralph 			return (-1);
57315646Sralph 		t = sp[i+1];
57415646Sralph 	}
57515646Sralph 	if (t < (sp[0]+1)*sizeof(short))
576*17023Sralph 		return (-1);
577*17023Sralph 	return (0);
57815646Sralph }
579