diff options
Diffstat (limited to 'src/cmd/tapefs/cpiofs.c')
-rw-r--r-- | src/cmd/tapefs/cpiofs.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/cmd/tapefs/cpiofs.c b/src/cmd/tapefs/cpiofs.c new file mode 100644 index 00000000..fc11346d --- /dev/null +++ b/src/cmd/tapefs/cpiofs.c @@ -0,0 +1,139 @@ +#include <u.h> +#include <libc.h> +#include <auth.h> +#include <fcall.h> +#include "tapefs.h" + +/* + * File system for cpio tapes (read-only) + */ + +#define TBLOCK 512 +#define NBLOCK 40 /* maximum blocksize */ +#define DBLOCK 20 /* default blocksize */ +#define TNAMSIZ 100 + +union hblock { + char dummy[TBLOCK]; + char tbuf[Maxbuf]; + struct header { + char magic[6]; + char dev[6]; + char ino[6]; + char mode[6]; + char uid[6]; + char gid[6]; + char nlink[6]; + char rdev[6]; + char mtime[11]; + char namesize[6]; + char size[11]; + } dbuf; + struct hname { + struct header x; + char name[1]; + } nbuf; +} dblock; + +int tapefile; +vlong getoct(char*, int); + +void +populate(char *name) +{ + vlong offset; + long isabs, magic, namesize, mode; + Fileinf f; + + tapefile = open(name, OREAD); + if (tapefile<0) + error("Can't open argument file"); + replete = 1; + for (offset = 0;;) { + seek(tapefile, offset, 0); + if (read(tapefile, (char *)&dblock.dbuf, TBLOCK)<TBLOCK) + break; + magic = getoct(dblock.dbuf.magic, sizeof(dblock.dbuf.magic)); + if (magic != 070707){ + print("%lo\n", magic); + error("out of phase--get help"); + } + if (dblock.nbuf.name[0]=='\0' || strcmp(dblock.nbuf.name, "TRAILER!!!")==0) + break; + mode = getoct(dblock.dbuf.mode, sizeof(dblock.dbuf.mode)); + f.mode = mode&0777; + switch(mode & 0170000) { + case 0040000: + f.mode |= DMDIR; + break; + case 0100000: + break; + default: + f.mode = 0; + break; + } + f.uid = getoct(dblock.dbuf.uid, sizeof(dblock.dbuf.uid)); + f.gid = getoct(dblock.dbuf.gid, sizeof(dblock.dbuf.gid)); + f.size = getoct(dblock.dbuf.size, sizeof(dblock.dbuf.size)); + f.mdate = getoct(dblock.dbuf.mtime, sizeof(dblock.dbuf.mtime)); + namesize = getoct(dblock.dbuf.namesize, sizeof(dblock.dbuf.namesize)); + f.addr = offset+sizeof(struct header)+namesize; + isabs = dblock.nbuf.name[0]=='/'; + f.name = &dblock.nbuf.name[isabs]; + poppath(f, 1); + offset += sizeof(struct header)+namesize+f.size; + } +} + +vlong +getoct(char *p, int l) +{ + vlong r; + + for (r=0; l>0; p++, l--){ + r <<= 3; + r += *p-'0'; + } + return r; +} + +void +dotrunc(Ram *r) +{ + USED(r); +} + +void +docreate(Ram *r) +{ + USED(r); +} + +char * +doread(Ram *r, vlong off, long cnt) +{ + seek(tapefile, r->addr+off, 0); + if (cnt>sizeof(dblock.tbuf)) + error("read too big"); + read(tapefile, dblock.tbuf, cnt); + return dblock.tbuf; +} + +void +popdir(Ram *r) +{ + USED(r); +} + +void +dowrite(Ram *r, char *buf, long off, long cnt) +{ + USED(r); USED(buf); USED(off); USED(cnt); +} + +int +dopermw(Ram *r) +{ + USED(r); + return 0; +} |