/** * 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)); }
/** * @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 */ }