FreeBSD/Linux Kernel Cross Reference
sys/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 }
Cache object: 06305888fbb33cba9624bf6ed263e53b
|