Add first cut at "fsck-cache" that validates the SHA1 object store.
[git/git.git] / fsck-cache.c
CommitLineData
20222118
LT
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 */
12static void fsck_tree(void *data, unsigned long size)
13{
14}
15
16static void fsck_commit(void *data, unsigned long size)
17{
18}
19
20static int mark_sha1_seen(unsigned char *sha1, char *tag)
21{
22 return 0;
23}
24
25static 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
38static 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
58static 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
92int 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}