File:  [CSRG BSD Unix] / 43BSDReno / contrib / isode-beta / quipu / turbo_disk.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Apr 24 16:12:56 2018 UTC (8 years, 1 month ago) by root
CVS tags: MAIN, HEAD
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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.