GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
meta_data.c File Reference

Storing of meta data. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_fs_service.h"
Include dependency graph for meta_data.c:

Go to the source code of this file.

Data Structures

struct  MetaItem
 Meta data item. More...
 
struct  GNUNET_FS_MetaData
 Meta data to associate with a file, directory or namespace. More...
 
struct  MetaDataHeader
 Header for serialized meta data. More...
 
struct  MetaDataEntry
 Entry of serialized meta data. More...
 

Macros

#define MAX_META_DATA   (1024 * 1024)
 Maximum size allowed for meta data written/read from disk.
 
#define LOG(kind, ...)
 
#define HEADER_COMPRESSED   0x80000000
 Flag in 'version' that indicates compressed meta-data.
 
#define HEADER_VERSION_MASK   0x7FFFFFFF
 Bits in 'version' that give the version number.
 

Functions

struct GNUNET_FS_MetaDataGNUNET_FS_meta_data_create ()
 Create a fresh struct FS_MetaData token.
 
static void meta_item_free (struct MetaItem *mi)
 Free meta data item.
 
static void invalidate_sbuf (struct GNUNET_FS_MetaData *md)
 The meta data has changed, invalidate its serialization buffer.
 
void GNUNET_FS_meta_data_destroy (struct GNUNET_FS_MetaData *md)
 Free meta data.
 
void GNUNET_FS_meta_data_clear (struct GNUNET_FS_MetaData *md)
 Remove all items in the container.
 
int GNUNET_FS_meta_data_test_equal (const struct GNUNET_FS_MetaData *md1, const struct GNUNET_FS_MetaData *md2)
 Test if two MDs are equal.
 
int GNUNET_FS_meta_data_insert (struct GNUNET_FS_MetaData *md, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_size)
 Extend metadata.
 
static int merge_helper (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_size)
 Merge given meta data.
 
void GNUNET_FS_meta_data_merge (struct GNUNET_FS_MetaData *md, const struct GNUNET_FS_MetaData *in)
 Extend metadata.
 
int GNUNET_FS_meta_data_delete (struct GNUNET_FS_MetaData *md, enum EXTRACTOR_MetaType type, const char *data, size_t data_size)
 Remove an item.
 
void GNUNET_FS_meta_data_add_publication_date (struct GNUNET_FS_MetaData *md)
 Add the current time as the publication date to the meta-data.
 
int GNUNET_FS_meta_data_iterate (const struct GNUNET_FS_MetaData *md, EXTRACTOR_MetaDataProcessor iter, void *iter_cls)
 Iterate over MD entries.
 
char * GNUNET_FS_meta_data_get_by_type (const struct GNUNET_FS_MetaData *md, enum EXTRACTOR_MetaType type)
 Get the first MD entry of the given type.
 
char * GNUNET_FS_meta_data_get_first_by_types (const struct GNUNET_FS_MetaData *md,...)
 Get the first matching MD entry of the given types.
 
size_t GNUNET_FS_meta_data_get_thumbnail (const struct GNUNET_FS_MetaData *md, unsigned char **thumb)
 Get a thumbnail from the meta-data (if present).
 
struct GNUNET_FS_MetaDataGNUNET_FS_meta_data_duplicate (const struct GNUNET_FS_MetaData *md)
 Duplicate a struct GNUNET_FS_MetaData.
 
ssize_t GNUNET_FS_meta_data_serialize (const struct GNUNET_FS_MetaData *md, char **target, size_t max, enum GNUNET_FS_MetaDataSerializationOptions opt)
 Serialize meta-data to target.
 
ssize_t GNUNET_FS_meta_data_get_serialized_size (const struct GNUNET_FS_MetaData *md)
 Get the size of the full meta-data in serialized form.
 
struct GNUNET_FS_MetaDataGNUNET_FS_meta_data_deserialize (const char *input, size_t size)
 Deserialize meta-data.
 
enum GNUNET_GenericReturnValue GNUNET_FS_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, struct GNUNET_FS_MetaData **result)
 Read a metadata container.
 
enum GNUNET_GenericReturnValue GNUNET_FS_write_meta_data (struct GNUNET_BIO_WriteHandle *h, const char *what, const struct GNUNET_FS_MetaData *m)
 Write a metadata container.
 
static int read_spec_handler_meta_data (void *cls, struct GNUNET_BIO_ReadHandle *h, const char *what, void *target, size_t target_size)
 Function used internally to read a metadata container from within a read spec.
 
struct GNUNET_BIO_ReadSpec GNUNET_FS_read_spec_meta_data (const char *what, struct GNUNET_FS_MetaData **result)
 Create the specification to read a metadata container.
 
static int write_spec_handler_meta_data (void *cls, struct GNUNET_BIO_WriteHandle *h, const char *what, void *source, size_t source_size)
 Function used internally to write a metadata container from within a write spec.
 
struct GNUNET_BIO_WriteSpec GNUNET_FS_write_spec_meta_data (const char *what, const struct GNUNET_FS_MetaData *m)
 Create the specification to write a metadata container.
 

Detailed Description

Storing of meta data.

Author
Christian Grothoff
Martin Schanzenbach

Definition in file meta_data.c.

Macro Definition Documentation

◆ MAX_META_DATA

#define MAX_META_DATA   (1024 * 1024)

Maximum size allowed for meta data written/read from disk.

File-sharing limits to 64k, so this should be rather generous.

Definition at line 35 of file meta_data.c.

◆ LOG

#define LOG (   kind,
  ... 
)
Value:
GNUNET_log_from (kind, "fs-meta-data", \
__VA_ARGS__)
#define GNUNET_log_from(kind, comp,...)

