|
|
Initial revision
#include <stdio.h>
#include <sys/fcntl.h>
#include "quipu/config.h"
#include "quipu/entry.h"
#include "psap.h"
#include "quipu/malloc.h"
#include "logger.h"
#ifdef TURBO_DISK
#include <gdbm.h>
extern RDN parse_rdn;
extern LLog *log_dsap;
extern int gdbm_errno;
extern datum turbo_header_key;
static turbo_write_entry(db, e)
GDBM_FILE db;
Entry e;
{
static char kbuf[512];
static char buf[10000];
int rc;
PS ps;
datum rdn;
datum ent;
LLOG (log_dsap, LLOG_TRACE,("turbo: write_entry"));
/* allocate the string presentation stream to print to */
if ( (ps = ps_alloc(str_open)) == NULLPS )
return(NOTOK);
if ( str_setup(ps, buf, sizeof(buf), 0) == NOTOK ) {
ps_free(ps);
return(NOTOK);
}
*ps->ps_ptr = 0;
rdn_print(ps, e->e_name, EDBOUT);
*ps->ps_ptr = '\0';
strcpy(kbuf, ps->ps_base);
rdn.dptr = kbuf;
rdn.dsize = strlen(rdn.dptr) + 1;
ps_print(ps, "\n");
as_print(ps, e->e_attributes, EDBOUT);
ps_print(ps, "\n");
*ps->ps_ptr = '\0';
ent.dptr = ps->ps_base;
ent.dsize = strlen(ent.dptr) + 1;
if ( (rc = gdbm_store(db, rdn, ent, GDBM_REPLACE)) != 0 ) {
LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_store %d, gdbm_errno %d", rc, gdbm_errno));
ps_free(ps);
return(NOTOK);
}
ps_free(ps);
return(OK);
}
/*
* turbo_writeall -- write the entries in list p to the proper edb
* dbm file the file is opened by turbo_open, then the list is traversed,
* calling turbo_write_entry to write each entry
*/
turbo_writeall(e)
Entry e;
{
GDBM_FILE db, turbo_open();
DN dn;
char *filename;
int save_heap;
LLOG (log_dsap, LLOG_TRACE,("turbo: write_all"));
save_heap = mem_heap;
GENERAL_HEAP;
if ( (db = turbo_open(e, 1)) == NULL ) {
mem_heap = save_heap;
return(NOTOK);
}
if ( turbo_write_header(db, e) != OK ) {
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
while (e) {
if ( turbo_write_entry(db, e) != OK ) {
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
e = e->e_sibling;
}
(void) gdbm_close(db);
mem_heap = save_heap;
return(OK);
}
/*
* turbo_write -- write the single entry pointed to by e to the proper
* edb dbm file. The edb dbm file is opened by turbo_open, then a new
* header is written by turbo_write_header, and finally the entry is
* written with a call to turbo_write_entry.
*/
turbo_write(e)
Entry e;
{
GDBM_FILE db, turbo_open();
int save_heap;
LLOG (log_dsap, LLOG_TRACE, ("turbo: write"));
save_heap = mem_heap;
GENERAL_HEAP;
if ( (db = turbo_open(e, 0)) == NULL ) {
mem_heap = save_heap;
return(NOTOK);
}
if ( turbo_write_header(db, e) != OK ) {
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
if ( turbo_write_entry(db, e) != OK ) {
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
(void) gdbm_close(db);
mem_heap = save_heap;
return(OK);
}
/*
* turbo_delete -- delete the entry pointed to by p from the proper
* edb dbm file.
*/
turbo_delete(e)
Entry e;
{
static char deletekey[256];
int rc;
GDBM_FILE db, turbo_open();
PS ps;
datum key;
int save_heap;
LLOG (log_dsap, LLOG_TRACE,("turbo: delete"));
save_heap = mem_heap;
GENERAL_HEAP;
if ( (db = turbo_open(e, 0)) == NULL ) {
mem_heap = save_heap;
return(NOTOK);
}
if ( turbo_write_header(db, e) != OK ) {
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
/* allocate the string presentation stream to print the key to */
if ( (ps = ps_alloc(str_open)) == NULLPS ) {
mem_heap = save_heap;
return(NOTOK);
}
if ( str_setup(ps, deletekey, sizeof(deletekey), 0) == NOTOK ) {
ps_free(ps);
mem_heap = save_heap;
return(NOTOK);
}
*ps->ps_ptr = 0;
rdn_print(ps, e->e_name, EDBOUT);
*ps->ps_ptr = '\0';
key.dptr = ps->ps_base;
key.dsize = strlen(key.dptr) + 1;
printf("deleting (%s)\n", key.dptr);
if ( (rc = gdbm_delete(db, key)) != 0 ) {
LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_delete %d gdbm_errno %d", rc, gdbm_errno));
ps_free(ps);
(void) gdbm_close(db);
mem_heap = save_heap;
return(NOTOK);
}
ps_free(ps);
(void) gdbm_close(db);
mem_heap = save_heap;
return(OK);
}
/*
* turbo_open -- open a dbm edb file for writing. e is a pointer to the
* entry to be written. It's parent is used to construct the name of
* the file to write. If create is 0 a new database will not be created,
* otherwise it will and a backup of the old one will be made.
*/
static GDBM_FILE turbo_open(e, create)
Entry e;
char create;
{
GDBM_FILE db;
DN dn, get_copy_dn();
char *filename, *dn2edbfile();
char bakname[1024], turbo_gfname[1024];
LLOG (log_dsap, LLOG_TRACE,("turbo: open"));
/* get the name of the edb file to write to */
dn = get_copy_dn (e->e_parent);
if ((filename = dn2edbfile (dn)) == NULLCP) {
dn_free (dn);
LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: dn2edbfile failed"));
return (NULL);
}
dn_free(dn);
strcpy(turbo_gfname, filename);
strcat(turbo_gfname, ".gdbm");
strcpy(bakname, turbo_gfname);
strcat(bakname, ".bak");
/* try to open it */
if ( create ) {
/* first make a backup of the old one */
(void) unlink(bakname);
if ( link(turbo_gfname, bakname) != 0 ) {
LLOG (log_dsap, LLOG_EXCEPTIONS, ("turbo: could not make backup"));
return(NULL);
}
(void) unlink(turbo_gfname);
/* then open the new one */
db = gdbm_open(turbo_gfname, 0, GDBM_WRCREAT, 0600, 0);
} else
db = gdbm_open(turbo_gfname, 0, GDBM_WRITER, 0, 0);
if ( db == NULL ) {
LLOG (log_dsap, LLOG_EXCEPTIONS, ("turbo: gdbm_open failed gdbm_errno %d", gdbm_errno));
return (NULL);
}
return(db);
}
/*
* turbo_write_header -- write a new header for the edb dbm file db.
* The version is taken from e's parent version
*/
turbo_write_header(db, e)
GDBM_FILE db;
Entry e;
{
static char hbuf[256];
PS ps;
int rc;
char *type;
datum newheader;
int save_heap;
LLOG (log_dsap, LLOG_TRACE,("turbo: write_header"));
save_heap = mem_heap;
GENERAL_HEAP;
switch (e->e_data) {
case E_DATA_MASTER:
type = "MASTER";
break;
case E_TYPE_SLAVE :
type = "SLAVE";
break;
default:
type = "CACHE";
break;
}
/* allocate the string presentation stream to print to */
if ( (ps = ps_alloc(str_open)) == NULLPS ) {
mem_heap = save_heap;
return(NOTOK);
}
if ( str_setup(ps, hbuf, sizeof(hbuf), 0) == NOTOK ) {
ps_free(ps);
mem_heap = save_heap;
return(NOTOK);
}
ps_print(ps, type);
ps_print(ps, "\n");
if (e->e_parent != NULLENTRY)
ps_print(ps, e->e_parent->e_edbversion);
else
ps_print(ps, new_version());
ps_print(ps, "\n");
*ps->ps_ptr = '\0';
newheader.dptr = ps->ps_base;
newheader.dsize = strlen(newheader.dptr) + 1;
if ( (rc = gdbm_store(db, turbo_header_key, newheader, GDBM_REPLACE)) != 0 ) {
LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_store %d gdbm_errno %d", rc, gdbm_errno));
mem_heap = save_heap;
return(NOTOK);
}
mem_heap = save_heap;
return(OK);
}
#else
/* ARGSUSED */
turbo_writeall(e)
Entry e;
{}
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.