]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/bitsy/tar.c
merge
[plan9front.git] / sys / src / 9 / bitsy / tar.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 typedef union Hblock Hblock;
10
11 #define TBLOCK  512
12 #define NAMSIZ  100
13 union   Hblock
14 {
15         char    dummy[TBLOCK];
16         struct  header
17         {
18                 char    name[NAMSIZ];
19                 char    mode[8];
20                 char    uid[8];
21                 char    gid[8];
22                 char    size[12];
23                 char    mtime[12];
24                 char    chksum[8];
25                 char    linkflag;
26                 char    linkname[NAMSIZ];
27         } dbuf;
28 };
29
30 static int getdir(Hblock *hb, Dir *sp);
31 static int checksum(Hblock *hb);
32
33 uchar*
34 tarlookup(uchar *addr, char *file, int *dlen)
35 {
36         Hblock *hp;
37         Dir dir;
38
39         hp = (Hblock*)addr;
40         while(getdir(hp, &dir) != 0) {
41                 if(strcmp(file, hp->dbuf.name) == 0) {
42                         *dlen = dir.length;
43                         return (uchar*)(hp+1);
44                 }
45                 hp += (dir.length+TBLOCK-1)/TBLOCK + 1;
46         }
47         return 0;
48 }
49
50 static int
51 getdir(Hblock *hp, Dir *sp)
52 {
53         int chksum;
54
55         if (hp->dbuf.name[0] == '\0')
56                 return 0;
57         sp->length = strtol(hp->dbuf.size, 0, 8);
58         sp->mtime = strtol(hp->dbuf.mtime, 0, 8);
59         chksum = strtol(hp->dbuf.chksum, 0, 8);
60         if (chksum != checksum(hp)) {
61                 print("directory checksum error\n");
62                 return 0;
63         }       
64         return 1;
65 }
66
67 static int
68 checksum(Hblock *hp)
69 {
70         int i;
71         char *cp;
72
73         i = 0;
74         for (cp = hp->dummy; cp < &hp->dummy[TBLOCK]; cp++) {
75                 if(cp < hp->dbuf.chksum || cp >= &hp->dbuf.chksum[sizeof(hp->dbuf.chksum)])
76                         i += *cp & 0xff;
77                 else
78                         i += ' ' & 0xff;
79         }
80         return(i);
81 }