From 83c2ccb2cabc5e2f85bdac3c4deb310dacad765a Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Thu, 13 Nov 2025 01:35:15 +0100 Subject: [PATCH] Implement DirectoryScanner object --- src/chunk_server.c | 54 ++++++++++------------------ src/file_system.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/file_system.h | 18 ++++++++++ 3 files changed, 125 insertions(+), 36 deletions(-) diff --git a/src/chunk_server.c b/src/chunk_server.c index b443eeb..8d020a7 100644 --- a/src/chunk_server.c +++ b/src/chunk_server.c @@ -223,6 +223,7 @@ static bool chunk_store_exists(ChunkStore *store, SHA256 hash) string path = hash2path(store, hash, buf); // Try to open the file to check if it exists + // TODO: this isn't right Handle fd; if (file_open(path, &fd) == 0) { file_close(fd); @@ -602,49 +603,30 @@ process_metadata_server_chunk_list_request(ChunkServer *state, int conn_idx, Byt uint32_t num_hashes = 0; // Dummy value message_write(&writer, &num_hashes, sizeof(num_hashes)); -#ifdef _WIN32 - WIN32_FIND_DATA find_data; - HANDLE handle = sys_FindFirstFileA(path, &find_data); - if (handle == INVALID_HANDLE_VALUE) { - if (sys_GetLastError() == ERROR_FILE_NOT_FOUND) { - // TODO + DirectoryScanner scanner; + if (directory_scanner_init(&scanner, xxx) < 0) + return -1; + + for (;;) { + + string name; + int ret = directory_scanner_next(&scanner, &name); + + if (ret == 1) + break; + + if (ret < 0) { + directory_scanner_free(&scanner); + return -1; } - return -1; - } - - do { SHA256 hash; - - // TODO - - message_write(&writer, &hash, sizeof(hash)); - num_hashes++; - - } while (sys_FindNextFileA(handle, &find_data)); - - if (sys_GetLastError() != ERROR_NO_MORE_FILES) - return -1; - - sys_FindClose(handle); -#else - DIR *d = sys_opendir(path); - if (d == NULL) - return -1; - - struct dirent *e; - while ((e = sys_readdir(d))) { - - SHA256 hash; - - // TODO + // TODO: file name to hash message_write(&writer, &hash, sizeof(hash)); num_hashes++; } - - sys_closedir(d); -#endif + directory_scanner_free(&scanner); byte_queue_patch(writer.output, offset, &num_hashes, sizeof(num_hashes)); diff --git a/src/file_system.c b/src/file_system.c index c64f630..91cef4a 100644 --- a/src/file_system.c +++ b/src/file_system.c @@ -268,3 +268,92 @@ int file_read_all(string path, string *data) file_close(fd); return 0; } + +#ifdef _WIN32 + +int directory_scanner_init(DirectoryScanner *scanner, string path) +{ + char pattern[PATH_MAX]; + int ret = snprintf(pattern, "%.*s\\*", path.len, path.ptr); + if (ret < 0 || ret >= sizeof(pattern)) + return -1; + + scanner->handle = sys_FindFirstFileA(path, &scanner->find_data); + if (scanner->handle == INVALID_HANDLE_VALUE) { + if (sys_GetLastError() == ERROR_FILE_NOT_FOUND) { + scanner->done = true; + return 0; + } + return -1; + } + + scanner->done = false; + scanner->first = true; + return 0; +} + +int directory_scanner_next(DirectoryScanner *scanner, string *name) +{ + if (scanner->done) + return 1; + + if (!scanner->first) { + BOOL ok = sys_FindNextFileA(scanner->handle, &scanner->find_data); + if (!ok) { + scanner->done = true; + if (sys_GetLastError() == ERROR_NO_MORE_FILES) + return 1; + return -1; + } + } + + char *p = scanner->find_data.cFileName;// TODO: is this the right field? + *name = (string) { p, strlen(p) }; + return 0; +} + +void directory_scanner_free(DirectoryScanner *scanner) +{ + sys_FindClose(scanner->handle); +} + +#else + +int directory_scanner_init(DirectoryScanner *scanner, string path) +{ + char path_copy[PATH_MAX]; + if (path.len >= PATH_MAX) + return -1; + memcpy(path_copy, path.ptr, path.len); + path_copy[path.len] = '\0'; + + scanner->d = sys_opendir(path_copy); + if (scanner->d == NULL) { + scanner->done = true; + return -1; + } + + return 0; +} + +int directory_scanner_next(DirectoryScanner *scanner, string *name) +{ + if (scanner->done) + return -1; + + scanner->e = sys_reddir(scanner->d); + if (scanner->e == NULL) { + scanner->done = true; + return 1; + } + + *name = (string) { scanner->e->d_name, strlen(scanner->e->d_name) }; + return 0; +} + +void directory_scanner_free(DirectoryScanner *scanner) +{ + sys_closedir(scanner->d); +} + +#endif diff --git a/src/file_system.h b/src/file_system.h index 125388d..f86ec2f 100644 --- a/src/file_system.h +++ b/src/file_system.h @@ -7,6 +7,20 @@ typedef struct { uint64_t data; } Handle; +#ifdef _WIN32 +typedef struct { + HANDLE handle; + WIN32_FIND_DATA find_data; + bool first; + bool done; +} DirectoryScanner; +#else +typedef struct { + DIR *d; + struct dirent *e; +} DirectoryScanner; +#endif + int file_open(string path, Handle *fd); void file_close(Handle fd); int file_lock(Handle fd); @@ -22,4 +36,8 @@ int remove_file_or_dir(string path); int get_full_path(string path, char *dst); int file_read_all(string path, string *data); +int directory_scanner_init(DirectoryScanner *scanner, string path); +int directory_scanner_next(DirectoryScanner *scanner, string *name); +void directory_scanner_free(DirectoryScanner *scanner); + #endif // FILE_SYSTEM_INCLUDED