Skip to content

Commit 2022211

Browse files
author
Linus Torvalds
committed
Add first cut at "fsck-cache" that validates the SHA1 object store.
It doesn't complain about mine. But it also doesn't yet check for inter-object reachability etc.
1 parent 2ade934 commit 2022211

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

fsck-cache.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include "cache.h"
2+
3+
#include <sys/types.h>
4+
#include <dirent.h>
5+
6+
/*
7+
* These three functions should build up a graph in memory about
8+
* what objects we've referenced, and found, and types..
9+
*
10+
* Right now we don't do that kind of reachability checking. Yet.
11+
*/
12+
static void fsck_tree(void *data, unsigned long size)
13+
{
14+
}
15+
16+
static void fsck_commit(void *data, unsigned long size)
17+
{
18+
}
19+
20+
static int mark_sha1_seen(unsigned char *sha1, char *tag)
21+
{
22+
return 0;
23+
}
24+
25+
static int fsck_entry(unsigned char *sha1, char *tag, void *data, unsigned long size)
26+
{
27+
if (!strcmp(tag, "blob"))
28+
/* Nothing to check */;
29+
else if (!strcmp(tag, "tree"))
30+
fsck_tree(data, size);
31+
else if (!strcmp(tag, "commit"))
32+
fsck_commit(data, size);
33+
else
34+
return -1;
35+
return mark_sha1_seen(sha1, tag);
36+
}
37+
38+
static int fsck_name(char *hex)
39+
{
40+
unsigned char sha1[20];
41+
if (!get_sha1_hex(hex, sha1)) {
42+
unsigned long mapsize;
43+
void *map = map_sha1_file(sha1, &mapsize);
44+
if (map) {
45+
char type[100];
46+
unsigned long size;
47+
void *buffer = NULL;
48+
if (!check_sha1_signature(sha1, map, mapsize))
49+
buffer = unpack_sha1_file(map, mapsize, type, &size);
50+
munmap(map, mapsize);
51+
if (buffer && !fsck_entry(sha1, type, buffer, size))
52+
return 0;
53+
}
54+
}
55+
return -1;
56+
}
57+
58+
static int fsck_dir(int i, char *path)
59+
{
60+
DIR *dir = opendir(path);
61+
struct dirent *de;
62+
63+
if (!dir) {
64+
fprintf(stderr, "missing sha1 directory '%s'", path);
65+
return -1;
66+
}
67+
68+
while ((de = readdir(dir)) != NULL) {
69+
char name[100];
70+
int len = strlen(de->d_name);
71+
72+
switch (len) {
73+
case 2:
74+
if (de->d_name[1] != '.')
75+
break;
76+
case 1:
77+
if (de->d_name[0] != '.')
78+
break;
79+
continue;
80+
case 38:
81+
sprintf(name, "%02x", i);
82+
memcpy(name+2, de->d_name, len+1);
83+
if (!fsck_name(name))
84+
continue;
85+
}
86+
fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
87+
}
88+
closedir(dir);
89+
return 0;
90+
}
91+
92+
int main(int argc, char **argv)
93+
{
94+
int i;
95+
char *sha1_dir;
96+
97+
if (argc != 1)
98+
usage("fsck-cache");
99+
sha1_dir = getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT;
100+
for (i = 0; i < 256; i++) {
101+
static char dir[4096];
102+
sprintf(dir, "%s/%02x", sha1_dir, i);
103+
fsck_dir(i, dir);
104+
}
105+
return 0;
106+
}

0 commit comments

Comments
 (0)