]>
Commit | Line | Data |
---|---|---|
bad50dc8 LT |
1 | #include "cache.h" |
2 | ||
3 | static int nr_entries; | |
4 | static const char *base_name; | |
5 | static const char unpack_usage[] = "git-unpack-objects basename"; | |
6 | ||
7 | struct pack_entry { | |
8 | unsigned int offset; | |
9 | unsigned char sha1[20]; | |
10 | }; | |
11 | ||
12 | static struct pack_entry **pack_list; | |
13 | ||
14 | static void *map_file(const char *suffix, unsigned long *sizep) | |
15 | { | |
16 | static char pathname[PATH_MAX]; | |
17 | unsigned long len; | |
18 | int fd; | |
19 | struct stat st; | |
20 | void *map; | |
21 | ||
22 | len = snprintf(pathname, PATH_MAX, "%s.%s", base_name, suffix); | |
23 | if (len >= PATH_MAX) | |
24 | die("bad pack base-name"); | |
25 | fd = open(pathname, O_RDONLY); | |
26 | if (fd < 0 || fstat(fd, &st)) | |
27 | die("unable to open '%s'", pathname); | |
28 | len = st.st_size; | |
29 | if (!len) | |
30 | die("bad pack file '%s'", pathname); | |
31 | map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); | |
32 | if (-1 == (int)(long)map) | |
33 | die("unable to mmap '%s'", pathname); | |
34 | close(fd); | |
35 | *sizep = len; | |
36 | return map; | |
37 | } | |
38 | ||
39 | static int sort_by_offset(const void *_a, const void *_b) | |
40 | { | |
41 | struct pack_entry *a = *(struct pack_entry **)_a; | |
42 | struct pack_entry *b = *(struct pack_entry **)_b; | |
43 | unsigned int o1, o2; | |
44 | ||
45 | o1 = ntohl(a->offset); | |
46 | o2 = ntohl(b->offset); | |
47 | return o1 < o2 ? -1 : 1; | |
48 | } | |
49 | ||
50 | static int check_index(void *index, unsigned long idx_size) | |
51 | { | |
52 | unsigned int *array = index; | |
53 | unsigned int nr; | |
54 | int i; | |
55 | ||
56 | if (idx_size < 4*256) | |
57 | return error("index file too small"); | |
58 | nr = 0; | |
59 | for (i = 0; i < 256; i++) { | |
60 | unsigned int n = ntohl(array[i]); | |
61 | if (n < nr) | |
62 | return error("non-monotonic index"); | |
63 | nr = n; | |
64 | } | |
65 | if (idx_size != 4*256 + nr * 24) { | |
66 | printf("idx_size=%d, expected %d (%d)\n", idx_size, 4*256 + nr * 24, nr); | |
67 | return error("wrong index file size"); | |
68 | } | |
69 | ||
70 | nr_entries = nr; | |
71 | pack_list = xmalloc(nr * sizeof(struct pack_entry *)); | |
72 | for (i = 0; i < nr; i++) | |
73 | pack_list[i] = index + 4*256 + i*24; | |
74 | ||
75 | qsort(pack_list, nr, sizeof(*pack_list), sort_by_offset); | |
76 | ||
77 | printf("%d entries\n", nr); | |
78 | return 0; | |
79 | } | |
80 | ||
81 | int main(int argc, char **argv) | |
82 | { | |
83 | int i; | |
84 | unsigned long idx_size, pack_size; | |
85 | void *index, *pack; | |
86 | ||
87 | for (i = 1 ; i < argc; i++) { | |
88 | const char *arg = argv[i]; | |
89 | ||
90 | if (*arg == '-') { | |
91 | /* Maybe we'll have some flags here some day.. */ | |
92 | usage(unpack_usage); | |
93 | } | |
94 | if (base_name) | |
95 | usage(unpack_usage); | |
96 | base_name = arg; | |
97 | } | |
98 | if (!base_name) | |
99 | usage(unpack_usage); | |
100 | index = map_file("idx", &idx_size); | |
101 | pack = map_file("pack", &pack_size); | |
102 | if (check_index(index, idx_size) < 0) | |
103 | die("bad index file"); | |
104 | return 0; | |
105 | } |