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 tar 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 name[TNAMSIZ]; 21 char mode[8]; 22 char uid[8]; 23 char gid[8]; 24 char size[12]; 25 char mtime[12]; 26 char chksum[8]; 27 char linkflag; 28 char linkname[TNAMSIZ]; 29 } dbuf; 30 } dblock; 31 32 int tapefile; 33 int checksum(void); 34 35 void 36 populate(char *name) 37 { 38 long blkno, isabs, chksum, linkflg; 39 Fileinf f; 40 41 tapefile = open(name, OREAD); 42 if (tapefile<0) 43 error("Can't open argument file"); 44 replete = 1; 45 for (blkno = 0;;) { 46 seek(tapefile, TBLOCK*blkno, 0); 47 if (read(tapefile, dblock.dummy, sizeof(dblock.dummy))<sizeof(dblock.dummy)) 48 break; 49 if (dblock.dbuf.name[0]=='\0') 50 break; 51 f.addr = (void*)(blkno+1); 52 f.mode = strtoul(dblock.dbuf.mode, 0, 8); 53 f.uid = strtoul(dblock.dbuf.uid, 0, 8); 54 f.gid = strtoul(dblock.dbuf.gid, 0, 8); 55 f.size = strtoul(dblock.dbuf.size, 0, 8); 56 f.mdate = strtoul(dblock.dbuf.mtime, 0, 8); 57 chksum = strtoul(dblock.dbuf.chksum, 0, 8); 58 /* the mode test is ugly but sometimes necessary */ 59 if (dblock.dbuf.linkflag == '5' || (f.mode&0170000) == 040000) 60 f.mode |= DMDIR; 61 linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1'; 62 isabs = dblock.dbuf.name[0]=='/'; 63 if (chksum != checksum()){ 64 fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name); 65 abort(); 66 } 67 if (linkflg) { 68 /*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name, 69 dblock.dbuf.linkname);*/ 70 f.size = 0; 71 blkno += 1; 72 continue; 73 } 74 f.name = dblock.dbuf.name+isabs; 75 if (f.name[0]=='\0') 76 fprint(1, "null name skipped\n"); 77 else 78 poppath(f, 1); 79 blkno += 1 + (f.size+TBLOCK-1)/TBLOCK; 80 } 81 } 82 83 void 84 dotrunc(Ram *r) 85 { 86 USED(r); 87 } 88 89 void 90 docreate(Ram *r) 91 { 92 USED(r); 93 } 94 95 char * 96 doread(Ram *r, long off, long cnt) 97 { 98 99 seek(tapefile, (TBLOCK * (long)r->data)+off, 0); 100 if (cnt>sizeof(dblock.tbuf)) 101 error("read too big"); 102 read(tapefile, dblock.tbuf, cnt); 103 return dblock.tbuf; 104 } 105 106 void 107 popdir(Ram *r) 108 { 109 USED(r); 110 } 111 112 void 113 dowrite(Ram *r, char *buf, long off, long cnt) 114 { 115 USED(r); USED(buf); USED(off); USED(cnt); 116 } 117 118 int 119 dopermw(Ram *r) 120 { 121 USED(r); 122 return 0; 123 } 124 125 int 126 checksum() 127 { 128 register i; 129 register char *cp; 130 131 for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++) 132 *cp = ' '; 133 i = 0; 134 for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++) 135 i += *cp&0xff; 136 return(i); 137 } 138