struct z_story_list_entry *store_current_entry() { struct z_story_list_entry *result; if ((result = malloc(sizeof(struct z_story_list_entry))) == NULL) return NULL; //printf("storing %s, %d, %d\n", serial_input, release_input, length_input); result->release_number = release_input; result->serial = fizmo_strdup(unquoted_serial_input); result->z_code_version = version_input; result->length = length_input; result->checksum = checksum_input; result->title = fizmo_strdup(unquoted_title_input); result->author = fizmo_strdup(unquoted_author_input); result->language = fizmo_strdup(unquoted_language_input); result->description = fizmo_strdup(unquoted_description_input); result->filename = fizmo_strdup(unquoted_filename_input); result->blorbfile = fizmo_strdup(unquoted_blorbfile_input); result->filetype = fizmo_strdup(unquoted_filetype_input); //result->entry_line_index = line_index; result->storyfile_timestamp = storyfile_timestamp_input; return result; }
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_entry *add_entry_to_story_list( struct z_story_list *story_list, char *title, char *author, char *language, char *description, char *serial, int version, int length, uint16_t checksum, uint16_t release, char *story_filename, char *story_blorbfile, char *story_filetype, long storyfile_timestamp) //, int line_index) { void *ptr; struct z_story_list_entry *result; int insert_index; //printf("Adding %d:%s\n", story_list->nof_entries, story_filename); TRACE_LOG("Adding new story entry #%d: %s, \"%s\".\n", story_list->nof_entries, story_filename, description != NULL ? description : ""); if (story_list->nof_entries == story_list->nof_entries_allocated) { if ((ptr = (struct z_story_list_entry**)fizmo_realloc( story_list->entries, sizeof(struct z_story_list_entry*) * (story_list->nof_entries_allocated + 10))) == NULL) { TRACE_LOG("Cannot realloc.\n"); return NULL; } story_list->entries = ptr; story_list->nof_entries_allocated += 10; } if ((result = malloc(sizeof(struct z_story_list_entry))) == NULL) { TRACE_LOG("Cannot malloc.\n"); return NULL; } result->release_number = release; result->serial = fizmo_strdup(serial); result->z_code_version = version; result->length = length; result->checksum = checksum; result->title = fizmo_strdup(title); result->author = fizmo_strdup(author); result->language = fizmo_strdup(language); result->description = fizmo_strdup(description); result->filename = fizmo_strdup(story_filename); result->blorbfile = (story_blorbfile != NULL ? fizmo_strdup(story_blorbfile) : NULL); result->filetype = fizmo_strdup(story_filetype); result->storyfile_timestamp = storyfile_timestamp; insert_index = 0; while (insert_index < story_list->nof_entries) { if (strcmp(result->title, story_list->entries[insert_index]->title) < 0) break; insert_index++; } TRACE_LOG("Insert index: %d.\n", insert_index); if (insert_index < story_list->nof_entries) { TRACE_LOG("Move to %p from %p.\n", story_list->entries + insert_index + 1, story_list->entries + insert_index); memmove( story_list->entries + insert_index + 1, story_list->entries + insert_index, (story_list->nof_entries - insert_index) * sizeof(struct z_story_list_entry*)); } story_list->entries[insert_index] = result; story_list->nof_entries++; return result; }
static int add_doc_to_babel_info(xmlDocPtr new_babel_doc, struct babel_info *babel, time_t last_mod_timestamp, char *filename) { xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; char *xmlExpr = "/ifindex"; char *xmlNamespacedExpr = "/if:ifindex"; bool uses_if_namespace; struct babel_doc_entry *new_entry; // Check contents xpathCtx = xmlXPathNewContext(new_babel_doc); if(xpathCtx == NULL) { fprintf(stderr,"Error: unable to create new XPath context\n"); return -1; } if (xmlXPathRegisterNs( xpathCtx, (xmlChar*)"if", (xmlChar*)"http://babel.ifarchive.org/protocol/iFiction/") == -1) { fprintf(stderr,"Error: unable to create new namespace\n"); xmlXPathFreeContext(xpathCtx); return -1; } xpathObj = xmlXPathEvalExpression((xmlChar*)xmlExpr, xpathCtx); if (xpathObj == NULL) { xmlXPathFreeContext(xpathCtx); fprintf( stderr, "Error: unable to evaluate xpath expression \"%s\"\n", xmlExpr); return -1; } if (xmlXPathNodeSetGetLength(xpathObj->nodesetval) != 1) { // "/ifindex" was not found. Try "/if:ifindex". xmlXPathFreeObject(xpathObj); xpathObj = xmlXPathEvalExpression( (xmlChar*)xmlNamespacedExpr, xpathCtx); if (xpathObj == NULL) { xmlXPathFreeContext(xpathCtx); fprintf( stderr, "Error: unable to evaluate xpath expression \"%s\"\n", xmlNamespacedExpr); return -1; } if (xmlXPathNodeSetGetLength(xpathObj->nodesetval) != 1) { // Neither "/ifindex" nor "/if:ifindex" found. Skip this file. xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); return -1; } else uses_if_namespace = true; } else uses_if_namespace = false; xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); if (babel->nof_entries == babel->entries_allocated) { babel->entries = (struct babel_doc_entry**)fizmo_realloc( babel->entries, sizeof(struct babel_doc_entry*) * (babel->entries_allocated+10)); babel->entries_allocated += 10; } new_entry = (struct babel_doc_entry*)fizmo_malloc( sizeof(struct babel_doc_entry)); new_entry->babel_doc = new_babel_doc; new_entry->uses_if_namespace = uses_if_namespace; new_entry->timestamp = last_mod_timestamp; new_entry->filename = fizmo_strdup(filename); babel->entries[babel->nof_entries] = new_entry; babel->nof_entries++; return 0; }
int set_configuration_value(char *key, char* new_unexpanded_value) { int i, return_code, result; char *new_value = NULL; char buf[BUFSIZE]; short color_code; char *endptr; if (key == NULL) return -1; if (new_unexpanded_value != NULL) if ((new_value = expand_configuration_value(new_unexpanded_value)) == NULL) return -1; #ifdef ENABLE_TRACING TRACE_LOG("Setting configuration key \"%s\".\n", key); if (new_value != NULL) { TRACE_LOG("New value: %s at %p.\n", new_value, new_value); } #endif //ENABLE_TRACING i = 0; while (configuration_options[i].name != NULL) { TRACE_LOG("i:%d, name:%s.\n", i, configuration_options[i].name); if (strcmp(configuration_options[i].name, key) == 0) { // Parse option values which cannot be simply copied: if (strcmp(key, "locale") == 0) { TRACE_LOG("Trying to set locale to \"%s\".\n", new_value); return_code = (strcmp(get_configuration_value( "dont-set-locale-from-config"), "true") == 0) ? 0 : set_current_locale_name(new_value); free(new_value); return return_code; } else if (strcmp(key, "random-mode") == 0) { if (new_value == NULL) return -1; else if (strcmp(new_value, "random") == 0) { if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = new_value; seed_random_generator(); return 0; } else if (strcmp(new_value, "predictable") == 0) { if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = new_value; TRACE_LOG("stored value: %p.\n", configuration_options[i].value); seed_random_generator(); return 0; } else return -1; } else if (strcmp(key, "i18n-search-path") == 0) { // Forward to i18n, since this is in tools and cannot access the // "config.c" file. return_code = set_i18n_search_path(new_value); free(new_value); return return_code; } // Options for values which can simply be copied. else if ( (strcmp(key, "z-code-path") == 0) || (strcmp(key, "z-code-root-path") == 0) || (strcmp(key, "autosave-filename") == 0) || (strcmp(key, "savegame-path") == 0) || (strcmp(key, "savegame-default-filename") == 0) || (strcmp(key, "transcript-filename") == 0) || (strcmp(key, "save-text-history-paragraphs") == 0) || (strcmp(key, "input-command-filename") == 0) || (strcmp(key, "record-command-filename") == 0) ) { if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = new_value; return 0; } // Integer values else if ( (strcmp(key, "stream-2-line-width") == 0) || (strcmp(key, "stream-2-left-margin") == 0) || (strcmp(key, "max-undo-steps") == 0) ) { if (new_value == NULL) return -1; if (strlen(new_value) == 0) { free(new_value); return -1; } strtol(new_value, &endptr, 10); if (*endptr != 0) { free(new_value); return -1; } if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = new_value; return 0; } // Color options else if (strcmp(key, "foreground-color") == 0) { if (new_value == NULL) return -1; color_code = color_name_to_z_colour(new_value); free(new_value); if (color_code == -1) return -1; if (snprintf(buf, BUFSIZE, "%d", color_code) >= BUFSIZE) return -1; if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = fizmo_strdup(buf); default_foreground_colour = color_code; return 0; } else if (strcmp(key, "background-color") == 0) { if (new_value == NULL) return -1; color_code = color_name_to_z_colour(new_value); free(new_value); if (color_code == -1) return -1; if (snprintf(buf, BUFSIZE, "%d", color_code) >= BUFSIZE) return -1; if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = fizmo_strdup(buf); default_background_colour = color_code; return 0; } // Boolean options else if ( (strcmp(key, "disable-external-streams") == 0) || (strcmp(key, "disable-restore") == 0) || (strcmp(key, "disable-save") == 0) || (strcmp(key, "disable-sound") == 0) || (strcmp(key, "enable-font3-conversion") == 0) || (strcmp(key, "quetzal-umem") == 0) || (strcmp(key, "random-mode") == 0) || (strcmp(key, "restore-after-save-and-quit-file-before-read") == 0) || (strcmp(key, "save-and-quit-file-before-read") == 0) || (strcmp(key, "set-tandy-flag") == 0) || (strcmp(key, "start-command-recording-when-story-starts") == 0) || (strcmp(key, "start-script-when-story-starts") == 0) || (strcmp(key, "start-file-input-when-story-starts") == 0) || (strcmp(key, "disable-stream-2-hyphenation") == 0) || (strcmp(key, "disable-stream-2-wrap") == 0) || (strcmp(key, "sync-transcript") == 0) || (strcmp(key, "dont-set-locale-from-config") == 0) ) { if ( (new_value == NULL) || (*new_value == 0) || (strcmp(new_value, config_true_value) == 0) ) { if (new_value != NULL) free(new_value); if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = fizmo_strdup(config_true_value); return 0; } else if ((new_value != NULL) && (strcmp(new_value, config_false_value)==0)) { free(new_value); if (configuration_options[i].value != NULL) free(configuration_options[i].value); configuration_options[i].value = fizmo_strdup(config_false_value); return -1; } else { free(new_value); return -1; } } else { i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_UNKNOWN_CONFIGURATION_OPTION_P0S, -0x0101, key); } } i++; } if (active_interface != NULL) { result = active_interface->parse_config_parameter(key, new_value); if (result == -1) { i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_INVALID_VALUE_P0S_FOR_PARAMETER_P1S, -0x0101, key, new_value); } } if (active_sound_interface == NULL) return -2; else { result = active_sound_interface->parse_config_parameter(key, new_value); if (result == -1) { i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_INVALID_VALUE_P0S_FOR_PARAMETER_P1S, -0x0101, key, new_value); } } return result; }