void detect_and_add_single_z_file(char *input_filename, char *blorb_filename) { struct z_story_list *z_story_list = get_z_story_list(); struct babel_info *babel = load_babel_info(); TRACE_LOG("noffiles: %d\n", z_story_list->nof_entries); detect_and_add_z_file(input_filename, blorb_filename, babel, z_story_list); TRACE_LOG("noffiles: %d\n", z_story_list->nof_entries); save_story_list(z_story_list); store_babel_info_timestamps(babel); free_z_story_list(z_story_list); free_babel_info(babel); }
void search_directory(char *absolute_dirname, bool recursive) { struct z_story_list *z_story_list = get_z_story_list(); struct babel_info *babel = load_babel_info(); #ifndef DISABLE_CONFIGFILES ensure_dot_fizmo_dir_exists(); #endif // DISABLE_CONFIGFILES if ((nof_files_found = count_files(absolute_dirname, recursive)) > 0) { show_progress = true; nof_files_searched = 0; nof_directories_searched = 0; build_filelist(absolute_dirname, z_story_list, recursive, babel); } //printf("%d, %s\n", z_story_list->nof_entries, absolute_dirname); save_story_list(z_story_list); store_babel_info_timestamps(babel); free_z_story_list(z_story_list); free_babel_info(babel); }
static int detect_and_add_z_file(char *filename, char *blorb_filename, struct babel_info *babel, struct z_story_list *story_list) { z_file *infile; uint8_t buf[30]; uint32_t val; char serial[7]; int version; uint16_t checksum; uint16_t release; struct babel_story_info *b_info = NULL; char *title; char *author; char *language; char *description; char *ptr, *ptr2; int length; time_t storyfile_timestamp; char *empty_string = ""; struct z_story_list_entry *entry; int chunk_length = -1; struct babel_info *file_babel = NULL; bool file_is_zblorb; char *cwd = NULL; char *abs_filename = NULL; if (filename == NULL) return -1; if (filename[0] != '/') { cwd = fsi->get_cwd(); abs_filename = fizmo_malloc(strlen(cwd) + strlen(filename) + 2); sprintf(abs_filename, "%s/%s", cwd, filename); } else abs_filename = filename; if ((infile = fsi->openfile(abs_filename, FILETYPE_DATA, FILEACCESS_READ)) == NULL) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if ((storyfile_timestamp = fsi->get_last_file_mod_timestamp(infile)) < 0) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if (fsi->readchars(buf, 30, infile) != 30) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if (memcmp(buf, "FORM", 4) == 0) { // IFF file. if ( (is_form_type(infile, "IFRS") != true) || (find_chunk("ZCOD", infile) == -1) ) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } file_is_zblorb = true; if (find_chunk("IFmd", infile) == 0) { read_chunk_length(infile); chunk_length = get_last_chunk_length(); file_babel = load_babel_info_from_blorb( infile, chunk_length, abs_filename, storyfile_timestamp); babel = file_babel; } find_chunk("ZCOD", infile); read_chunk_length(infile); length = get_last_chunk_length(); if (fsi->readchars(buf, 30, infile) != 30) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } } else { fsi->setfilepos(infile, 0, SEEK_END); length = fsi->getfilepos(infile); file_is_zblorb = false; } fsi->closefile(infile); val = (buf[16] << 24) | (buf[17] << 16) | (buf[18] << 8) | (buf[19]); if ( ((val & 0xbe00f0f0) != 0x3030) || (*buf < 1) || (*buf > 8) ) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -2; } version = *buf; memcpy(serial, buf + 0x12, 6); serial[6] = '\0'; checksum = (buf[0x1c] << 8) | buf[0x1d]; release = (buf[2] << 8) | buf[3]; if ((entry = get_z_story_entry(serial, release, length, story_list)) != NULL) { // We already have the story in our story-list. If we have a raw file // we can just quit if the support-blorbfilename is the same (raw files // don't contain metadata which might have changed). if ( (file_is_zblorb == false) && ( ( (entry->blorbfile == NULL) && (blorb_filename != NULL) ) // || (Don't delete blorb file) // ( (blorb_filename == NULL) && (entry->blorbfile != NULL) ) || ( (entry->blorbfile != NULL) && (blorb_filename != NULL) && (strcmp(blorb_filename, entry->blorbfile) == 0) ) ) ) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -3; } //printf("%ld / %ld\n", storyfile_timestamp, entry->storyfile_timestamp); // In case new file is a zblorb and we have save a raw file, remove the // raw and keep the blorb (so we can get images and sound). We'll also // re-read the file contents if the file has changed (metadata might // have been altered). if ( (strcmp(entry->filetype, filetype_raw) == 0) || (storyfile_timestamp > entry->storyfile_timestamp) ) { remove_entry_from_list(story_list, entry); //printf("%s...\n", abs_filename); } else { if (cwd != NULL) { free(cwd); free(abs_filename); } return -4; } } ptr2 = NULL; if ((b_info = get_babel_story_info( release, serial, checksum, babel, file_is_zblorb)) != NULL) { title = (b_info->title == NULL ? empty_string : b_info->title); author = (b_info->author == NULL ? empty_string : b_info->author); language = (b_info->language == NULL ? empty_string : b_info->language); description = (b_info->description != NULL) ? b_info->description : empty_string; } else { if ((title = strrchr(abs_filename, '/')) == NULL) title = abs_filename; else title++; if ((ptr = strrchr(title, '.')) != NULL) { TRACE_LOG("strdup: %s\n", title); ptr2 = fizmo_strdup(title); ptr = strrchr(ptr2, '.'); if ( ( (strlen(ptr) == 3) && (ptr[1] == 'z') && (isdigit(ptr[2]) != 0) ) || (strcasecmp(ptr, ".dat") == 0) || (strcasecmp(ptr, ".zblorb") == 0) ) *ptr = '\0'; *ptr2 = toupper(*ptr2); title = ptr2; } author = empty_string; language = empty_string; description = empty_string; } add_entry_to_story_list( story_list, title, author, language, description, serial, version, length, checksum, release, abs_filename, file_is_zblorb ? NULL : blorb_filename, file_is_zblorb ? filetype_zblorb : filetype_raw, storyfile_timestamp); if (b_info != NULL) free_babel_story_info(b_info); if (ptr2 != NULL) free(ptr2); if (file_babel != NULL) free_babel_info(file_babel); if (cwd != NULL) { free(cwd); free(abs_filename); } return 0; }
struct z_story_list *update_fizmo_story_list() { #ifdef DISABLE_CONFIGFILES return NULL; #else // DISABLE_CONFIGFILES struct z_story_list *result; struct z_story_list_entry *entry; char *str, *str_copy, *path; z_file *file; struct babel_info *babel; int i; nof_files_found = 0; nof_files_searched = 0; nof_directories_searched = 0; ensure_dot_fizmo_dir_exists(); babel = load_babel_info(); if (babel_files_have_changed(babel) == true) { // Don't load current list of story, rebuild index with the newly // changed babel data. result = get_empty_z_story_list(); store_babel_info_timestamps(babel); } else { // Babel data is the same, use pre-indexed story list. result = get_z_story_list(); i = 0; while (i < result->nof_entries) { entry = result->entries[i]; if ((file = fsi->openfile( entry->filename, FILETYPE_DATA, FILEACCESS_READ)) == NULL) remove_entry_from_list(result, entry); else { fsi->closefile(file); i++; } } } if ((str = getenv("ZCODE_PATH")) == NULL) str = getenv("INFOCOM_PATH"); if (str != NULL) set_configuration_value("z-code-path", str); if ((str = getenv("ZCODE_ROOT_PATH")) != NULL) set_configuration_value("z-code-root-path", str); if ((str = get_configuration_value("z-code-path")) != NULL) { path = strtok(str, ":"); while (path != NULL) { TRACE_LOG("Counting for token \"%s\".\n", path); nof_files_found += count_files(path, false); path = strtok(NULL, ":"); } } if ((str = get_configuration_value("z-code-root-path")) != NULL) { str_copy = strdup(str); path = strtok(str_copy, ":"); while (path != NULL) { TRACE_LOG("Counting for token \"%s\".\n", path); nof_files_found += count_files(path, true); path = strtok(NULL, ":"); } free(str_copy); } TRACE_LOG("nof_files_found: %d, %d\n", nof_files_found, NUMBER_OF_FILES_TO_SHOW_PROGRESS_FOR); if (nof_files_found >= NUMBER_OF_FILES_TO_SHOW_PROGRESS_FOR) show_progress = true; else show_progress = false; //printf("\n"); // newline for \r-progress indicator //build_filelist(".", result, false, babel); if ((str = get_configuration_value("z-code-path")) != NULL) { str_copy = strdup(str); path = strtok(str_copy, ":"); while (path != NULL) { build_filelist(path, result, false, babel); path = strtok(NULL, ":"); } free(str_copy); } if ((str = get_configuration_value("z-code-root-path")) != NULL) { str_copy = strdup(str); path = strtok(str_copy, ":"); while (path != NULL) { build_filelist(path, result, true, babel); path = strtok(NULL, ":"); } free(str_copy); } if (show_progress == true) printf("\n"); TRACE_LOG("noffiles: %d\n", result->nof_entries); save_story_list(result); store_babel_info_timestamps(babel); free_babel_info(babel); return result; #endif // DISABLE_CONFIGFILES }
struct babel_info *load_babel_info() { struct babel_info *result = NULL; #ifndef DISABLE_BABEL char *cwd = NULL; char *config_dir_name = NULL; z_dir *config_dir; struct z_dir_ent z_dir_entry; time_t last_mod_timestamp; z_file *new_babel_doc_file; xmlDocPtr new_babel_doc; #ifndef DISABLE_CONFIGFILES config_dir_name = get_fizmo_config_dir_name(); #endif // DISABLE_CONFIGFILES if ((config_dir = fsi->open_dir(config_dir_name)) == NULL) return NULL; cwd = fsi->get_cwd(); if (fsi->ch_dir(config_dir_name) != 0) { fsi->close_dir(config_dir); free(cwd); return NULL; } result = (struct babel_info*)fizmo_malloc(sizeof(struct babel_info)); result->entries = NULL; result->entries_allocated = 0; result->nof_entries = 0; while (fsi->read_dir(&z_dir_entry, config_dir) == 0) { if ( (fsi->is_filename_directory(z_dir_entry.d_name) == false) && (strlen(z_dir_entry.d_name) >= 9) && (strcasecmp( z_dir_entry.d_name + strlen(z_dir_entry.d_name) - 9, ".iFiction") == 0) ) { if ((new_babel_doc = xmlReadFile( z_dir_entry.d_name, NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR)) != NULL) { if ((new_babel_doc_file = fsi->openfile( z_dir_entry.d_name, FILETYPE_DATA, FILEACCESS_READ)) == NULL) { free_babel_info(result); fsi->ch_dir(cwd); free(cwd); fsi->close_dir(config_dir); return NULL; } last_mod_timestamp = fsi->get_last_file_mod_timestamp(new_babel_doc_file); fsi->closefile(new_babel_doc_file); if ((add_doc_to_babel_info( new_babel_doc, result, last_mod_timestamp, z_dir_entry.d_name)) != 0) { xmlFreeDoc(new_babel_doc); free_babel_info(result); fsi->ch_dir(cwd); free(cwd); fsi->close_dir(config_dir); return NULL; } } } } fsi->ch_dir(cwd); free(cwd); fsi->close_dir(config_dir); #endif return result; }