/* Copy the file src to dst 4KB per time */ int pyi_copy_file(const char *src, const char *dst, const char *filename) { FILE *in = stb_fopen(src, "rb"); FILE *out = pyi_open_target(dst, filename); char buf[4096]; int error = 0; if (in == NULL || out == NULL) return -1; while (!feof(in)) { if (fread(buf, 4096, 1, in) == -1) { if (ferror(in)) { clearerr(in); error = -1; break; } } else { fwrite(buf, 4096, 1, out); if (ferror(out)) { clearerr(out); error = -1; break; } } } #ifndef WIN32 fchmod(fileno(out), S_IRUSR | S_IWUSR | S_IXUSR); #endif fclose(in); fclose(out); return error; }
static void vfs_reload(struct vfs_file *f, int force) { time_t lastChange = stb_ftimestamp(f->name); if (f->lastChange != lastChange || force) { f->file = stb_fopen(f->name, "rb"); if (f->file == 0) { return; } fseek(f->file, 0, SEEK_SET); free(f->data); f->lastChange = lastChange; // Hacky solution to make sure the OS is finished with the fseek call // How can this be solved better? f->size = 0; while (f->size == 0) { f->size = stb_filelen(f->file); } f->data = malloc(f->size); fread(f->data, 1, f->size, f->file); stb_fclose(f->file, 0); for (int j = 0, j_size = stb_arr_len(f->read_callbacks); j < j_size; j++) { read_callback_t cbck = f->read_callbacks[j].fn; cbck(f->simplename, f->size, f->data, f->read_callbacks[j].userdata); } } }
void vfs_mount(const char* dir) { if (dir == NULL) { vfs_error("Mount directory is NULL\n"); return; } char path[VFS_MOUNT_PATH_MAX]; strcpy(path, dir); size_t pathlen = strlen(path); if (pathlen == 0) { vfs_error("Mount directory is of length 0\n"); return; } if (path[pathlen - 1] == '\\' || path[pathlen - 1] == '/') { path[pathlen - 1] = '\0'; } char** filenames = stb_readdir_recursive(path, NULL); if (filenames == NULL) { vfs_error("Could not read directory: %s\n", path); return; } int num_new_files = stb_arr_len(filenames); for (int i = 0; i < num_new_files; i++) { struct vfs_file new_file; strcpy(new_file.name, filenames[i]); strcpy(new_file.simplename, filenames[i] + strlen(path) + 1); int replaced = 0; for (int j = 0; j < vfs_global->file_count; j++) { if (strcmp(vfs_global->file_table[j].simplename, new_file.simplename) == 0) { stb_fclose(vfs_global->file_table[j].file, 0); free(vfs_global->file_table[j].data); strcpy(vfs_global->file_table[j].name, new_file.name); vfs_global->file_table[j].file = stb_fopen(vfs_global->file_table[j].name, "rb"); vfs_global->file_table[j].lastChange = stb_ftimestamp(vfs_global->file_table[j].name); vfs_global->file_table[j].size = stb_filelen(vfs_global->file_table[j].file); vfs_global->file_table[j].data = malloc(vfs_global->file_table[j].size); fread(vfs_global->file_table[j].data, 1, vfs_global->file_table[j].size, vfs_global->file_table[j].file); stb_fclose(vfs_global->file_table[i].file, 0); replaced = 1; break; } } if (!replaced) { new_file.read_callbacks = 0; new_file.file = stb_fopen(new_file.name, "rb"); new_file.lastChange = stb_ftimestamp(new_file.name); new_file.size = stb_filelen(new_file.file); new_file.data = malloc(new_file.size); fread(new_file.data, 1, new_file.size, new_file.file); stb_fclose(new_file.file, 0); vfs_global->file_table[vfs_global->file_count] = new_file; vfs_global->file_count++; } } }