static char sccsid
[] = "@(#)ndbm.c 4.4 (Berkeley) %G%";
dbm_open(file
, flags
, mode
)
if ((db
= (DBM
*)malloc(sizeof *db
)) == 0) {
db
->dbm_flags
= (flags
& 03) == O_RDONLY
? _DBM_RDONLY
: 0;
if ((flags
& 03) == O_WRONLY
)
flags
= (flags
& ~03) | O_RDWR
;
strcpy(db
->dbm_pagbuf
, file
);
strcat(db
->dbm_pagbuf
, ".pag");
db
->dbm_pagf
= open(db
->dbm_pagbuf
, flags
, mode
);
strcpy(db
->dbm_pagbuf
, file
);
strcat(db
->dbm_pagbuf
, ".dir");
db
->dbm_dirf
= open(db
->dbm_pagbuf
, flags
, mode
);
fstat(db
->dbm_dirf
, &statb
);
db
->dbm_maxbno
= statb
.st_size
*BYTESIZ
-1;
db
->dbm_pagbno
= db
->dbm_dirbno
= -1;
(void) close(db
->dbm_pagf
);
(void) close(db
->dbm_dirf
);
(void) close(db
->dbm_pagf
);
for (db
->dbm_hmask
=0;; db
->dbm_hmask
=(db
->dbm_hmask
<<1)+1) {
db
->dbm_blkno
= hash
& db
->dbm_hmask
;
db
->dbm_bitno
= db
->dbm_blkno
+ db
->dbm_hmask
;
dbm_access(db
, dcalchash(key
));
if ((i
= finddatum(db
->dbm_pagbuf
, key
)) >= 0) {
item
= makdatum(db
->dbm_pagbuf
, i
+1);
dbm_access(db
, dcalchash(key
));
if ((i
= finddatum(db
->dbm_pagbuf
, key
)) < 0)
if (!delitem(db
->dbm_pagbuf
, i
))
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
dbm_store(db
, key
, dat
, replace
)
dbm_access(db
, dcalchash(key
));
if ((i
= finddatum(db
->dbm_pagbuf
, key
)) >= 0) {
if (!delitem(db
->dbm_pagbuf
, i
)) {
db
->dbm_flags
|= _DBM_IOERR
;
if (!additem(db
->dbm_pagbuf
, key
, dat
))
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
if (key
.dsize
+dat
.dsize
+3*sizeof(short) >= PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
item
= makdatum(db
->dbm_pagbuf
, i
);
if (dcalchash(item
) & (db
->dbm_hmask
+1)) {
item1
= makdatum(db
->dbm_pagbuf
, i
+1);
if (item1
.dptr
== NULL
) {
fprintf(stderr
, "ndbm: split not paired\n");
db
->dbm_flags
|= _DBM_IOERR
;
if (!additem(ovfbuf
, item
, item1
) ||
!delitem(db
->dbm_pagbuf
, i
)) {
db
->dbm_flags
|= _DBM_IOERR
;
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
(void) lseek(db
->dbm_pagf
, (db
->dbm_blkno
+db
->dbm_hmask
+1)*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, ovfbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
return (dbm_nextkey(db
));
if (dbm_error(db
) || fstat(db
->dbm_pagf
, &statb
) < 0)
statb
.st_size
/= PBLKSIZ
;
if (db
->dbm_blkptr
!= db
->dbm_pagbno
) {
db
->dbm_pagbno
= db
->dbm_blkptr
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkptr
*PBLKSIZ
, L_SET
);
if (read(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
)
bzero(db
->dbm_pagbuf
, PBLKSIZ
);
else if (chkblk(db
->dbm_pagbuf
) < 0)
db
->dbm_flags
|= _DBM_IOERR
;
if (((short *)db
->dbm_pagbuf
)[0] != 0) {
item
= makdatum(db
->dbm_pagbuf
, db
->dbm_keyptr
);
if (++db
->dbm_blkptr
>= statb
.st_size
)
for (db
->dbm_hmask
=0;; db
->dbm_hmask
=(db
->dbm_hmask
<<1)+1) {
db
->dbm_blkno
= hash
& db
->dbm_hmask
;
db
->dbm_bitno
= db
->dbm_blkno
+ db
->dbm_hmask
;
if (db
->dbm_blkno
!= db
->dbm_pagbno
) {
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (read(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
)
bzero(db
->dbm_pagbuf
, PBLKSIZ
);
else if (chkblk(db
->dbm_pagbuf
) < 0)
db
->dbm_flags
|= _DBM_IOERR
;
if (db
->dbm_bitno
> db
->dbm_maxbno
)
n
= db
->dbm_bitno
% BYTESIZ
;
bn
= db
->dbm_bitno
/ BYTESIZ
;
if (b
!= db
->dbm_dirbno
) {
(void) lseek(db
->dbm_dirf
, (long)b
*DBLKSIZ
, L_SET
);
if (read(db
->dbm_dirf
, db
->dbm_dirbuf
, DBLKSIZ
) != DBLKSIZ
)
bzero(db
->dbm_dirbuf
, DBLKSIZ
);
return (db
->dbm_dirbuf
[i
] & (1<<n
));
if (db
->dbm_bitno
> db
->dbm_maxbno
)
db
->dbm_maxbno
= db
->dbm_bitno
;
n
= db
->dbm_bitno
% BYTESIZ
;
bn
= db
->dbm_bitno
/ BYTESIZ
;
if (b
!= db
->dbm_dirbno
) {
(void) lseek(db
->dbm_dirf
, (long)b
*DBLKSIZ
, L_SET
);
if (read(db
->dbm_dirf
, db
->dbm_dirbuf
, DBLKSIZ
) != DBLKSIZ
)
bzero(db
->dbm_dirbuf
, DBLKSIZ
);
db
->dbm_dirbuf
[i
] |= 1<<n
;
(void) lseek(db
->dbm_dirf
, (long)b
*DBLKSIZ
, L_SET
);
if (write(db
->dbm_dirf
, db
->dbm_dirbuf
, DBLKSIZ
) != DBLKSIZ
)
db
->dbm_flags
|= _DBM_IOERR
;
if ((unsigned)n
>= sp
[0]) {
item
.dsize
= t
- sp
[n
+1];
for (i
=0, j
=sp
[0]; i
<j
; i
+=2, n
= sp
[i
]) {
if (n
== 0 || bcmp(&buf
[sp
[i
+1]], item
.dptr
, n
) == 0)
055,043,036,054,063,014,004,005,
010,064,077,000,035,027,025,071,
= { 61, 57, 53, 49, 45, 41, 37, 33,
29, 25, 21, 17, 13, 9, 5, 1,
06100151277L,06106161736L,06452611562L,05001724107L,
02614772546L,04120731531L,04665262210L,07347467531L,
06735253126L,06042345173L,03072226605L,01464164730L,
03247435524L,07652510057L,01546775256L,05714532133L,
06173260402L,07517101630L,02431460343L,01743245566L,
00261675137L,02433103631L,03421772437L,04447707466L,
04435620103L,03757017115L,03641531772L,06767633246L,
02673230344L,00260612216L,04133454451L,00615531516L,
06137717526L,02574116560L,02304023373L,07061702261L,
05153031405L,05322056705L,07401116734L,06552375715L,
06165233473L,05311063631L,01212221723L,01052267235L,
06000615237L,01075222665L,06330216006L,04402355630L,
01451177262L,02000133436L,06025467062L,07121076461L,
03123433522L,01010635225L,01716177066L,05161746527L,
01736635071L,06243505026L,03637211610L,01756474365L,
04723077174L,03642763134L,05750130273L,03655541561L,
for (cp
= item
.dptr
, s
=item
.dsize
; --s
>= 0; ) {
for (j
=0; j
<BYTESIZ
; j
+=4) {
hashl
+= hltab
[hashi
&63];
* Delete pairs of items (n & n+1).
register short *sp
, *sp1
;
if ((unsigned)n
>= i2
|| (n
& 1))
bcopy(&buf
[i2
], &buf
[i2
+ i1
], sp
[n
+2] - i2
);
for (sp1
= sp
+ sp
[0], sp
+= n
+1; sp
<= sp1
; sp
++)
* Add pairs of items (item & item1).
additem(buf
, item
, item1
)
i1
-= item
.dsize
+ item1
.dsize
;
if (i1
<= (i2
+3) * sizeof(short))
sp
[++i2
] = i1
+ item1
.dsize
;
bcopy(item
.dptr
, &buf
[i1
+ item1
.dsize
], item
.dsize
);
bcopy(item1
.dptr
, &buf
[i1
], item1
.dsize
);
for (i
=0; i
<sp
[0]; i
++) {
if (t
< (sp
[0]+1)*sizeof(short))