7 * File system for cpio tapes (read-only)
14 typedef void HdrReader(Fileinf *);
19 addrfatal(char *fmt, va_list arg)
23 vseprint(buf, buf+sizeof(buf), fmt, arg);
24 fprint(2, "%s: %#llx: %s\n", argv0, Bseek(tape, 0, 1), buf);
33 if((c = Bgetc(tape)) == Beof)
34 sysfatal("unexpected eof");
36 sysfatal("read error: %r");
45 return x = egetc(), x |= egetc()<<8;
53 return x = egetc()<<16, x |= egetc()<<24, x |= egetc(), x |= egetc()<<8;
56 /* sysvr3 and sysvr4 skip records with names longer than 256. pwb 1.0,
57 32V, sysiii, sysvr1, and sysvr2 overrun their 256 byte buffer */
59 rdpwb(Fileinf *f, ushort (*rd16)(void), ulong (*rd32)(void))
75 /* namesz include the trailing nul */
77 sysfatal("name too small");
78 if(namesz > sizeof(buf))
79 sysfatal("name too big");
81 if((n = Bread(tape, buf, namesz)) < 0)
82 sysfatal("read error: %r");
84 sysfatal("unexpected eof");
87 sysfatal("no nul after file name");
88 if((n = strlen(buf)) != namesz-1)
89 sysfatal("mismatched name length: saw %d; expected %d", n, namesz-1);
93 if(Bseek(tape, 0, 1) & 1)
100 rdpwb(f, rd16le, rd3211);
109 for(x = 0; n > 0; n--) {
110 if((y = egetc() - '0') & ~7)
111 sysfatal("not octal");
117 /* sysvr3 and sysvr4 skip records with names longer than 256. sysiii,
118 sysvr1, and sysvr2 overrun their 256 byte buffer */
123 static char buf[256];
130 rdasc(6); /* nlink */
132 f->mdate = rdasc(11);
136 /* namesz includes the trailing nul */
138 sysfatal("name too small");
139 if(namesz > sizeof (buf))
140 sysfatal("name too big");
142 if((n = Bread(tape, buf, namesz)) < 0)
143 sysfatal("read error: %r");
145 sysfatal("unexpected eof");
148 sysfatal("no nul after file name");
149 if((n = strlen(buf)) != namesz-1)
150 sysfatal("mismatched name length: saw %d; expected %d", n, namesz-1);
161 if(buf[0] == 0xc7 && buf[1] == 0x71)
168 if(memcmp(buf, "070707", 6) == 0)
171 sysfatal("Out of phase--get MERT help");
178 HdrReader *rdhdr, *prevhdr;
181 /* the tape buffer may not be the ideal size for scanning the
183 if((tape = Bopen(name, OREAD)) == nil)
184 sysfatal("Can't open argument file");
186 extern void (*_sysfatal)(char *, va_list);
187 _sysfatal = addrfatal;
192 /* sysiii and sysv implementations don't allow
193 multiple header types within a single tape, so we
196 if(prevhdr != nil && rdhdr != prevhdr)
197 sysfatal("mixed headers");
200 while(f.name[0] == '/')
202 if(f.name[0] == '\0')
203 sysfatal("nameless record");
204 if(strcmp(f.name, "TRAILER!!!") == 0)
206 switch(f.mode & 0170000) {
208 f.mode = DMDIR | f.mode&0777;
210 case 0100000: /* normal file */
211 case 0120000: /* symlink */
214 default: /* sockets, pipes, devices */
218 f.addr = Bseek(tape, 0, 1);
221 Bseek(tape, f.size, 1);
224 if(rdhdr == rdpwb11 && (Bseek(tape, 0, 1) & 1))
242 doread(Ram *r, vlong off, long cnt)
244 Bseek(tape, r->addr+off, 0);
245 if (cnt>sizeof(dblock.tbuf))
246 sysfatal("read too big");
247 Bread(tape, dblock.tbuf, cnt);
258 dowrite(Ram *r, char *buf, long off, long cnt)
260 USED(r); USED(buf); USED(off); USED(cnt);