xref: /plan9/sys/src/cmd/tapefs/tpfs.c (revision ff8c3af2f44d95267f67219afa20ba82ff6cf7e4)
1 #include <u.h>
2 #include <libc.h>
3 #include "tapefs.h"
4 
5 /*
6  * File system for tp tapes.  dectape versions have 192
7  * entries, magtape have 496.  This treats the same
8  * by ignoring entries with bad header checksums
9  */
10 
11 struct tp {
12 	unsigned char	name[32];
13 	unsigned char	mode[2];
14 	unsigned char	uid[1];
15 	unsigned char	gid[1];
16 	unsigned char	unused[1];
17 	unsigned char	size[3];
18 	unsigned char	tmod[4];
19 	unsigned char	taddress[2];
20 	unsigned char	unused[16];
21 	unsigned char	checksum[2];
22 } dir[496+8];
23 
24 char	buffer[8192];
25 int	tapefile;
26 
27 void
28 populate(char *name)
29 {
30 	int i, isabs, badcksum, goodcksum;
31 	struct tp *tpp;
32 	Fileinf f;
33 
34 	replete = 1;
35 	tapefile = open(name, OREAD);
36 	if (tapefile<0)
37 		error("Can't open argument file");
38 	read(tapefile, dir, sizeof dir);
39 	badcksum = goodcksum = 0;
40 	for (i=0, tpp=&dir[8]; i<496; i++, tpp++) {
41 		unsigned char *sp = (unsigned char *)tpp;
42 		int j, cksum = 0;
43 		for (j=0; j<32; j++, sp+=2)
44 			cksum += sp[0] + (sp[1]<<8);
45 		cksum &= 0xFFFF;
46 		if (cksum!=0) {
47 			badcksum++;
48 			continue;
49 		}
50 		goodcksum++;
51 		if (tpp->name[0]=='\0')
52 			continue;
53 		f.addr = (void *)(tpp->taddress[0] + (tpp->taddress[1]<<8));
54 		if (f.addr==0)
55 			continue;
56 		f.size = (tpp->size[0]<<16) + (tpp->size[1]<<0) + (tpp->size[2]<<8);
57 		f.mdate = (tpp->tmod[2]<<0) + (tpp->tmod[3]<<8)
58 		     +(tpp->tmod[0]<<16) + (tpp->tmod[1]<<24);
59 		f.mode = tpp->mode[0]&0777;
60 		isabs = tpp->name[0]=='/';
61 		f.name = (char *)tpp->name+isabs;
62 		poppath(f, 1);
63 	}
64 	fprint(2, "%d bad checksums, %d good\n", badcksum, goodcksum);
65 }
66 
67 void
68 popdir(Ram *r)
69 {
70 	USED(r);
71 }
72 
73 void
74 dotrunc(Ram *r)
75 {
76 	USED(r);
77 }
78 
79 void
80 docreate(Ram *r)
81 {
82 	USED(r);
83 }
84 
85 char *
86 doread(Ram *r, long off, long cnt)
87 {
88 	if (cnt>sizeof(buffer))
89 		print("count too big\n");
90 	seek(tapefile, 512*(int)r->data+off, 0);
91 	read(tapefile, buffer, cnt);
92 	return buffer;
93 }
94 
95 void
96 dowrite(Ram *r, char *buf, long off, long cnt)
97 {
98 	USED(r); USED(buf); USED(off); USED(cnt);
99 }
100 
101 int
102 dopermw(Ram *r)
103 {
104 	USED(r);
105 	return 0;
106 }
107