static void test_Local_Open_Dir(TestBatchRunner *runner) { Folder *real_folder = S_folder_with_contents(); CompoundFileReader *cf_reader = CFReader_open(real_folder); bool saw_foo = false; bool saw_stuff = false; bool stuff_was_dir = false; CFReader_MkDir(cf_reader, stuff); DirHandle *dh = CFReader_Local_Open_Dir(cf_reader); while (DH_Next(dh)) { String *entry = DH_Get_Entry(dh); if (Str_Equals(entry, (Obj*)foo)) { saw_foo = true; } else if (Str_Equals(entry, (Obj*)stuff)) { saw_stuff = true; stuff_was_dir = DH_Entry_Is_Dir(dh); } DECREF(entry); } TEST_TRUE(runner, saw_foo, "DirHandle iterated over virtual file"); TEST_TRUE(runner, saw_stuff, "DirHandle iterated over real directory"); TEST_TRUE(runner, stuff_was_dir, "DirHandle knew that real entry was dir"); DECREF(dh); DECREF(cf_reader); DECREF(real_folder); }
bool_t Folder_delete_tree(Folder *self, const CharBuf *path) { Folder *enclosing_folder = Folder_Enclosing_Folder(self, path); // Don't allow Folder to delete itself. if (!path || !CB_Get_Size(path)) { return false; } if (enclosing_folder) { ZombieCharBuf *local = IxFileNames_local_part(path, ZCB_BLANK()); if (Folder_Local_Is_Directory(enclosing_folder, (CharBuf*)local)) { Folder *inner_folder = Folder_Local_Find_Folder(enclosing_folder, (CharBuf*)local); DirHandle *dh = Folder_Local_Open_Dir(inner_folder); if (dh) { VArray *files = VA_new(20); VArray *dirs = VA_new(20); CharBuf *entry = DH_Get_Entry(dh); while (DH_Next(dh)) { VA_Push(files, (Obj*)CB_Clone(entry)); if (DH_Entry_Is_Dir(dh) && !DH_Entry_Is_Symlink(dh)) { VA_Push(dirs, (Obj*)CB_Clone(entry)); } } for (uint32_t i = 0, max = VA_Get_Size(dirs); i < max; i++) { CharBuf *name = (CharBuf*)VA_Fetch(files, i); bool_t success = Folder_Delete_Tree(inner_folder, name); if (!success && Folder_Local_Exists(inner_folder, name)) { break; } } for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) { CharBuf *name = (CharBuf*)VA_Fetch(files, i); bool_t success = Folder_Local_Delete(inner_folder, name); if (!success && Folder_Local_Exists(inner_folder, name)) { break; } } DECREF(dirs); DECREF(files); DECREF(dh); } } return Folder_Local_Delete(enclosing_folder, (CharBuf*)local); } else { // Return failure if the entry wasn't there in the first place. return false; } }
static void S_add_to_file_list(Folder *self, VArray *list, CharBuf *dir, CharBuf *prefix) { size_t orig_prefix_size = CB_Get_Size(prefix); DirHandle *dh = Folder_Open_Dir(self, dir); CharBuf *entry; if (!dh) { RETHROW(INCREF(Err_get_error())); } entry = DH_Get_Entry(dh); while (DH_Next(dh)) { // Updates entry if (!S_is_updir(entry)) { CharBuf *relpath = CB_newf("%o%o", prefix, entry); if (VA_Get_Size(list) == VA_Get_Capacity(list)) { VA_Grow(list, VA_Get_Size(list) * 2); } VA_Push(list, (Obj*)relpath); if (DH_Entry_Is_Dir(dh) && !DH_Entry_Is_Symlink(dh)) { CharBuf *subdir = CB_Get_Size(dir) ? CB_newf("%o/%o", dir, entry) : CB_Clone(entry); CB_catf(prefix, "%o/", entry); S_add_to_file_list(self, list, subdir, prefix); // recurse CB_Set_Size(prefix, orig_prefix_size); DECREF(subdir); } } } if (!DH_Close(dh)) { RETHROW(INCREF(Err_get_error())); } DECREF(dh); }