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