2 * archfs - mount mkfs style archives
17 typedef struct Ahdr Ahdr;
23 typedef struct Arch Arch;
36 sysfatal("malloc %lud fails", sz);
46 sysfatal("strdup (%.10s) fails", s);
55 if(p = Brdline(b, '\n'))
56 p[Blinelen(b)-1] = '\0';
66 if((p = Bgetline(b)) == nil)
69 if(strcmp(p, "end of archive") == 0) {
74 if(tokenize(p, f, nelem(f)) != 6) {
75 werrstr("bad format");
79 a = emalloc(sizeof(*a));
80 a->name = estrdup(f[0]);
81 a->mode = strtoul(f[1], 0, 8);
82 a->uid = estrdup(f[2]);
83 a->gid = estrdup(f[3]);
84 a->mtime = strtoll(f[4], 0, 10);
85 a->length = strtoll(f[5], 0, 10);
90 newarch(vlong off, vlong length)
97 abuf = emalloc(sizeof(Arch)*nabuf);
102 abuf->length = length;
107 createpath(File *f, char *name, char *u, ulong m)
113 fprint(2, "createpath %s\n", name);
115 while(f && (p = strchr(name, '/'))) {
117 if(strcmp(name, "") != 0 && strcmp(name, ".") != 0){
118 /* this would be a race if we were multithreaded */
119 incref(f); /* so walk doesn't kill it immediately on failure */
120 if((nf = walkfile(f, name)) == nil)
121 nf = createfile(f, name, u, DMDIR|0777, nil);
132 if((nf = walkfile(f, name)) == nil)
133 nf = createfile(f, name, u, m, nil);
139 archcreatefile(char *name, Arch *arch, Dir *d)
142 f = createpath(archtree->root, name, d->uid, d->mode);
144 sysfatal("creating %s: %r", name);
146 f->gid = estrdup9p(d->gid);
149 f->length = d->length;
160 a = r->fid->file->aux;
161 if(a->length <= r->ifcall.offset)
163 else if(a->length <= r->ifcall.offset+r->ifcall.count)
164 r->ifcall.count = a->length - r->ifcall.offset;
166 werrstr("unknown error");
167 if(Bseek(b, a->off+r->ifcall.offset, 0) < 0
168 || (n = Bread(b, r->ofcall.data, r->ifcall.count)) < 0) {
170 errstr(err, sizeof err);
185 fprint(2, "usage: archfs [-abcC] [-m mtpt] archfile\n");
190 main(int argc, char **argv)
216 mtpt = EARGF(usage());
226 if((b = Bopen(argv[0], OREAD)) == nil)
227 sysfatal("open '%s': %r", argv[0]);
229 archtree = fs.tree = alloctree("sys", "sys", DMDIR|0775, nil);
230 while(a = gethdr(b)) {
231 archcreatefile(a->name, newarch(Boffset(b), a->length), a);
232 Bseek(b, a->length, 1);
236 errstr(err, sizeof err);
238 sysfatal("reading archive: %s", err);
240 postmountsrv(&fs, nil, mtpt, flag);