Created
March 27, 2025 04:13
-
-
Save morganabc/b225b0d2754caa4fc479c0fab9f9e6d7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <dirent.h> | |
| #include <sys/stat.h> | |
| #include <string.h> | |
| long count = 0; | |
| int path_exists(const char *path) { | |
| struct stat st; | |
| return stat(path, &st) == 0; | |
| } | |
| void find_missing(const char *old_base, const char *new_base, const char *relative_path) { | |
| char old_path[4096]; | |
| char new_path[4096]; | |
| if (relative_path[0] == '\0') { | |
| snprintf(old_path, sizeof(old_path), "%s", old_base); | |
| snprintf(new_path, sizeof(new_path), "%s", new_base); | |
| } else { | |
| snprintf(old_path, sizeof(old_path), "%s/%s", old_base, relative_path); | |
| snprintf(new_path, sizeof(new_path), "%s/%s", new_base, relative_path); | |
| } | |
| if (!path_exists(new_path)) { | |
| printf("Missing: %s\n", relative_path[0] == '\0' ? old_base : old_path); | |
| return; | |
| } | |
| DIR *dir = opendir(old_path); | |
| if (!dir) { | |
| perror("opendir"); | |
| return; | |
| } | |
| struct dirent *entry; | |
| while ((entry = readdir(dir)) != NULL) { | |
| count++; | |
| if (count % 100000 == 0) { | |
| fprintf(stderr, "%ld\r", count); | |
| } | |
| if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { | |
| continue; | |
| } | |
| char next_relative_path[4096]; | |
| char next_old_path[4096]; | |
| if (relative_path[0] == '\0') { | |
| snprintf(next_relative_path, sizeof(next_relative_path), "%s", entry->d_name); | |
| } else { | |
| snprintf(next_relative_path, sizeof(next_relative_path), "%s/%s", relative_path, entry->d_name); | |
| } | |
| snprintf(next_old_path, sizeof(next_old_path), "%s/%s", old_path, entry->d_name); | |
| struct stat st; | |
| if (lstat(next_old_path, &st) != 0) { | |
| fprintf(stderr, "Error stating %s\n", next_old_path); | |
| continue; | |
| } | |
| if (S_ISDIR(st.st_mode)) { | |
| if (!S_ISLNK(st.st_mode)) { | |
| find_missing(old_base, new_base, next_relative_path); | |
| } | |
| } else { | |
| char next_new_path[4096]; | |
| snprintf(next_new_path, sizeof(next_new_path), "%s/%s", new_path, entry->d_name); | |
| if (!path_exists(next_new_path)) { | |
| printf("Missing: %s\n", next_new_path); | |
| } | |
| } | |
| } | |
| closedir(dir); | |
| } | |
| int main(int argc, char *argv[]) { | |
| if (argc != 3) { | |
| fprintf(stderr, "Usage: %s [OLD_PATH] [NEW_PATH]\n", argv[0]); | |
| return 1; | |
| } | |
| const char *old_path = argv[1]; | |
| const char *new_path = argv[2]; | |
| if (!path_exists(old_path)) { | |
| fprintf(stderr, "Error: '%s' does not exist\n", old_path); | |
| return 1; | |
| } | |
| if (!path_exists(new_path)) { | |
| fprintf(stderr, "Error: '%s' does not exist\n", new_path); | |
| return 1; | |
| } | |
| find_missing(old_path, new_path, ""); | |
| fprintf(stderr, "Total: %ld\n", count); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment