@ -3,18 +3,113 @@
@@ -3,18 +3,113 @@
#include <sys/types.h>
#include <dirent.h>
struct needs {
unsigned char parent[20];
unsigned char needs[20];
char tag[10];
};
struct seen {
unsigned char sha1[20];
char tag[10];
unsigned needed;
};
static struct needs *needs;
static struct seen *seen;
static int nr_seen, alloc_seen, nr_needs, alloc_needs;
/*
* These two functions should build up a graph in memory about
* These two functions build up a graph in memory about
* what objects we've referenced, and found, and types..
*
* Right now we don't do that kind of reachability checking. Yet.
*/
static void mark_needs_sha1(unsigned char *parent, const char * type, unsigned char *child)
static int compare_seen(const void *s1, const void *s2)
{
return memcmp(s1, s2, 20);
}
static int lookup_seen(unsigned char *sha1, char *tag)
{
int first = 0, last = nr_seen;
while (last > first) {
int next = (last + first) / 2;
struct seen *s = seen + next;
int cmp = memcmp(sha1, s->sha1, 20);
if (cmp < 0) {
last = next;
continue;
}
if (cmp > 0) {
first = next+1;
continue;
}
if (strcmp(tag, s->tag))
break;
s->needed++;
return 1;
}
return 0;
}
static void check_connectivity(void)
{
int i;
/* Sort the "seen" tags for quicker lookup */
qsort(seen, nr_seen, sizeof(struct seen), compare_seen);
/* Look up all the requirements, warn about missing objects.. */
for (i = 0; i < nr_needs; i++) {
struct needs *n = needs + i;
char hex[60];
if (lookup_seen(n->needs, n->tag))
continue;
strcpy(hex, sha1_to_hex(n->parent));
}
/* Tell the user about things not referenced.. */
for (i = 0; i < nr_seen; i++) {
struct seen *s = seen + i;
if (s->needed)
continue;
printf("unreferenced %s: %s\n", s->tag, sha1_to_hex(s->sha1));
}
}
static void mark_needs_sha1(unsigned char *parent, const char * tag, unsigned char *child)
{
struct needs *n;
if (nr_needs == alloc_needs) {
alloc_needs = alloc_nr(alloc_needs);
needs = realloc(needs, alloc_needs*sizeof(struct needs));
}
n = needs + nr_needs;
nr_needs++;
memcpy(n->parent, parent, 20);
memcpy(n->needs, child, 20);
strncpy(n->tag, tag, sizeof(n->tag));
}
static int mark_sha1_seen(unsigned char *sha1, char *tag)
{
struct seen *s;
if (nr_seen == alloc_seen) {
alloc_seen = alloc_nr(alloc_seen);
seen = realloc(seen, alloc_seen*sizeof(struct seen));
}
s = seen + nr_seen;
memset(s, 0, sizeof(s));
nr_seen++;
memcpy(s->sha1, sha1, 20);
strncpy(s->tag, tag, sizeof(s->tag));
return 0;
}
@ -150,5 +245,6 @@ int main(int argc, char **argv)
@@ -150,5 +245,6 @@ int main(int argc, char **argv)
sprintf(dir, "%s/%02x", sha1_dir, i);
fsck_dir(i, dir);
}
check_connectivity();
return 0;
}