diff options
Diffstat (limited to 'src/fs/fs_directory.c')
-rw-r--r-- | src/fs/fs_directory.c | 612 |
1 files changed, 304 insertions, 308 deletions
diff --git a/src/fs/fs_directory.c b/src/fs/fs_directory.c index 2dadc4835..ae7727cf0 100644 --- a/src/fs/fs_directory.c +++ b/src/fs/fs_directory.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 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/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file fs/fs_directory.c | 22 | * @file fs/fs_directory.c |
@@ -51,18 +51,18 @@ | |||
51 | * we have no mime-type information (treat as #GNUNET_NO) | 51 | * we have no mime-type information (treat as #GNUNET_NO) |
52 | */ | 52 | */ |
53 | int | 53 | int |
54 | GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData *md) | 54 | GNUNET_FS_meta_data_test_for_directory(const struct GNUNET_CONTAINER_MetaData *md) |
55 | { | 55 | { |
56 | char *mime; | 56 | char *mime; |
57 | int ret; | 57 | int ret; |
58 | 58 | ||
59 | if (NULL == md) | 59 | if (NULL == md) |
60 | return GNUNET_SYSERR; | 60 | return GNUNET_SYSERR; |
61 | mime = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | 61 | mime = GNUNET_CONTAINER_meta_data_get_by_type(md, EXTRACTOR_METATYPE_MIMETYPE); |
62 | if (NULL == mime) | 62 | if (NULL == mime) |
63 | return GNUNET_SYSERR; | 63 | return GNUNET_SYSERR; |
64 | ret = (0 == strcasecmp (mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO; | 64 | ret = (0 == strcasecmp(mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO; |
65 | GNUNET_free (mime); | 65 | GNUNET_free(mime); |
66 | return ret; | 66 | return ret; |
67 | } | 67 | } |
68 | 68 | ||
@@ -74,32 +74,30 @@ GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData * | |||
74 | * @param md metadata to add mimetype to | 74 | * @param md metadata to add mimetype to |
75 | */ | 75 | */ |
76 | void | 76 | void |
77 | GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md) | 77 | GNUNET_FS_meta_data_make_directory(struct GNUNET_CONTAINER_MetaData *md) |
78 | { | 78 | { |
79 | char *mime; | 79 | char *mime; |
80 | 80 | ||
81 | mime = | 81 | mime = |
82 | GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | 82 | GNUNET_CONTAINER_meta_data_get_by_type(md, EXTRACTOR_METATYPE_MIMETYPE); |
83 | if (mime != NULL) | 83 | if (mime != NULL) |
84 | { | 84 | { |
85 | GNUNET_break (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)); | 85 | GNUNET_break(0 == strcmp(mime, GNUNET_FS_DIRECTORY_MIME)); |
86 | GNUNET_free (mime); | 86 | GNUNET_free(mime); |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>", | 89 | GNUNET_CONTAINER_meta_data_insert(md, "<gnunet>", |
90 | EXTRACTOR_METATYPE_MIMETYPE, | 90 | EXTRACTOR_METATYPE_MIMETYPE, |
91 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", | 91 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", |
92 | GNUNET_FS_DIRECTORY_MIME, | 92 | GNUNET_FS_DIRECTORY_MIME, |
93 | strlen (GNUNET_FS_DIRECTORY_MIME) + 1); | 93 | strlen(GNUNET_FS_DIRECTORY_MIME) + 1); |
94 | } | 94 | } |
95 | 95 | ||
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Closure for 'find_full_data'. | 98 | * Closure for 'find_full_data'. |
99 | */ | 99 | */ |
100 | struct GetFullDataClosure | 100 | struct GetFullDataClosure { |
101 | { | ||
102 | |||
103 | /** | 101 | /** |
104 | * Extracted binary meta data. | 102 | * Extracted binary meta data. |
105 | */ | 103 | */ |
@@ -130,22 +128,22 @@ struct GetFullDataClosure | |||
130 | * @return 0 to continue extracting, 1 to abort | 128 | * @return 0 to continue extracting, 1 to abort |
131 | */ | 129 | */ |
132 | static int | 130 | static int |
133 | find_full_data (void *cls, const char *plugin_name, | 131 | find_full_data(void *cls, const char *plugin_name, |
134 | enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, | 132 | enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, |
135 | const char *data_mime_type, const char *data, size_t data_len) | 133 | const char *data_mime_type, const char *data, size_t data_len) |
136 | { | 134 | { |
137 | struct GetFullDataClosure *gfdc = cls; | 135 | struct GetFullDataClosure *gfdc = cls; |
138 | 136 | ||
139 | if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA) | 137 | if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA) |
140 | { | ||
141 | gfdc->size = data_len; | ||
142 | if (data_len > 0) | ||
143 | { | 138 | { |
144 | gfdc->data = GNUNET_malloc (data_len); | 139 | gfdc->size = data_len; |
145 | GNUNET_memcpy (gfdc->data, data, data_len); | 140 | if (data_len > 0) |
141 | { | ||
142 | gfdc->data = GNUNET_malloc(data_len); | ||
143 | GNUNET_memcpy(gfdc->data, data, data_len); | ||
144 | } | ||
145 | return 1; | ||
146 | } | 146 | } |
147 | return 1; | ||
148 | } | ||
149 | return 0; | 147 | return 0; |
150 | } | 148 | } |
151 | 149 | ||
@@ -176,11 +174,11 @@ find_full_data (void *cls, const char *plugin_name, | |||
176 | * #GNUNET_SYSERR if @a data does not represent a directory | 174 | * #GNUNET_SYSERR if @a data does not represent a directory |
177 | */ | 175 | */ |
178 | int | 176 | int |
179 | GNUNET_FS_directory_list_contents (size_t size, | 177 | GNUNET_FS_directory_list_contents(size_t size, |
180 | const void *data, | 178 | const void *data, |
181 | uint64_t offset, | 179 | uint64_t offset, |
182 | GNUNET_FS_DirectoryEntryProcessor dep, | 180 | GNUNET_FS_DirectoryEntryProcessor dep, |
183 | void *dep_cls) | 181 | void *dep_cls) |
184 | { | 182 | { |
185 | struct GetFullDataClosure full_data; | 183 | struct GetFullDataClosure full_data; |
186 | const char *cdata = data; | 184 | const char *cdata = data; |
@@ -194,132 +192,131 @@ GNUNET_FS_directory_list_contents (size_t size, | |||
194 | char *filename; | 192 | char *filename; |
195 | 193 | ||
196 | if ((offset == 0) && | 194 | if ((offset == 0) && |
197 | ((size < 8 + sizeof (uint32_t)) || | 195 | ((size < 8 + sizeof(uint32_t)) || |
198 | (0 != memcmp (cdata, | 196 | (0 != memcmp(cdata, |
199 | GNUNET_FS_DIRECTORY_MAGIC, | 197 | GNUNET_FS_DIRECTORY_MAGIC, |
200 | 8)))) | 198 | 8)))) |
201 | return GNUNET_SYSERR; | 199 | return GNUNET_SYSERR; |
202 | pos = offset; | 200 | pos = offset; |
203 | if (offset == 0) | 201 | if (offset == 0) |
204 | { | ||
205 | GNUNET_memcpy (&mdSize, | ||
206 | &cdata[8], | ||
207 | sizeof (uint32_t)); | ||
208 | mdSize = ntohl (mdSize); | ||
209 | if (mdSize > size - 8 - sizeof (uint32_t)) | ||
210 | { | 202 | { |
211 | /* invalid size */ | 203 | GNUNET_memcpy(&mdSize, |
212 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 204 | &cdata[8], |
213 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); | 205 | sizeof(uint32_t)); |
214 | return GNUNET_SYSERR; | 206 | mdSize = ntohl(mdSize); |
215 | } | 207 | if (mdSize > size - 8 - sizeof(uint32_t)) |
216 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + sizeof (uint32_t)], | 208 | { |
217 | mdSize); | 209 | /* invalid size */ |
218 | if (md == NULL) | 210 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, |
219 | { | 211 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); |
220 | GNUNET_break (0); | 212 | return GNUNET_SYSERR; |
221 | return GNUNET_SYSERR; /* malformed ! */ | 213 | } |
214 | md = GNUNET_CONTAINER_meta_data_deserialize(&cdata[8 + sizeof(uint32_t)], | ||
215 | mdSize); | ||
216 | if (md == NULL) | ||
217 | { | ||
218 | GNUNET_break(0); | ||
219 | return GNUNET_SYSERR; /* malformed ! */ | ||
220 | } | ||
221 | dep(dep_cls, | ||
222 | NULL, | ||
223 | NULL, | ||
224 | md, | ||
225 | 0, | ||
226 | NULL); | ||
227 | GNUNET_CONTAINER_meta_data_destroy(md); | ||
228 | pos = 8 + sizeof(uint32_t) + mdSize; | ||
222 | } | 229 | } |
223 | dep (dep_cls, | ||
224 | NULL, | ||
225 | NULL, | ||
226 | md, | ||
227 | 0, | ||
228 | NULL); | ||
229 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
230 | pos = 8 + sizeof (uint32_t) + mdSize; | ||
231 | } | ||
232 | while (pos < size) | 230 | while (pos < size) |
233 | { | ||
234 | /* find end of URI */ | ||
235 | if (cdata[pos] == '\0') | ||
236 | { | ||
237 | /* URI is never empty, must be end of block, | ||
238 | * skip to next alignment */ | ||
239 | align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; | ||
240 | if (align == pos) | ||
241 | { | ||
242 | /* if we were already aligned, still skip a block! */ | ||
243 | align += DBLOCK_SIZE; | ||
244 | } | ||
245 | pos = align; | ||
246 | if (pos >= size) | ||
247 | { | ||
248 | /* malformed - or partial download... */ | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | epos = pos; | ||
253 | while ((epos < size) && (cdata[epos] != '\0')) | ||
254 | epos++; | ||
255 | if (epos >= size) | ||
256 | return GNUNET_NO; /* malformed - or partial download */ | ||
257 | |||
258 | uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg); | ||
259 | pos = epos + 1; | ||
260 | if (NULL == uri) | ||
261 | { | ||
262 | GNUNET_free (emsg); | ||
263 | pos--; /* go back to '\0' to force going to next alignment */ | ||
264 | continue; | ||
265 | } | ||
266 | if (GNUNET_FS_uri_test_ksk (uri)) | ||
267 | { | 231 | { |
268 | GNUNET_FS_uri_destroy (uri); | 232 | /* find end of URI */ |
269 | GNUNET_break (0); | 233 | if (cdata[pos] == '\0') |
270 | return GNUNET_NO; /* illegal in directory! */ | 234 | { |
271 | } | 235 | /* URI is never empty, must be end of block, |
236 | * skip to next alignment */ | ||
237 | align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; | ||
238 | if (align == pos) | ||
239 | { | ||
240 | /* if we were already aligned, still skip a block! */ | ||
241 | align += DBLOCK_SIZE; | ||
242 | } | ||
243 | pos = align; | ||
244 | if (pos >= size) | ||
245 | { | ||
246 | /* malformed - or partial download... */ | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | epos = pos; | ||
251 | while ((epos < size) && (cdata[epos] != '\0')) | ||
252 | epos++; | ||
253 | if (epos >= size) | ||
254 | return GNUNET_NO; /* malformed - or partial download */ | ||
255 | |||
256 | uri = GNUNET_FS_uri_parse(&cdata[pos], &emsg); | ||
257 | pos = epos + 1; | ||
258 | if (NULL == uri) | ||
259 | { | ||
260 | GNUNET_free(emsg); | ||
261 | pos--; /* go back to '\0' to force going to next alignment */ | ||
262 | continue; | ||
263 | } | ||
264 | if (GNUNET_FS_uri_test_ksk(uri)) | ||
265 | { | ||
266 | GNUNET_FS_uri_destroy(uri); | ||
267 | GNUNET_break(0); | ||
268 | return GNUNET_NO; /* illegal in directory! */ | ||
269 | } | ||
272 | 270 | ||
273 | GNUNET_memcpy (&mdSize, | 271 | GNUNET_memcpy(&mdSize, |
274 | &cdata[pos], | 272 | &cdata[pos], |
275 | sizeof (uint32_t)); | 273 | sizeof(uint32_t)); |
276 | mdSize = ntohl (mdSize); | 274 | mdSize = ntohl(mdSize); |
277 | pos += sizeof (uint32_t); | 275 | pos += sizeof(uint32_t); |
278 | if (pos + mdSize > size) | 276 | if (pos + mdSize > size) |
279 | { | 277 | { |
280 | GNUNET_FS_uri_destroy (uri); | 278 | GNUNET_FS_uri_destroy(uri); |
281 | return GNUNET_NO; /* malformed - or partial download */ | 279 | return GNUNET_NO; /* malformed - or partial download */ |
282 | } | 280 | } |
283 | 281 | ||
284 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], | 282 | md = GNUNET_CONTAINER_meta_data_deserialize(&cdata[pos], |
285 | mdSize); | 283 | mdSize); |
286 | if (NULL == md) | 284 | if (NULL == md) |
287 | { | 285 | { |
288 | GNUNET_FS_uri_destroy (uri); | 286 | GNUNET_FS_uri_destroy(uri); |
289 | GNUNET_break (0); | 287 | GNUNET_break(0); |
290 | return GNUNET_NO; /* malformed ! */ | 288 | return GNUNET_NO; /* malformed ! */ |
291 | } | 289 | } |
292 | pos += mdSize; | 290 | pos += mdSize; |
293 | filename = | 291 | filename = |
294 | GNUNET_CONTAINER_meta_data_get_by_type (md, | 292 | GNUNET_CONTAINER_meta_data_get_by_type(md, |
295 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); | 293 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); |
296 | full_data.size = 0; | 294 | full_data.size = 0; |
297 | full_data.data = NULL; | 295 | full_data.data = NULL; |
298 | GNUNET_CONTAINER_meta_data_iterate (md, | 296 | GNUNET_CONTAINER_meta_data_iterate(md, |
299 | &find_full_data, | 297 | &find_full_data, |
300 | &full_data); | 298 | &full_data); |
301 | if (NULL != dep) | 299 | if (NULL != dep) |
302 | { | 300 | { |
303 | dep (dep_cls, | 301 | dep(dep_cls, |
304 | filename, | 302 | filename, |
305 | uri, | 303 | uri, |
306 | md, | 304 | md, |
307 | full_data.size, | 305 | full_data.size, |
308 | full_data.data); | 306 | full_data.data); |
307 | } | ||
308 | GNUNET_free_non_null(full_data.data); | ||
309 | GNUNET_free_non_null(filename); | ||
310 | GNUNET_CONTAINER_meta_data_destroy(md); | ||
311 | GNUNET_FS_uri_destroy(uri); | ||
309 | } | 312 | } |
310 | GNUNET_free_non_null (full_data.data); | ||
311 | GNUNET_free_non_null (filename); | ||
312 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
313 | GNUNET_FS_uri_destroy (uri); | ||
314 | } | ||
315 | return GNUNET_OK; | 313 | return GNUNET_OK; |
316 | } | 314 | } |
317 | 315 | ||
318 | /** | 316 | /** |
319 | * Entries in the directory (builder). | 317 | * Entries in the directory (builder). |
320 | */ | 318 | */ |
321 | struct BuilderEntry | 319 | struct BuilderEntry { |
322 | { | ||
323 | /** | 320 | /** |
324 | * This is a linked list. | 321 | * This is a linked list. |
325 | */ | 322 | */ |
@@ -334,8 +331,7 @@ struct BuilderEntry | |||
334 | /** | 331 | /** |
335 | * Internal state of a directory builder. | 332 | * Internal state of a directory builder. |
336 | */ | 333 | */ |
337 | struct GNUNET_FS_DirectoryBuilder | 334 | struct GNUNET_FS_DirectoryBuilder { |
338 | { | ||
339 | /** | 335 | /** |
340 | * Meta-data for the directory itself. | 336 | * Meta-data for the directory itself. |
341 | */ | 337 | */ |
@@ -359,17 +355,17 @@ struct GNUNET_FS_DirectoryBuilder | |||
359 | * @param mdir metadata for the directory | 355 | * @param mdir metadata for the directory |
360 | */ | 356 | */ |
361 | struct GNUNET_FS_DirectoryBuilder * | 357 | struct GNUNET_FS_DirectoryBuilder * |
362 | GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData | 358 | GNUNET_FS_directory_builder_create(const struct GNUNET_CONTAINER_MetaData |
363 | *mdir) | 359 | *mdir) |
364 | { | 360 | { |
365 | struct GNUNET_FS_DirectoryBuilder *ret; | 361 | struct GNUNET_FS_DirectoryBuilder *ret; |
366 | 362 | ||
367 | ret = GNUNET_new (struct GNUNET_FS_DirectoryBuilder); | 363 | ret = GNUNET_new(struct GNUNET_FS_DirectoryBuilder); |
368 | if (mdir != NULL) | 364 | if (mdir != NULL) |
369 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir); | 365 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate(mdir); |
370 | else | 366 | else |
371 | ret->meta = GNUNET_CONTAINER_meta_data_create (); | 367 | ret->meta = GNUNET_CONTAINER_meta_data_create(); |
372 | GNUNET_FS_meta_data_make_directory (ret->meta); | 368 | GNUNET_FS_meta_data_make_directory(ret->meta); |
373 | return ret; | 369 | return ret; |
374 | } | 370 | } |
375 | 371 | ||
@@ -385,10 +381,10 @@ GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData | |||
385 | * by the uri which must be of type LOC or CHK | 381 | * by the uri which must be of type LOC or CHK |
386 | */ | 382 | */ |
387 | void | 383 | void |
388 | GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | 384 | GNUNET_FS_directory_builder_add(struct GNUNET_FS_DirectoryBuilder *bld, |
389 | const struct GNUNET_FS_Uri *uri, | 385 | const struct GNUNET_FS_Uri *uri, |
390 | const struct GNUNET_CONTAINER_MetaData *md, | 386 | const struct GNUNET_CONTAINER_MetaData *md, |
391 | const void *data) | 387 | const void *data) |
392 | { | 388 | { |
393 | struct GNUNET_FS_Uri *curi; | 389 | struct GNUNET_FS_Uri *curi; |
394 | struct BuilderEntry *e; | 390 | struct BuilderEntry *e; |
@@ -404,71 +400,71 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | |||
404 | struct GNUNET_CONTAINER_MetaData *meta; | 400 | struct GNUNET_CONTAINER_MetaData *meta; |
405 | const struct GNUNET_CONTAINER_MetaData *meta_use; | 401 | const struct GNUNET_CONTAINER_MetaData *meta_use; |
406 | 402 | ||
407 | GNUNET_assert (!GNUNET_FS_uri_test_ksk (uri)); | 403 | GNUNET_assert(!GNUNET_FS_uri_test_ksk(uri)); |
408 | if (NULL != data) | 404 | if (NULL != data) |
409 | { | ||
410 | GNUNET_assert (!GNUNET_FS_uri_test_sks (uri)); | ||
411 | if (GNUNET_FS_uri_test_chk (uri)) | ||
412 | { | 405 | { |
413 | fsize = GNUNET_FS_uri_chk_get_file_size (uri); | 406 | GNUNET_assert(!GNUNET_FS_uri_test_sks(uri)); |
407 | if (GNUNET_FS_uri_test_chk(uri)) | ||
408 | { | ||
409 | fsize = GNUNET_FS_uri_chk_get_file_size(uri); | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | curi = GNUNET_FS_uri_loc_get_uri(uri); | ||
414 | GNUNET_assert(NULL != curi); | ||
415 | fsize = GNUNET_FS_uri_chk_get_file_size(curi); | ||
416 | GNUNET_FS_uri_destroy(curi); | ||
417 | } | ||
414 | } | 418 | } |
415 | else | 419 | else |
416 | { | 420 | { |
417 | curi = GNUNET_FS_uri_loc_get_uri (uri); | 421 | fsize = 0; /* not given */ |
418 | GNUNET_assert (NULL != curi); | ||
419 | fsize = GNUNET_FS_uri_chk_get_file_size (curi); | ||
420 | GNUNET_FS_uri_destroy (curi); | ||
421 | } | 422 | } |
422 | } | ||
423 | else | ||
424 | { | ||
425 | fsize = 0; /* not given */ | ||
426 | } | ||
427 | if (fsize > MAX_INLINE_SIZE) | 423 | if (fsize > MAX_INLINE_SIZE) |
428 | fsize = 0; /* too large */ | 424 | fsize = 0; /* too large */ |
429 | uris = GNUNET_FS_uri_to_string (uri); | 425 | uris = GNUNET_FS_uri_to_string(uri); |
430 | slen = strlen (uris) + 1; | 426 | slen = strlen(uris) + 1; |
431 | mds = GNUNET_CONTAINER_meta_data_get_serialized_size (md); | 427 | mds = GNUNET_CONTAINER_meta_data_get_serialized_size(md); |
432 | meta_use = md; | 428 | meta_use = md; |
433 | meta = NULL; | 429 | meta = NULL; |
434 | if (fsize > 0) | 430 | if (fsize > 0) |
435 | { | ||
436 | meta = GNUNET_CONTAINER_meta_data_duplicate (md); | ||
437 | GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", | ||
438 | EXTRACTOR_METATYPE_GNUNET_FULL_DATA, | ||
439 | EXTRACTOR_METAFORMAT_BINARY, NULL, data, | ||
440 | fsize); | ||
441 | mdxs = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
442 | if ((slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE == | ||
443 | (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE) | ||
444 | { | 431 | { |
445 | /* adding full data would not cause us to cross | 432 | meta = GNUNET_CONTAINER_meta_data_duplicate(md); |
446 | * additional blocks, so add it! */ | 433 | GNUNET_CONTAINER_meta_data_insert(meta, "<gnunet>", |
447 | meta_use = meta; | 434 | EXTRACTOR_METATYPE_GNUNET_FULL_DATA, |
448 | mds = mdxs; | 435 | EXTRACTOR_METAFORMAT_BINARY, NULL, data, |
436 | fsize); | ||
437 | mdxs = GNUNET_CONTAINER_meta_data_get_serialized_size(meta); | ||
438 | if ((slen + sizeof(uint32_t) + mdxs - 1) / DBLOCK_SIZE == | ||
439 | (slen + sizeof(uint32_t) + mds - 1) / DBLOCK_SIZE) | ||
440 | { | ||
441 | /* adding full data would not cause us to cross | ||
442 | * additional blocks, so add it! */ | ||
443 | meta_use = meta; | ||
444 | mds = mdxs; | ||
445 | } | ||
449 | } | 446 | } |
450 | } | ||
451 | 447 | ||
452 | if (mds > GNUNET_MAX_MALLOC_CHECKED / 2) | 448 | if (mds > GNUNET_MAX_MALLOC_CHECKED / 2) |
453 | mds = GNUNET_MAX_MALLOC_CHECKED / 2; | 449 | mds = GNUNET_MAX_MALLOC_CHECKED / 2; |
454 | e = GNUNET_malloc (sizeof (struct BuilderEntry) + slen + mds + | 450 | e = GNUNET_malloc(sizeof(struct BuilderEntry) + slen + mds + |
455 | sizeof (uint32_t)); | 451 | sizeof(uint32_t)); |
456 | ser = (char *) &e[1]; | 452 | ser = (char *)&e[1]; |
457 | GNUNET_memcpy (ser, uris, slen); | 453 | GNUNET_memcpy(ser, uris, slen); |
458 | GNUNET_free (uris); | 454 | GNUNET_free(uris); |
459 | sptr = &ser[slen + sizeof (uint32_t)]; | 455 | sptr = &ser[slen + sizeof(uint32_t)]; |
460 | ret = | 456 | ret = |
461 | GNUNET_CONTAINER_meta_data_serialize (meta_use, &sptr, mds, | 457 | GNUNET_CONTAINER_meta_data_serialize(meta_use, &sptr, mds, |
462 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | 458 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); |
463 | if (NULL != meta) | 459 | if (NULL != meta) |
464 | GNUNET_CONTAINER_meta_data_destroy (meta); | 460 | GNUNET_CONTAINER_meta_data_destroy(meta); |
465 | if (ret == -1) | 461 | if (ret == -1) |
466 | mds = 0; | 462 | mds = 0; |
467 | else | 463 | else |
468 | mds = ret; | 464 | mds = ret; |
469 | big = htonl (mds); | 465 | big = htonl(mds); |
470 | GNUNET_memcpy (&ser[slen], &big, sizeof (uint32_t)); | 466 | GNUNET_memcpy(&ser[slen], &big, sizeof(uint32_t)); |
471 | e->len = slen + sizeof (uint32_t) + mds; | 467 | e->len = slen + sizeof(uint32_t) + mds; |
472 | e->next = bld->head; | 468 | e->next = bld->head; |
473 | bld->head = e; | 469 | bld->head = e; |
474 | bld->count++; | 470 | bld->count++; |
@@ -481,7 +477,7 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | |||
481 | * after alignment to the DBLOCK_SIZE. | 477 | * after alignment to the DBLOCK_SIZE. |
482 | */ | 478 | */ |
483 | static size_t | 479 | static size_t |
484 | do_align (size_t start_position, size_t end_position) | 480 | do_align(size_t start_position, size_t end_position) |
485 | { | 481 | { |
486 | size_t align; | 482 | size_t align; |
487 | 483 | ||
@@ -502,8 +498,8 @@ do_align (size_t start_position, size_t end_position) | |||
502 | * @param perm the permutation of the blocks (updated) | 498 | * @param perm the permutation of the blocks (updated) |
503 | */ | 499 | */ |
504 | static void | 500 | static void |
505 | block_align (size_t start, unsigned int count, const size_t * sizes, | 501 | block_align(size_t start, unsigned int count, const size_t * sizes, |
506 | unsigned int *perm) | 502 | unsigned int *perm) |
507 | { | 503 | { |
508 | unsigned int i; | 504 | unsigned int i; |
509 | unsigned int j; | 505 | unsigned int j; |
@@ -517,46 +513,46 @@ block_align (size_t start, unsigned int count, const size_t * sizes, | |||
517 | 513 | ||
518 | cpos = start; | 514 | cpos = start; |
519 | for (i = 0; i < count; i++) | 515 | for (i = 0; i < count; i++) |
520 | { | ||
521 | start = cpos; | ||
522 | badness = 0x7FFFFFFF; | ||
523 | best = -1; | ||
524 | for (j = i; j < count; j++) | ||
525 | { | 516 | { |
526 | cval = perm[j]; | 517 | start = cpos; |
527 | cend = cpos + sizes[cval]; | 518 | badness = 0x7FFFFFFF; |
528 | if (cpos % DBLOCK_SIZE == 0) | 519 | best = -1; |
529 | { | 520 | for (j = i; j < count; j++) |
530 | /* prefer placing the largest blocks first */ | ||
531 | cbad = -(cend % DBLOCK_SIZE); | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | if (cpos / DBLOCK_SIZE == cend / DBLOCK_SIZE) | ||
536 | { | ||
537 | /* Data fits into the same block! Prefer small left-overs! */ | ||
538 | cbad = DBLOCK_SIZE - cend % DBLOCK_SIZE; | ||
539 | } | ||
540 | else | ||
541 | { | 521 | { |
542 | /* Would have to waste space to re-align, add big factor, this | 522 | cval = perm[j]; |
543 | * case is a real loss (proportional to space wasted)! */ | 523 | cend = cpos + sizes[cval]; |
544 | cbad = DBLOCK_SIZE * (DBLOCK_SIZE - cpos % DBLOCK_SIZE); | 524 | if (cpos % DBLOCK_SIZE == 0) |
525 | { | ||
526 | /* prefer placing the largest blocks first */ | ||
527 | cbad = -(cend % DBLOCK_SIZE); | ||
528 | } | ||
529 | else | ||
530 | { | ||
531 | if (cpos / DBLOCK_SIZE == cend / DBLOCK_SIZE) | ||
532 | { | ||
533 | /* Data fits into the same block! Prefer small left-overs! */ | ||
534 | cbad = DBLOCK_SIZE - cend % DBLOCK_SIZE; | ||
535 | } | ||
536 | else | ||
537 | { | ||
538 | /* Would have to waste space to re-align, add big factor, this | ||
539 | * case is a real loss (proportional to space wasted)! */ | ||
540 | cbad = DBLOCK_SIZE * (DBLOCK_SIZE - cpos % DBLOCK_SIZE); | ||
541 | } | ||
542 | } | ||
543 | if (cbad < badness) | ||
544 | { | ||
545 | best = j; | ||
546 | badness = cbad; | ||
547 | } | ||
545 | } | 548 | } |
546 | } | 549 | GNUNET_assert(best != -1); |
547 | if (cbad < badness) | 550 | tmp = perm[i]; |
548 | { | 551 | perm[i] = perm[best]; |
549 | best = j; | 552 | perm[best] = tmp; |
550 | badness = cbad; | 553 | cpos += sizes[perm[i]]; |
551 | } | 554 | cpos = do_align(start, cpos); |
552 | } | 555 | } |
553 | GNUNET_assert (best != -1); | ||
554 | tmp = perm[i]; | ||
555 | perm[i] = perm[best]; | ||
556 | perm[best] = tmp; | ||
557 | cpos += sizes[perm[i]]; | ||
558 | cpos = do_align (start, cpos); | ||
559 | } | ||
560 | } | 556 | } |
561 | 557 | ||
562 | 558 | ||
@@ -571,9 +567,9 @@ block_align (size_t start, unsigned int count, const size_t * sizes, | |||
571 | * @return #GNUNET_OK on success | 567 | * @return #GNUNET_OK on success |
572 | */ | 568 | */ |
573 | int | 569 | int |
574 | GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, | 570 | GNUNET_FS_directory_builder_finish(struct GNUNET_FS_DirectoryBuilder *bld, |
575 | size_t * rsize, | 571 | size_t * rsize, |
576 | void **rdata) | 572 | void **rdata) |
577 | { | 573 | { |
578 | char *data; | 574 | char *data; |
579 | char *sptr; | 575 | char *sptr; |
@@ -589,82 +585,82 @@ GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, | |||
589 | ssize_t ret; | 585 | ssize_t ret; |
590 | uint32_t big; | 586 | uint32_t big; |
591 | 587 | ||
592 | size = strlen (GNUNET_DIRECTORY_MAGIC) + sizeof (uint32_t); | 588 | size = strlen(GNUNET_DIRECTORY_MAGIC) + sizeof(uint32_t); |
593 | size += GNUNET_CONTAINER_meta_data_get_serialized_size (bld->meta); | 589 | size += GNUNET_CONTAINER_meta_data_get_serialized_size(bld->meta); |
594 | sizes = NULL; | 590 | sizes = NULL; |
595 | perm = NULL; | 591 | perm = NULL; |
596 | bes = NULL; | 592 | bes = NULL; |
597 | if (0 < bld->count) | 593 | if (0 < bld->count) |
598 | { | ||
599 | sizes = GNUNET_new_array (bld->count, | ||
600 | size_t); | ||
601 | perm = GNUNET_new_array (bld->count, | ||
602 | unsigned int); | ||
603 | bes = GNUNET_new_array (bld->count, | ||
604 | struct BuilderEntry *); | ||
605 | pos = bld->head; | ||
606 | for (i = 0; i < bld->count; i++) | ||
607 | { | ||
608 | perm[i] = i; | ||
609 | bes[i] = pos; | ||
610 | sizes[i] = pos->len; | ||
611 | pos = pos->next; | ||
612 | } | ||
613 | block_align (size, bld->count, sizes, perm); | ||
614 | /* compute final size with alignment */ | ||
615 | for (i = 0; i < bld->count; i++) | ||
616 | { | 594 | { |
617 | psize = size; | 595 | sizes = GNUNET_new_array(bld->count, |
618 | size += sizes[perm[i]]; | 596 | size_t); |
619 | size = do_align (psize, size); | 597 | perm = GNUNET_new_array(bld->count, |
598 | unsigned int); | ||
599 | bes = GNUNET_new_array(bld->count, | ||
600 | struct BuilderEntry *); | ||
601 | pos = bld->head; | ||
602 | for (i = 0; i < bld->count; i++) | ||
603 | { | ||
604 | perm[i] = i; | ||
605 | bes[i] = pos; | ||
606 | sizes[i] = pos->len; | ||
607 | pos = pos->next; | ||
608 | } | ||
609 | block_align(size, bld->count, sizes, perm); | ||
610 | /* compute final size with alignment */ | ||
611 | for (i = 0; i < bld->count; i++) | ||
612 | { | ||
613 | psize = size; | ||
614 | size += sizes[perm[i]]; | ||
615 | size = do_align(psize, size); | ||
616 | } | ||
620 | } | 617 | } |
621 | } | ||
622 | *rsize = size; | 618 | *rsize = size; |
623 | data = GNUNET_malloc_large (size); | 619 | data = GNUNET_malloc_large(size); |
624 | if (data == NULL) | 620 | if (data == NULL) |
625 | { | 621 | { |
626 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | 622 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, |
627 | "malloc"); | 623 | "malloc"); |
628 | *rsize = 0; | 624 | *rsize = 0; |
629 | *rdata = NULL; | 625 | *rdata = NULL; |
630 | GNUNET_free_non_null (sizes); | 626 | GNUNET_free_non_null(sizes); |
631 | GNUNET_free_non_null (perm); | 627 | GNUNET_free_non_null(perm); |
632 | GNUNET_free_non_null (bes); | 628 | GNUNET_free_non_null(bes); |
633 | return GNUNET_SYSERR; | 629 | return GNUNET_SYSERR; |
634 | } | 630 | } |
635 | *rdata = data; | 631 | *rdata = data; |
636 | GNUNET_memcpy (data, | 632 | GNUNET_memcpy(data, |
637 | GNUNET_DIRECTORY_MAGIC, | 633 | GNUNET_DIRECTORY_MAGIC, |
638 | strlen (GNUNET_DIRECTORY_MAGIC)); | 634 | strlen(GNUNET_DIRECTORY_MAGIC)); |
639 | off = strlen (GNUNET_DIRECTORY_MAGIC); | 635 | off = strlen(GNUNET_DIRECTORY_MAGIC); |
640 | 636 | ||
641 | sptr = &data[off + sizeof (uint32_t)]; | 637 | sptr = &data[off + sizeof(uint32_t)]; |
642 | ret = | 638 | ret = |
643 | GNUNET_CONTAINER_meta_data_serialize (bld->meta, | 639 | GNUNET_CONTAINER_meta_data_serialize(bld->meta, |
644 | &sptr, | 640 | &sptr, |
645 | size - off - sizeof (uint32_t), | 641 | size - off - sizeof(uint32_t), |
646 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); | 642 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); |
647 | GNUNET_assert (ret != -1); | 643 | GNUNET_assert(ret != -1); |
648 | big = htonl (ret); | 644 | big = htonl(ret); |
649 | GNUNET_memcpy (&data[off], | 645 | GNUNET_memcpy(&data[off], |
650 | &big, | 646 | &big, |
651 | sizeof (uint32_t)); | 647 | sizeof(uint32_t)); |
652 | off += sizeof (uint32_t) + ret; | 648 | off += sizeof(uint32_t) + ret; |
653 | for (j = 0; j < bld->count; j++) | 649 | for (j = 0; j < bld->count; j++) |
654 | { | 650 | { |
655 | i = perm[j]; | 651 | i = perm[j]; |
656 | psize = off; | 652 | psize = off; |
657 | off += sizes[i]; | 653 | off += sizes[i]; |
658 | off = do_align (psize, off); | 654 | off = do_align(psize, off); |
659 | GNUNET_memcpy (&data[off - sizes[i]], &(bes[i])[1], sizes[i]); | 655 | GNUNET_memcpy(&data[off - sizes[i]], &(bes[i])[1], sizes[i]); |
660 | GNUNET_free (bes[i]); | 656 | GNUNET_free(bes[i]); |
661 | } | 657 | } |
662 | GNUNET_free_non_null (sizes); | 658 | GNUNET_free_non_null(sizes); |
663 | GNUNET_free_non_null (perm); | 659 | GNUNET_free_non_null(perm); |
664 | GNUNET_free_non_null (bes); | 660 | GNUNET_free_non_null(bes); |
665 | GNUNET_assert (off == size); | 661 | GNUNET_assert(off == size); |
666 | GNUNET_CONTAINER_meta_data_destroy (bld->meta); | 662 | GNUNET_CONTAINER_meta_data_destroy(bld->meta); |
667 | GNUNET_free (bld); | 663 | GNUNET_free(bld); |
668 | return GNUNET_OK; | 664 | return GNUNET_OK; |
669 | } | 665 | } |
670 | 666 | ||