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