Charles.Forsyth20060303a828770d19 years agoHistory
285 lines · 7.9 KB · C
RawDownload
#include "lib9.h"#include "logfs.h"#include "local.h"#include "fcall.h" static voidpn(uchar **pp, char *v){	uchar *p = *pp;	int l;	l = v ? strlen(v) : 0;	PBIT16(p, l); p += BIT16SZ;	memmove(p, v, l);	p += l;	*pp = p;} static uintsn(char *p){	if(p == nil)		return BIT16SZ;	return strlen(p) + BIT16SZ;} uintlogfsconvM2S(uchar *ap, uint nap, LogMessage *f){	uchar *p = ap;	uchar *ep = p + nap;	uchar *mep;	uint size;//print("conv(%d)\n", nap);	if(p + 1 > ep)		return 0;	f->type = *p++;//print("type %c\n", f->type);	switch(f->type) {	case LogfsLogTstart:	case LogfsLogTcreate:	case LogfsLogTtrunc:	case LogfsLogTremove:	case LogfsLogTwrite:	case LogfsLogTwstat:		break;	case LogfsLogTend:		return 1;	default:			return 0;	}	if(p + BIT16SZ > ep)		return 0;	size = GBIT16(p); p += BIT16SZ;//print("size %ud\n", size);	if(p + size > ep)		return 0;	mep = p + size;	if(p + BIT32SZ > mep)		return 0;	f->path = GBIT32(p); p += BIT32SZ;	switch(f->type) {	case LogfsLogTstart:		/* 's' size[2] path[4] nerase[4] */		if(p + BIT32SZ > ep)			return 0;		f->u.start.nerase = GBIT32(p); p += BIT32SZ;		break;	case LogfsLogTcreate:		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */		if(p + 4 * BIT32SZ > mep)			return 0;		f->u.create.perm = GBIT32(p); p+= BIT32SZ;		f->u.create.newpath = GBIT32(p); p+= BIT32SZ;		f->u.create.mtime = GBIT32(p); p+= BIT32SZ;		f->u.create.cvers = GBIT32(p); p+= BIT32SZ;		if(!logfsgn(&p, mep, &f->u.create.name)			|| !logfsgn(&p, mep, &f->u.create.uid)			|| !logfsgn(&p, mep, &f->u.create.gid))			return 0;		break;	case LogfsLogTremove:		/* 'r' size[2] path[4] mtime[4] muid[s] */		if(p + BIT32SZ > mep)			return 0;		f->u.remove.mtime = GBIT32(p); p += BIT32SZ;		if(!logfsgn(&p, mep, &f->u.remove.muid))			return 0;		break;	case LogfsLogTtrunc:		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */		if(p + 2 * BIT32SZ > mep)			return 0;		f->u.trunc.mtime = GBIT32(p); p += BIT32SZ;		f->u.trunc.cvers = GBIT32(p); p += BIT32SZ;		if(!logfsgn(&p, mep, &f->u.trunc.muid))			return 0;		break;	case LogfsLogTwrite:		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */		if(p + BIT32SZ + BIT16SZ + 2 * BIT32SZ > mep)			return 0;		f->u.write.offset = GBIT32(p); p += BIT32SZ;		f->u.write.count = GBIT16(p); p += BIT16SZ;		f->u.write.mtime = GBIT32(p); p += BIT32SZ;		f->u.write.cvers = GBIT32(p); p += BIT32SZ;		if(!logfsgn(&p, mep, &f->u.write.muid))			return 0;		if(p + BIT32SZ > mep)			return 0;		f->u.write.flashaddr = GBIT32(p); p += BIT32SZ;		if(f->u.write.flashaddr & LogAddr) {			if(p + f->u.write.count > mep)				return 0;			f->u.write.data = p;			p += f->u.write.count;		}		else			f->u.write.data = nil;		break;	case LogfsLogTwstat:		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] or */		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */		if(!logfsgn(&p, mep, &f->u.wstat.name))			return 0;		if(p + BIT32SZ > mep)			return 0;		f->u.wstat.perm = GBIT32(p); p += BIT32SZ;		if(!logfsgn(&p, mep, &f->u.wstat.uid))			return 0;		if(!logfsgn(&p, mep, &f->u.wstat.gid))			return 0;		if(p + BIT32SZ > mep)			return 0;		f->u.wstat.mtime = GBIT32(p); p += BIT32SZ;		if(!logfsgn(&p, mep, &f->u.wstat.muid))			return 0;		break;	default:		return 0;	}	if(p != mep)		return 0;	return p - ap;} uintlogfssizeS2M(LogMessage *m){	switch(m->type) {	case LogfsLogTend:		return 1;	case LogfsLogTstart:		return 11;	case LogfsLogTcreate:		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */		return 1 + BIT16SZ + 5 * BIT32SZ			+ sn(m->u.create.name) + sn(m->u.create.uid) + sn(m->u.create.gid);	case LogfsLogTremove:		/* 'r' size[2] path[4] mtime[4] muid[s] */		return 1 + BIT16SZ + 2 * BIT32SZ + sn(m->u.remove.muid);	case LogfsLogTtrunc:		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */		return 1 + BIT16SZ + 3 * BIT32SZ + sn(m->u.trunc.muid);	case LogfsLogTwrite:		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */		return 1 + BIT16SZ + 2 * BIT32SZ + BIT16SZ + 2 * BIT32SZ + sn(m->u.write.muid)			+ BIT32SZ + (m->u.write.data ? m->u.write.count : 0);	case LogfsLogTwstat:		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] */		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */		return 1 + BIT16SZ + BIT32SZ + sn(m->u.wstat.name) + BIT32SZ			+ sn(m->u.wstat.uid)			+ sn(m->u.wstat.gid) + BIT32SZ + sn(m->u.wstat.muid);	default:		return 0;	}} uintlogfsconvS2M(LogMessage *s, uchar *ap, uint nap){	uint size;	uchar *p;	size = logfssizeS2M(s);	if(size == 0 || size > nap)		return 0;	p = ap;	*p++ = s->type;	if(s->type == LogfsLogTend)		return 1;	size -= 1 + BIT16SZ;	PBIT16(p, size); p += BIT16SZ;	PBIT32(p, s->path); p += BIT32SZ;	switch(s->type) {	case LogfsLogTstart:		PBIT32(p, s->u.start.nerase); p += BIT32SZ;		break;	case LogfsLogTcreate:		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */		PBIT32(p, s->u.create.perm); p += BIT32SZ;		PBIT32(p, s->u.create.newpath); p += BIT32SZ;		PBIT32(p, s->u.create.mtime); p += BIT32SZ;		PBIT32(p, s->u.create.cvers); p += BIT32SZ;		pn(&p, s->u.create.name);		pn(&p, s->u.create.uid);		pn(&p, s->u.create.gid);		break;	case LogfsLogTremove:		/* 'r' size[2] path[4] mtime[4] muid[s] */		PBIT32(p, s->u.remove.mtime); p += BIT32SZ;		pn(&p, s->u.remove.muid);		break;	case LogfsLogTtrunc:		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */		PBIT32(p, s->u.trunc.mtime); p += BIT32SZ;		PBIT32(p, s->u.trunc.cvers); p += BIT32SZ;		pn(&p, s->u.trunc.muid);		break;	case LogfsLogTwrite:		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */		PBIT32(p, s->u.write.offset); p += BIT32SZ;		PBIT16(p, s->u.write.count); p += BIT16SZ;		PBIT32(p, s->u.write.mtime); p += BIT32SZ;		PBIT32(p, s->u.write.cvers); p += BIT32SZ;		pn(&p, s->u.write.muid);		PBIT32(p, s->u.write.flashaddr); p += BIT32SZ;		if(s->u.write.data) {			memmove(p, s->u.write.data, s->u.write.count);			p += s->u.write.count;		}		break;	case LogfsLogTwstat:		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] */		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */		pn(&p, s->u.wstat.name);		PBIT32(p, s->u.wstat.perm); p += BIT32SZ;		pn(&p, s->u.wstat.uid);		pn(&p, s->u.wstat.gid);		PBIT32(p, s->u.wstat.mtime); p+= BIT32SZ;		pn(&p, s->u.wstat.muid);		break;	default:		return 0;	}	return p - ap;}		voidlogfsdumpS(LogMessage *m){	switch(m->type) {	case LogfsLogTend:		print("LogfsLogTend()");		break;	case LogfsLogTstart:		print("LogfsLogTstart(path=%ud, nerase=%ud)", m->path, m->u.start.nerase);		break;	case LogfsLogTcreate:		print("LogfsLogTcreate(path=%ud, perm=0%uo, newpath=%ud, mtime=%ud, cvers=%ud, name=%s, uid=%s, gid=%s)",			m->path, m->u.create.perm, m->u.create.newpath, m->u.create.mtime, m->u.create.cvers,			m->u.create.name, m->u.create.uid, m->u.create.gid);		break;	case LogfsLogTremove:		print("LogfsLogTremove(path=%ud, mtime=%ud, muid=%s)",			m->path, m->u.remove.mtime, m->u.remove.muid);		break;	case LogfsLogTtrunc:		print("LogfsLogTtrunc(path=%ud, mtime=%ud, cvers=%ud, muid=%s)",			m->path, m->u.trunc.mtime, m->u.trunc.cvers, m->u.trunc.muid);		break;	case LogfsLogTwrite:		print("LogfsLogTwrite(path=%ud, offset=%ud, count=%ud, mtime=%ud, cvers=%ud, muid=%s, flashaddr=0x%.8ux)",			m->path, m->u.write.offset, m->u.write.count, m->u.write.mtime, m->u.write.cvers, m->u.write.muid,			m->u.write.flashaddr);		break;	case LogfsLogTwstat:		print("LogfsLogTwstat(path=%ud, name=%s, perm=0%uo, uid=%s, gid=%s, mtime=%ud, muid=%s)",			m->path, m->u.wstat.name, m->u.wstat.perm, m->u.wstat.uid, m->u.wstat.gid,			m->u.wstat.mtime, m->u.wstat.muid);		break;	default:		print("LogfsLogTother(%c)", m->type);		break;	}}