blob: fc11346dbcf428004a4d34270b0b3dea88056dfd [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include "tapefs.h"
/*
* File system for cpio tapes (read-only)
*/
#define TBLOCK 512
#define NBLOCK 40 /* maximum blocksize */
#define DBLOCK 20 /* default blocksize */
#define TNAMSIZ 100
union hblock {
char dummy[TBLOCK];
char tbuf[Maxbuf];
struct header {
char magic[6];
char dev[6];
char ino[6];
char mode[6];
char uid[6];
char gid[6];
char nlink[6];
char rdev[6];
char mtime[11];
char namesize[6];
char size[11];
} dbuf;
struct hname {
struct header x;
char name[1];
} nbuf;
} dblock;
int tapefile;
vlong getoct(char*, int);
void
populate(char *name)
{
vlong offset;
long isabs, magic, namesize, mode;
Fileinf f;
tapefile = open(name, OREAD);
if (tapefile<0)
error("Can't open argument file");
replete = 1;
for (offset = 0;;) {
seek(tapefile, offset, 0);
if (read(tapefile, (char *)&dblock.dbuf, TBLOCK)<TBLOCK)
break;
magic = getoct(dblock.dbuf.magic, sizeof(dblock.dbuf.magic));
if (magic != 070707){
print("%lo\n", magic);
error("out of phase--get help");
}
if (dblock.nbuf.name[0]=='\0' || strcmp(dblock.nbuf.name, "TRAILER!!!")==0)
break;
mode = getoct(dblock.dbuf.mode, sizeof(dblock.dbuf.mode));
f.mode = mode&0777;
switch(mode & 0170000) {
case 0040000:
f.mode |= DMDIR;
break;
case 0100000:
break;
default:
f.mode = 0;
break;
}
f.uid = getoct(dblock.dbuf.uid, sizeof(dblock.dbuf.uid));
f.gid = getoct(dblock.dbuf.gid, sizeof(dblock.dbuf.gid));
f.size = getoct(dblock.dbuf.size, sizeof(dblock.dbuf.size));
f.mdate = getoct(dblock.dbuf.mtime, sizeof(dblock.dbuf.mtime));
namesize = getoct(dblock.dbuf.namesize, sizeof(dblock.dbuf.namesize));
f.addr = offset+sizeof(struct header)+namesize;
isabs = dblock.nbuf.name[0]=='/';
f.name = &dblock.nbuf.name[isabs];
poppath(f, 1);
offset += sizeof(struct header)+namesize+f.size;
}
}
vlong
getoct(char *p, int l)
{
vlong r;
for (r=0; l>0; p++, l--){
r <<= 3;
r += *p-'0';
}
return r;
}
void
dotrunc(Ram *r)
{
USED(r);
}
void
docreate(Ram *r)
{
USED(r);
}
char *
doread(Ram *r, vlong off, long cnt)
{
seek(tapefile, r->addr+off, 0);
if (cnt>sizeof(dblock.tbuf))
error("read too big");
read(tapefile, dblock.tbuf, cnt);
return dblock.tbuf;
}
void
popdir(Ram *r)
{
USED(r);
}
void
dowrite(Ram *r, char *buf, long off, long cnt)
{
USED(r); USED(buf); USED(off); USED(cnt);
}
int
dopermw(Ram *r)
{
USED(r);
return 0;
}