Definition at line 38 of file meta_data.c.

45{
49 struct MetaItem *next;
50
54 struct MetaItem *prev;
55
59 char *plugin_name;
60
64 char *mime_type;
65
69 char *data;
70
74 size_t data_size;
75
80
85};
86
91{
95 struct MetaItem *items_head;
96
100 struct MetaItem *items_tail;
101
106 char *sbuf;
107
111 size_t sbuf_size;
112
116 unsigned int item_count;
117};
118
119
125struct GNUNET_FS_MetaData *
127{
128 return GNUNET_new (struct GNUNET_FS_MetaData);
129}
130
131
137static void
138meta_item_free (struct MetaItem *mi)
139{
142 GNUNET_free (mi->data);
143 GNUNET_free (mi);
144}
145
146
153static void
155{
156 if (NULL == md->sbuf)
157 return;
158 GNUNET_free (md->sbuf);
159 md->sbuf = NULL;
160 md->sbuf_size = 0;
161}
162
163
164void
166{
167 struct MetaItem *pos;
168
169 if (NULL == md)
170 return;
171 while (NULL != (pos = md->items_head))
172 {
174 meta_item_free (pos);
175 }
176 GNUNET_free (md->sbuf);
177 GNUNET_free (md);
178}
179
180
181void
183{
184 struct MetaItem *mi;
185
186 if (NULL == md)
187 return;
188 while (NULL != (mi = md->items_head))
189 {
191 meta_item_free (mi);
192 }
193 GNUNET_free (md->sbuf);
194 memset (md, 0, sizeof(struct GNUNET_FS_MetaData));
195}
196
197
198int
200 *md1,
201 const struct GNUNET_FS_MetaData
202 *md2)
203{
204 struct MetaItem *i;
205 struct MetaItem *j;
206 int found;
207
208 if (md1 == md2)
209 return GNUNET_YES;
210 if (md1->item_count != md2->item_count)
211 return GNUNET_NO;
212 for (i = md1->items_head; NULL != i; i = i->next)
213 {
214 found = GNUNET_NO;
215 for (j = md2->items_head; NULL != j; j = j->next)
216 {
217 if ((i->type == j->type) && (i->format == j->format) &&
218 (i->data_size == j->data_size) &&
219 (0 == memcmp (i->data, j->data, i->data_size)))
220 {
221 found = GNUNET_YES;
222 break;
223 }
224 if (j->data_size < i->data_size)
225 break; /* elements are sorted by (decreasing) size... */
226 }
227 if (GNUNET_NO == found)
228 return GNUNET_NO;
229 }
230 return GNUNET_YES;
231}
232
233
252int
254 const char *plugin_name,
257 const char *data_mime_type, const char *data,
258 size_t data_size)
259{
260 struct MetaItem *pos;
261 struct MetaItem *mi;
262 char *p;
263
266 GNUNET_break ('\0' == data[data_size - 1]);
267
268 for (pos = md->items_head; NULL != pos; pos = pos->next)
269 {
270 if (pos->data_size < data_size)
271 break; /* elements are sorted by size in the list */
272 if ((pos->type == type) && (pos->data_size == data_size) &&
273 (0 == memcmp (pos->data, data, data_size)))
274 {
275 if ((NULL == pos->mime_type) && (NULL != data_mime_type))
276 {
277 pos->mime_type = GNUNET_strdup (data_mime_type);
278 invalidate_sbuf (md);
279 }
282 {
284 invalidate_sbuf (md);
285 }
286 return GNUNET_SYSERR;
287 }
288 }
289 md->item_count++;
290 mi = GNUNET_new (struct MetaItem);
291 mi->type = type;
292 mi->format = format;
293 mi->data_size = data_size;
294 if (NULL == pos)
296 md->items_tail,
297 mi);
298 else
300 md->items_tail,
301 pos->prev,
302 mi);
303 mi->mime_type =
304 (NULL == data_mime_type) ? NULL : GNUNET_strdup (data_mime_type);
305 mi->plugin_name = (NULL == plugin_name) ? NULL : GNUNET_strdup (plugin_name);
308 /* change all dir separators to POSIX style ('/') */
311 {
312 p = mi->data;
313 while (('\0' != *p) && (p < mi->data + data_size))
314 {
315 if ('\\' == *p)
316 *p = '/';
317 p++;
318 }
319 }
320 invalidate_sbuf (md);
321 return GNUNET_OK;
322}
323
324
341static int
342merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type,
343 enum EXTRACTOR_MetaFormat format, const char *data_mime_type,
344 const char *data, size_t data_size)
345{
346 struct GNUNET_FS_MetaData *md = cls;
347
348 (void) GNUNET_FS_meta_data_insert (md, plugin_name, type, format,
349 data_mime_type, data, data_size);
350 return 0;
351}
352
353
354void
356 const struct GNUNET_FS_MetaData *in)
357{
359}
360
361
362int
365 const char *data, size_t data_size)
366{
367 struct MetaItem *pos;
368
369 for (pos = md->items_head; NULL != pos; pos = pos->next)
370 {
371 if (pos->data_size < data_size)
372 break; /* items are sorted by (decreasing) size */
373 if ((pos->type == type) &&
374 ((NULL == data) ||
375 ((pos->data_size == data_size) &&
376 (0 == memcmp (pos->data, data, data_size)))))
377 {
379 meta_item_free (pos);
380 md->item_count--;
381 invalidate_sbuf (md);
382 return GNUNET_OK;
383 }
384 }
385 return GNUNET_SYSERR;
386}
387
388
389void
392{
393 const char *dat;
394 struct GNUNET_TIME_Absolute t;
395
399 NULL, 0);
401 GNUNET_FS_meta_data_insert (md, "<gnunet>",
403 EXTRACTOR_METAFORMAT_UTF8, "text/plain",
404 dat, strlen (dat) + 1);
405}
406
407
416int
419 void *iter_cls)
420{
421 struct MetaItem *pos;
422
423 if (NULL == md)
424 return 0;
425 if (NULL == iter)
426 return md->item_count;
427 for (pos = md->items_head; NULL != pos; pos = pos->next)
428 if (0 !=
429 iter (iter_cls, pos->plugin_name, pos->type, pos->format,
430 pos->mime_type, pos->data, pos->data_size))
431 return md->item_count;
432 return md->item_count;
433}
434
435
436char *
440{
441 struct MetaItem *pos;
442
443 if (NULL == md)
444 return NULL;
445 for (pos = md->items_head; NULL != pos; pos = pos->next)
446 if ((type == pos->type) &&
449 return GNUNET_strdup (pos->data);
450 return NULL;
451}
452
453
454char *
457 ...)
458{
459 char *ret;
460 va_list args;
461 int type;
462
463 if (NULL == md)
464 return NULL;
465 ret = NULL;
466 va_start (args, md);
467 while (1)
468 {
469 type = va_arg (args, int);
470 if (-1 == type)
471 break;
472 if (NULL != (ret = GNUNET_FS_meta_data_get_by_type (md, type)))
473 break;
474 }
475 va_end (args);
476 return ret;
477}
478
479
488size_t
490 *md, unsigned char **thumb)
491{
492 struct MetaItem *pos;
493 struct MetaItem *match;
494
495 if (NULL == md)
496 return 0;
497 match = NULL;
498 for (pos = md->items_head; NULL != pos; pos = pos->next)
499 {
500 if ((NULL != pos->mime_type) &&
501 (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) &&
503 {
504 if (NULL == match)
505 match = pos;
506 else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
508 match = pos;
509 }
510 }
511 if ((NULL == match) || (0 == match->data_size))
512 return 0;
513 *thumb = GNUNET_malloc (match->data_size);
514 GNUNET_memcpy (*thumb, match->data, match->data_size);
515 return match->data_size;
516}
517
518
525struct GNUNET_FS_MetaData *
527 *md)
528{
529 struct GNUNET_FS_MetaData *ret;
530 struct MetaItem *pos;
531
532 if (NULL == md)
533 return NULL;
535 for (pos = md->items_tail; NULL != pos; pos = pos->prev)
537 pos->format, pos->mime_type, pos->data,
538 pos->data_size);
539 return ret;
540}
541
542
546#define HEADER_COMPRESSED 0x80000000
547
548
552#define HEADER_VERSION_MASK 0x7FFFFFFF
553
554
558struct MetaDataHeader
559{
569 uint32_t version;
570
574 uint32_t entries;
575
579 uint32_t size;
580
586};
587
588
592struct MetaDataEntry
593{
597 uint32_t type;
598
602 uint32_t format;
603
607 uint32_t data_size;
608
612 uint32_t plugin_name_len;
613
617 uint32_t mime_type_len;
618};
619
620
635ssize_t
637 *md, char **target, size_t max,
638 enum
640 opt)
641{
642 struct GNUNET_FS_MetaData *vmd;
643 struct MetaItem *pos;
644 struct MetaDataHeader ihdr;
645 struct MetaDataHeader *hdr;
646 struct MetaDataEntry *ent;
647 char *dst;
648 unsigned int i;
649 uint64_t msize;
650 size_t off;
651 char *mdata;
652 char *cdata;
653 size_t mlen;
654 size_t plen;
655 size_t size;
656 size_t left;
657 size_t clen;
658 size_t rlen;
659 int comp;
660
661 if (max < sizeof(struct MetaDataHeader))
662 return GNUNET_SYSERR; /* far too small */
663 if (NULL == md)
664 return 0;
665
666 if (NULL != md->sbuf)
667 {
668 /* try to use serialization cache */
669 if (md->sbuf_size <= max)
670 {
671 if (NULL == *target)
672 *target = GNUNET_malloc (md->sbuf_size);
673 GNUNET_memcpy (*target, md->sbuf, md->sbuf_size);
674 return md->sbuf_size;
675 }
676 if (0 == (opt & GNUNET_FS_META_DATA_SERIALIZE_PART))
677 return GNUNET_SYSERR; /* can say that this will fail */
678 /* need to compute a partial serialization, sbuf useless ... */
679 }
680 dst = NULL;
681 msize = 0;
682 for (pos = md->items_tail; NULL != pos; pos = pos->prev)
683 {
684 msize += sizeof(struct MetaDataEntry);
685 msize += pos->data_size;
686 if (NULL != pos->plugin_name)
687 msize += strlen (pos->plugin_name) + 1;
688 if (NULL != pos->mime_type)
689 msize += strlen (pos->mime_type) + 1;
690 }
691 size = (size_t) msize;
692 if (size != msize)
693 {
694 GNUNET_break (0); /* integer overflow */
695 return GNUNET_SYSERR;
696 }
698 {
699 /* too large to be processed */
700 return GNUNET_SYSERR;
701 }
702 ent = GNUNET_malloc (size);
703 mdata = (char *) &ent[md->item_count];
704 off = size - (md->item_count * sizeof(struct MetaDataEntry));
705 i = 0;
706 for (pos = md->items_head; NULL != pos; pos = pos->next)
707 {
708 ent[i].type = htonl ((uint32_t) pos->type);
709 ent[i].format = htonl ((uint32_t) pos->format);
710 ent[i].data_size = htonl ((uint32_t) pos->data_size);
711 if (NULL == pos->plugin_name)
712 plen = 0;
713 else
714 plen = strlen (pos->plugin_name) + 1;
715 ent[i].plugin_name_len = htonl ((uint32_t) plen);
716 if (NULL == pos->mime_type)
717 mlen = 0;
718 else
719 mlen = strlen (pos->mime_type) + 1;
720 ent[i].mime_type_len = htonl ((uint32_t) mlen);
721 off -= pos->data_size;
722 if ((EXTRACTOR_METAFORMAT_UTF8 == pos->format) ||
724 GNUNET_break ('\0' == pos->data[pos->data_size - 1]);
725 GNUNET_memcpy (&mdata[off], pos->data, pos->data_size);
726 off -= plen;
727 if (NULL != pos->plugin_name)
728 GNUNET_memcpy (&mdata[off], pos->plugin_name, plen);
729 off -= mlen;
730 if (NULL != pos->mime_type)
731 GNUNET_memcpy (&mdata[off], pos->mime_type, mlen);
732 i++;
733 }
734 GNUNET_assert (0 == off);
735
736 clen = 0;
737 cdata = NULL;
738 left = size;
739 i = 0;
740 for (pos = md->items_head; NULL != pos; pos = pos->next)
741 {
742 comp = GNUNET_NO;
744 comp = GNUNET_try_compression ((const char *) &ent[i],
745 left,
746 &cdata,
747 &clen);
748
749 if ((NULL == md->sbuf) && (0 == i))
750 {
751 /* fill 'sbuf'; this "modifies" md, but since this is only
752 * an internal cache we will cast away the 'const' instead
753 * of making the API look strange. */
754 vmd = (struct GNUNET_FS_MetaData *) md;
755 hdr = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
756 hdr->size = htonl (left);
757 hdr->entries = htonl (md->item_count);
758 if (GNUNET_YES == comp)
759 {
760 GNUNET_assert (clen < left);
761 hdr->version = htonl (2 | HEADER_COMPRESSED);
762 GNUNET_memcpy (&hdr[1], cdata, clen);
763 vmd->sbuf_size = clen + sizeof(struct MetaDataHeader);
764 }
765 else
766 {
767 hdr->version = htonl (2);
768 GNUNET_memcpy (&hdr[1], &ent[0], left);
769 vmd->sbuf_size = left + sizeof(struct MetaDataHeader);
770 }
771 vmd->sbuf = (char *) hdr;
772 }
773
774 if (((left + sizeof(struct MetaDataHeader)) <= max) ||
775 ((GNUNET_YES == comp) && (clen <= max)))
776 {
777 /* success, this now fits! */
778 if (GNUNET_YES == comp)
779 {
780 if (NULL == dst)
781 dst = GNUNET_malloc (clen + sizeof(struct MetaDataHeader));
782 hdr = (struct MetaDataHeader *) dst;
783 hdr->version = htonl (2 | HEADER_COMPRESSED);
784 hdr->size = htonl (left);
785 hdr->entries = htonl (md->item_count - i);
786 GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], cdata, clen);
787 GNUNET_free (cdata);
788 cdata = NULL;
789 GNUNET_free (ent);
790 rlen = clen + sizeof(struct MetaDataHeader);
791 }
792 else
793 {
794 if (NULL == dst)
795 dst = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
796 hdr = (struct MetaDataHeader *) dst;
797 hdr->version = htonl (2);
798 hdr->entries = htonl (md->item_count - i);
799 hdr->size = htonl (left);
800 GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], &ent[i], left);
801 GNUNET_free (ent);
802 rlen = left + sizeof(struct MetaDataHeader);
803 }
804 if (NULL != *target)
805 {
806 if (GNUNET_YES == comp)
807 GNUNET_memcpy (*target, dst, clen + sizeof(struct MetaDataHeader));
808 else
809 GNUNET_memcpy (*target, dst, left + sizeof(struct MetaDataHeader));
810 GNUNET_free (dst);
811 }
812 else
813 {
814 *target = dst;
815 }
816 return rlen;
817 }
818
819 if (0 == (opt & GNUNET_FS_META_DATA_SERIALIZE_PART))
820 {
821 /* does not fit! */
822 GNUNET_free (ent);
823 if (NULL != cdata)
824 GNUNET_free (cdata);
825 cdata = NULL;
826 return GNUNET_SYSERR;
827 }
828
829 /* next iteration: ignore the corresponding meta data at the
830 * end and try again without it */
831 left -= sizeof(struct MetaDataEntry);
832 left -= pos->data_size;
833 if (NULL != pos->plugin_name)
834 left -= strlen (pos->plugin_name) + 1;
835 if (NULL != pos->mime_type)
836 left -= strlen (pos->mime_type) + 1;
837
838 if (NULL != cdata)
839 GNUNET_free (cdata);
840 cdata = NULL;
841 i++;
842 }
843 GNUNET_free (ent);
844
845 /* nothing fit, only write header! */
846 ihdr.version = htonl (2);
847 ihdr.entries = htonl (0);
848 ihdr.size = htonl (0);
849 if (NULL == *target)
850 *target = (char *) GNUNET_new (struct MetaDataHeader);
851 GNUNET_memcpy (*target, &ihdr, sizeof(struct MetaDataHeader));
852 return sizeof(struct MetaDataHeader);
853}
854
855
856ssize_t
859{
860 ssize_t ret;
861 char *ptr;
862
863 if (NULL != md->sbuf)
864 return md->sbuf_size;
865 ptr = NULL;
866 ret =
869 if (-1 != ret)
870 GNUNET_free (ptr);
871 return ret;
872}
873
874
883struct GNUNET_FS_MetaData *
884GNUNET_FS_meta_data_deserialize (const char *input, size_t size)
885{
886 struct GNUNET_FS_MetaData *md;
887 struct MetaDataHeader hdr;
888 struct MetaDataEntry ent;
889 uint32_t ic;
890 uint32_t i;
891 char *data;
892 const char *cdata;
893 uint32_t version;
894 uint32_t dataSize;
895 int compressed;
896 size_t left;
897 uint32_t mlen;
898 uint32_t plen;
899 uint32_t dlen;
900 const char *mdata;
901 const char *meta_data;
902 const char *plugin_name;
903 const char *mime_type;
905
906 if (size < sizeof(struct MetaDataHeader))
907 return NULL;
908 GNUNET_memcpy (&hdr, input, sizeof(struct MetaDataHeader));
909 version = ntohl (hdr.version) & HEADER_VERSION_MASK;
910 compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0;
911
912 if (1 == version)
913 return NULL; /* null pointer */
914 if (2 != version)
915 {
916 GNUNET_break_op (0); /* unsupported version */
917 return NULL;
918 }
919
920 ic = ntohl (hdr.entries);
921 dataSize = ntohl (hdr.size);
922 if (((sizeof(struct MetaDataEntry) * ic) > dataSize) ||
923 ((0 != ic) &&
924 (dataSize / ic < sizeof(struct MetaDataEntry))))
925 {
926 GNUNET_break_op (0);
927 return NULL;
928 }
929
930 if (compressed)
931 {
932 if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
933 {
934 /* make sure we don't blow our memory limit because of a mal-formed
935 * message... */
936 GNUNET_break_op (0);
937 return NULL;
938 }
939 data =
940 GNUNET_decompress ((const char *) &input[sizeof(struct MetaDataHeader)],
941 size - sizeof(struct MetaDataHeader),
942 dataSize);
943 if (NULL == data)
944 {
945 GNUNET_break_op (0);
946 return NULL;
947 }
948 cdata = data;
949 }
950 else
951 {
952 data = NULL;
953 cdata = (const char *) &input[sizeof(struct MetaDataHeader)];
954 if (dataSize != size - sizeof(struct MetaDataHeader))
955 {
956 GNUNET_break_op (0);
957 return NULL;
958 }
959 }
960
962 left = dataSize - ic * sizeof(struct MetaDataEntry);
963 mdata = &cdata[ic * sizeof(struct MetaDataEntry)];
964 for (i = 0; i < ic; i++)
965 {
966 GNUNET_memcpy (&ent, &cdata[i * sizeof(struct MetaDataEntry)],
967 sizeof(struct MetaDataEntry));
968 format = ntohl (ent.format);
972 {
973 GNUNET_break_op (0);
974 break;
975 }
976 dlen = ntohl (ent.data_size);
977 plen = ntohl (ent.plugin_name_len);
978 mlen = ntohl (ent.mime_type_len);
979 if (dlen > left)
980 {
981 GNUNET_break_op (0);
982 break;
983 }
984 left -= dlen;
985 meta_data = &mdata[left];
988 {
989 if (0 == dlen)
990 {
991 GNUNET_break_op (0);
992 break;
993 }
994 if ('\0' != meta_data[dlen - 1])
995 {
996 GNUNET_break_op (0);
997 break;
998 }
999 }
1000 if (plen > left)
1001 {
1002 GNUNET_break_op (0);
1003 break;
1004 }
1005 left -= plen;
1006 if ((plen > 0) && ('\0' != mdata[left + plen - 1]))
1007 {
1008 GNUNET_break_op (0);
1009 break;
1010 }
1011 if (0 == plen)
1012 plugin_name = NULL;
1013 else
1014 plugin_name = &mdata[left];
1015
1016 if (mlen > left)
1017 {
1018 GNUNET_break_op (0);
1019 break;
1020 }
1021 left -= mlen;
1022 if ((mlen > 0) && ('\0' != mdata[left + mlen - 1]))
1023 {
1024 GNUNET_break_op (0);
1025 break;
1026 }
1027 if (0 == mlen)
1028 mime_type = NULL;
1029 else
1030 mime_type = &mdata[left];
1032 ntohl (ent.type), format,
1033 mime_type,
1034 meta_data, dlen);
1035 }
1036 GNUNET_free (data);
1037 return md;
1038}
1039
1040
1051 const char *what,
1052 struct GNUNET_FS_MetaData **result)
1053{
1054 uint32_t size;
1055 char *buf;
1056 char *emsg;
1057 struct GNUNET_FS_MetaData *meta;
1058
1060 _ ("metadata length"),
1061 (int32_t *) &size))
1062 return GNUNET_SYSERR;
1063 if (0 == size)
1064 {
1065 *result = NULL;
1066 return GNUNET_OK;
1067 }
1068 if (MAX_META_DATA < size)
1069 {
1070 GNUNET_asprintf (&emsg,
1071 _ (
1072 "Serialized metadata `%s' larger than allowed (%u > %u)\n"),
1073 what,
1074 size,
1077 GNUNET_free (emsg);
1078 return GNUNET_SYSERR;
1079 }
1080 buf = GNUNET_malloc (size);
1081 if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, size))
1082 {
1083 GNUNET_free (buf);
1084 return GNUNET_SYSERR;
1085 }
1087 if (NULL == meta)
1088 {
1089 GNUNET_free (buf);
1091 _ ("Failed to deserialize metadata `%s'"), what);
1092 return GNUNET_SYSERR;
1093 }
1094 GNUNET_free (buf);
1095 *result = meta;
1096 return GNUNET_OK;
1097}
1098
1099
1110 const char *what,
1111 const struct GNUNET_FS_MetaData *m)
1112{
1113 ssize_t size;
1114 char *buf;
1115
1116 if (m == NULL)
1117 return GNUNET_BIO_write_int32 (h, _ ("metadata length"), 0);
1118 buf = NULL;
1120 &buf,
1124 "Serialized %lld bytes of metadata",
1125 (long long) size);
1126
1127 if (-1 == size)
1128 {
1129 GNUNET_free (buf);
1131 "Failed to serialize metadata `%s'",
1132 what);
1133 return GNUNET_SYSERR;
1134 }
1135 if ( (GNUNET_OK !=
1137 "metadata length",
1138 (uint32_t) size)) ||
1139 (GNUNET_OK !=
1141 what,
1142 buf,
1143 size)) )
1144 {
1145 GNUNET_free (buf);
1146 return GNUNET_SYSERR;
1147 }
1148 GNUNET_free (buf);
1149 return GNUNET_OK;
1150}
1151
1152
1164static int
1166 struct GNUNET_BIO_ReadHandle *h,
1167 const char *what,
1168 void *target,
1169 size_t target_size)
1170{
1171 struct GNUNET_FS_MetaData **result = target;
1172 return GNUNET_FS_read_meta_data (h, what, result);
1173}
1174
1175
1185 struct GNUNET_FS_MetaData **result)
1186{
1187 struct GNUNET_BIO_ReadSpec rs = {
1189 .cls = NULL,
1190 .target = result,
1191 .size = 0,
1192 };
1193
1194 return rs;
1195}
1196
1197
1209static int
1211 struct GNUNET_BIO_WriteHandle *h,
1212 const char *what,
1213 void *source,
1214 size_t source_size)
1215{
1216 const struct GNUNET_FS_MetaData *m = source;
1217 return GNUNET_FS_write_meta_data (h, what, m);
1218}
1219
1220
1223 const struct GNUNET_FS_MetaData *m)
1224{
1225 struct GNUNET_BIO_WriteSpec ws = {
1227 .cls = NULL,
1228 .what = what,
1229 .source = (void *) m,
1230 .source_size = 0,
1231 };
1232
1233 return ws;
1234}
1235
1236
1237/* end of meta_data.c */
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static char * plugin_name
Name of our plugin.
static char * data
The data to insert into the dht.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static struct GNUNET_FS_MetaData * meta
Meta-data provided via command-line option.
static int result
Global testing status.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
enum GNUNET_GenericReturnValue GNUNET_BIO_read(struct GNUNET_BIO_ReadHandle *h, const char *what, void *result, size_t len)
Read some contents into a buffer.
Definition bio.c:291
enum GNUNET_GenericReturnValue GNUNET_BIO_write_int32(struct GNUNET_BIO_WriteHandle *h, const char *what, int32_t i)
Write an (u)int32_t.
Definition bio.c:845
enum GNUNET_GenericReturnValue GNUNET_BIO_write(struct GNUNET_BIO_WriteHandle *h, const char *what, const void *buffer, size_t n)
Write a buffer to a handle.
Definition bio.c:750
void GNUNET_BIO_read_set_error(struct GNUNET_BIO_ReadHandle *h, const char *emsg)
Set read error to handle.
Definition bio.c:187
enum GNUNET_GenericReturnValue GNUNET_BIO_read_int32(struct GNUNET_BIO_ReadHandle *h, const char *what, int32_t *i)
Read an (u)int32_t.
Definition bio.c:427
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
enum GNUNET_GenericReturnValue GNUNET_FS_write_meta_data(struct GNUNET_BIO_WriteHandle *h, const char *what, const struct GNUNET_FS_MetaData *m)
Write a metadata container.
Definition meta_data.c:1110
enum GNUNET_GenericReturnValue GNUNET_FS_read_meta_data(struct GNUNET_BIO_ReadHandle *h, const char *what, struct GNUNET_FS_MetaData **result)
Read a metadata container.
Definition meta_data.c:1051
int(* EXTRACTOR_MetaDataProcessor)(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)
Type of a function that libextractor calls for each meta data item found.
EXTRACTOR_MetaFormat
Format in which the extracted meta data is presented.
struct GNUNET_BIO_ReadSpec GNUNET_FS_read_spec_meta_data(const char *what, struct GNUNET_FS_MetaData **result)
Create the specification to read a metadata container.
Definition meta_data.c:1185
struct GNUNET_BIO_WriteSpec GNUNET_FS_write_spec_meta_data(const char *what, const struct GNUNET_FS_MetaData *m)
Create the specification to write a metadata container.
Definition meta_data.c:1223
EXTRACTOR_MetaType
Enumeration defining various sources of keywords.
@ EXTRACTOR_METAFORMAT_BINARY
Some kind of binary format, see given Mime type.
@ EXTRACTOR_METAFORMAT_C_STRING
0-terminated string.
@ EXTRACTOR_METAFORMAT_UTF8
0-terminated, UTF-8 encoded string.
@ EXTRACTOR_METATYPE_PUBLICATION_DATE
@ EXTRACTOR_METATYPE_THUMBNAIL
@ EXTRACTOR_METATYPE_FILENAME
#define GNUNET_log(kind,...)
char * GNUNET_decompress(const char *input, size_t input_size, size_t output_size)
Decompress input, return the decompressed data as output.
Definition compress.c:70
int GNUNET_try_compression(const char *data, size_t old_size, char **result, size_t *new_size)
Try to compress the given block of data using libz.
Definition compress.c:33
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
int GNUNET_FS_meta_data_iterate(const struct GNUNET_FS_MetaData *md, EXTRACTOR_MetaDataProcessor iter, void *iter_cls)
Iterate over MD entries.
Definition meta_data.c:418
char * GNUNET_FS_meta_data_get_by_type(const struct GNUNET_FS_MetaData *md, enum EXTRACTOR_MetaType type)
Get the first MD entry of the given type.
Definition meta_data.c:438
void GNUNET_FS_meta_data_add_publication_date(struct GNUNET_FS_MetaData *md)
Add the current time as the publication date to the meta-data.
Definition meta_data.c:391
ssize_t GNUNET_FS_meta_data_get_serialized_size(const struct GNUNET_FS_MetaData *md)
Get the size of the full meta-data in serialized form.
Definition meta_data.c:858
size_t GNUNET_FS_meta_data_get_thumbnail(const struct GNUNET_FS_MetaData *md, unsigned char **thumb)
Get a thumbnail from the meta-data (if present).
Definition meta_data.c:490
GNUNET_FS_MetaDataSerializationOptions
Options for metadata serialization.
ssize_t GNUNET_FS_meta_data_serialize(const struct GNUNET_FS_MetaData *md, char **target, size_t max, enum GNUNET_FS_MetaDataSerializationOptions opt)
Serialize meta-data to target.
Definition meta_data.c:637
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_create()
Create a fresh struct FS_MetaData token.
Definition meta_data.c:127
void GNUNET_FS_meta_data_merge(struct GNUNET_FS_MetaData *md, const struct GNUNET_FS_MetaData *in)
Extend metadata.
Definition meta_data.c:356
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_duplicate(const struct GNUNET_FS_MetaData *md)
Duplicate a struct GNUNET_FS_MetaData.
Definition meta_data.c:527
int GNUNET_FS_meta_data_insert(struct GNUNET_FS_MetaData *md, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_size)
Extend metadata.
Definition meta_data.c:254
void GNUNET_FS_meta_data_destroy(struct GNUNET_FS_MetaData *md)
Free meta data.
Definition meta_data.c:166
int GNUNET_FS_meta_data_test_equal(const struct GNUNET_FS_MetaData *md1, const struct GNUNET_FS_MetaData *md2)
Test if two MDs are equal.
Definition meta_data.c:200
void GNUNET_FS_meta_data_clear(struct GNUNET_FS_MetaData *md)
Remove all items in the container.
Definition meta_data.c:183
int GNUNET_FS_meta_data_delete(struct GNUNET_FS_MetaData *md, enum EXTRACTOR_MetaType type, const char *data, size_t data_size)
Remove an item.
Definition meta_data.c:364
struct GNUNET_FS_MetaData * GNUNET_FS_meta_data_deserialize(const char *input, size_t size)
Deserialize meta-data.
Definition meta_data.c:885
char * GNUNET_FS_meta_data_get_first_by_types(const struct GNUNET_FS_MetaData *md,...)
Get the first matching MD entry of the given types.
Definition meta_data.c:456
@ GNUNET_FS_META_DATA_SERIALIZE_FULL
Serialize all of the data.
@ GNUNET_FS_META_DATA_SERIALIZE_PART
If not enough space is available, it is acceptable to only serialize some of the metadata.
@ GNUNET_FS_META_DATA_SERIALIZE_NO_COMPRESS
Speed is of the essence, do not allow compression.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:660
#define max(x, y)
static void meta_item_free(struct MetaItem *mi)
Free meta data item.
Definition meta_data.c:139
static int write_spec_handler_meta_data(void *cls, struct GNUNET_BIO_WriteHandle *h, const char *what, void *source, size_t source_size)
Function used internally to write a metadata container from within a write spec.
Definition meta_data.c:1211
#define HEADER_VERSION_MASK
Bits in 'version' that give the version number.
Definition meta_data.c:553
static int read_spec_handler_meta_data(void *cls, struct GNUNET_BIO_ReadHandle *h, const char *what, void *target, size_t target_size)
Function used internally to read a metadata container from within a read spec.
Definition meta_data.c:1166
static int merge_helper(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_size)
Merge given meta data.
Definition meta_data.c:343
#define MAX_META_DATA
Maximum size allowed for meta data written/read from disk.
Definition meta_data.c:35
static void invalidate_sbuf(struct GNUNET_FS_MetaData *md)
The meta data has changed, invalidate its serialization buffer.
Definition meta_data.c:155
#define HEADER_COMPRESSED
Flag in 'version' that indicates compressed meta-data.
Definition meta_data.c:547
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
Handle for buffered reading.
Definition bio.c:69
Structure specifying a reading operation on an IO handle.
void * cls
Closure for rh.
const char * what
What is being read (for error message creation)
GNUNET_BIO_ReadHandler rh
Function performing data deserialization.
Handle for buffered writing.
Definition bio.c:466
Structure specifying a writing operation on an IO handle.
GNUNET_BIO_WriteHandler wh
Function performing data serialization.
size_t source_size
Size of source.
const char * what
What is being read (for error message creation)
Meta data to associate with a file, directory or namespace.
Definition meta_data.c:92
size_t sbuf_size
Number of bytes in 'sbuf'.
Definition meta_data.c:112
struct MetaItem * items_head
Head of linked list of the meta data items.
Definition meta_data.c:96
unsigned int item_count
Number of items in the linked list.
Definition meta_data.c:117
struct MetaItem * items_tail
Tail of linked list of the meta data items.
Definition meta_data.c:101
char * sbuf
Complete serialized and compressed buffer of the items.
Definition meta_data.c:107
Time for absolute times used by GNUnet, in microseconds.
Entry of serialized meta data.
Definition meta_data.c:594
uint32_t plugin_name_len
Number of bytes in the plugin name including 0-terminator.
Definition meta_data.c:613
uint32_t mime_type_len
Number of bytes in the mime type including 0-terminator.
Definition meta_data.c:618
uint32_t type
Meta data type.
Definition meta_data.c:598
uint32_t data_size
Number of bytes of meta data.
Definition meta_data.c:608
uint32_t format
Meta data format.
Definition meta_data.c:603
Header for serialized meta data.
Definition meta_data.c:560
uint32_t entries
How many MD entries are there?
Definition meta_data.c:575
uint32_t size
Size of the decompressed meta data.
Definition meta_data.c:580
uint32_t version
The version of the MD serialization.
Definition meta_data.c:570
Meta data item.
Definition meta_data.c:46
struct MetaItem * prev
This is a doubly linked list.
Definition meta_data.c:55
struct MetaItem * next
This is a doubly linked list.
Definition meta_data.c:50
enum EXTRACTOR_MetaType type
Type of the meta data.
Definition meta_data.c:80
size_t data_size
Number of bytes in 'data'.
Definition meta_data.c:75
char * mime_type
Mime-type of data.
Definition meta_data.c:65
enum EXTRACTOR_MetaFormat format
Format of the meta data.
Definition meta_data.c:85
char * data
The actual meta data.
Definition meta_data.c:70
char * plugin_name
Name of the extracting plugin.
Definition meta_data.c:60

