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 cpio 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[Maxbuf];
19 	struct header {
20 		char magic[6];
21 		char dev[6];
22 		char ino[6];
23 		char mode[6];
24 		char uid[6];
25 		char gid[6];
26 		char nlink[6];
27 		char rdev[6];
28 		char mtime[11];
29 		char namesize[6];
30 		char size[11];
31 	} dbuf;
32 	struct hname {
33 		struct	header x;
34 		char	name[1];
35 	} nbuf;
36 } dblock;
37 
38 int	tapefile;
39 vlong	getoct(char*, int);
40 
41 void
populate(char * name)42 populate(char *name)
43 {
44 	vlong offset;
45 	long isabs, magic, namesize, mode;
46 	Fileinf f;
47 
48 	tapefile = open(name, OREAD);
49 	if (tapefile<0)
50 		error("Can't open argument file");
51 	replete = 1;
52 	for (offset = 0;;) {
53 		seek(tapefile, offset, 0);
54 		if (read(tapefile, (char *)&dblock.dbuf, TBLOCK)<TBLOCK)
55 			break;
56 		magic = getoct(dblock.dbuf.magic, sizeof(dblock.dbuf.magic));
57 		if (magic != 070707){
58 			print("%lo\n", magic);
59 			error("out of phase--get help");
60 		}
61 		if (dblock.nbuf.name[0]=='\0' || strcmp(dblock.nbuf.name, "TRAILER!!!")==0)
62 			break;
63 		mode = getoct(dblock.dbuf.mode, sizeof(dblock.dbuf.mode));
64 		f.mode = mode&0777;
65 		switch(mode & 0170000) {
66 		case 0040000:
67 			f.mode |= DMDIR;
68 			break;
69 		case 0100000:
70 			break;
71 		default:
72 			f.mode = 0;
73 			break;
74 		}
75 		f.uid = getoct(dblock.dbuf.uid, sizeof(dblock.dbuf.uid));
76 		f.gid = getoct(dblock.dbuf.gid, sizeof(dblock.dbuf.gid));
77 		f.size = getoct(dblock.dbuf.size, sizeof(dblock.dbuf.size));
78 		f.mdate = getoct(dblock.dbuf.mtime, sizeof(dblock.dbuf.mtime));
79 		namesize = getoct(dblock.dbuf.namesize, sizeof(dblock.dbuf.namesize));
80 		f.addr = offset+sizeof(struct header)+namesize;
81 		isabs = dblock.nbuf.name[0]=='/';
82 		f.name = &dblock.nbuf.name[isabs];
83 		poppath(f, 1);
84 		offset += sizeof(struct header)+namesize+f.size;
85 	}
86 }
87 
88 vlong
getoct(char * p,int l)89 getoct(char *p, int l)
90 {
91 	vlong r;
92 
93 	for (r=0; l>0; p++, l--){
94 		r <<= 3;
95 		r += *p-'0';
96 	}
97 	return r;
98 }
99 
100 void
dotrunc(Ram * r)101 dotrunc(Ram *r)
102 {
103 	USED(r);
104 }
105 
106 void
docreate(Ram * r)107 docreate(Ram *r)
108 {
109 	USED(r);
110 }
111 
112 char *
doread(Ram * r,vlong off,long cnt)113 doread(Ram *r, vlong off, long cnt)
114 {
115 	seek(tapefile, r->addr+off, 0);
116 	if (cnt>sizeof(dblock.tbuf))
117 		error("read too big");
118 	read(tapefile, dblock.tbuf, cnt);
119 	return dblock.tbuf;
120 }
121 
122 void
popdir(Ram * r)123 popdir(Ram *r)
124 {
125 	USED(r);
126 }
127 
128 void
dowrite(Ram * r,char * buf,long off,long cnt)129 dowrite(Ram *r, char *buf, long off, long cnt)
130 {
131 	USED(r); USED(buf); USED(off); USED(cnt);
132 }
133 
134 int
dopermw(Ram * r)135 dopermw(Ram *r)
136 {
137 	USED(r);
138 	return 0;
139 }
140