81fd25a10050fd60d6f901191c9cc9e5cdb4f3d6
   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}