◆ HEADER_COMPRESSED

#define HEADER_COMPRESSED   0x80000000

Flag in 'version' that indicates compressed meta-data.

Definition at line 547 of file meta_data.c.

◆ HEADER_VERSION_MASK

#define HEADER_VERSION_MASK   0x7FFFFFFF

Bits in 'version' that give the version number.

Definition at line 553 of file meta_data.c.

Function Documentation

◆ meta_item_free()

static void meta_item_free ( struct MetaItem mi)
static

Free meta data item.

Parameters
miitem to free

Definition at line 139 of file meta_data.c.

140{
143 GNUNET_free (mi->data);
144 GNUNET_free (mi);
145}

References MetaItem::data, GNUNET_free, MetaItem::mime_type, and MetaItem::plugin_name.

Referenced by GNUNET_FS_meta_data_clear(), GNUNET_FS_meta_data_delete(), and GNUNET_FS_meta_data_destroy().

Here is the caller graph for this function:

◆ invalidate_sbuf()

static void invalidate_sbuf ( struct GNUNET_FS_MetaData md)
static

The meta data has changed, invalidate its serialization buffer.

Parameters
mdmeta data that changed

Definition at line 155 of file meta_data.c.

156{
157 if (NULL == md->sbuf)
158 return;
159 GNUNET_free (md->sbuf);
160 md->sbuf = NULL;
161 md->sbuf_size = 0;
162}

