1 #include "lib9.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