| #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; |
| } |