min-list-garbage.c (1607B)
1 #include <dirent.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 typedef char hash_t[32]; 9 hash_t *hash_list = NULL; 10 int hash_list_entries = 0; 11 int hash_list_size = 0; 12 13 int add_list_entry(char *name) 14 { 15 name += strlen("/nix/store/"); 16 if(hash_list_entries >= hash_list_size) { 17 if(hash_list_size == 0) hash_list_size = 4; 18 hash_list_size = hash_list_size * 2; 19 hash_list = realloc(hash_list, hash_list_size * sizeof(hash_t)); 20 } 21 strncpy(hash_list[hash_list_entries++], name, 32); 22 } 23 24 int read_list(char *filename) 25 { 26 char s[1024]; 27 FILE *fp; 28 if(fp = fopen(filename, "r")) { 29 while(fgets(s, 1024, fp)) { 30 if(strrchr(s, '\n')) { 31 add_list_entry(s); 32 } else { 33 puts("hash list entry too long"); 34 exit(1); 35 } 36 } 37 } 38 fclose(fp); 39 } 40 41 int on_list(char *name) 42 { 43 int i; 44 for(i = 0; i < hash_list_entries; i++) { 45 if(!strncmp(hash_list[i], name, 32)) { 46 return 1; 47 } 48 } 49 return 0; 50 } 51 52 int main(int argc, char * argv[]) 53 { 54 struct dirent * de; 55 DIR * dirp; 56 char hash[32]; 57 58 if(argc < 2) { 59 puts("Usage: min-list-garbage store-paths-file\n\nChecks all store paths against the list of expected paths in store-paths-file,\n and prints any which are present unexpectedly"); 60 exit(1); 61 } 62 63 read_list(argv[1]); 64 65 if((dirp = opendir("/nix/store")) == NULL) { 66 puts("can't open /nix/store"); 67 exit(1); 68 } 69 70 while(de = readdir(dirp)) { 71 if(strlen(de->d_name) >= 32) { 72 strncpy(hash, de->d_name, 32); 73 if(!on_list(hash)) puts(de->d_name); 74 } 75 } 76 77 closedir(dirp); 78 }