int dbm_delete(DBM *db, datum key) { int i; if (dbm_error(db)) return (-1); if (dbm_rdonly(db)) { errno = EPERM; return (-1); } dbm_access(db, dcalchash(key)); if ((i = finddatum(db->dbm_pagbuf, key)) < 0) return (-1); if (!delitem(db->dbm_pagbuf, i)) goto err; db->dbm_pagbno = db->dbm_blkno; if (dbm_defwrite(db)) { dbm_setdirty(db); } else { (void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET); if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) { err: db->dbm_flags |= _DBM_IOERR; return (-1); } } return (0); }
/* store a record */ int dbm_store(DBM *db, datum key, datum dat, int replace){ int i; datum item, item1; char ovfbuf[PBLKSIZ]; if(dbm_error(db)) return (-1); if(dbm_rdonly(db)){ errno = EPERM; return (-1); } loop: dbm_access(db, dcalchash(key)); if((i = finddatum(db->dbm_pagbuf, key)) >= 0){ if(!replace) return (1); if(!delitem(db->dbm_pagbuf, i)){ db->dbm_flags |= _DBM_IOERR; return (-1); } } if(!additem(db->dbm_pagbuf, key, dat)) goto split; db->dbm_pagbno = db->dbm_blkno; (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, SEEK_SET); if(write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ){ db->dbm_flags |= _DBM_IOERR; return (-1); } return (0); split: if(key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ){ db->dbm_flags |= _DBM_IOERR; errno = ENOSPC; return (-1); } memset(ovfbuf, 0, PBLKSIZ); for(i=0;;){ item = makdatum(db->dbm_pagbuf, i); if(item.dptr == NULL) break; if(dcalchash(item) & (db->dbm_hmask+1)){ item1 = makdatum(db->dbm_pagbuf, i+1); if(item1.dptr == NULL){ db->dbm_flags |= _DBM_IOERR; break; } if(!additem(ovfbuf, item, item1) || !delitem(db->dbm_pagbuf, i)){ db->dbm_flags |= _DBM_IOERR; return (-1); } continue; } i += 2; } db->dbm_pagbno = db->dbm_blkno; (void) lseek(db->dbm_pagf, db->dbm_blkno*PBLKSIZ, SEEK_SET); if(write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ){ db->dbm_flags |= _DBM_IOERR; return (-1); } (void) lseek(db->dbm_pagf, (db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ, SEEK_SET); if(write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ){ db->dbm_flags |= _DBM_IOERR; return (-1); } setbit(db); goto loop; }
int dbm_store(DBM *db, datum key, datum dat, int replace) { int i; datum item, item1; char ovfbuf[PBLKSIZ]; if (dbm_error(db)) return (-1); if (dbm_rdonly(db)) { errno = EPERM; return (-1); } loop: dbm_access(db, dcalchash(key)); if ((i = finddatum(db->dbm_pagbuf, key)) >= 0) { if (!replace) return (1); if (!delitem(db->dbm_pagbuf, i)) { db->dbm_flags |= _DBM_IOERR; return (-1); } } if (!additem(db->dbm_pagbuf, key, dat)) goto split; db->dbm_pagbno = db->dbm_blkno; if (dbm_defwrite(db)) { dbm_setdirty(db); } else { (void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET); if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) { db->dbm_flags |= _DBM_IOERR; return (-1); } } return (0); split: if (key.dsize+dat.dsize+3*sizeof(short) >= PBLKSIZ) { db->dbm_flags |= _DBM_IOERR; errno = ENOSPC; return (-1); } bzero(ovfbuf, PBLKSIZ); for (i=0;;) { item = makdatum(db->dbm_pagbuf, i); if (item.dptr == NULL) break; if (dcalchash(item) & (db->dbm_hmask+1)) { item1 = makdatum(db->dbm_pagbuf, i+1); if (item1.dptr == NULL) { /*(void) fprintf(stderr, "ndbm: split not paired\n");*/ db->dbm_flags |= _DBM_IOERR; break; } if (!additem(ovfbuf, item, item1) || !delitem(db->dbm_pagbuf, i)) { db->dbm_flags |= _DBM_IOERR; return (-1); } continue; } i += 2; } db->dbm_pagbno = db->dbm_blkno; (void) lseek(db->dbm_pagf, (long)(db->dbm_blkno*PBLKSIZ), L_SET); if (write(db->dbm_pagf, db->dbm_pagbuf, PBLKSIZ) != PBLKSIZ) { db->dbm_flags |= _DBM_IOERR; return (-1); } dbm_clrdirty(db); /*clear dirty*/ (void) lseek(db->dbm_pagf, (long)((db->dbm_blkno+db->dbm_hmask+1)*PBLKSIZ), L_SET); if (write(db->dbm_pagf, ovfbuf, PBLKSIZ) != PBLKSIZ) { db->dbm_flags |= _DBM_IOERR; return (-1); } if (setbit(db) < 0) { db->dbm_flags |= _DBM_IOERR; return (-1); } goto loop; }