summaryrefslogtreecommitdiff
path: root/liblogfs/conv.c
diff options
context:
space:
mode:
Diffstat (limited to 'liblogfs/conv.c')
-rw-r--r--liblogfs/conv.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/liblogfs/conv.c b/liblogfs/conv.c
new file mode 100644
index 00000000..fbc48130
--- /dev/null
+++ b/liblogfs/conv.c
@@ -0,0 +1,285 @@
+#include "lib9.h"
+#include "logfs.h"
+#include "local.h"
+#include "fcall.h"
+
+static void
+pn(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 uint
+sn(char *p)
+{
+ if(p == nil)
+ return BIT16SZ;
+ return strlen(p) + BIT16SZ;
+}
+
+uint
+logfsconvM2S(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;
+}
+
+uint
+logfssizeS2M(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;
+ }
+}
+
+uint
+logfsconvS2M(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;
+}
+
+void
+logfsdumpS(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;
+ }
+}