xref: /plan9-contrib/sys/src/cmd/tapefs/cpiofs.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 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[MAXFDATA];
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 int	getoct(char*, int);
40 
41 void
42 populate(char *name)
43 {
44 	long offset, isabs, magic, linkflg, namesize, mode;
45 	Fileinf f;
46 
47 	tapefile = open(name, OREAD);
48 	if (tapefile<0)
49 		error("Can't open argument file");
50 	replete = 1;
51 	for (offset = 0;;) {
52 		seek(tapefile, offset, 0);
53 		if (read(tapefile, (char *)&dblock.dbuf, TBLOCK)<TBLOCK)
54 			break;
55 		magic = getoct(dblock.dbuf.magic, sizeof(dblock.dbuf.magic));
56 		if (magic != 070707){
57 			print("%o\n", magic);
58 			error("out of phase--get help");
59 		}
60 		if (dblock.nbuf.name[0]=='\0' || strcmp(dblock.nbuf.name, "TRAILER!!!")==0)
61 			break;
62 		mode = getoct(dblock.dbuf.mode, sizeof(dblock.dbuf.mode));
63 		f.mode = mode&0777;
64 		switch(mode & 0170000) {
65 		case 0040000:
66 			f.mode |= CHDIR;
67 			break;
68 		case 0100000:
69 			break;
70 		default:
71 			f.mode = 0;
72 			break;
73 		}
74 		f.uid = getoct(dblock.dbuf.uid, sizeof(dblock.dbuf.uid));
75 		f.gid = getoct(dblock.dbuf.gid, sizeof(dblock.dbuf.gid));
76 		f.size = getoct(dblock.dbuf.size, sizeof(dblock.dbuf.size));
77 		f.mdate = getoct(dblock.dbuf.mtime, sizeof(dblock.dbuf.mtime));
78 		linkflg = 0;
79 		namesize = getoct(dblock.dbuf.namesize, sizeof(dblock.dbuf.namesize));
80 		f.addr = (void*)(offset+sizeof(struct header)+namesize);
81 		isabs = dblock.nbuf.name[0]=='/';
82 	/*	if (linkflg) {
83 			fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
84 			   dblock.dbuf.linkname);
85 			f.size = 0;
86 			blkno += 1;
87 			continue;
88 		}*/
89 		f.name = &dblock.nbuf.name[isabs];
90 		poppath(f, 1);
91 		offset += sizeof(struct header)+namesize+f.size;
92 	}
93 }
94 
95 int
96 getoct(char *p, int l)
97 {
98 	int r;
99 
100 	for (r=0; l>0; p++, l--){
101 		r <<= 3;
102 		r += *p-'0';
103 	}
104 	return r;
105 }
106 
107 void
108 dotrunc(Ram *r)
109 {
110 	USED(r);
111 }
112 
113 void
114 docreate(Ram *r)
115 {
116 	USED(r);
117 }
118 
119 char *
120 doread(Ram *r, long off, long cnt)
121 {
122 
123 	seek(tapefile, (long)r->data+off, 0);
124 	if (cnt>sizeof(dblock.tbuf))
125 		error("read too big");
126 	read(tapefile, dblock.tbuf, cnt);
127 	return dblock.tbuf;
128 }
129 
130 void
131 popdir(Ram *r)
132 {
133 	USED(r);
134 }
135 
136 void
137 dowrite(Ram *r, char *buf, long off, long cnt)
138 {
139 	USED(r); USED(buf); USED(off); USED(cnt);
140 }
141 
142 int
143 dopermw(Ram *r)
144 {
145 	USED(r);
146 	return 0;
147 }
148