summaryrefslogtreecommitdiff
path: root/sys/src/cmd/tapefs/tpfs.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/tapefs/tpfs.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/tapefs/tpfs.c')
-rwxr-xr-xsys/src/cmd/tapefs/tpfs.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/sys/src/cmd/tapefs/tpfs.c b/sys/src/cmd/tapefs/tpfs.c
new file mode 100755
index 000000000..02079a3ae
--- /dev/null
+++ b/sys/src/cmd/tapefs/tpfs.c
@@ -0,0 +1,108 @@
+#include <u.h>
+#include <libc.h>
+#include "tapefs.h"
+
+/*
+ * File system for tp tapes. dectape versions have 192
+ * entries, magtape have 496. This treats the same
+ * by ignoring entries with bad header checksums
+ */
+
+struct tp {
+ unsigned char name[32];
+ unsigned char mode[2];
+ unsigned char uid[1];
+ unsigned char gid[1];
+ unsigned char unused[1];
+ unsigned char size[3];
+ unsigned char tmod[4];
+ unsigned char taddress[2];
+ unsigned char unused2[16];
+ unsigned char checksum[2];
+} dir[496+8];
+
+char buffer[8192];
+int tapefile;
+
+void
+populate(char *name)
+{
+ int i, isabs, badcksum, goodcksum;
+ struct tp *tpp;
+ Fileinf f;
+
+ replete = 1;
+ tapefile = open(name, OREAD);
+ if (tapefile<0)
+ error("Can't open argument file");
+ read(tapefile, dir, sizeof dir);
+ badcksum = goodcksum = 0;
+ for (i=0, tpp=&dir[8]; i<496; i++, tpp++) {
+ unsigned char *sp = (unsigned char *)tpp;
+ int j, cksum = 0;
+ for (j=0; j<32; j++, sp+=2)
+ cksum += sp[0] + (sp[1]<<8);
+ cksum &= 0xFFFF;
+ if (cksum!=0) {
+ badcksum++;
+ continue;
+ }
+ goodcksum++;
+ if (tpp->name[0]=='\0')
+ continue;
+ f.addr = tpp->taddress[0] + (tpp->taddress[1]<<8);
+ if (f.addr==0)
+ continue;
+ f.size = (tpp->size[0]<<16) + (tpp->size[1]<<0) + (tpp->size[2]<<8);
+ f.mdate = (tpp->tmod[2]<<0) + (tpp->tmod[3]<<8)
+ +(tpp->tmod[0]<<16) + (tpp->tmod[1]<<24);
+ f.mode = tpp->mode[0]&0777;
+ f.uid = tpp->uid[0];
+ f.gid = tpp->gid[0];
+ isabs = tpp->name[0]=='/';
+ f.name = (char *)tpp->name+isabs;
+ poppath(f, 1);
+ }
+ fprint(2, "%d bad checksums, %d good\n", badcksum, goodcksum);
+}
+
+void
+popdir(Ram *r)
+{
+ USED(r);
+}
+
+void
+dotrunc(Ram *r)
+{
+ USED(r);
+}
+
+void
+docreate(Ram *r)
+{
+ USED(r);
+}
+
+char *
+doread(Ram *r, vlong off, long cnt)
+{
+ if (cnt>sizeof(buffer))
+ print("count too big\n");
+ seek(tapefile, 512*r->addr+off, 0);
+ read(tapefile, buffer, cnt);
+ return buffer;
+}
+
+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;
+}