plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

cpiofs.c (2491B)


      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
     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
     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
    101 dotrunc(Ram *r)
    102 {
    103 	USED(r);
    104 }
    105 
    106 void
    107 docreate(Ram *r)
    108 {
    109 	USED(r);
    110 }
    111 
    112 char *
    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
    123 popdir(Ram *r)
    124 {
    125 	USED(r);
    126 }
    127 
    128 void
    129 dowrite(Ram *r, char *buf, long off, long cnt)
    130 {
    131 	USED(r); USED(buf); USED(off); USED(cnt);
    132 }
    133 
    134 int
    135 dopermw(Ram *r)
    136 {
    137 	USED(r);
    138 	return 0;
    139 }