xref: /plan9/sys/src/cmd/tapefs/tarfs.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3*219b2ee8SDavid du Colombier #include <auth.h>
4bd389b36SDavid du Colombier #include <fcall.h>
5bd389b36SDavid du Colombier #include "tapefs.h"
6bd389b36SDavid du Colombier 
7bd389b36SDavid du Colombier /*
8bd389b36SDavid du Colombier  * File system for tar tapes (read-only)
9bd389b36SDavid du Colombier  */
10bd389b36SDavid du Colombier 
11bd389b36SDavid du Colombier #define TBLOCK	512
12bd389b36SDavid du Colombier #define NBLOCK	40	/* maximum blocksize */
13bd389b36SDavid du Colombier #define DBLOCK	20	/* default blocksize */
14bd389b36SDavid du Colombier #define TNAMSIZ	100
15bd389b36SDavid du Colombier 
16bd389b36SDavid du Colombier union hblock {
17bd389b36SDavid du Colombier 	char dummy[TBLOCK];
18bd389b36SDavid du Colombier 	char tbuf[MAXFDATA];
19bd389b36SDavid du Colombier 	struct header {
20bd389b36SDavid du Colombier 		char name[TNAMSIZ];
21bd389b36SDavid du Colombier 		char mode[8];
22bd389b36SDavid du Colombier 		char uid[8];
23bd389b36SDavid du Colombier 		char gid[8];
24bd389b36SDavid du Colombier 		char size[12];
25bd389b36SDavid du Colombier 		char mtime[12];
26bd389b36SDavid du Colombier 		char chksum[8];
27bd389b36SDavid du Colombier 		char linkflag;
28bd389b36SDavid du Colombier 		char linkname[TNAMSIZ];
29bd389b36SDavid du Colombier 	} dbuf;
30bd389b36SDavid du Colombier } dblock;
31bd389b36SDavid du Colombier 
32bd389b36SDavid du Colombier int	tapefile;
33bd389b36SDavid du Colombier int	checksum(void);
34bd389b36SDavid du Colombier 
35bd389b36SDavid du Colombier void
36bd389b36SDavid du Colombier populate(char *name)
37bd389b36SDavid du Colombier {
38bd389b36SDavid du Colombier 	long blkno, isabs, chksum, linkflg;
39bd389b36SDavid du Colombier 	Fileinf f;
40bd389b36SDavid du Colombier 
41bd389b36SDavid du Colombier 	tapefile = open(name, OREAD);
42bd389b36SDavid du Colombier 	if (tapefile<0)
43bd389b36SDavid du Colombier 		error("Can't open argument file");
44bd389b36SDavid du Colombier 	replete = 1;
45bd389b36SDavid du Colombier 	for (blkno = 0;;) {
46bd389b36SDavid du Colombier 		seek(tapefile, TBLOCK*blkno, 0);
47bd389b36SDavid du Colombier 		if (read(tapefile, (char *)&dblock.dbuf, sizeof(dblock.dbuf))<sizeof(dblock.dbuf))
48bd389b36SDavid du Colombier 			break;
49bd389b36SDavid du Colombier 		if (dblock.dbuf.name[0]=='\0')
50bd389b36SDavid du Colombier 			break;
51bd389b36SDavid du Colombier 		f.addr = (void*)(blkno+1);
52bd389b36SDavid du Colombier 		f.mode = strtoul(dblock.dbuf.mode, 0, 8);
53bd389b36SDavid du Colombier 		f.uid = strtoul(dblock.dbuf.uid, 0, 8);
54bd389b36SDavid du Colombier 		f.gid = strtoul(dblock.dbuf.gid, 0, 8);
55bd389b36SDavid du Colombier 		f.size = strtoul(dblock.dbuf.size, 0, 8);
56bd389b36SDavid du Colombier 		f.mdate = strtoul(dblock.dbuf.mtime, 0, 8);
57bd389b36SDavid du Colombier 		chksum = strtoul(dblock.dbuf.chksum, 0, 8);
58bd389b36SDavid du Colombier 		linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1';
59bd389b36SDavid du Colombier 		isabs = dblock.dbuf.name[0]=='/';
60bd389b36SDavid du Colombier 		if (chksum != checksum()){
61bd389b36SDavid du Colombier 			fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name);
62bd389b36SDavid du Colombier 			abort();
63bd389b36SDavid du Colombier 		}
64bd389b36SDavid du Colombier 		if (linkflg) {
65bd389b36SDavid du Colombier 			/*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
66bd389b36SDavid du Colombier 			   dblock.dbuf.linkname);*/
67bd389b36SDavid du Colombier 			f.size = 0;
68bd389b36SDavid du Colombier 			blkno += 1;
69bd389b36SDavid du Colombier 			continue;
70bd389b36SDavid du Colombier 		}
71bd389b36SDavid du Colombier 		f.name = dblock.dbuf.name+isabs;
72*219b2ee8SDavid du Colombier 		if (f.name[0]=='\0')
73*219b2ee8SDavid du Colombier 			fprint(1, "null name skipped\n");
74*219b2ee8SDavid du Colombier 		else
75bd389b36SDavid du Colombier 			poppath(f, 1);
76bd389b36SDavid du Colombier 		blkno += 1 + (f.size+TBLOCK-1)/TBLOCK;
77bd389b36SDavid du Colombier 	}
78bd389b36SDavid du Colombier }
79bd389b36SDavid du Colombier 
80bd389b36SDavid du Colombier void
81bd389b36SDavid du Colombier dotrunc(Ram *r)
82bd389b36SDavid du Colombier {
83bd389b36SDavid du Colombier 	USED(r);
84bd389b36SDavid du Colombier }
85bd389b36SDavid du Colombier 
86bd389b36SDavid du Colombier void
87bd389b36SDavid du Colombier docreate(Ram *r)
88bd389b36SDavid du Colombier {
89bd389b36SDavid du Colombier 	USED(r);
90bd389b36SDavid du Colombier }
91bd389b36SDavid du Colombier 
92bd389b36SDavid du Colombier char *
93bd389b36SDavid du Colombier doread(Ram *r, long off, long cnt)
94bd389b36SDavid du Colombier {
95bd389b36SDavid du Colombier 
96bd389b36SDavid du Colombier 	seek(tapefile, (TBLOCK * (long)r->data)+off, 0);
97bd389b36SDavid du Colombier 	if (cnt>sizeof(dblock.tbuf))
98bd389b36SDavid du Colombier 		error("read too big");
99bd389b36SDavid du Colombier 	read(tapefile, dblock.tbuf, cnt);
100bd389b36SDavid du Colombier 	return dblock.tbuf;
101bd389b36SDavid du Colombier }
102bd389b36SDavid du Colombier 
103bd389b36SDavid du Colombier void
104bd389b36SDavid du Colombier popdir(Ram *r)
105bd389b36SDavid du Colombier {
106bd389b36SDavid du Colombier 	USED(r);
107bd389b36SDavid du Colombier }
108bd389b36SDavid du Colombier 
109bd389b36SDavid du Colombier void
110bd389b36SDavid du Colombier dowrite(Ram *r, char *buf, long off, long cnt)
111bd389b36SDavid du Colombier {
112bd389b36SDavid du Colombier 	USED(r); USED(buf); USED(off); USED(cnt);
113bd389b36SDavid du Colombier }
114bd389b36SDavid du Colombier 
115bd389b36SDavid du Colombier int
116bd389b36SDavid du Colombier dopermw(Ram *r)
117bd389b36SDavid du Colombier {
118bd389b36SDavid du Colombier 	USED(r);
119bd389b36SDavid du Colombier 	return 0;
120bd389b36SDavid du Colombier }
121bd389b36SDavid du Colombier 
122bd389b36SDavid du Colombier int
123bd389b36SDavid du Colombier checksum()
124bd389b36SDavid du Colombier {
125bd389b36SDavid du Colombier 	register i;
126bd389b36SDavid du Colombier 	register char *cp;
127bd389b36SDavid du Colombier 
128bd389b36SDavid du Colombier 	for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
129bd389b36SDavid du Colombier 		*cp = ' ';
130bd389b36SDavid du Colombier 	i = 0;
131bd389b36SDavid du Colombier 	for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
132bd389b36SDavid du Colombier 		i += *cp;
133bd389b36SDavid du Colombier 	return(i);
134bd389b36SDavid du Colombier }
135