aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-helper-fs-publish.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-helper-fs-publish.c')
-rw-r--r--src/fs/gnunet-helper-fs-publish.c194
1 files changed, 97 insertions, 97 deletions
diff --git a/src/fs/gnunet-helper-fs-publish.c b/src/fs/gnunet-helper-fs-publish.c
index fefb33e14..dcb4b47cd 100644
--- a/src/fs/gnunet-helper-fs-publish.c
+++ b/src/fs/gnunet-helper-fs-publish.c
@@ -78,7 +78,6 @@ struct ScanTreeNode
78 * #GNUNET_YES if this is a directory 78 * #GNUNET_YES if this is a directory
79 */ 79 */
80 int is_directory; 80 int is_directory;
81
82}; 81};
83 82
84 83
@@ -124,20 +123,30 @@ add_to_md (void *cls,
124{ 123{
125 struct GNUNET_CONTAINER_MetaData *md = cls; 124 struct GNUNET_CONTAINER_MetaData *md = cls;
126 125
127 if ( ((EXTRACTOR_METAFORMAT_UTF8 == format) || 126 if (((EXTRACTOR_METAFORMAT_UTF8 == format) ||
128 (EXTRACTOR_METAFORMAT_C_STRING == format)) && 127 (EXTRACTOR_METAFORMAT_C_STRING == format)) &&
129 ('\0' != data[data_len - 1]) ) 128 ('\0' != data[data_len - 1]))
130 { 129 {
131 char zdata[data_len + 1]; 130 char zdata[data_len + 1];
132 GNUNET_memcpy (zdata, data, data_len); 131 GNUNET_memcpy (zdata, data, data_len);
133 zdata[data_len] = '\0'; 132 zdata[data_len] = '\0';
134 (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, 133 (void) GNUNET_CONTAINER_meta_data_insert (md,
135 data_mime_type, zdata, data_len + 1); 134 plugin_name,
135 type,
136 format,
137 data_mime_type,
138 zdata,
139 data_len + 1);
136 } 140 }
137 else 141 else
138 { 142 {
139 (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, 143 (void) GNUNET_CONTAINER_meta_data_insert (md,
140 data_mime_type, data, data_len); 144 plugin_name,
145 type,
146 format,
147 data_mime_type,
148 data,
149 data_len);
141 } 150 }
142 return 0; 151 return 0;
143} 152}
@@ -158,8 +167,8 @@ free_tree (struct ScanTreeNode *tree)
158 free_tree (pos); 167 free_tree (pos);
159 if (NULL != tree->parent) 168 if (NULL != tree->parent)
160 GNUNET_CONTAINER_DLL_remove (tree->parent->children_head, 169 GNUNET_CONTAINER_DLL_remove (tree->parent->children_head,
161 tree->parent->children_tail, 170 tree->parent->children_tail,
162 tree); 171 tree);
163 GNUNET_free (tree->filename); 172 GNUNET_free (tree->filename);
164 GNUNET_free (tree); 173 GNUNET_free (tree);
165} 174}
@@ -173,8 +182,7 @@ free_tree (struct ScanTreeNode *tree)
173 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 182 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
174 */ 183 */
175static int 184static int
176write_all (const void *buf, 185write_all (const void *buf, size_t size)
177 size_t size)
178{ 186{
179 const char *cbuf = buf; 187 const char *cbuf = buf;
180 size_t total; 188 size_t total;
@@ -183,16 +191,14 @@ write_all (const void *buf,
183 total = 0; 191 total = 0;
184 do 192 do
185 { 193 {
186 wr = write (output_stream, 194 wr = write (output_stream, &cbuf[total], size - total);
187 &cbuf[total],
188 size - total);
189 if (wr > 0) 195 if (wr > 0)
190 total += wr; 196 total += wr;
191 } while ( (wr > 0) && (total < size) ); 197 } while ((wr > 0) && (total < size));
192 if (wr <= 0) 198 if (wr <= 0)
193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
194 "Failed to write to stdout: %s\n", 200 "Failed to write to stdout: %s\n",
195 strerror (errno)); 201 strerror (errno));
196 return (total == size) ? GNUNET_OK : GNUNET_SYSERR; 202 return (total == size) ? GNUNET_OK : GNUNET_SYSERR;
197} 203}
198 204
@@ -206,9 +212,7 @@ write_all (const void *buf,
206 * @return #GNUNET_SYSERR to stop scanning (the pipe was broken somehow) 212 * @return #GNUNET_SYSERR to stop scanning (the pipe was broken somehow)
207 */ 213 */
208static int 214static int
209write_message (uint16_t message_type, 215write_message (uint16_t message_type, const char *data, size_t data_length)
210 const char *data,
211 size_t data_length)
212{ 216{
213 struct GNUNET_MessageHeader hdr; 217 struct GNUNET_MessageHeader hdr;
214 218
@@ -220,12 +224,8 @@ write_message (uint16_t message_type,
220#endif 224#endif
221 hdr.type = htons (message_type); 225 hdr.type = htons (message_type);
222 hdr.size = htons (sizeof (struct GNUNET_MessageHeader) + data_length); 226 hdr.size = htons (sizeof (struct GNUNET_MessageHeader) + data_length);
223 if ( (GNUNET_OK != 227 if ((GNUNET_OK != write_all (&hdr, sizeof (hdr))) ||
224 write_all (&hdr, 228 (GNUNET_OK != write_all (data, data_length)))
225 sizeof (hdr))) ||
226 (GNUNET_OK !=
227 write_all (data,
228 data_length)) )
229 return GNUNET_SYSERR; 229 return GNUNET_SYSERR;
230 return GNUNET_OK; 230 return GNUNET_OK;
231} 231}
@@ -242,8 +242,7 @@ write_message (uint16_t message_type,
242 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 242 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
243 */ 243 */
244static int 244static int
245preprocess_file (const char *filename, 245preprocess_file (const char *filename, struct ScanTreeNode **dst);
246 struct ScanTreeNode **dst);
247 246
248 247
249/** 248/**
@@ -273,15 +272,12 @@ struct RecursionContext
273 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 272 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
274 */ 273 */
275static int 274static int
276scan_callback (void *cls, 275scan_callback (void *cls, const char *filename)
277 const char *filename)
278{ 276{
279 struct RecursionContext *rc = cls; 277 struct RecursionContext *rc = cls;
280 struct ScanTreeNode *chld; 278 struct ScanTreeNode *chld;
281 279
282 if (GNUNET_OK != 280 if (GNUNET_OK != preprocess_file (filename, &chld))
283 preprocess_file (filename,
284 &chld))
285 { 281 {
286 rc->stop = GNUNET_YES; 282 rc->stop = GNUNET_YES;
287 return GNUNET_SYSERR; 283 return GNUNET_SYSERR;
@@ -290,8 +286,8 @@ scan_callback (void *cls,
290 return GNUNET_OK; 286 return GNUNET_OK;
291 chld->parent = rc->parent; 287 chld->parent = rc->parent;
292 GNUNET_CONTAINER_DLL_insert (rc->parent->children_head, 288 GNUNET_CONTAINER_DLL_insert (rc->parent->children_head,
293 rc->parent->children_tail, 289 rc->parent->children_tail,
294 chld); 290 chld);
295 return GNUNET_OK; 291 return GNUNET_OK;
296} 292}
297 293
@@ -307,22 +303,23 @@ scan_callback (void *cls,
307 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 303 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
308 */ 304 */
309static int 305static int
310preprocess_file (const char *filename, 306preprocess_file (const char *filename, struct ScanTreeNode **dst)
311 struct ScanTreeNode **dst)
312{ 307{
313 struct ScanTreeNode *item; 308 struct ScanTreeNode *item;
314 struct stat sbuf; 309 struct stat sbuf;
315 uint64_t fsize = 0; 310 uint64_t fsize = 0;
316 311
317 if ((0 != STAT (filename, &sbuf)) || 312 if ((0 != stat (filename, &sbuf)) ||
318 ((!S_ISDIR (sbuf.st_mode)) && (GNUNET_OK != GNUNET_DISK_file_size ( 313 ((! S_ISDIR (sbuf.st_mode)) &&
319 filename, &fsize, GNUNET_NO, GNUNET_YES)))) 314 (GNUNET_OK !=
315 GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES))))
320 { 316 {
321 /* If the file doesn't exist (or is not stat-able for any other reason) 317 /* If the file doesn't exist (or is not stat-able for any other reason)
322 skip it (but report it), but do continue. */ 318 skip it (but report it), but do continue. */
323 if (GNUNET_OK != 319 if (GNUNET_OK !=
324 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE, 320 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE,
325 filename, strlen (filename) + 1)) 321 filename,
322 strlen (filename) + 1))
326 return GNUNET_SYSERR; 323 return GNUNET_SYSERR;
327 /* recoverable error, store 'NULL' in *dst */ 324 /* recoverable error, store 'NULL' in *dst */
328 *dst = NULL; 325 *dst = NULL;
@@ -330,11 +327,13 @@ preprocess_file (const char *filename,
330 } 327 }
331 328
332 /* Report the progress */ 329 /* Report the progress */
333 if (GNUNET_OK != 330 if (
334 write_message (S_ISDIR (sbuf.st_mode) 331 GNUNET_OK !=
335 ? GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY 332 write_message (S_ISDIR (sbuf.st_mode)
336 : GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE, 333 ? GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY
337 filename, strlen (filename) + 1)) 334 : GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE,
335 filename,
336 strlen (filename) + 1))
338 return GNUNET_SYSERR; 337 return GNUNET_SYSERR;
339 item = GNUNET_new (struct ScanTreeNode); 338 item = GNUNET_new (struct ScanTreeNode);
340 item->filename = GNUNET_strdup (filename); 339 item->filename = GNUNET_strdup (filename);
@@ -346,13 +345,13 @@ preprocess_file (const char *filename,
346 345
347 rc.parent = item; 346 rc.parent = item;
348 rc.stop = GNUNET_NO; 347 rc.stop = GNUNET_NO;
349 GNUNET_DISK_directory_scan (filename, 348 GNUNET_DISK_directory_scan (filename, &scan_callback, &rc);
350 &scan_callback, 349 if (
351 &rc); 350 (GNUNET_YES == rc.stop) ||
352 if ( (GNUNET_YES == rc.stop) || 351 (GNUNET_OK !=
353 (GNUNET_OK != 352 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY,
354 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY, 353 "..",
355 "..", 3)) ) 354 3)))
356 { 355 {
357 free_tree (item); 356 free_tree (item);
358 return GNUNET_SYSERR; 357 return GNUNET_SYSERR;
@@ -383,20 +382,15 @@ extract_files (struct ScanTreeNode *item)
383 struct ScanTreeNode *pos; 382 struct ScanTreeNode *pos;
384 383
385 for (pos = item->children_head; NULL != pos; pos = pos->next) 384 for (pos = item->children_head; NULL != pos; pos = pos->next)
386 if (GNUNET_OK != 385 if (GNUNET_OK != extract_files (pos))
387 extract_files (pos)) 386 return GNUNET_SYSERR;
388 return GNUNET_SYSERR;
389 return GNUNET_OK; 387 return GNUNET_OK;
390 } 388 }
391 389
392 /* this is the expensive operation, *afterwards* we'll check for aborts */ 390 /* this is the expensive operation, *afterwards* we'll check for aborts */
393 meta = GNUNET_CONTAINER_meta_data_create (); 391 meta = GNUNET_CONTAINER_meta_data_create ();
394#if HAVE_LIBEXTRACTOR 392#if HAVE_LIBEXTRACTOR
395 EXTRACTOR_extract (plugins, 393 EXTRACTOR_extract (plugins, item->filename, NULL, 0, &add_to_md, meta);
396 item->filename,
397 NULL, 0,
398 &add_to_md,
399 meta);
400#endif 394#endif
401 slen = strlen (item->filename) + 1; 395 slen = strlen (item->filename) + 1;
402 size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); 396 size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
@@ -405,8 +399,9 @@ extract_files (struct ScanTreeNode *item)
405 /* no meta data */ 399 /* no meta data */
406 GNUNET_CONTAINER_meta_data_destroy (meta); 400 GNUNET_CONTAINER_meta_data_destroy (meta);
407 if (GNUNET_OK != 401 if (GNUNET_OK !=
408 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA, 402 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA,
409 item->filename, slen)) 403 item->filename,
404 slen))
410 return GNUNET_SYSERR; 405 return GNUNET_SYSERR;
411 return GNUNET_OK; 406 return GNUNET_OK;
412 } 407 }
@@ -420,9 +415,11 @@ extract_files (struct ScanTreeNode *item)
420 char *dst = &buf[slen]; 415 char *dst = &buf[slen];
421 416
422 GNUNET_memcpy (buf, item->filename, slen); 417 GNUNET_memcpy (buf, item->filename, slen);
423 size = GNUNET_CONTAINER_meta_data_serialize (meta, 418 size = GNUNET_CONTAINER_meta_data_serialize (
424 &dst, size, 419 meta,
425 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); 420 &dst,
421 size,
422 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
426 if (size < 0) 423 if (size < 0)
427 { 424 {
428 GNUNET_break (0); 425 GNUNET_break (0);
@@ -430,9 +427,9 @@ extract_files (struct ScanTreeNode *item)
430 } 427 }
431 GNUNET_CONTAINER_meta_data_destroy (meta); 428 GNUNET_CONTAINER_meta_data_destroy (meta);
432 if (GNUNET_OK != 429 if (GNUNET_OK !=
433 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA, 430 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA,
434 buf, 431 buf,
435 slen + size)) 432 slen + size))
436 return GNUNET_SYSERR; 433 return GNUNET_SYSERR;
437 } 434 }
438 return GNUNET_OK; 435 return GNUNET_OK;
@@ -453,13 +450,14 @@ ignore_sigpipe ()
453 sig.sa_handler = SIG_IGN; 450 sig.sa_handler = SIG_IGN;
454 sigemptyset (&sig.sa_mask); 451 sigemptyset (&sig.sa_mask);
455#ifdef SA_INTERRUPT 452#ifdef SA_INTERRUPT
456 sig.sa_flags = SA_INTERRUPT; /* SunOS */ 453 sig.sa_flags = SA_INTERRUPT; /* SunOS */
457#else 454#else
458 sig.sa_flags = SA_RESTART; 455 sig.sa_flags = SA_RESTART;
459#endif 456#endif
460 if (0 != sigaction (SIGPIPE, &sig, &oldsig)) 457 if (0 != sigaction (SIGPIPE, &sig, &oldsig))
461 fprintf (stderr, 458 fprintf (stderr,
462 "Failed to install SIGPIPE handler: %s\n", strerror (errno)); 459 "Failed to install SIGPIPE handler: %s\n",
460 strerror (errno));
463} 461}
464 462
465 463
@@ -470,8 +468,7 @@ ignore_sigpipe ()
470 * @param flags flags to use (O_RDONLY or O_WRONLY) 468 * @param flags flags to use (O_RDONLY or O_WRONLY)
471 */ 469 */
472static void 470static void
473make_dev_zero (int fd, 471make_dev_zero (int fd, int flags)
474 int flags)
475{ 472{
476 int z; 473 int z;
477 474
@@ -498,8 +495,7 @@ make_dev_zero (int fd,
498 * @return 0 on success 495 * @return 0 on success
499 */ 496 */
500int 497int
501main (int argc, 498main (int argc, char *const *argv)
502 char *const *argv)
503{ 499{
504 const char *filename_expanded; 500 const char *filename_expanded;
505 const char *ex; 501 const char *ex;
@@ -524,79 +520,83 @@ main (int argc,
524#endif 520#endif
525 521
526 /* parse command line */ 522 /* parse command line */
527 if ( (3 != argc) && (2 != argc) ) 523 if ((3 != argc) && (2 != argc))
528 { 524 {
529 FPRINTF (stderr, 525 fprintf (stderr,
530 "%s", 526 "%s",
531 "gnunet-helper-fs-publish needs exactly one or two arguments\n"); 527 "gnunet-helper-fs-publish needs exactly one or two arguments\n");
532#if WINDOWS 528#if WINDOWS
533 GNUNET_free ((void*) argv); 529 GNUNET_free ((void *) argv);
534#endif 530#endif
535 return 1; 531 return 1;
536 } 532 }
537 filename_expanded = argv[1]; 533 filename_expanded = argv[1];
538 ex = argv[2]; 534 ex = argv[2];
539 if ( (NULL == ex) || 535 if ((NULL == ex) || (0 != strcmp (ex, "-")))
540 (0 != strcmp (ex, "-")) )
541 { 536 {
542#if HAVE_LIBEXTRACTOR 537#if HAVE_LIBEXTRACTOR
543 plugins = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); 538 plugins = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY);
544 if (NULL != ex) 539 if (NULL != ex)
545 plugins = EXTRACTOR_plugin_add_config (plugins, ex, 540 plugins = EXTRACTOR_plugin_add_config (plugins,
546 EXTRACTOR_OPTION_DEFAULT_POLICY); 541 ex,
542 EXTRACTOR_OPTION_DEFAULT_POLICY);
547#endif 543#endif
548 } 544 }
549 545
550 /* scan tree to find out how much work there is to be done */ 546 /* scan tree to find out how much work there is to be done */
551 if (GNUNET_OK != preprocess_file (filename_expanded, 547 if (GNUNET_OK != preprocess_file (filename_expanded, &root))
552 &root))
553 { 548 {
554 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); 549 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0);
555#if HAVE_LIBEXTRACTOR 550#if HAVE_LIBEXTRACTOR
556 EXTRACTOR_plugin_remove_all (plugins); 551 EXTRACTOR_plugin_remove_all (plugins);
557#endif 552#endif
558#if WINDOWS 553#if WINDOWS
559 GNUNET_free ((void*) argv); 554 GNUNET_free ((void *) argv);
560#endif 555#endif
561 return 2; 556 return 2;
562 } 557 }
563 /* signal that we're done counting files, so that a percentage of 558 /* signal that we're done counting files, so that a percentage of
564 progress can now be calculated */ 559 progress can now be calculated */
565 if (GNUNET_OK != 560 if (GNUNET_OK !=
566 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE, NULL, 0)) 561 write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE,
562 NULL,
563 0))
567 { 564 {
568#if HAVE_LIBEXTRACTOR 565#if HAVE_LIBEXTRACTOR
569 EXTRACTOR_plugin_remove_all (plugins); 566 EXTRACTOR_plugin_remove_all (plugins);
570#endif 567#endif
571#if WINDOWS 568#if WINDOWS
572 GNUNET_free ((void*) argv); 569 GNUNET_free ((void *) argv);
573#endif 570#endif
574 return 3; 571 return 3;
575 } 572 }
576 if (NULL != root) 573 if (NULL != root)
577 { 574 {
578 if (GNUNET_OK != 575 if (GNUNET_OK != extract_files (root))
579 extract_files (root))
580 { 576 {
581 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); 577 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR,
578 NULL,
579 0);
582 free_tree (root); 580 free_tree (root);
583#if HAVE_LIBEXTRACTOR 581#if HAVE_LIBEXTRACTOR
584 EXTRACTOR_plugin_remove_all (plugins); 582 EXTRACTOR_plugin_remove_all (plugins);
585#endif 583#endif
586#if WINDOWS 584#if WINDOWS
587 GNUNET_free ((void*) argv); 585 GNUNET_free ((void *) argv);
588#endif 586#endif
589 return 4; 587 return 4;
590 } 588 }
591 free_tree (root); 589 free_tree (root);
592 } 590 }
593 /* enable "clean" shutdown by telling parent that we are done */ 591 /* enable "clean" shutdown by telling parent that we are done */
594 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED, NULL, 0); 592 (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED,
593 NULL,
594 0);
595#if HAVE_LIBEXTRACTOR 595#if HAVE_LIBEXTRACTOR
596 EXTRACTOR_plugin_remove_all (plugins); 596 EXTRACTOR_plugin_remove_all (plugins);
597#endif 597#endif
598#if WINDOWS 598#if WINDOWS
599 GNUNET_free ((void*) argv); 599 GNUNET_free ((void *) argv);
600#endif 600#endif
601 return 0; 601 return 0;
602} 602}