References GNUNET_free, GNUNET_FS_MetaData::sbuf, and GNUNET_FS_MetaData::sbuf_size.

Referenced by GNUNET_FS_meta_data_delete(), and GNUNET_FS_meta_data_insert().

Here is the caller graph for this function:

◆ merge_helper()

static int merge_helper ( 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_size 
)
static

Merge given meta data.

Parameters
clsthe struct GNUNET_FS_MetaData to merge into
plugin_namename of the plugin that produced this value; special values can be used (e.g. '<zlib>' for zlib being used in the main libextractor library and yielding meta data).
typelibextractor-type describing the meta data
formatbasic format information about data
data_mime_typemime-type of data (not of the original file); can be NULL (if mime-type is not known)
dataactual meta-data found
data_sizenumber of bytes in data
Returns
0 (to continue)

Definition at line 343 of file meta_data.c.

346{
347 struct GNUNET_FS_MetaData *md = cls;
348
349 (void) GNUNET_FS_meta_data_insert (md, plugin_name, type, format,
350 data_mime_type, data, data_size);
351 return 0;
352}

References data, data_size, GNUNET_FS_meta_data_insert(), plugin_name, and type.

Referenced by GNUNET_FS_meta_data_merge().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_spec_handler_meta_data()

static int read_spec_handler_meta_data ( void *  cls,
struct GNUNET_BIO_ReadHandle h,
const char *  what,
void *  target,
size_t  target_size 
)
static

