xref: /csrg-svn/old/libndbm/ndbm.c (revision 48500)
1*48500Sbostic /*-
2*48500Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*48500Sbostic  * All rights reserved.
4*48500Sbostic  *
5*48500Sbostic  * %sccs.include.proprietary.c%
621348Sdist  */
721348Sdist 
826571Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*48500Sbostic static char sccsid[] = "@(#)ndbm.c	5.7 (Berkeley) 04/22/91";
10*48500Sbostic #endif /* LIBC_SCCS and not lint */
1115646Sralph 
1215646Sralph #include <sys/types.h>
1315646Sralph #include <sys/stat.h>
1415646Sralph #include <sys/file.h>
1517023Sralph #include <stdio.h>
1615646Sralph #include <errno.h>
1746497Sbostic #include "ndbm.h"
1815646Sralph 
1915646Sralph #define BYTESIZ 8
2023568Smckusick #undef setbit
2115646Sralph 
2247255Sbostic static	datum makdatum();
2347255Sbostic static	long hashinc();
2447255Sbostic static	long dcalchash();
2547255Sbostic static	int additem(), delitem(), finddatum(), getbit();
2647255Sbostic static	void dbm_access(), setbit();
2747255Sbostic extern	int errno;
2815646Sralph 
2915646Sralph DBM *
dbm_open(file,flags,mode)3017023Sralph dbm_open(file, flags, mode)
3147255Sbostic 	const char *file;
3215646Sralph 	int flags, mode;
3315646Sralph {
3415646Sralph 	struct stat statb;
3515646Sralph 	register DBM *db;
3615646Sralph 
3715646Sralph 	if ((db = (DBM *)malloc(sizeof *db)) == 0) {
3815646Sralph 		errno = ENOMEM;
3915646Sralph 		return ((DBM *)0);
4015646Sralph 	}
4117023Sralph 	db->dbm_flags = (flags & 03) == O_RDONLY ? _DBM_RDONLY : 0;
4215646Sralph 	if ((flags & 03) == O_WRONLY)
4315646Sralph 		flags = (flags & ~03) | O_RDWR;
4417023Sralph 	strcpy(db->dbm_pagbuf, file);
4517023Sralph 	strcat(db->dbm_pagbuf, ".pag");
4617023Sralph 	db->dbm_pagf = open(db->dbm_pagbuf, flags, mode);
4717023Sralph 	if (db->dbm_pagf < 0)
4815646Sralph 		goto bad;
4917023Sralph 	strcpy(db->dbm_pagbuf, file);
5017023Sralph 	strcat(db->dbm_pagbuf, ".dir");
5117023Sralph 	db->dbm_dirf = open(db->dbm_pagbuf, flags, mode);
5217023Sralph 	if (db->dbm_dirf < 0)
5315646Sralph 		goto bad1;
5417023Sralph 	fstat(db->dbm_dirf, &statb);
5517023Sralph 	db->dbm_maxbno = statb.st_size*BYTESIZ-1;
5617023Sralph 	db->dbm_pagbno = db->dbm_dirbno = -1;
5715646Sralph 	return (db);
5815646Sralph bad1:
5917023Sralph 	(void) close(db->dbm_pagf);
6015646Sralph bad:
6115646Sralph 	free((char *)db);
6215646Sralph 	return ((DBM *)0);
6315646Sralph }
6415646Sralph 
6515646Sralph void
dbm_close(db)6617023Sralph dbm_close(db)
6715646Sralph 	DBM *db;
6815646Sralph {
6915646Sralph 
7017023Sralph 	(void) close(db->dbm_dirf);
7117023Sralph 	(void) close(db->dbm_pagf);
7215646Sralph 	free((char *)db);
7315646Sralph }
7415646Sralph 
7515646Sralph long
dbm_forder(db,key)7617023Sralph dbm_forder(db, key)
7715646Sralph 	register DBM *db;
7815646Sralph 	datum key;
7915646Sralph {
8015646Sralph 	long hash;
8115646Sralph 
8215646Sralph 	hash = dcalchash(key);
8317023Sralph 	for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1) {
8417023Sralph 		db->dbm_blkno = hash & db->dbm_hmask;
8517023Sralph 		db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
8615646Sralph 		if (getbit(db) == 0)
8715646Sralph 			break;
8815646Sralph 	}
8917023Sralph 	return (db->dbm_blkno);
9015646Sralph }
9115646Sralph 
9215646Sralph datum
dbm_fetch(db,key)9317023Sralph dbm_fetch(db, key)
9415646Sralph 	register DBM *db;
9515646Sralph 	datum key;
9615646Sralph {
9715646Sralph 	register i;
9815646Sralph 	datum item;
9915646Sralph 
10017023Sralph 	if (dbm_error(db))
10117023Sralph 		goto err;
10215646Sralph 	dbm_access(db, dcalchash(key));
10317164Sralph 	if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) {
10417164Sralph 		item = makdatum(db->dbm_pagbuf, i+1);
10517164Sralph 		if (item.dptr != NULL)
10615646Sralph 			return (item);
10715646Sralph 	}
10817023Sralph err:
10917023Sralph 	item.dptr = NULL;
11017023Sralph 	item.dsize = 0;
11117023Sralph 	return (item);
11215646Sralph }
11315646Sralph 
dbm_delete(db,key)11417023Sralph dbm_delete(db, key)
11515646Sralph 	register DBM *db;
11615646Sralph 	datum key;
11715646Sralph {
11815646Sralph 	register i;
11915646Sralph 	datum item;
12015646Sralph 
12117023Sralph 	if (dbm_error(db))
12217023Sralph 		return (-1);
12317023Sralph 	if (dbm_rdonly(db)) {
12415646Sralph 		errno = EPERM;
12515646Sralph 		return (-1);
12615646Sralph 	}
12715646Sralph 	dbm_access(db, dcalchash(key));
12817164Sralph 	if ((i = finddatum(db->dbm_pagbuf, key)) < 0)
12917023Sralph 		return (-1);
13017164Sralph 	if (!delitem(db->dbm_pagbuf, i))
13117164Sralph 		goto err;
13217023Sralph 	db->dbm_pagbno = db->dbm_blkno;
13317023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
13417023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
13517164Sralph 	err:
13617023Sralph 		db->dbm_flags |= _DBM_IOERR;
13717023Sralph 		return (-1);
13817023Sralph 	}
13915646Sralph 	return (0);
14015646Sralph }
14115646Sralph 
dbm_store(db,key,dat,replace)14217023Sralph dbm_store(db, key, dat, replace)
14315646Sralph 	register DBM *db;
14415646Sralph 	datum key, dat;
14515749Sralph 	int replace;
14615646Sralph {
14715646Sralph 	register i;
14817164Sralph 	datum item, item1;
14915646Sralph 	char ovfbuf[PBLKSIZ];
15015646Sralph 
15117023Sralph 	if (dbm_error(db))
15217023Sralph 		return (-1);
15317023Sralph 	if (dbm_rdonly(db)) {
15415646Sralph 		errno = EPERM;
15515646Sralph 		return (-1);
15615646Sralph 	}
15715646Sralph loop:
15815646Sralph 	dbm_access(db, dcalchash(key));
15917164Sralph 	if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) {
16017164Sralph 		if (!replace)
16117164Sralph 			return (1);
16217164Sralph 		if (!delitem(db->dbm_pagbuf, i)) {
16317164Sralph 			db->dbm_flags |= _DBM_IOERR;
16417164Sralph 			return (-1);
16515646Sralph 		}
16615646Sralph 	}
16717164Sralph 	if (!additem(db->dbm_pagbuf, key, dat))
16815646Sralph 		goto split;
16917023Sralph 	db->dbm_pagbno = db->dbm_blkno;
17017023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
17117023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
17217023Sralph 		db->dbm_flags |= _DBM_IOERR;
17317023Sralph 		return (-1);
17417023Sralph 	}
17515646Sralph 	return (0);
17615646Sralph 
17715646Sralph split:
17817164Sralph 	if (key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ) {
17917023Sralph 		db->dbm_flags |= _DBM_IOERR;
18015646Sralph 		errno = ENOSPC;
18115646Sralph 		return (-1);
18215646Sralph 	}
18315646Sralph 	bzero(ovfbuf, PBLKSIZ);
18415646Sralph 	for (i=0;;) {
18517023Sralph 		item = makdatum(db->dbm_pagbuf, i);
18615646Sralph 		if (item.dptr == NULL)
18715646Sralph 			break;
18817023Sralph 		if (dcalchash(item) & (db->dbm_hmask+1)) {
18917164Sralph 			item1 = makdatum(db->dbm_pagbuf, i+1);
19017164Sralph 			if (item1.dptr == NULL) {
19117023Sralph 				fprintf(stderr, "ndbm: split not paired\n");
19217023Sralph 				db->dbm_flags |= _DBM_IOERR;
19315646Sralph 				break;
19415646Sralph 			}
19517164Sralph 			if (!additem(ovfbuf, item, item1) ||
19617023Sralph 			    !delitem(db->dbm_pagbuf, i)) {
19717023Sralph 				db->dbm_flags |= _DBM_IOERR;
19817023Sralph 				return (-1);
19917023Sralph 			}
20015646Sralph 			continue;
20115646Sralph 		}
20215646Sralph 		i += 2;
20315646Sralph 	}
20417023Sralph 	db->dbm_pagbno = db->dbm_blkno;
20517023Sralph 	(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
20617023Sralph 	if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) {
20717023Sralph 		db->dbm_flags |= _DBM_IOERR;
20817023Sralph 		return (-1);
20917023Sralph 	}
21017023Sralph 	(void) lseek(db->dbm_pagf, (db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ, L_SET);
21117023Sralph 	if (write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ) {
21217023Sralph 		db->dbm_flags |= _DBM_IOERR;
21317023Sralph 		return (-1);
21417023Sralph 	}
21515646Sralph 	setbit(db);
21615646Sralph 	goto loop;
21715646Sralph }
21815646Sralph 
21915646Sralph datum
dbm_firstkey(db)22017023Sralph dbm_firstkey(db)
22115646Sralph 	DBM *db;
22215646Sralph {
22315646Sralph 
22417164Sralph 	db->dbm_blkptr = 0L;
22517164Sralph 	db->dbm_keyptr = 0;
22617164Sralph 	return (dbm_nextkey(db));
22715646Sralph }
22815646Sralph 
22915646Sralph datum
dbm_nextkey(db)23017164Sralph dbm_nextkey(db)
23115646Sralph 	register DBM *db;
23215646Sralph {
23317164Sralph 	struct stat statb;
23417164Sralph 	datum item;
23515646Sralph 
23617164Sralph 	if (dbm_error(db) || fstat(db->dbm_pagf, &statb) < 0)
23717023Sralph 		goto err;
23817164Sralph 	statb.st_size /= PBLKSIZ;
23917164Sralph 	for (;;) {
24017164Sralph 		if (db->dbm_blkptr != db->dbm_pagbno) {
24117164Sralph 			db->dbm_pagbno = db->dbm_blkptr;
24217164Sralph 			(void) lseek(db->dbm_pagf, db->dbm_blkptr*PBLKSIZ, L_SET);
24317164Sralph 			if (read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
24417164Sralph 				bzero(db->dbm_pagbuf, PBLKSIZ);
24517164Sralph #ifdef DEBUG
24617164Sralph 			else if (chkblk(db->dbm_pagbuf) < 0)
24717164Sralph 				db->dbm_flags |= _DBM_IOERR;
24817164Sralph #endif
24917164Sralph 		}
25017164Sralph 		if (((short *)db->dbm_pagbuf)[0] != 0) {
25117164Sralph 			item = makdatum(db->dbm_pagbuf, db->dbm_keyptr);
25217164Sralph 			if (item.dptr != NULL) {
25317164Sralph 				db->dbm_keyptr += 2;
25417164Sralph 				return (item);
25517164Sralph 			}
25617164Sralph 			db->dbm_keyptr = 0;
25717164Sralph 		}
25817164Sralph 		if (++db->dbm_blkptr >= statb.st_size)
25915646Sralph 			break;
26015646Sralph 	}
26117023Sralph err:
26217023Sralph 	item.dptr = NULL;
26317023Sralph 	item.dsize = 0;
26417023Sralph 	return (item);
26515646Sralph }
26615646Sralph 
26747255Sbostic static void
dbm_access(db,hash)26815646Sralph dbm_access(db, hash)
26915646Sralph 	register DBM *db;
27015646Sralph 	long hash;
27115646Sralph {
27217164Sralph 
27317023Sralph 	for (db->dbm_hmask=0;; db->dbm_hmask=(db->dbm_hmask<<1)+1) {
27417023Sralph 		db->dbm_blkno = hash & db->dbm_hmask;
27517023Sralph 		db->dbm_bitno = db->dbm_blkno + db->dbm_hmask;
27615646Sralph 		if (getbit(db) == 0)
27715646Sralph 			break;
27815646Sralph 	}
27917023Sralph 	if (db->dbm_blkno != db->dbm_pagbno) {
28017023Sralph 		db->dbm_pagbno = db->dbm_blkno;
28117023Sralph 		(void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, L_SET);
28217023Sralph 		if (read(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ)
28317023Sralph 			bzero(db->dbm_pagbuf, PBLKSIZ);
28417164Sralph #ifdef DEBUG
28517023Sralph 		else if (chkblk(db->dbm_pagbuf) < 0)
28617023Sralph 			db->dbm_flags |= _DBM_IOERR;
28717164Sralph #endif
28815646Sralph 	}
28915646Sralph }
29015646Sralph 
29115646Sralph static
getbit(db)29215646Sralph getbit(db)
29315646Sralph 	register DBM *db;
29415646Sralph {
29515646Sralph 	long bn;
29615646Sralph 	register b, i, n;
29715646Sralph 
29815646Sralph 
29917023Sralph 	if (db->dbm_bitno > db->dbm_maxbno)
30015646Sralph 		return (0);
30117023Sralph 	n = db->dbm_bitno % BYTESIZ;
30217023Sralph 	bn = db->dbm_bitno / BYTESIZ;
30315646Sralph 	i = bn % DBLKSIZ;
30415646Sralph 	b = bn / DBLKSIZ;
30517023Sralph 	if (b != db->dbm_dirbno) {
30617023Sralph 		db->dbm_dirbno = b;
30717023Sralph 		(void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
30817023Sralph 		if (read(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
30917023Sralph 			bzero(db->dbm_dirbuf, DBLKSIZ);
31015646Sralph 	}
31117164Sralph 	return (db->dbm_dirbuf[i] & (1<<n));
31215646Sralph }
31315646Sralph 
31447255Sbostic static void
setbit(db)31515646Sralph setbit(db)
31615646Sralph 	register DBM *db;
31715646Sralph {
31815646Sralph 	long bn;
31915646Sralph 	register i, n, b;
32015646Sralph 
32117164Sralph 	if (db->dbm_bitno > db->dbm_maxbno)
32217023Sralph 		db->dbm_maxbno = db->dbm_bitno;
32317023Sralph 	n = db->dbm_bitno % BYTESIZ;
32417023Sralph 	bn = db->dbm_bitno / BYTESIZ;
32515646Sralph 	i = bn % DBLKSIZ;
32615646Sralph 	b = bn / DBLKSIZ;
32717164Sralph 	if (b != db->dbm_dirbno) {
32817164Sralph 		db->dbm_dirbno = b;
32917164Sralph 		(void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
33017164Sralph 		if (read(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
33117164Sralph 			bzero(db->dbm_dirbuf, DBLKSIZ);
33217164Sralph 	}
33317023Sralph 	db->dbm_dirbuf[i] |= 1<<n;
33417023Sralph 	db->dbm_dirbno = b;
33517023Sralph 	(void) lseek(db->dbm_dirf, (long)b*DBLKSIZ, L_SET);
33617164Sralph 	if (write(db->dbm_dirf, db->dbm_dirbuf, DBLKSIZ) != DBLKSIZ)
33717023Sralph 		db->dbm_flags |= _DBM_IOERR;
33815646Sralph }
33915646Sralph 
34015646Sralph static datum
makdatum(buf,n)34115646Sralph makdatum(buf, n)
34215646Sralph 	char buf[PBLKSIZ];
34315646Sralph {
34415646Sralph 	register short *sp;
34515646Sralph 	register t;
34615646Sralph 	datum item;
34715646Sralph 
34815646Sralph 	sp = (short *)buf;
34917164Sralph 	if ((unsigned)n >= sp[0]) {
35017023Sralph 		item.dptr = NULL;
35117023Sralph 		item.dsize = 0;
35217023Sralph 		return (item);
35317023Sralph 	}
35415646Sralph 	t = PBLKSIZ;
35515646Sralph 	if (n > 0)
35617023Sralph 		t = sp[n];
35715646Sralph 	item.dptr = buf+sp[n+1];
35815646Sralph 	item.dsize = t - sp[n+1];
35915646Sralph 	return (item);
36015646Sralph }
36115646Sralph 
36215646Sralph static
finddatum(buf,item)36317164Sralph finddatum(buf, item)
36417164Sralph 	char buf[PBLKSIZ];
36517164Sralph 	datum item;
36615646Sralph {
36717164Sralph 	register short *sp;
36817164Sralph 	register int i, n, j;
36915646Sralph 
37017164Sralph 	sp = (short *)buf;
37117164Sralph 	n = PBLKSIZ;
37217164Sralph 	for (i=0, j=sp[0]; i<j; i+=2, n = sp[i]) {
37317164Sralph 		n -= sp[i+1];
37417164Sralph 		if (n != item.dsize)
37517164Sralph 			continue;
37617164Sralph 		if (n == 0 || bcmp(&buf[sp[i+1]], item.dptr, n) == 0)
37717164Sralph 			return (i);
37817164Sralph 	}
37917164Sralph 	return (-1);
38015646Sralph }
38115646Sralph 
38215646Sralph static  int hitab[16]
38315646Sralph /* ken's
38415646Sralph {
38515646Sralph 	055,043,036,054,063,014,004,005,
38615646Sralph 	010,064,077,000,035,027,025,071,
38715646Sralph };
38815646Sralph */
38915646Sralph  = {    61, 57, 53, 49, 45, 41, 37, 33,
39015646Sralph 	29, 25, 21, 17, 13,  9,  5,  1,
39115646Sralph };
39215646Sralph static  long hltab[64]
39315646Sralph  = {
39415646Sralph 	06100151277L,06106161736L,06452611562L,05001724107L,
39515646Sralph 	02614772546L,04120731531L,04665262210L,07347467531L,
39615646Sralph 	06735253126L,06042345173L,03072226605L,01464164730L,
39715646Sralph 	03247435524L,07652510057L,01546775256L,05714532133L,
39815646Sralph 	06173260402L,07517101630L,02431460343L,01743245566L,
39915646Sralph 	00261675137L,02433103631L,03421772437L,04447707466L,
40015646Sralph 	04435620103L,03757017115L,03641531772L,06767633246L,
40115646Sralph 	02673230344L,00260612216L,04133454451L,00615531516L,
40215646Sralph 	06137717526L,02574116560L,02304023373L,07061702261L,
40315646Sralph 	05153031405L,05322056705L,07401116734L,06552375715L,
40415646Sralph 	06165233473L,05311063631L,01212221723L,01052267235L,
40515646Sralph 	06000615237L,01075222665L,06330216006L,04402355630L,
40615646Sralph 	01451177262L,02000133436L,06025467062L,07121076461L,
40715646Sralph 	03123433522L,01010635225L,01716177066L,05161746527L,
40815646Sralph 	01736635071L,06243505026L,03637211610L,01756474365L,
40915646Sralph 	04723077174L,03642763134L,05750130273L,03655541561L,
41015646Sralph };
41115646Sralph 
41215646Sralph static long
hashinc(db,hash)41315646Sralph hashinc(db, hash)
41415646Sralph 	register DBM *db;
41515646Sralph 	long hash;
41615646Sralph {
41715646Sralph 	long bit;
41815646Sralph 
41917023Sralph 	hash &= db->dbm_hmask;
42017023Sralph 	bit = db->dbm_hmask+1;
42115646Sralph 	for (;;) {
42215646Sralph 		bit >>= 1;
42315646Sralph 		if (bit == 0)
42415646Sralph 			return (0L);
42517023Sralph 		if ((hash & bit) == 0)
42617023Sralph 			return (hash | bit);
42715646Sralph 		hash &= ~bit;
42815646Sralph 	}
42915646Sralph }
43015646Sralph 
43115646Sralph static long
dcalchash(item)43215646Sralph dcalchash(item)
43315646Sralph 	datum item;
43415646Sralph {
43517023Sralph 	register int s, c, j;
43617023Sralph 	register char *cp;
43717023Sralph 	register long hashl;
43817023Sralph 	register int hashi;
43915646Sralph 
44015646Sralph 	hashl = 0;
44115646Sralph 	hashi = 0;
44217023Sralph 	for (cp = item.dptr, s=item.dsize; --s >= 0; ) {
44317023Sralph 		c = *cp++;
44415646Sralph 		for (j=0; j<BYTESIZ; j+=4) {
44517023Sralph 			hashi += hitab[c&017];
44615646Sralph 			hashl += hltab[hashi&63];
44717023Sralph 			c >>= 4;
44815646Sralph 		}
44915646Sralph 	}
45015646Sralph 	return (hashl);
45115646Sralph }
45215646Sralph 
45317164Sralph /*
45417164Sralph  * Delete pairs of items (n & n+1).
45517164Sralph  */
45615646Sralph static
delitem(buf,n)45715646Sralph delitem(buf, n)
45815646Sralph 	char buf[PBLKSIZ];
45915646Sralph {
46017023Sralph 	register short *sp, *sp1;
46117023Sralph 	register i1, i2;
46215646Sralph 
46315646Sralph 	sp = (short *)buf;
46417023Sralph 	i2 = sp[0];
46517164Sralph 	if ((unsigned)n >= i2 || (n & 1))
46617023Sralph 		return (0);
46717164Sralph 	if (n == i2-2) {
46817164Sralph 		sp[0] -= 2;
46917023Sralph 		return (1);
47017023Sralph 	}
47117023Sralph 	i1 = PBLKSIZ;
47215646Sralph 	if (n > 0)
47317023Sralph 		i1 = sp[n];
47417164Sralph 	i1 -= sp[n+2];
47517023Sralph 	if (i1 > 0) {
47617023Sralph 		i2 = sp[i2];
47717164Sralph 		bcopy(&buf[i2], &buf[i2 + i1], sp[n+2] - i2);
47815646Sralph 	}
47917164Sralph 	sp[0] -= 2;
48017164Sralph 	for (sp1 = sp + sp[0], sp += n+1; sp <= sp1; sp++)
48117164Sralph 		sp[0] = sp[2] + i1;
48217023Sralph 	return (1);
48315646Sralph }
48415646Sralph 
48517164Sralph /*
48617164Sralph  * Add pairs of items (item & item1).
48717164Sralph  */
48815646Sralph static
additem(buf,item,item1)48917164Sralph additem(buf, item, item1)
49015646Sralph 	char buf[PBLKSIZ];
49117164Sralph 	datum item, item1;
49215646Sralph {
49315646Sralph 	register short *sp;
49415646Sralph 	register i1, i2;
49515646Sralph 
49615646Sralph 	sp = (short *)buf;
49715646Sralph 	i1 = PBLKSIZ;
49817023Sralph 	i2 = sp[0];
49917023Sralph 	if (i2 > 0)
50017023Sralph 		i1 = sp[i2];
50117164Sralph 	i1 -= item.dsize + item1.dsize;
50232107Smckusick 	if (i1 <= (i2+3) * (int)sizeof(short))
50317023Sralph 		return (0);
50417164Sralph 	sp[0] += 2;
50517164Sralph 	sp[++i2] = i1 + item1.dsize;
50617164Sralph 	bcopy(item.dptr, &buf[i1 + item1.dsize], item.dsize);
50717164Sralph 	sp[++i2] = i1;
50817164Sralph 	bcopy(item1.dptr, &buf[i1], item1.dsize);
50917023Sralph 	return (1);
51015646Sralph }
51115646Sralph 
51217164Sralph #ifdef DEBUG
51315646Sralph static
chkblk(buf)51415646Sralph chkblk(buf)
51515646Sralph 	char buf[PBLKSIZ];
51615646Sralph {
51715646Sralph 	register short *sp;
51815646Sralph 	register t, i;
51915646Sralph 
52015646Sralph 	sp = (short *)buf;
52115646Sralph 	t = PBLKSIZ;
52215646Sralph 	for (i=0; i<sp[0]; i++) {
52315646Sralph 		if (sp[i+1] > t)
52417023Sralph 			return (-1);
52515646Sralph 		t = sp[i+1];
52615646Sralph 	}
52715646Sralph 	if (t < (sp[0]+1)*sizeof(short))
52817023Sralph 		return (-1);
52917023Sralph 	return (0);
53015646Sralph }
53117164Sralph #endif
532