GNUnet 0.22.2
meta_data.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_fs_service.h"
30
35#define MAX_META_DATA (1024 * 1024)
36
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "fs-meta-data", \
39 __VA_ARGS__)
40
41
46{
50 struct MetaItem *next;
51
55 struct MetaItem *prev;
56
61
65 char *mime_type;
66
70 char *data;
71
75 size_t data_size;
76
80 enum EXTRACTOR_MetaType type;
81
85 enum EXTRACTOR_MetaFormat format;
86};
87
92{
97
102
107 char *sbuf;
108
112 size_t sbuf_size;
113
117 unsigned int item_count;
118};
119
120
126struct GNUNET_FS_MetaData *
128{
129 return GNUNET_new (struct GNUNET_FS_MetaData);
130}
131
132
138static void
140{
143 GNUNET_free (mi->data);
144 GNUNET_free (mi);
145}
146
147
154static void
156{
157 if (NULL == md->sbuf)
158 return;
159 GNUNET_free (md->sbuf);
160 md->sbuf = NULL;
161 md->sbuf_size = 0;
162}
163
164
165void
167{
168 struct MetaItem *pos;
169
170 if (NULL == md)
171 return;
172 while (NULL != (pos = md->items_head))
173 {
175 meta_item_free (pos);
176 }
177 GNUNET_free (md->sbuf);
178 GNUNET_free (md);
179}
180
181
182void
184{
185 struct MetaItem *mi;
186
187 if (NULL == md)
188 return;
189 while (NULL != (mi = md->items_head))
190 {
192 meta_item_free (mi);
193 }
194 GNUNET_free (md->sbuf);
195 memset (md, 0, sizeof(struct GNUNET_FS_MetaData));
196}
197
198
199int
201 *md1,
202 const struct GNUNET_FS_MetaData
203 *md2)
204{
205 struct MetaItem *i;
206 struct MetaItem *j;
207 int found;
208
209 if (md1 == md2)
210 return GNUNET_YES;
211 if (md1->item_count != md2->item_count)
212 return GNUNET_NO;
213 for (i = md1->items_head; NULL != i; i = i->next)
214 {
215 found = GNUNET_NO;
216 for (j = md2->items_head; NULL != j; j = j->next)
217 {
218 if ((i->type == j->type) && (i->format == j->format) &&
219 (i->data_size == j->data_size) &&
220 (0 == memcmp (i->data, j->data, i->data_size)))
221 {
222 found = GNUNET_YES;
223 break;
224 }
225 if (j->data_size < i->data_size)
226 break; /* elements are sorted by (decreasing) size... */
227 }
228 if (GNUNET_NO == found)
229 return GNUNET_NO;
230 }
231 return GNUNET_YES;
232}
233
234
253int
255 const char *plugin_name,
256 enum EXTRACTOR_MetaType type,
257 enum EXTRACTOR_MetaFormat format,
258 const char *data_mime_type, const char *data,
259 size_t data_size)
260{
261 struct MetaItem *pos;
262 struct MetaItem *mi;
263 char *p;
264
265 if ((EXTRACTOR_METAFORMAT_UTF8 == format) ||
266 (EXTRACTOR_METAFORMAT_C_STRING == format))
267 GNUNET_break ('\0' == data[data_size - 1]);
268
269 for (pos = md->items_head; NULL != pos; pos = pos->next)
270 {
271 if (pos->data_size < data_size)
272 break; /* elements are sorted by size in the list */
273 if ((pos->type == type) && (pos->data_size == data_size) &&
274 (0 == memcmp (pos->data, data, data_size)))
275 {
276 if ((NULL == pos->mime_type) && (NULL != data_mime_type))
277 {
278 pos->mime_type = GNUNET_strdup (data_mime_type);
279 invalidate_sbuf (md);
280 }
281 if ((EXTRACTOR_METAFORMAT_C_STRING == pos->format) &&
282 (EXTRACTOR_METAFORMAT_UTF8 == format))
283 {
284 pos->format = EXTRACTOR_METAFORMAT_UTF8;
285 invalidate_sbuf (md);
286 }
287 return GNUNET_SYSERR;
288 }
289 }
290 md->item_count++;
291 mi = GNUNET_new (struct MetaItem);
292 mi->type = type;
293 mi->format = format;
294 mi->data_size = data_size;
295 if (NULL == pos)
297 md->items_tail,
298 mi);
299 else
301 md->items_tail,
302 pos->prev,
303 mi);
304 mi->mime_type =
305 (NULL == data_mime_type) ? NULL : GNUNET_strdup (data_mime_type);
306 mi->plugin_name = (NULL == plugin_name) ? NULL : GNUNET_strdup (plugin_name);
309 /* change all dir separators to POSIX style ('/') */
310 if ((EXTRACTOR_METATYPE_FILENAME == type) ||
312 {
313 p = mi->data;
314 while (('\0' != *p) && (p < mi->data + data_size))
315 {
316 if ('\\' == *p)
317 *p = '/';
318 p++;
319 }
320 }
321 invalidate_sbuf (md);
322 return GNUNET_OK;
323}
324
325
342static int
343merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type,
344 enum EXTRACTOR_MetaFormat format, const char *data_mime_type,
345 const char *data, size_t data_size)
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}
353
354
355void
357 const struct GNUNET_FS_MetaData *in)
358{
360}
361
362
363int
365 enum EXTRACTOR_MetaType type,
366 const char *data, size_t data_size)
367{
368 struct MetaItem *pos;
369
370 for (pos = md->items_head; NULL != pos; pos = pos->next)
371 {
372 if (pos->data_size < data_size)
373 break; /* items are sorted by (decreasing) size */
374 if ((pos->type == type) &&
375 ((NULL == data) ||
376 ((pos->data_size == data_size) &&
377 (0 == memcmp (pos->data, data, data_size)))))
378 {
380 meta_item_free (pos);
381 md->item_count--;
382 invalidate_sbuf (md);
383 return GNUNET_OK;
384 }
385 }
386 return GNUNET_SYSERR;
387}
388
389
390void
393{
394 const char *dat;
395 struct GNUNET_TIME_Absolute t;
396
399 EXTRACTOR_METATYPE_PUBLICATION_DATE,
400 NULL, 0);
402 GNUNET_FS_meta_data_insert (md, "<gnunet>",
403 EXTRACTOR_METATYPE_PUBLICATION_DATE,
404 EXTRACTOR_METAFORMAT_UTF8, "text/plain",
405 dat, strlen (dat) + 1);
406}
407
408
417int
419 EXTRACTOR_MetaDataProcessor iter,
420 void *iter_cls)
421{
422 struct MetaItem *pos;
423
424 if (NULL == md)
425 return 0;
426 if (NULL == iter)
427 return md->item_count;
428 for (pos = md->items_head; NULL != pos; pos = pos->next)
429 if (0 !=
430 iter (iter_cls, pos->plugin_name, pos->type, pos->format,
431 pos->mime_type, pos->data, pos->data_size))
432 return md->item_count;
433 return md->item_count;
434}
435
436
437char *
440 enum EXTRACTOR_MetaType type)
441{
442 struct MetaItem *pos;
443
444 if (NULL == md)
445 return NULL;
446 for (pos = md->items_head; NULL != pos; pos = pos->next)
447 if ((type == pos->type) &&
448 ((pos->format == EXTRACTOR_METAFORMAT_UTF8) ||
449 (pos->format == EXTRACTOR_METAFORMAT_C_STRING)))
450 return GNUNET_strdup (pos->data);
451 return NULL;
452}
453
454
455char *
458 ...)
459{
460 char *ret;
461 va_list args;
462 int type;
463
464 if (NULL == md)
465 return NULL;
466 ret = NULL;
467 va_start (args, md);
468 while (1)
469 {
470 type = va_arg (args, int);
471 if (-1 == type)
472 break;
473 if (NULL != (ret = GNUNET_FS_meta_data_get_by_type (md, type)))
474 break;
475 }
476 va_end (args);
477 return ret;
478}
479
480
489size_t
491 *md, unsigned char **thumb)
492{
493 struct MetaItem *pos;
494 struct MetaItem *match;
495
496 if (NULL == md)
497 return 0;
498 match = NULL;
499 for (pos = md->items_head; NULL != pos; pos = pos->next)
500 {
501 if ((NULL != pos->mime_type) &&
502 (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) &&
503 (EXTRACTOR_METAFORMAT_BINARY == pos->format))
504 {
505 if (NULL == match)
506 match = pos;
507 else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
508 (pos->type == EXTRACTOR_METATYPE_THUMBNAIL))
509 match = pos;
510 }
511 }
512 if ((NULL == match) || (0 == match->data_size))
513 return 0;
514 *thumb = GNUNET_malloc (match->data_size);
515 GNUNET_memcpy (*thumb, match->data, match->data_size);
516 return match->data_size;
517}
518
519
526struct GNUNET_FS_MetaData *
528 *md)
529{
530 struct GNUNET_FS_MetaData *ret;
531 struct MetaItem *pos;
532
533 if (NULL == md)
534 return NULL;
536 for (pos = md->items_tail; NULL != pos; pos = pos->prev)
538 pos->format, pos->mime_type, pos->data,
539 pos->data_size);
540 return ret;
541}
542
543
547#define HEADER_COMPRESSED 0x80000000
548
549
553#define HEADER_VERSION_MASK 0x7FFFFFFF
554
555
560{
570 uint32_t version;
571
575 uint32_t entries;
576
580 uint32_t size;
581
587};
588
589
594{
598 uint32_t type;
599
603 uint32_t format;
604
608 uint32_t data_size;
609
614
619};
620
621
636ssize_t
638 *md, char **target, size_t max,
639 enum
641 opt)
642{
643 struct GNUNET_FS_MetaData *vmd;
644 struct MetaItem *pos;
645 struct MetaDataHeader ihdr;
646 struct MetaDataHeader *hdr;
647 struct MetaDataEntry *ent;
648 char *dst;
649 unsigned int i;
650 uint64_t msize;
651 size_t off;
652 char *mdata;
653 char *cdata;
654 size_t mlen;
655 size_t plen;
656 size_t size;
657 size_t left;
658 size_t clen;
659 size_t rlen;
660 int comp;
661
662 if (max < sizeof(struct MetaDataHeader))
663 return GNUNET_SYSERR; /* far too small */
664 if (NULL == md)
665 return 0;
666
667 if (NULL != md->sbuf)
668 {
669 /* try to use serialization cache */
670 if (md->sbuf_size <= max)
671 {
672 if (NULL == *target)
673 *target = GNUNET_malloc (md->sbuf_size);
674 GNUNET_memcpy (*target, md->sbuf, md->sbuf_size);
675 return md->sbuf_size;
676 }
677 if (0 == (opt & GNUNET_FS_META_DATA_SERIALIZE_PART))
678 return GNUNET_SYSERR; /* can say that this will fail */
679 /* need to compute a partial serialization, sbuf useless ... */
680 }
681 dst = NULL;
682 msize = 0;
683 for (pos = md->items_tail; NULL != pos; pos = pos->prev)
684 {
685 msize += sizeof(struct MetaDataEntry);
686 msize += pos->data_size;
687 if (NULL != pos->plugin_name)
688 msize += strlen (pos->plugin_name) + 1;
689 if (NULL != pos->mime_type)
690 msize += strlen (pos->mime_type) + 1;
691 }
692 size = (size_t) msize;
693 if (size != msize)
694 {
695 GNUNET_break (0); /* integer overflow */
696 return GNUNET_SYSERR;
697 }
699 {
700 /* too large to be processed */
701 return GNUNET_SYSERR;
702 }
703 ent = GNUNET_malloc (size);
704 mdata = (char *) &ent[md->item_count];
705 off = size - (md->item_count * sizeof(struct MetaDataEntry));
706 i = 0;
707 for (pos = md->items_head; NULL != pos; pos = pos->next)
708 {
709 ent[i].type = htonl ((uint32_t) pos->type);
710 ent[i].format = htonl ((uint32_t) pos->format);
711 ent[i].data_size = htonl ((uint32_t) pos->data_size);
712 if (NULL == pos->plugin_name)
713 plen = 0;
714 else
715 plen = strlen (pos->plugin_name) + 1;
716 ent[i].plugin_name_len = htonl ((uint32_t) plen);
717 if (NULL == pos->mime_type)
718 mlen = 0;
719 else
720 mlen = strlen (pos->mime_type) + 1;
721 ent[i].mime_type_len = htonl ((uint32_t) mlen);
722 off -= pos->data_size;
723 if ((EXTRACTOR_METAFORMAT_UTF8 == pos->format) ||
724 (EXTRACTOR_METAFORMAT_C_STRING == pos->format))
725 GNUNET_break ('\0' == pos->data[pos->data_size - 1]);
726 GNUNET_memcpy (&mdata[off], pos->data, pos->data_size);
727 off -= plen;
728 if (NULL != pos->plugin_name)
729 GNUNET_memcpy (&mdata[off], pos->plugin_name, plen);
730 off -= mlen;
731 if (NULL != pos->mime_type)
732 GNUNET_memcpy (&mdata[off], pos->mime_type, mlen);
733 i++;
734 }
735 GNUNET_assert (0 == off);
736
737 clen = 0;
738 cdata = NULL;
739 left = size;
740 i = 0;
741 for (pos = md->items_head; NULL != pos; pos = pos->next)
742 {
743 comp = GNUNET_NO;
745 comp = GNUNET_try_compression ((const char *) &ent[i],
746 left,
747 &cdata,
748 &clen);
749
750 if ((NULL == md->sbuf) && (0 == i))
751 {
752 /* fill 'sbuf'; this "modifies" md, but since this is only
753 * an internal cache we will cast away the 'const' instead
754 * of making the API look strange. */
755 vmd = (struct GNUNET_FS_MetaData *) md;
756 hdr = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
757 hdr->size = htonl (left);
758 hdr->entries = htonl (md->item_count);
759 if (GNUNET_YES == comp)
760 {
761 GNUNET_assert (clen < left);
762 hdr->version = htonl (2 | HEADER_COMPRESSED);
763 GNUNET_memcpy (&hdr[1], cdata, clen);
764 vmd->sbuf_size = clen + sizeof(struct MetaDataHeader);
765 }
766 else
767 {
768 hdr->version = htonl (2);
769 GNUNET_memcpy (&hdr[1], &ent[0], left);
770 vmd->sbuf_size = left + sizeof(struct MetaDataHeader);
771 }
772 vmd->sbuf = (char *) hdr;
773 }
774
775 if (((left + sizeof(struct MetaDataHeader)) <= max) ||
776 ((GNUNET_YES == comp) && (clen <= max)))
777 {
778 /* success, this now fits! */
779 if (GNUNET_YES == comp)
780 {
781 if (NULL == dst)
782 dst = GNUNET_malloc (clen + sizeof(struct MetaDataHeader));
783 hdr = (struct MetaDataHeader *) dst;
784 hdr->version = htonl (2 | HEADER_COMPRESSED);
785 hdr->size = htonl (left);
786 hdr->entries = htonl (md->item_count - i);
787 GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], cdata, clen);
788 GNUNET_free (cdata);
789 cdata = NULL;
790 GNUNET_free (ent);
791 rlen = clen + sizeof(struct MetaDataHeader);
792 }
793 else
794 {
795 if (NULL == dst)
796 dst = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
797 hdr = (struct MetaDataHeader *) dst;
798 hdr->version = htonl (2);
799 hdr->entries = htonl (md->item_count - i);
800 hdr->size = htonl (left);
801 GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], &ent[i], left);
802 GNUNET_free (ent);
803 rlen = left + sizeof(struct MetaDataHeader);
804 }
805 if (NULL != *target)
806 {
807 if (GNUNET_YES == comp)
808 GNUNET_memcpy (*target, dst, clen + sizeof(struct MetaDataHeader));
809 else
810 GNUNET_memcpy (*target, dst, left + sizeof(struct MetaDataHeader));
811 GNUNET_free (dst);
812 }
813 else
814 {
815 *target = dst;
816 }
817 return rlen;
818 }
819
820 if (0 == (opt & GNUNET_FS_META_DATA_SERIALIZE_PART))
821 {
822 /* does not fit! */
823 GNUNET_free (ent);
824 if (NULL != cdata)
825 GNUNET_free (cdata);
826 cdata = NULL;
827 return GNUNET_SYSERR;
828 }
829
830 /* next iteration: ignore the corresponding meta data at the
831 * end and try again without it */
832 left -= sizeof(struct MetaDataEntry);
833 left -= pos->data_size;
834 if (NULL != pos->plugin_name)
835 left -= strlen (pos->plugin_name) + 1;
836 if (NULL != pos->mime_type)
837 left -= strlen (pos->mime_type) + 1;
838
839 if (NULL != cdata)
840 GNUNET_free (cdata);
841 cdata = NULL;
842 i++;
843 }
844 GNUNET_free (ent);
845
846 /* nothing fit, only write header! */
847 ihdr.version = htonl (2);
848 ihdr.entries = htonl (0);
849 ihdr.size = htonl (0);
850 if (NULL == *target)
851 *target = (char *) GNUNET_new (struct MetaDataHeader);
852 GNUNET_memcpy (*target, &ihdr, sizeof(struct MetaDataHeader));
853 return sizeof(struct MetaDataHeader);
854}
855
856
857ssize_t
860{
861 ssize_t ret;
862 char *ptr;
863
864 if (NULL != md->sbuf)
865 return md->sbuf_size;
866 ptr = NULL;
867 ret =
870 if (-1 != ret)
871 GNUNET_free (ptr);
872 return ret;
873}
874
875
884struct GNUNET_FS_MetaData *
885GNUNET_FS_meta_data_deserialize (const char *input, size_t size)
886{
887 struct GNUNET_FS_MetaData *md;
888 struct MetaDataHeader hdr;
889 struct MetaDataEntry ent;
890 uint32_t ic;
891 uint32_t i;
892 char *data;
893 const char *cdata;
894 uint32_t version;
895 uint32_t dataSize;
896 int compressed;
897 size_t left;
898 uint32_t mlen;
899 uint32_t plen;
900 uint32_t dlen;
901 const char *mdata;
902 const char *meta_data;
903 const char *plugin_name;
904 const char *mime_type;
905 enum EXTRACTOR_MetaFormat format;
906
907 if (size < sizeof(struct MetaDataHeader))
908 return NULL;
909 GNUNET_memcpy (&hdr, input, sizeof(struct MetaDataHeader));
910 version = ntohl (hdr.version) & HEADER_VERSION_MASK;
911 compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0;
912
913 if (1 == version)
914 return NULL; /* null pointer */
915 if (2 != version)
916 {
917 GNUNET_break_op (0); /* unsupported version */
918 return NULL;
919 }
920
921 ic = ntohl (hdr.entries);
922 dataSize = ntohl (hdr.size);
923 if (((sizeof(struct MetaDataEntry) * ic) > dataSize) ||
924 ((0 != ic) &&
925 (dataSize / ic < sizeof(struct MetaDataEntry))))
926 {
927 GNUNET_break_op (0);
928 return NULL;
929 }
930
931 if (compressed)
932 {
933 if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
934 {
935 /* make sure we don't blow our memory limit because of a mal-formed
936 * message... */
937 GNUNET_break_op (0);
938 return NULL;
939 }
940 data =
941 GNUNET_decompress ((const char *) &input[sizeof(struct MetaDataHeader)],
942 size - sizeof(struct MetaDataHeader),
943 dataSize);
944 if (NULL == data)
945 {
946 GNUNET_break_op (0);
947 return NULL;
948 }
949 cdata = data;
950 }
951 else
952 {
953 data = NULL;
954 cdata = (const char *) &input[sizeof(struct MetaDataHeader)];
955 if (dataSize != size - sizeof(struct MetaDataHeader))
956 {
957 GNUNET_break_op (0);
958 return NULL;
959 }
960 }
961
963 left = dataSize - ic * sizeof(struct MetaDataEntry);
964 mdata = &cdata[ic * sizeof(struct MetaDataEntry)];
965 for (i = 0; i < ic; i++)
966 {
967 GNUNET_memcpy (&ent, &cdata[i * sizeof(struct MetaDataEntry)],
968 sizeof(struct MetaDataEntry));
969 format = ntohl (ent.format);
970 if ((EXTRACTOR_METAFORMAT_UTF8 != format) &&
971 (EXTRACTOR_METAFORMAT_C_STRING != format) &&
972 (EXTRACTOR_METAFORMAT_BINARY != format))
973 {
974 GNUNET_break_op (0);
975 break;
976 }
977 dlen = ntohl (ent.data_size);
978 plen = ntohl (ent.plugin_name_len);
979 mlen = ntohl (ent.mime_type_len);
980 if (dlen > left)
981 {
982 GNUNET_break_op (0);
983 break;
984 }
985 left -= dlen;
986 meta_data = &mdata[left];
987 if ((EXTRACTOR_METAFORMAT_UTF8 == format) ||
988 (EXTRACTOR_METAFORMAT_C_STRING == format))
989 {
990 if (0 == dlen)
991 {
992 GNUNET_break_op (0);
993 break;
994 }
995 if ('\0' != meta_data[dlen - 1])
996 {
997 GNUNET_break_op (0);
998 break;
999 }
1000 }
1001 if (plen > left)
1002 {
1003 GNUNET_break_op (0);
1004 break;
1005 }
1006 left -= plen;
1007 if ((plen > 0) && ('\0' != mdata[left + plen - 1]))
1008 {
1009 GNUNET_break_op (0);
1010 break;
1011 }
1012 if (0 == plen)
1013 plugin_name = NULL;
1014 else
1015 plugin_name = &mdata[left];
1016
1017 if (mlen > left)
1018 {
1019 GNUNET_break_op (0);
1020 break;
1021 }
1022 left -= mlen;
1023 if ((mlen > 0) && ('\0' != mdata[left + mlen - 1]))
1024 {
1025 GNUNET_break_op (0);
1026 break;
1027 }
1028 if (0 == mlen)
1029 mime_type = NULL;
1030 else
1031 mime_type = &mdata[left];
1033 ntohl (ent.type), format,
1034 mime_type,
1035 meta_data, dlen);
1036 }
1037 GNUNET_free (data);
1038 return md;
1039}
1040
1041
1052 const char *what,
1053 struct GNUNET_FS_MetaData **result)
1054{
1055 uint32_t size;
1056 char *buf;
1057 char *emsg;
1058 struct GNUNET_FS_MetaData *meta;
1059
1061 _ ("metadata length"),
1062 (int32_t *) &size))
1063 return GNUNET_SYSERR;
1064 if (0 == size)
1065 {
1066 *result = NULL;
1067 return GNUNET_OK;
1068 }
1069 if (MAX_META_DATA < size)
1070 {
1071 GNUNET_asprintf (&emsg,
1072 _ (
1073 "Serialized metadata `%s' larger than allowed (%u > %u)\n"),
1074 what,
1075 size,
1078 GNUNET_free (emsg);
1079 return GNUNET_SYSERR;
1080 }
1081 buf = GNUNET_malloc (size);
1082 if (GNUNET_OK != GNUNET_BIO_read (h, what, buf, size))
1083 {
1084 GNUNET_free (buf);
1085 return GNUNET_SYSERR;
1086 }
1088 if (NULL == meta)
1089 {
1090 GNUNET_free (buf);
1092 _ ("Failed to deserialize metadata `%s'"), what);
1093 return GNUNET_SYSERR;
1094 }
1095 GNUNET_free (buf);
1096 *result = meta;
1097 return GNUNET_OK;
1098}
1099
1100
1111 const char *what,
1112 const struct GNUNET_FS_MetaData *m)
1113{
1114 ssize_t size;
1115 char *buf;
1116
1117 if (m == NULL)
1118 return GNUNET_BIO_write_int32 (h, _ ("metadata length"), 0);
1119 buf = NULL;
1121 &buf,
1125 "Serialized %lld bytes of metadata",
1126 (long long) size);
1127
1128 if (-1 == size)
1129 {
1130 GNUNET_free (buf);
1132 "Failed to serialize metadata `%s'",
1133 what);
1134 return GNUNET_SYSERR;
1135 }
1136 if ( (GNUNET_OK !=
1138 "metadata length",
1139 (uint32_t) size)) ||
1140 (GNUNET_OK !=
1142 what,
1143 buf,
1144 size)) )
1145 {
1146 GNUNET_free (buf);
1147 return GNUNET_SYSERR;
1148 }
1149 GNUNET_free (buf);
1150 return GNUNET_OK;
1151}
1152
1153
1165static int
1167 struct GNUNET_BIO_ReadHandle *h,
1168 const char *what,
1169 void *target,
1170 size_t target_size)
1171{
1172 struct GNUNET_FS_MetaData **result = target;
1173 return GNUNET_FS_read_meta_data (h, what, result);
1174}
1175
1176
1186 struct GNUNET_FS_MetaData **result)
1187{
1188 struct GNUNET_BIO_ReadSpec rs = {
1190 .cls = NULL,
1191 .target = result,
1192 .size = 0,
1193 };
1194
1195 return rs;
1196}
1197
1198
1210static int
1212 struct GNUNET_BIO_WriteHandle *h,
1213 const char *what,
1214 void *source,
1215 size_t source_size)
1216{
1217 const struct GNUNET_FS_MetaData *m = source;
1218 return GNUNET_FS_write_meta_data (h, what, m);
1219}
1220
1221
1224 const struct GNUNET_FS_MetaData *m)
1225{
1226 struct GNUNET_BIO_WriteSpec ws = {
1228 .cls = NULL,
1229 .what = what,
1230 .source = (void *) m,
1231 .source_size = 0,
1232 };
1233
1234 return ws;
1235}
1236
1237
1238/* 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.
API for file sharing via GNUnet.
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
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
#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:640
#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