aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/tapefs/cpiofs.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-02-24 21:17:00 +0000
committerrsc <devnull@localhost>2006-02-24 21:17:00 +0000
commit64f7506b34106955fbbd5f6bf944ecd839610672 (patch)
treefa1efe1df3804519ef796042c457a34a2d9e187f /src/cmd/tapefs/cpiofs.c
parent21b291a64e4f059744b4094a8f8e52784ad323f4 (diff)
downloadplan9port-64f7506b34106955fbbd5f6bf944ecd839610672.tar.gz
plan9port-64f7506b34106955fbbd5f6bf944ecd839610672.tar.bz2
plan9port-64f7506b34106955fbbd5f6bf944ecd839610672.zip
tapefs from plan9
Diffstat (limited to 'src/cmd/tapefs/cpiofs.c')
-rw-r--r--src/cmd/tapefs/cpiofs.c139
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;
+}