/**
 * Extract metadata from files.
 *
 * @param item entry we are processing
 * @return GNUNET_OK on success, GNUNET_SYSERR on fatal errors
 */
static int
extract_files (struct ScanTreeNode *item)
{  
  struct GNUNET_CONTAINER_MetaData *meta;
  ssize_t size;
  size_t slen;

  if (GNUNET_YES == item->is_directory)
  {
    /* for directories, we simply only descent, no extraction, no
       progress reporting */
    struct ScanTreeNode *pos;

    for (pos = item->children_head; NULL != pos; pos = pos->next)
      if (GNUNET_OK !=
	  extract_files (pos))
	return GNUNET_SYSERR;
    return GNUNET_OK;
  }
  
  /* this is the expensive operation, *afterwards* we'll check for aborts */
  meta = GNUNET_CONTAINER_meta_data_create ();
  if (NULL != plugins)
    EXTRACTOR_extract (plugins, item->filename, NULL, 0, &add_to_md, meta);
  slen = strlen (item->filename) + 1;
  size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
  if (-1 == size)
  {
    /* no meta data */
    GNUNET_CONTAINER_meta_data_destroy (meta);
    if (GNUNET_OK !=
	write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA,
		       item->filename, slen))
      return GNUNET_SYSERR;    
    return GNUNET_OK;
  }
  {
    char buf[size + slen];
    char *dst = &buf[slen];
    
    memcpy (buf, item->filename, slen);
    size = GNUNET_CONTAINER_meta_data_serialize (meta,
						 &dst, size,
						 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
    if (size < 0)
    {
      GNUNET_break (0);
      size = 0;
    }
    GNUNET_CONTAINER_meta_data_destroy (meta);
    if (GNUNET_OK !=
	write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA,
		       buf, 
		       slen + size))
      return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
void cMetainfoMenu::Display(void)
{
  cOsdMenu::Display();

  CallbackData data;

#ifdef HAVE_LIBEXTRACTOR
#  if EXTRACTOR_VERSION >= 0x00060000

  EXTRACTOR_PluginList * plugins;

  plugins = EXTRACTOR_plugin_add_defaults(EXTRACTOR_OPTION_DEFAULT_POLICY);
  EXTRACTOR_extract(plugins, m_Filename, NULL, 0, (EXTRACTOR_MetaDataProcessor)&extractor_callback_metainfo, &data);
  EXTRACTOR_plugin_remove_all(plugins); /* unload plugins */

#  else // EXTRACTOR_VERSION >= 0x00060000

  EXTRACTOR_ExtractorList * plugins;
  EXTRACTOR_KeywordList   * md_list;

  plugins = EXTRACTOR_loadDefaultLibraries();
  md_list = EXTRACTOR_getKeywords(plugins, m_Filename);
  md_list = EXTRACTOR_removeEmptyKeywords (md_list);
  md_list = EXTRACTOR_removeDuplicateKeywords(md_list, 0);
  md_list = EXTRACTOR_removeKeywordsOfType(md_list, EXTRACTOR_THUMBNAILS);

  while(md_list) {
    const char *key = EXTRACTOR_getKeywordTypeAsString(md_list->keywordType);
    if (key)
      data.Append(key, md_list->keyword);
    md_list = md_list->next;
  }

  EXTRACTOR_freeKeywords(md_list);
  EXTRACTOR_removeAll(plugins); /* unload plugins */

#  endif // EXTRACTOR_VERSION >= 0x00060000
#else // HAVE_LIBEXTRACTOR

  cString cmd;
  if(xc.IsPlaylistFile(m_Filename))
    cmd = cString::sprintf("file -b '%s'; cat '%s'", *m_Filename, *m_Filename);
  else if(xc.IsAudioFile(m_Filename))
    cmd = cString::sprintf("mp3info -x '%s' ; file -b '%s'", *m_Filename, *m_Filename);
  else if(xc.IsVideoFile(m_Filename))
    cmd = cString::sprintf("file -b '%s'; midentify '%s'", *m_Filename, *m_Filename);
  else if(xc.IsImageFile(m_Filename))
    cmd = cString::sprintf("file -b '%s'; identify '%s'", *m_Filename, *m_Filename);
  else
    cmd = cString::sprintf("file -b '%s'", *m_Filename);

  cPipe p;
  if(p.Open(*cmd, "r")) {
    data.text_len = fread(data.text, 1, data.text_size - 1, p);
    if (data.text_len > 0) {
      data.text[data.text_len] = 0;
      strreplace(data.text, ',', '\n');
    }
  }

#endif // HAVE_LIBEXTRACTOR

  DisplayMenu()->SetText(data.text, false);
  data.text = NULL;

  cStatus::MsgOsdTextItem(cString::sprintf("%s\n%s", tr("Metainfo"), *m_Filename));
}
Ejemplo n.º 3
0
/**
 * @return 0 on success, 1 on error.
 */
static int do_fork(struct EXTRACT_Process * proc) {
  int filedes1[2];
  int filedes2[2];
  char buffer[FILENAME_MAX+2];
  size_t pos;
  ssize_t ret;
  size_t slen;
  struct EXTRACTOR_PluginList * list;
  char * filename;
  struct AccuCtx acc_ctx;

#if DEBUG_IPC
  fprintf(stderr, "Forking!\n");
#endif
  if (0 != pipe(filedes1)) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "pipe",
		 strerror(errno));
    return 1;
  }
  if (0 != pipe(filedes2)) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "pipe",
		 strerror(errno));
    close(filedes1[0]);
    close(filedes1[1]);
    return 1;
  } 
  /* log before fork, just to avoid out-of-process problems
     with my_log */
  if (proc->do_default)
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_VERY_VERBOSE,
		 (_("Loading default set of libextractor plugins.\n")));
  if (proc->libs != NULL) 
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_VERY_VERBOSE,
		 _("Loading libextractor plugins: '%s'\n"),
		 proc->libs);  

  proc->pid = fork();
  if (proc->pid == -1) {
    proc->my_log(proc->log_ctx,
		 DOODLE_LOG_CRITICAL,
		 _("Call to '%s' failed: %s\n"),
		 "fork",
		 strerror(errno));
    close(filedes1[0]);
    close(filedes1[1]);
    close(filedes2[0]);
    close(filedes2[1]);
    return 1;
  }
  if (proc->pid != 0) {
    close(filedes1[1]);
    close(filedes2[0]);
    proc->send_pipe = filedes2[1];
    proc->read_pipe = filedes1[0];
    return 0;
  }
  /* we're now in the forked process! */
  close(filedes1[0]);
  close(filedes2[1]);
  list = NULL;

  if (proc->do_default)
    list = EXTRACTOR_plugin_add_defaults(EXTRACTOR_OPTION_DEFAULT_POLICY);
  if (proc->libs != NULL) 
    list = EXTRACTOR_plugin_add_config(list,
				       proc->libs,
				       EXTRACTOR_OPTION_DEFAULT_POLICY);  
  
  pos = 0;
  buffer[FILENAME_MAX + 1] = '\0';
  ret = read(filedes2[0], &buffer[pos], FILENAME_MAX + 1 - pos);
  while ( (-1 != ret) &&
	  (ret != 0) ) {
    pos += ret;
    slen = strlen(buffer) + 1;
    if (slen <= pos) {
      filename = strdup(buffer);
      memmove(buffer,
	      &buffer[slen],
	      pos - slen);
      pos = pos - slen;
      acc_ctx.count = 0;
      acc_ctx.size = 0;
      acc_ctx.keywords = NULL;
      acc_ctx.types = NULL;
      EXTRACTOR_extract(list,
			filename,
			NULL, 0,
			&accumulator,
			&acc_ctx);
      DO_WRITE(filedes1[1], &acc_ctx.count, sizeof(unsigned int));
      while (0 != acc_ctx.count--) {
	DO_WRITE(filedes1[1], 
		 &acc_ctx.types[acc_ctx.count],
		 sizeof(enum EXTRACTOR_MetaType));
	slen = strlen(acc_ctx.keywords[acc_ctx.count]);
	if (slen > MAX_SLEN)
	  slen = MAX_SLEN; /* cut off -- far too large! */
	DO_WRITE(filedes1[1], &slen, sizeof(size_t));
	DO_WRITE(filedes1[1], acc_ctx.keywords[acc_ctx.count], slen);
	free(acc_ctx.keywords[acc_ctx.count]);
      }
      free (acc_ctx.keywords);
      free (acc_ctx.types);
      acc_ctx.keywords = NULL;
      acc_ctx.types = NULL;
      acc_ctx.size = 0;
    }
    ret = read(filedes2[0], &buffer[pos], FILENAME_MAX + 1 - pos);
  }
  /* exit / cleanup */
 ERROR:
  free (acc_ctx.keywords);
  free (acc_ctx.types);
  EXTRACTOR_plugin_remove_all (list);
  close(filedes2[0]);
  close(filedes1[1]);
  /* never return - we were forked! */
  exit(0);
  return 1; /* eh, dead */
}