Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/repl/db.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <bio.h>
#include <error.h>
#include <b.h>
#include <avl.h>
#include "repl.h"

int
dbcmp(Avl* l, Avl* r)
{
	Dbent*	ldb = (Dbent*)l;
	Dbent*	rdb = (Dbent*)r;

	return strcmp(ldb->fname, rdb->fname);
}

Dbent*
readdbent(Biobufhdr* bp)
{
	char*	ln;
	Dbent*	dp;
	char*	p;
	char*	e;

	while (ln = Brdstr(bp, '\n', 1)){
		dp = emalloc(sizeof(Dbent));
		memset(dp, 0, sizeof(Dbent));

		dp->fname = ln;
		p = strchr(ln, ' ');
		if (p == nil)
			goto bad;
		*p++ = 0;

		dp->hist = p;
		p = strchr(p, ' ');
		if (p == nil)
			goto bad;
		*p++ = 0;

		dp->uid = p;
		p = strchr(p, ' ');
		if (p == nil)
			goto bad;
		*p++ = 0;

		dp->gid = p;
		p = strchr(p, ' ');
		if (p == nil)
			goto bad;
		*p++ = 0;

		dp->mode  = strtoul(p, &e, 16);
		p = e++;

		dp->mtime = strtoul(p, &e, 16);
		p = e++;

		dp->length = strtoll(p,&e, 10);
		p = e;
		if (p && *p == ' ')
			dp->vers = strtoul(p+1, nil, 10);
		else
			dp->vers = ~0;
		dp->fname= estrdup(dp->fname);
		dp->hist = estrdup(dp->hist);
		dp->hlen = strlen(dp->hist);
		dp->uid  = estrdup(dp->uid);
		dp->gid  = estrdup(dp->gid);
		free(ln);
		return dp;
	bad:
		warn("malformed db entry for %s", dp->fname);
		free(ln);
		free(dp);
	}
	return nil;
}

void
insertdb(Db* db, Dbent* dp)
{
	Dbent*	old;

	insertavl(db->tree, (Avl*)dp, (Avl**)&old);
	if (old)
		free(old);
}

Db*
readdb(Biobufhdr* bp)
{
	Db*	db;
	Dbent*	dp;
	char*	ln;

	ln = Brdstr(bp, '\n', 1);
	if (ln == nil)
		return nil;
	db = emalloc(sizeof(Db));
	memset(db, 0, sizeof(Db));
	db->id = ln[0];
	if (strstr(ln, "replica")) // old format
		db->mtime=0UL;
	else
		db->mtime = strtoul(ln+2, nil, 16);
	free(ln);
	db->tree = mkavltree(dbcmp);
	while(dp = readdbent(bp))
		insertdb(db, dp);
	return db;
}

Db*
newdb(char id)
{
	Db*	db;

	db = emalloc(sizeof(Db));
	memset(db, 0, sizeof(Db));
	db->id = id;
	db->tree = mkavltree(dbcmp);
	db->mtime = time(nil);
	return db;
}

Db*
readdbfile(char* file)
{
	Db*	db;
	Biobuf* bin;
	Dir*	d;

	d = dirstat(file);
	if (d != nil){
		if (d->qid.type&QTDIR)
			error("dbfile is a directory.");
		free(d);
	}
	bin = Bopen(file, OREAD);
	if (bin == nil)
		error("can't open %s: %r", file);
	db = readdb(bin);

	/* We'll keep the db locked until the caller process
	 * 
	 * Bterm(bin);
	 */
	return db;
}


void
writedb(Biobufhdr* bp, Db* db)
{
	Avlwalk*w;
	Dbent*	dp;

	Bprint(bp, "%c %08ulx repl db:\n", db->id, db->mtime);
	w = avlwalk(db->tree);
	while(dp = (Dbent*)avlnext(w)){
		if (Bprint(bp, "%s %s %s %s %08ulx %08ulx %lld %uld\n",
			dp->fname, dp->hist,
			dp->uid, dp->gid, dp->mode, dp->mtime, dp->length,
			dp->vers) < 0)
			sysfatal("writedb");
	}
	endwalk(w);
}


void
writedbfile(char* file, Db* db)
{
	Biobuf* bout;
	Dir*	dp;
	Dir	d;

	bout = Bopen(file,OWRITE|OTRUNC);
	if (bout == nil)
		error("can't open %s: %r", file);
	writedb(bout, db);
	if (Bterm(bout) < 0)
		error("closing %s: %r", file);

	dp = dirstat(file);
	if (dp != nil){
		if (!(dp->mode&DMEXCL)){
			nulldir(&d);
			d.mode = dp->mode|DMEXCL;
			dirwstat(file, &d);
		}
		free(dp);
	}
}


void
rename(char* to, char* frompath)
{
	Dir	d;
	char*	p;

	remove(to);
	p = strrchr(to, '/');
	if (p != nil)
		to = p + 1;
	nulldir(&d);
	d.name = to;
	if (dirwstat(frompath, &d) < 0)
		error("can't rename %s: %r", frompath);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].