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