コード例 #1
0
ファイル: filelist.c プロジェクト: chrender/libfizmo
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;
}
コード例 #2
0
ファイル: filelist.c プロジェクト: chrender/libfizmo
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;
}
コード例 #3
0
ファイル: filelist.c プロジェクト: chrender/libfizmo
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: config.c プロジェクト: dfjdejulio/fizmo
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;
}