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' 60 || (f.mode&0170000) == 040000 61 || strrchr(dblock.dbuf.name, '\0')[-1] == '/') 62 f.mode |= DMDIR; 63 f.mode &= DMDIR|0777; 64 linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1'; 65 isabs = dblock.dbuf.name[0]=='/'; 66 if (chksum != checksum()){ 67 fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name); 68 abort(); 69 } 70 if (linkflg) { 71 /*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name, 72 dblock.dbuf.linkname);*/ 73 f.size = 0; 74 blkno += 1; 75 continue; 76 } 77 f.name = dblock.dbuf.name+isabs; 78 if (f.name[0]=='\0') 79 fprint(1, "null name skipped\n"); 80 else 81 poppath(f, 1); 82 blkno += 1 + (f.size+TBLOCK-1)/TBLOCK; 83 } 84 } 85 86 void 87 dotrunc(Ram *r) 88 { 89 USED(r); 90 } 91 92 void 93 docreate(Ram *r) 94 { 95 USED(r); 96 } 97 98 char * 99 doread(Ram *r, long off, long cnt) 100 { 101 102 seek(tapefile, (TBLOCK * (long)r->data)+off, 0); 103 if (cnt>sizeof(dblock.tbuf)) 104 error("read too big"); 105 read(tapefile, dblock.tbuf, cnt); 106 return dblock.tbuf; 107 } 108 109 void 110 popdir(Ram *r) 111 { 112 USED(r); 113 } 114 115 void 116 dowrite(Ram *r, char *buf, long off, long cnt) 117 { 118 USED(r); USED(buf); USED(off); USED(cnt); 119 } 120 121 int 122 dopermw(Ram *r) 123 { 124 USED(r); 125 return 0; 126 } 127 128 int 129 checksum() 130 { 131 register i; 132 register char *cp; 133 134 for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++) 135 *cp = ' '; 136 i = 0; 137 for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++) 138 i += *cp&0xff; 139 return(i); 140 } 141