xref: /inferno-os/liblogfs/conv.c (revision 68c71d4caea0ad74b14fc837a1b3b595fcfdc1d7)
1 #include "logfsos.h"
2 #include "logfs.h"
3 #include "local.h"
4 #include "fcall.h"
5 
6 static void
7 pn(uchar **pp, char *v)
8 {
9 	uchar *p = *pp;
10 	int l;
11 	l = v ? strlen(v) : 0;
12 	PBIT16(p, l); p += BIT16SZ;
13 	memmove(p, v, l);
14 	p += l;
15 	*pp = p;
16 }
17 
18 static uint
19 sn(char *p)
20 {
21 	if(p == nil)
22 		return BIT16SZ;
23 	return strlen(p) + BIT16SZ;
24 }
25 
26 uint
27 logfsconvM2S(uchar *ap, uint nap, LogMessage *f)
28 {
29 	uchar *p = ap;
30 	uchar *ep = p + nap;
31 	uchar *mep;
32 	uint size;
33 //print("conv(%d)\n", nap);
34 	if(p + 1 > ep)
35 		return 0;
36 	f->type = *p++;
37 //print("type %c\n", f->type);
38 	switch(f->type) {
39 	case LogfsLogTstart:
40 	case LogfsLogTcreate:
41 	case LogfsLogTtrunc:
42 	case LogfsLogTremove:
43 	case LogfsLogTwrite:
44 	case LogfsLogTwstat:
45 		break;
46 	case LogfsLogTend:
47 		return 1;
48 	default:
49 		return 0;
50 	}
51 	if(p + BIT16SZ > ep)
52 		return 0;
53 	size = GBIT16(p); p += BIT16SZ;
54 //print("size %ud\n", size);
55 	if(p + size > ep)
56 		return 0;
57 	mep = p + size;
58 	if(p + BIT32SZ > mep)
59 		return 0;
60 	f->path = GBIT32(p); p += BIT32SZ;
61 	switch(f->type) {
62 	case LogfsLogTstart:
63 		/* 's' size[2] path[4] nerase[4] */
64 		if(p + BIT32SZ > ep)
65 			return 0;
66 		f->u.start.nerase = GBIT32(p); p += BIT32SZ;
67 		break;
68 	case LogfsLogTcreate:
69 		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */
70 		if(p + 4 * BIT32SZ > mep)
71 			return 0;
72 		f->u.create.perm = GBIT32(p); p+= BIT32SZ;
73 		f->u.create.newpath = GBIT32(p); p+= BIT32SZ;
74 		f->u.create.mtime = GBIT32(p); p+= BIT32SZ;
75 		f->u.create.cvers = GBIT32(p); p+= BIT32SZ;
76 		if(!logfsgn(&p, mep, &f->u.create.name)
77 			|| !logfsgn(&p, mep, &f->u.create.uid)
78 			|| !logfsgn(&p, mep, &f->u.create.gid))
79 			return 0;
80 		break;
81 	case LogfsLogTremove:
82 		/* 'r' size[2] path[4] mtime[4] muid[s] */
83 		if(p + BIT32SZ > mep)
84 			return 0;
85 		f->u.remove.mtime = GBIT32(p); p += BIT32SZ;
86 		if(!logfsgn(&p, mep, &f->u.remove.muid))
87 			return 0;
88 		break;
89 	case LogfsLogTtrunc:
90 		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */
91 		if(p + 2 * BIT32SZ > mep)
92 			return 0;
93 		f->u.trunc.mtime = GBIT32(p); p += BIT32SZ;
94 		f->u.trunc.cvers = GBIT32(p); p += BIT32SZ;
95 		if(!logfsgn(&p, mep, &f->u.trunc.muid))
96 			return 0;
97 		break;
98 	case LogfsLogTwrite:
99 		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */
100 		if(p + BIT32SZ + BIT16SZ + 2 * BIT32SZ > mep)
101 			return 0;
102 		f->u.write.offset = GBIT32(p); p += BIT32SZ;
103 		f->u.write.count = GBIT16(p); p += BIT16SZ;
104 		f->u.write.mtime = GBIT32(p); p += BIT32SZ;
105 		f->u.write.cvers = GBIT32(p); p += BIT32SZ;
106 		if(!logfsgn(&p, mep, &f->u.write.muid))
107 			return 0;
108 		if(p + BIT32SZ > mep)
109 			return 0;
110 		f->u.write.flashaddr = GBIT32(p); p += BIT32SZ;
111 		if(f->u.write.flashaddr & LogAddr) {
112 			if(p + f->u.write.count > mep)
113 				return 0;
114 			f->u.write.data = p;
115 			p += f->u.write.count;
116 		}
117 		else
118 			f->u.write.data = nil;
119 		break;
120 	case LogfsLogTwstat:
121 		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] or */
122 		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */
123 		if(!logfsgn(&p, mep, &f->u.wstat.name))
124 			return 0;
125 		if(p + BIT32SZ > mep)
126 			return 0;
127 		f->u.wstat.perm = GBIT32(p); p += BIT32SZ;
128 		if(!logfsgn(&p, mep, &f->u.wstat.uid))
129 			return 0;
130 		if(!logfsgn(&p, mep, &f->u.wstat.gid))
131 			return 0;
132 		if(p + BIT32SZ > mep)
133 			return 0;
134 		f->u.wstat.mtime = GBIT32(p); p += BIT32SZ;
135 		if(!logfsgn(&p, mep, &f->u.wstat.muid))
136 			return 0;
137 		break;
138 	default:
139 		return 0;
140 	}
141 	if(p != mep)
142 		return 0;
143 	return p - ap;
144 }
145 
146 uint
147 logfssizeS2M(LogMessage *m)
148 {
149 	switch(m->type) {
150 	case LogfsLogTend:
151 		return 1;
152 	case LogfsLogTstart:
153 		return 11;
154 	case LogfsLogTcreate:
155 		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */
156 		return 1 + BIT16SZ + 5 * BIT32SZ
157 			+ sn(m->u.create.name) + sn(m->u.create.uid) + sn(m->u.create.gid);
158 	case LogfsLogTremove:
159 		/* 'r' size[2] path[4] mtime[4] muid[s] */
160 		return 1 + BIT16SZ + 2 * BIT32SZ + sn(m->u.remove.muid);
161 	case LogfsLogTtrunc:
162 		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */
163 		return 1 + BIT16SZ + 3 * BIT32SZ + sn(m->u.trunc.muid);
164 	case LogfsLogTwrite:
165 		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */
166 		return 1 + BIT16SZ + 2 * BIT32SZ + BIT16SZ + 2 * BIT32SZ + sn(m->u.write.muid)
167 			+ BIT32SZ + (m->u.write.data ? m->u.write.count : 0);
168 	case LogfsLogTwstat:
169 		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] */
170 		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */
171 		return 1 + BIT16SZ + BIT32SZ + sn(m->u.wstat.name) + BIT32SZ
172 			+ sn(m->u.wstat.uid)
173 			+ sn(m->u.wstat.gid) + BIT32SZ + sn(m->u.wstat.muid);
174 	default:
175 		return 0;
176 	}
177 }
178 
179 uint
180 logfsconvS2M(LogMessage *s, uchar *ap, uint nap)
181 {
182 	uint size;
183 	uchar *p;
184 	size = logfssizeS2M(s);
185 	if(size == 0 || size > nap)
186 		return 0;
187 	p = ap;
188 	*p++ = s->type;
189 	if(s->type == LogfsLogTend)
190 		return 1;
191 	size -= 1 + BIT16SZ;
192 	PBIT16(p, size); p += BIT16SZ;
193 	PBIT32(p, s->path); p += BIT32SZ;
194 	switch(s->type) {
195 	case LogfsLogTstart:
196 		PBIT32(p, s->u.start.nerase); p += BIT32SZ;
197 		break;
198 	case LogfsLogTcreate:
199 		/* 'c' size[2] path[4] perm[4] newpath[4] mtime[4] cvers[4] name[s] uid[s] gid[s] */
200 		PBIT32(p, s->u.create.perm); p += BIT32SZ;
201 		PBIT32(p, s->u.create.newpath); p += BIT32SZ;
202 		PBIT32(p, s->u.create.mtime); p += BIT32SZ;
203 		PBIT32(p, s->u.create.cvers); p += BIT32SZ;
204 		pn(&p, s->u.create.name);
205 		pn(&p, s->u.create.uid);
206 		pn(&p, s->u.create.gid);
207 		break;
208 	case LogfsLogTremove:
209 		/* 'r' size[2] path[4] mtime[4] muid[s] */
210 		PBIT32(p, s->u.remove.mtime); p += BIT32SZ;
211 		pn(&p, s->u.remove.muid);
212 		break;
213 	case LogfsLogTtrunc:
214 		/* 't' size[2] path[4] mtime[4] cvers[4] muid[s] */
215 		PBIT32(p, s->u.trunc.mtime); p += BIT32SZ;
216 		PBIT32(p, s->u.trunc.cvers); p += BIT32SZ;
217 		pn(&p, s->u.trunc.muid);
218 		break;
219 	case LogfsLogTwrite:
220 		/* 'w' size[2] path[4] offset[4] count[2] mtime[4] cvers[4] muid[s] flashaddr[4] [data[n]] */
221 		PBIT32(p, s->u.write.offset); p += BIT32SZ;
222 		PBIT16(p, s->u.write.count); p += BIT16SZ;
223 		PBIT32(p, s->u.write.mtime); p += BIT32SZ;
224 		PBIT32(p, s->u.write.cvers); p += BIT32SZ;
225 		pn(&p, s->u.write.muid);
226 		PBIT32(p, s->u.write.flashaddr); p += BIT32SZ;
227 		if(s->u.write.data) {
228 			memmove(p, s->u.write.data, s->u.write.count);
229 			p += s->u.write.count;
230 		}
231 		break;
232 	case LogfsLogTwstat:
233 		/* 'W' size[2] path[4] name[s] perm[4] uid[s] gid[s] mtime[4] muid[s] */
234 		/* 'W' size[2] path[4] name[s] perm[4] gid[s] mtime[4] muid[s] */
235 		pn(&p, s->u.wstat.name);
236 		PBIT32(p, s->u.wstat.perm); p += BIT32SZ;
237 		pn(&p, s->u.wstat.uid);
238 		pn(&p, s->u.wstat.gid);
239 		PBIT32(p, s->u.wstat.mtime); p+= BIT32SZ;
240 		pn(&p, s->u.wstat.muid);
241 		break;
242 	default:
243 		return 0;
244 	}
245 	return p - ap;
246 }
247 
248 void
249 logfsdumpS(LogMessage *m)
250 {
251 	switch(m->type) {
252 	case LogfsLogTend:
253 		print("LogfsLogTend()");
254 		break;
255 	case LogfsLogTstart:
256 		print("LogfsLogTstart(path=%ud, nerase=%ud)", m->path, m->u.start.nerase);
257 		break;
258 	case LogfsLogTcreate:
259 		print("LogfsLogTcreate(path=%ud, perm=0%uo, newpath=%ud, mtime=%ud, cvers=%ud, name=%s, uid=%s, gid=%s)",
260 			m->path, m->u.create.perm, m->u.create.newpath, m->u.create.mtime, m->u.create.cvers,
261 			m->u.create.name, m->u.create.uid, m->u.create.gid);
262 		break;
263 	case LogfsLogTremove:
264 		print("LogfsLogTremove(path=%ud, mtime=%ud, muid=%s)",
265 			m->path, m->u.remove.mtime, m->u.remove.muid);
266 		break;
267 	case LogfsLogTtrunc:
268 		print("LogfsLogTtrunc(path=%ud, mtime=%ud, cvers=%ud, muid=%s)",
269 			m->path, m->u.trunc.mtime, m->u.trunc.cvers, m->u.trunc.muid);
270 		break;
271 	case LogfsLogTwrite:
272 		print("LogfsLogTwrite(path=%ud, offset=%ud, count=%ud, mtime=%ud, cvers=%ud, muid=%s, flashaddr=0x%.8ux)",
273 			m->path, m->u.write.offset, m->u.write.count, m->u.write.mtime, m->u.write.cvers, m->u.write.muid,
274 			m->u.write.flashaddr);
275 		break;
276 	case LogfsLogTwstat:
277 		print("LogfsLogTwstat(path=%ud, name=%s, perm=0%uo, uid=%s, gid=%s, mtime=%ud, muid=%s)",
278 			m->path, m->u.wstat.name, m->u.wstat.perm, m->u.wstat.uid, m->u.wstat.gid,
279 			m->u.wstat.mtime, m->u.wstat.muid);
280 		break;
281 	default:
282 		print("LogfsLogTother(%c)", m->type);
283 		break;
284 	}
285 }
286