/* This file is part of GNUnet. (C) 2010 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file src/fs/gnunet-fs-gtk_common.c * @brief Common functions used in various places * @author Christian Grothoff */ #include "gnunet-fs-gtk-common.h" /** * Converts metadata specified by @data of size @data_len * and saved in format @format to UTF-8 encoded string. * Works only for C-string and UTF8 metadata formats * (returns NULL for everything else). * Verifies UTF-8 strings. * * @param format format of the @data * @param data data to convert * @param data_len length of the data buffer (in bytes) * @return NULL if can't be converted, allocated string otherwise, * freeable with GNUNET_free* (). */ char * GNUNET_FS_GTK_dubious_meta_to_utf8 (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len) { switch (format) { case EXTRACTOR_METAFORMAT_UTF8: /* data must not contain NULLs (hence the -1) */ if (g_utf8_validate (data, data_len - 1, NULL)) return GNUNET_strdup (data); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to validate supposedly utf-8 string `%s' of length %u, assuming it to be a C string\n"), data, (unsigned int) data_len); format = EXTRACTOR_METAFORMAT_C_STRING; /* fall-through */ case EXTRACTOR_METAFORMAT_C_STRING: if (data_len > 0) { /* There are no guarantees that data is NULL-terminated, AFAIU, * so let's play it safe, shall we? */ char data_copy[data_len + 1]; memcpy (data_copy, data, data_len); data_copy[data_len] = '\0'; return GNUNET_GTK_from_loc_to_utf8 (data_copy); } break; default: break; } return NULL; } /** * Add meta data to list store. * * @param cls closure (the GtkListStore) * @param plugin_name name of the plugin that produced this value; * special values can be used (i.e. '' for zlib being * used in the main libextractor library and yielding * meta data). * @param type libextractor-type describing the meta data * @param format basic format information about data * @param data_mime_type mime-type of data (not of the original file); * can be NULL (if mime-type is not known) * @param data actual meta-data found * @param data_len number of bytes in data * @return 0 to continue (always) */ int GNUNET_FS_GTK_add_meta_data_to_list_store (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len) { GtkListStore *ls = GTK_LIST_STORE (cls); char *data_to_insert; data_to_insert = GNUNET_FS_GTK_dubious_meta_to_utf8 (format, data, data_len); if (NULL == data_to_insert) return 0; gtk_list_store_insert_with_values (ls, NULL, G_MAXINT, 0, type, 1, format, 2, EXTRACTOR_metatype_to_string (type), 3, data_to_insert, -1); GNUNET_free (data_to_insert); return 0; } /** * Convert the year from the spin button to an expiration * time (on midnight, January 1st of that year). * * @param spin button with an expiration year * @return expiration time in the usual GNUnet format */ struct GNUNET_TIME_Absolute GNUNET_FS_GTK_get_expiration_time (GtkSpinButton * spin) { struct GNUNET_TIME_Absolute ret; int year; year = gtk_spin_button_get_value_as_int (spin); GNUNET_assert (year >= 0); ret = GNUNET_FS_year_to_time ((unsigned int) year); GNUNET_break (GNUNET_TIME_absolute_get ().abs_value < ret.abs_value); return ret; } /** * Initialize the 'expiration_year_adjustment' of the given * builder to have a lower range of current-year+1 and a * default of current-year+2. * * @param builder builder object for which we should manipulate * the adjustment */ void GNUNET_FS_GTK_setup_expiration_year_adjustment (GtkBuilder * builder) { GtkAdjustment *aj; unsigned int year; year = GNUNET_FS_get_current_year (); aj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "expiration_year_adjustment")); gtk_adjustment_set_value (aj, year + 2); gtk_adjustment_set_lower (aj, year + 1); } /** * Obtain pixbuf from thumbnail data in meta data. * * @param meta input meta data * @return NULL on error, otherwise the embedded thumbnail */ GdkPixbuf * GNUNET_FS_GTK_get_thumbnail_from_meta_data (const struct GNUNET_CONTAINER_MetaData *meta) { GdkPixbuf *pixbuf; GdkPixbufLoader *loader; size_t ts; unsigned char *thumb; thumb = NULL; ts = GNUNET_CONTAINER_meta_data_get_thumbnail (meta, &thumb); if (0 == ts) return NULL; loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, (const guchar *) thumb, ts, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); gdk_pixbuf_loader_close (loader, NULL); if (NULL != pixbuf) g_object_ref (pixbuf); g_object_unref (loader); GNUNET_free (thumb); return pixbuf; } /** * mmap the given file and run the GNUNET_FS_directory_list_contents * function on it. * * @param filename name with the directory * @param dep function to call on each entry * @param dep_cls closure for 'dep' */ void GNUNET_FS_GTK_mmap_and_scan (const char *filename, GNUNET_FS_DirectoryEntryProcessor dep, void *dep_cls) { struct GNUNET_DISK_FileHandle *fh; struct GNUNET_DISK_MapHandle *mh; uint64_t fsize; void *ddata; if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_YES)) { GNUNET_break (0); return; } if (NULL == (fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE))) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); return; } if (NULL == (ddata = GNUNET_DISK_file_map (fh, &mh, GNUNET_DISK_MAP_TYPE_READ, (size_t) fsize))) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mmap", filename); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); return; } if (GNUNET_SYSERR == GNUNET_FS_directory_list_contents ((size_t) fsize, ddata, 0, dep, dep_cls)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Selected file `%s' is not a GNUnet directory!\n"), filename); } GNUNET_break (GNUNET_OK == GNUNET_DISK_file_unmap (mh)); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); } /* end of gnunet-fs-gtk-common.c */