Function used internally to read a metadata container from within a read spec.

Parameters
clsignored, always NULL
hthe IO handle to read from
whatwhat is being read (for error message creation)
targetwhere to store the data
target_sizeignored
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 1166 of file meta_data.c.

1171{
1172 struct GNUNET_FS_MetaData **result = target;
1173 return GNUNET_FS_read_meta_data (h, what, result);
1174}

References GNUNET_FS_read_meta_data(), h, and result.

Referenced by GNUNET_FS_read_spec_meta_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_spec_handler_meta_data()

static int write_spec_handler_meta_data ( void *  cls,
struct GNUNET_BIO_WriteHandle h,
const char *  what,
void *  source,
size_t  source_size 
)
static

Function used internally to write a metadata container from within a write spec.

Parameters
clsignored, always NULL
hthe IO handle to write to
whatwhat is being written (for error message creation)
sourcethe data to write
source_sizeignored
Returns
GNUNET_OK on success, GNUNET_SYSERR otherwise

Definition at line 1211 of file meta_data.c.

1216{
1217 const struct GNUNET_FS_MetaData *m = source;
1218 return GNUNET_FS_write_meta_data (h, what, m);
1219}

References GNUNET_FS_write_meta_data(), h, m, and source.

Referenced by GNUNET_FS_write_spec_meta_data().

Here is the call graph for this function:
Here is the caller graph for this function: