URI:
       ttarfs.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       ttarfs.c (2759B)
       ---
            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 = 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                 if((uchar)dblock.dbuf.size[0] == 0x80)
           56                         f.size = b8byte(dblock.dbuf.size+3);
           57                 else
           58                         f.size = strtoull(dblock.dbuf.size, 0, 8);
           59                 f.mdate = strtoul(dblock.dbuf.mtime, 0, 8);
           60                 chksum = strtoul(dblock.dbuf.chksum, 0, 8);
           61                 /* the mode test is ugly but sometimes necessary */
           62                 if (dblock.dbuf.linkflag == '5'
           63                 || (f.mode&0170000) == 040000
           64                 ||  strrchr(dblock.dbuf.name, '\0')[-1] == '/'){
           65                         f.mode |= DMDIR;
           66                         f.size = 0;
           67                 }
           68                 f.mode &= DMDIR|0777;
           69                 linkflg = dblock.dbuf.linkflag=='s' || dblock.dbuf.linkflag=='1';
           70                 isabs = dblock.dbuf.name[0]=='/';
           71                 if (chksum != checksum()){
           72                         fprint(1, "bad checksum on %.28s\n", dblock.dbuf.name);
           73                         exits("checksum");
           74                 }
           75                 if (linkflg) {
           76                         /*fprint(2, "link %s->%s skipped\n", dblock.dbuf.name,
           77                            dblock.dbuf.linkname);*/
           78                         f.size = 0;
           79                         blkno += 1;
           80                         continue;
           81                 }
           82                 f.name = dblock.dbuf.name+isabs;
           83                 if (f.name[0]=='\0')
           84                         fprint(1, "null name skipped\n");
           85                 else
           86                         poppath(f, 1);
           87                 blkno += 1 + (f.size+TBLOCK-1)/TBLOCK;
           88         }
           89 }
           90 
           91 void
           92 dotrunc(Ram *r)
           93 {
           94         USED(r);
           95 }
           96 
           97 void
           98 docreate(Ram *r)
           99 {
          100         USED(r);
          101 }
          102 
          103 char *
          104 doread(Ram *r, vlong off, long cnt)
          105 {
          106         seek(tapefile, TBLOCK*r->addr+off, 0);
          107         if (cnt>sizeof(dblock.tbuf))
          108                 error("read too big");
          109         read(tapefile, dblock.tbuf, cnt);
          110         return dblock.tbuf;
          111 }
          112 
          113 void
          114 popdir(Ram *r)
          115 {
          116         USED(r);
          117 }
          118 
          119 void
          120 dowrite(Ram *r, char *buf, long off, long cnt)
          121 {
          122         USED(r); USED(buf); USED(off); USED(cnt);
          123 }
          124 
          125 int
          126 dopermw(Ram *r)
          127 {
          128         USED(r);
          129         return 0;
          130 }
          131 
          132 int
          133 checksum()
          134 {
          135         int i;
          136         char *cp;
          137 
          138         for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
          139                 *cp = ' ';
          140         i = 0;
          141         for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
          142                 i += *cp&0xff;
          143         return(i);
          144 }