xref: /inferno-os/liblogfs/conv.c (revision e57c7e16a3789cd4de1a3c2560d49b1ee39cd10a)
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