Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
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
}
Esempio n. 5
0
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;
}