aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-publish.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-publish.c')
-rw-r--r--src/fs/gnunet-publish.c1008
1 files changed, 0 insertions, 1008 deletions
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
deleted file mode 100644
index c62edcd61..000000000
--- a/src/fs/gnunet-publish.c
+++ /dev/null
@@ -1,1008 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2013 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/**
21 * @file fs/gnunet-publish.c
22 * @brief publishing files on GNUnet
23 * @author Christian Grothoff
24 * @author Krista Bennett
25 * @author James Blackwell
26 * @author Igor Wronsky
27 */
28#include "platform.h"
29#include "gnunet_fs_service.h"
30#include "gnunet_identity_service.h"
31
32/**
33 * Global return value from #main().
34 */
35static int ret;
36
37/**
38 * Command line option 'verbose' set
39 */
40static unsigned int verbose;
41
42/**
43 * Handle to our configuration.
44 */
45static const struct GNUNET_CONFIGURATION_Handle *cfg;
46
47/**
48 * Handle for interaction with file-sharing service.
49 */
50static struct GNUNET_FS_Handle *ctx;
51
52/**
53 * Handle to FS-publishing operation.
54 */
55static struct GNUNET_FS_PublishContext *pc;
56
57/**
58 * Meta-data provided via command-line option.
59 */
60static struct GNUNET_CONTAINER_MetaData *meta;
61
62/**
63 * Keywords provided via command-line option.
64 */
65static struct GNUNET_FS_Uri *topKeywords;
66
67/**
68 * Options we set for published blocks.
69 */
70static struct GNUNET_FS_BlockOptions bo = { { 0LL }, 1, 365, 1 };
71
72/**
73 * Value of URI provided on command-line (when not publishing
74 * a file but just creating UBlocks to refer to an existing URI).
75 */
76static char *uri_string;
77
78/**
79 * Value of URI provided on command-line (when not publishing
80 * a file but just creating UBlocks to refer to an existing URI);
81 * parsed version of 'uri_string'.
82 */
83static struct GNUNET_FS_Uri *uri;
84
85/**
86 * Command-line option for namespace publishing: identifier for updates
87 * to this publication.
88 */
89static char *next_id;
90
91/**
92 * Command-line option for namespace publishing: identifier for this
93 * publication.
94 */
95static char *this_id;
96
97/**
98 * Command-line option identifying the pseudonym to use for the publication.
99 */
100static char *pseudonym;
101
102/**
103 * Command-line option for 'inserting'
104 */
105static int do_insert;
106
107/**
108 * Command-line option to disable meta data extraction.
109 */
110static int disable_extractor;
111
112/**
113 * Command-line option to merely simulate publishing operation.
114 */
115static int do_simulate;
116
117/**
118 * Command-line option to only perform meta data extraction, but not publish.
119 */
120static int extract_only;
121
122/**
123 * Command-line option to disable adding creation time.
124 */
125static int enable_creation_time;
126
127/**
128 * Handle to the directory scanner (for recursive insertions).
129 */
130static struct GNUNET_FS_DirScanner *ds;
131
132/**
133 * Which namespace do we publish to? NULL if we do not publish to
134 * a namespace.
135 */
136static struct GNUNET_IDENTITY_Ego *namespace;
137
138/**
139 * Handle to identity service.
140 */
141static struct GNUNET_IDENTITY_Handle *identity;
142
143
144/**
145 * We are finished with the publishing operation, clean up all
146 * FS state.
147 *
148 * @param cls NULL
149 */
150static void
151do_stop_task (void *cls)
152{
153 struct GNUNET_FS_PublishContext *p;
154
155 if (NULL != ds)
156 {
157 GNUNET_FS_directory_scan_abort (ds);
158 ds = NULL;
159 }
160 if (NULL != identity)
161 {
162 GNUNET_IDENTITY_disconnect (identity);
163 identity = NULL;
164 }
165 if (NULL != pc)
166 {
167 p = pc;
168 pc = NULL;
169 GNUNET_FS_publish_stop (p);
170 }
171 if (NULL != ctx)
172 {
173 GNUNET_FS_stop (ctx);
174 ctx = NULL;
175 }
176 if (NULL != meta)
177 {
178 GNUNET_CONTAINER_meta_data_destroy (meta);
179 meta = NULL;
180 }
181 if (NULL != uri)
182 {
183 GNUNET_FS_uri_destroy (uri);
184 uri = NULL;
185 }
186}
187
188
189/**
190 * Called by FS client to give information about the progress of an
191 * operation.
192 *
193 * @param cls closure
194 * @param info details about the event, specifying the event type
195 * and various bits about the event
196 * @return client-context (for the next progress call
197 * for this operation; should be set to NULL for
198 * SUSPEND and STOPPED events). The value returned
199 * will be passed to future callbacks in the respective
200 * field in the GNUNET_FS_ProgressInfo struct.
201 */
202static void *
203progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
204{
205 const char *s;
206 char *suri;
207
208 switch (info->status)
209 {
210 case GNUNET_FS_STATUS_PUBLISH_START:
211 break;
212
213 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
214 if (verbose)
215 {
216 s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.eta,
217 GNUNET_YES);
218 fprintf (stdout,
219 _ ("Publishing `%s' at %llu/%llu (%s remaining)\n"),
220 info->value.publish.filename,
221 (unsigned long long) info->value.publish.completed,
222 (unsigned long long) info->value.publish.size,
223 s);
224 }
225 break;
226
227 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
228 if (verbose)
229 {
230 s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.specifics
231 .progress_directory.eta,
232 GNUNET_YES);
233 fprintf (stdout,
234 _ ("Publishing `%s' at %llu/%llu (%s remaining)\n"),
235 info->value.publish.filename,
236 (unsigned long long)
237 info->value.publish.specifics.progress_directory.completed,
238 (unsigned long long)
239 info->value.publish.specifics.progress_directory.total,
240 s);
241 }
242 break;
243
244 case GNUNET_FS_STATUS_PUBLISH_ERROR:
245 fprintf (stderr,
246 _ ("Error publishing: %s.\n"),
247 info->value.publish.specifics.error.message);
248 ret = 1;
249 GNUNET_SCHEDULER_shutdown ();
250 break;
251
252 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
253 fprintf (stdout,
254 _ ("Publishing `%s' done.\n"),
255 info->value.publish.filename);
256 suri =
257 GNUNET_FS_uri_to_string (info->value.publish.specifics.completed.chk_uri);
258 fprintf (stdout, _ ("URI is `%s'.\n"), suri);
259 GNUNET_free (suri);
260 if (NULL != info->value.publish.specifics.completed.sks_uri)
261 {
262 suri = GNUNET_FS_uri_to_string (
263 info->value.publish.specifics.completed.sks_uri);
264 fprintf (stdout, _ ("Namespace URI is `%s'.\n"), suri);
265 GNUNET_free (suri);
266 }
267 if (NULL == info->value.publish.pctx)
268 {
269 ret = 0;
270 GNUNET_SCHEDULER_shutdown ();
271 }
272 break;
273
274 case GNUNET_FS_STATUS_PUBLISH_STOPPED:
275 GNUNET_break (NULL == pc);
276 return NULL;
277
278 case GNUNET_FS_STATUS_UNINDEX_START:
279 fprintf (stderr, "%s", _ ("Starting cleanup after abort\n"));
280 return NULL;
281
282 case GNUNET_FS_STATUS_UNINDEX_PROGRESS:
283 return NULL;
284
285 case GNUNET_FS_STATUS_UNINDEX_COMPLETED:
286 fprintf (stderr, "%s", _ ("Cleanup after abort completed.\n"));
287 GNUNET_FS_unindex_stop (info->value.unindex.uc);
288 return NULL;
289
290 case GNUNET_FS_STATUS_UNINDEX_ERROR:
291 fprintf (stderr, "%s", _ ("Cleanup after abort failed.\n"));
292 GNUNET_FS_unindex_stop (info->value.unindex.uc);
293 return NULL;
294
295 case GNUNET_FS_STATUS_UNINDEX_STOPPED:
296 return NULL;
297
298 default:
299 fprintf (stderr, _ ("Unexpected status: %d\n"), info->status);
300 return NULL;
301 }
302 return ""; /* non-null */
303}
304
305
306/**
307 * Print metadata entries (except binary
308 * metadata and the filename).
309 *
310 * @param cls closure
311 * @param plugin_name name of the plugin that generated the meta data
312 * @param type type of the meta data
313 * @param format format of data
314 * @param data_mime_type mime type of @a data
315 * @param data value of the meta data
316 * @param data_size number of bytes in @a data
317 * @return always 0
318 */
319static int
320meta_printer (void *cls,
321 const char *plugin_name,
322 enum EXTRACTOR_MetaType type,
323 enum EXTRACTOR_MetaFormat format,
324 const char *data_mime_type,
325 const char *data,
326 size_t data_size)
327{
328 if ((EXTRACTOR_METAFORMAT_UTF8 != format) &&
329 (EXTRACTOR_METAFORMAT_C_STRING != format))
330 return 0;
331 if (EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME == type)
332 return 0;
333#if HAVE_LIBEXTRACTOR
334 fprintf (stdout, "\t%s - %s\n", EXTRACTOR_metatype_to_string (type), data);
335#else
336 fprintf (stdout, "\t%d - %s\n", type, data);
337#endif
338 return 0;
339}
340
341
342/**
343 * Iterator printing keywords
344 *
345 * @param cls closure
346 * @param keyword the keyword
347 * @param is_mandatory is the keyword mandatory (in a search)
348 * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to abort
349 */
350static int
351keyword_printer (void *cls, const char *keyword, int is_mandatory)
352{
353 fprintf (stdout, "\t%s\n", keyword);
354 return GNUNET_OK;
355}
356
357
358/**
359 * Function called on all entries before the publication. This is
360 * where we perform modifications to the default based on command-line
361 * options.
362 *
363 * @param cls closure
364 * @param fi the entry in the publish-structure
365 * @param length length of the file or directory
366 * @param m metadata for the file or directory (can be modified)
367 * @param uri pointer to the keywords that will be used for this entry (can be modified)
368 * @param bo block options
369 * @param do_index should we index?
370 * @param client_info pointer to client context set upon creation (can be modified)
371 * @return #GNUNET_OK to continue, #GNUNET_NO to remove
372 * this entry from the directory, #GNUNET_SYSERR
373 * to abort the iteration
374 */
375static int
376publish_inspector (void *cls,
377 struct GNUNET_FS_FileInformation *fi,
378 uint64_t length,
379 struct GNUNET_CONTAINER_MetaData *m,
380 struct GNUNET_FS_Uri **uri,
381 struct GNUNET_FS_BlockOptions *bo,
382 int *do_index,
383 void **client_info)
384{
385 char *fn;
386 char *fs;
387 struct GNUNET_FS_Uri *new_uri;
388
389 if (cls == fi)
390 return GNUNET_OK;
391 if ((disable_extractor) && (NULL != *uri))
392 {
393 GNUNET_FS_uri_destroy (*uri);
394 *uri = NULL;
395 }
396 if (NULL != topKeywords)
397 {
398 if (NULL != *uri)
399 {
400 new_uri = GNUNET_FS_uri_ksk_merge (topKeywords, *uri);
401 GNUNET_FS_uri_destroy (*uri);
402 *uri = new_uri;
403 GNUNET_FS_uri_destroy (topKeywords);
404 }
405 else
406 {
407 *uri = topKeywords;
408 }
409 topKeywords = NULL;
410 }
411 if (NULL != meta)
412 {
413 GNUNET_CONTAINER_meta_data_merge (m, meta);
414 GNUNET_CONTAINER_meta_data_destroy (meta);
415 meta = NULL;
416 }
417 if (enable_creation_time)
418 GNUNET_CONTAINER_meta_data_add_publication_date (m);
419 if (extract_only)
420 {
421 fn = GNUNET_CONTAINER_meta_data_get_by_type (
422 m,
423 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
424 fs = GNUNET_STRINGS_byte_size_fancy (length);
425 fprintf (stdout, _ ("Meta data for file `%s' (%s)\n"), fn, fs);
426 GNUNET_CONTAINER_meta_data_iterate (m, &meta_printer, NULL);
427 fprintf (stdout, _ ("Keywords for file `%s' (%s)\n"), fn, fs);
428 GNUNET_free (fn);
429 GNUNET_free (fs);
430 if (NULL != *uri)
431 GNUNET_FS_uri_ksk_get_keywords (*uri, &keyword_printer, NULL);
432 fprintf (stdout, "%s", "\n");
433 }
434 if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (m))
435 GNUNET_FS_file_information_inspect (fi, &publish_inspector, fi);
436 return GNUNET_OK;
437}
438
439
440/**
441 * Function called upon completion of the publishing
442 * of the UBLOCK for the SKS URI. As this is the last
443 * step, stop our interaction with FS (clean up).
444 *
445 * @param cls NULL (closure)
446 * @param sks_uri URI for the block that was published
447 * @param emsg error message, NULL on success
448 */
449static void
450uri_sks_continuation (void *cls,
451 const struct GNUNET_FS_Uri *sks_uri,
452 const char *emsg)
453{
454 if (NULL != emsg)
455 {
456 fprintf (stderr, "%s\n", emsg);
457 ret = 1;
458 }
459 GNUNET_SCHEDULER_shutdown ();
460}
461
462
463/**
464 * Function called upon completion of the publishing
465 * of the UBLOCK for the KSK URI. Continue with
466 * publishing the SKS URI (if applicable) or clean up.
467 *
468 * @param cls NULL (closure)
469 * @param ksk_uri URI for the block that was published
470 * @param emsg error message, NULL on success
471 */
472static void
473uri_ksk_continuation (void *cls,
474 const struct GNUNET_FS_Uri *ksk_uri,
475 const char *emsg)
476{
477 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
478 const struct GNUNET_IDENTITY_PrivateKey *pk;
479
480 if (NULL != emsg)
481 {
482 fprintf (stderr, "%s\n", emsg);
483 ret = 1;
484 }
485 if (NULL == namespace)
486 {
487 GNUNET_SCHEDULER_shutdown ();
488 return;
489 }
490 pk = GNUNET_IDENTITY_ego_get_private_key (namespace);
491 if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (pk->type))
492 return;
493 priv = &pk->ecdsa_key;
494 GNUNET_FS_publish_sks (ctx,
495 priv,
496 this_id,
497 next_id,
498 meta,
499 uri,
500 &bo,
501 GNUNET_FS_PUBLISH_OPTION_NONE,
502 &uri_sks_continuation,
503 NULL);
504}
505
506
507/**
508 * Iterate over the results from the directory scan and extract
509 * the desired information for the publishing operation.
510 *
511 * @param item root with the data from the directory scan
512 * @return handle with the information for the publishing operation
513 */
514static struct GNUNET_FS_FileInformation *
515get_file_information (struct GNUNET_FS_ShareTreeItem *item)
516{
517 struct GNUNET_FS_FileInformation *fi;
518 struct GNUNET_FS_FileInformation *fic;
519 struct GNUNET_FS_ShareTreeItem *child;
520
521 if (GNUNET_YES == item->is_directory)
522 {
523 if (NULL == item->meta)
524 item->meta = GNUNET_CONTAINER_meta_data_create ();
525 GNUNET_CONTAINER_meta_data_delete (item->meta,
526 EXTRACTOR_METATYPE_MIMETYPE,
527 NULL,
528 0);
529 GNUNET_FS_meta_data_make_directory (item->meta);
530 if (NULL == item->ksk_uri)
531 {
532 const char *mime = GNUNET_FS_DIRECTORY_MIME;
533 item->ksk_uri = GNUNET_FS_uri_ksk_create_from_args (1, &mime);
534 }
535 else
536 GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri,
537 GNUNET_FS_DIRECTORY_MIME,
538 GNUNET_NO);
539 fi = GNUNET_FS_file_information_create_empty_directory (ctx,
540 NULL,
541 item->ksk_uri,
542 item->meta,
543 &bo,
544 item->filename);
545 for (child = item->children_head; child; child = child->next)
546 {
547 fic = get_file_information (child);
548 GNUNET_break (GNUNET_OK == GNUNET_FS_file_information_add (fi, fic));
549 }
550 }
551 else
552 {
553 fi = GNUNET_FS_file_information_create_from_file (ctx,
554 NULL,
555 item->filename,
556 item->ksk_uri,
557 item->meta,
558 ! do_insert,
559 &bo);
560 }
561 return fi;
562}
563
564
565/**
566 * We've finished scanning the directory and optimized the meta data.
567 * Begin the publication process.
568 *
569 * @param directory_scan_result result from the directory scan, freed in this function
570 */
571static void
572directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result)
573{
574 struct GNUNET_FS_FileInformation *fi;
575 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
576 const struct GNUNET_IDENTITY_PrivateKey *pk;
577
578 fi = get_file_information (directory_scan_result);
579 GNUNET_FS_share_tree_free (directory_scan_result);
580 if (NULL == fi)
581 {
582 fprintf (stderr, "%s", _ ("Could not publish\n"));
583 ret = 1;
584 GNUNET_SCHEDULER_shutdown ();
585 return;
586 }
587 GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL);
588 if (extract_only)
589 {
590 GNUNET_FS_file_information_destroy (fi, NULL, NULL);
591 GNUNET_SCHEDULER_shutdown ();
592 return;
593 }
594 priv = NULL;
595 if (NULL != namespace)
596 {
597 pk = GNUNET_IDENTITY_ego_get_private_key (namespace);
598 GNUNET_assert (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pk->type));
599 priv = &pk->ecdsa_key;
600 }
601 pc = GNUNET_FS_publish_start (ctx,
602 fi,
603 priv,
604 this_id,
605 next_id,
606 (do_simulate)
607 ? GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY
608 : GNUNET_FS_PUBLISH_OPTION_NONE);
609 if (NULL == pc)
610 {
611 fprintf (stderr, "%s", _ ("Could not start publishing.\n"));
612 ret = 1;
613 GNUNET_SCHEDULER_shutdown ();
614 return;
615 }
616}
617
618
619/**
620 * Function called by the directory scanner as we build the tree
621 * that we will need to publish later.
622 *
623 * @param cls closure
624 * @param filename which file we are making progress on
625 * @param is_directory #GNUNET_YES if this is a directory,
626 * #GNUNET_NO if this is a file
627 * #GNUNET_SYSERR if it is neither (or unknown)
628 * @param reason kind of progress we are making
629 */
630static void
631directory_scan_cb (void *cls,
632 const char *filename,
633 int is_directory,
634 enum GNUNET_FS_DirScannerProgressUpdateReason reason)
635{
636 struct GNUNET_FS_ShareTreeItem *directory_scan_result;
637
638 switch (reason)
639 {
640 case GNUNET_FS_DIRSCANNER_FILE_START:
641 if (verbose > 1)
642 {
643 if (is_directory == GNUNET_YES)
644 fprintf (stdout, _ ("Scanning directory `%s'.\n"), filename);
645 else
646 fprintf (stdout, _ ("Scanning file `%s'.\n"), filename);
647 }
648 break;
649
650 case GNUNET_FS_DIRSCANNER_FILE_IGNORED:
651 fprintf (stderr,
652 _ ("There was trouble processing file `%s', skipping it.\n"),
653 filename);
654 break;
655
656 case GNUNET_FS_DIRSCANNER_ALL_COUNTED:
657 if (verbose)
658 fprintf (stdout, "%s", _ ("Preprocessing complete.\n"));
659 break;
660
661 case GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED:
662 if (verbose > 2)
663 fprintf (stdout,
664 _ ("Extracting meta data from file `%s' complete.\n"),
665 filename);
666 break;
667
668 case GNUNET_FS_DIRSCANNER_FINISHED:
669 if (verbose > 1)
670 fprintf (stdout, "%s", _ ("Meta data extraction has finished.\n"));
671 directory_scan_result = GNUNET_FS_directory_scan_get_result (ds);
672 ds = NULL;
673 GNUNET_FS_share_tree_trim (directory_scan_result);
674 directory_trim_complete (directory_scan_result);
675 break;
676
677 case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR:
678 fprintf (stdout, "%s", _ ("Error scanning directory.\n"));
679 ret = 1;
680 GNUNET_SCHEDULER_shutdown ();
681 break;
682
683 default:
684 GNUNET_assert (0);
685 break;
686 }
687 fflush (stdout);
688}
689
690
691/**
692 * Continuation proceeding with initialization after identity subsystem
693 * has been initialized.
694 *
695 * @param args0 filename to publish
696 */
697static void
698identity_continuation (const char *args0)
699{
700 char *ex;
701 char *emsg;
702
703 if ((NULL != pseudonym) && (NULL == namespace))
704 {
705 fprintf (stderr, _ ("Selected pseudonym `%s' unknown\n"), pseudonym);
706 ret = 1;
707 GNUNET_SCHEDULER_shutdown ();
708 return;
709 }
710 if (NULL != uri_string)
711 {
712 emsg = NULL;
713 if (NULL == (uri = GNUNET_FS_uri_parse (uri_string, &emsg)))
714 {
715 fprintf (stderr, _ ("Failed to parse URI: %s\n"), emsg);
716 GNUNET_free (emsg);
717 ret = 1;
718 GNUNET_SCHEDULER_shutdown ();
719 return;
720 }
721 GNUNET_FS_publish_ksk (ctx,
722 topKeywords,
723 meta,
724 uri,
725 &bo,
726 GNUNET_FS_PUBLISH_OPTION_NONE,
727 &uri_ksk_continuation,
728 NULL);
729 return;
730 }
731 if (GNUNET_OK !=
732 GNUNET_CONFIGURATION_get_value_string (cfg, "FS", "EXTRACTORS", &ex))
733 ex = NULL;
734 if (0 != access (args0, R_OK))
735 {
736 fprintf (stderr,
737 _ ("Failed to access `%s': %s\n"),
738 args0,
739 strerror (errno));
740 GNUNET_free (ex);
741 return;
742 }
743 ds = GNUNET_FS_directory_scan_start (args0,
744 disable_extractor,
745 ex,
746 &directory_scan_cb,
747 NULL);
748 if (NULL == ds)
749 {
750 fprintf (
751 stderr,
752 "%s",
753 _ (
754 "Failed to start meta directory scanner. Is gnunet-helper-publish-fs installed?\n"));
755 GNUNET_free (ex);
756 return;
757 }
758 GNUNET_free (ex);
759}
760
761
762/**
763 * Function called by identity service with known pseudonyms.
764 *
765 * @param cls closure with 'const char *' of filename to publish
766 * @param ego ego handle
767 * @param ctx context for application to store data for this ego
768 * (during the lifetime of this process, initially NULL)
769 * @param name name assigned by the user for this ego,
770 * NULL if the user just deleted the ego and it
771 * must thus no longer be used
772 */
773static void
774identity_cb (void *cls,
775 struct GNUNET_IDENTITY_Ego *ego,
776 void **ctx,
777 const char *name)
778{
779 const char *args0 = cls;
780
781 if (NULL == ego)
782 {
783 identity_continuation (args0);
784 return;
785 }
786 if (NULL == name)
787 return;
788 if (0 == strcmp (name, pseudonym))
789 namespace = ego;
790}
791
792
793/**
794 * Main function that will be run by the scheduler.
795 *
796 * @param cls closure
797 * @param args remaining command-line arguments
798 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
799 * @param c configuration
800 */
801static void
802run (void *cls,
803 char *const *args,
804 const char *cfgfile,
805 const struct GNUNET_CONFIGURATION_Handle *c)
806{
807 /* check arguments */
808 if ((NULL != uri_string) && (extract_only))
809 {
810 printf (_ ("Cannot extract metadata from a URI!\n"));
811 ret = -1;
812 return;
813 }
814 if (((NULL == uri_string) || (extract_only)) &&
815 ((NULL == args[0]) || (NULL != args[1])))
816 {
817 printf (_ ("You must specify one and only one filename for insertion.\n"));
818 ret = -1;
819 return;
820 }
821 if ((NULL != uri_string) && (NULL != args[0]))
822 {
823 printf (_ ("You must NOT specify an URI and a filename.\n"));
824 ret = -1;
825 return;
826 }
827 if (NULL != pseudonym)
828 {
829 if (NULL == this_id)
830 {
831 fprintf (stderr,
832 _ ("Option `%s' is required when using option `%s'.\n"),
833 "-t",
834 "-P");
835 ret = -1;
836 return;
837 }
838 }
839 else
840 { /* ordinary insertion checks */
841 if (NULL != next_id)
842 {
843 fprintf (stderr,
844 _ ("Option `%s' makes no sense without option `%s'.\n"),
845 "-N",
846 "-P");
847 ret = -1;
848 return;
849 }
850 if (NULL != this_id)
851 {
852 fprintf (stderr,
853 _ ("Option `%s' makes no sense without option `%s'.\n"),
854 "-t",
855 "-P");
856 ret = -1;
857 return;
858 }
859 }
860 cfg = c;
861 ctx = GNUNET_FS_start (cfg,
862 "gnunet-publish",
863 &progress_cb,
864 NULL,
865 GNUNET_FS_FLAGS_NONE,
866 GNUNET_FS_OPTIONS_END);
867 if (NULL == ctx)
868 {
869 fprintf (stderr, _ ("Could not initialize `%s' subsystem.\n"), "FS");
870 ret = 1;
871 return;
872 }
873 GNUNET_SCHEDULER_add_shutdown (&do_stop_task, NULL);
874 if (NULL != pseudonym)
875 identity = GNUNET_IDENTITY_connect (cfg, &identity_cb, args[0]);
876 else
877 identity_continuation (args[0]);
878}
879
880
881/**
882 * The main function to publish content to GNUnet.
883 *
884 * @param argc number of arguments from the command line
885 * @param argv command line arguments
886 * @return 0 ok, 1 on error
887 */
888int
889main (int argc, char *const *argv)
890{
891 struct GNUNET_GETOPT_CommandLineOption options[] =
892 { GNUNET_GETOPT_option_uint ('a',
893 "anonymity",
894 "LEVEL",
895 gettext_noop (
896 "set the desired LEVEL of sender-anonymity"),
897 &bo.anonymity_level),
898 GNUNET_GETOPT_option_flag (
899 'D',
900 "disable-extractor",
901 gettext_noop ("do not use libextractor to add keywords or metadata"),
902 &disable_extractor),
903 GNUNET_GETOPT_option_flag ('E',
904 "enable-creation-time",
905 gettext_noop (
906 "enable adding the creation time to the "
907 "metadata of the uploaded file"),
908 &enable_creation_time),
909 GNUNET_GETOPT_option_flag ('e',
910 "extract",
911 gettext_noop (
912 "print list of extracted keywords that would "
913 "be used, but do not perform upload"),
914 &extract_only),
915 GNUNET_FS_GETOPT_KEYWORDS (
916 'k',
917 "key",
918 "KEYWORD",
919 gettext_noop (
920 "add an additional keyword for the top-level "
921 "file or directory (this option can be specified multiple times)"),
922 &topKeywords),
923 GNUNET_FS_GETOPT_METADATA (
924 'm',
925 "meta",
926 "TYPE:VALUE",
927 gettext_noop ("set the meta-data for the given TYPE to the given VALUE"),
928 &meta),
929 GNUNET_GETOPT_option_flag (
930 'n',
931 "noindex",
932 gettext_noop ("do not index, perform full insertion (stores "
933 "entire file in encrypted form in GNUnet database)"),
934 &do_insert),
935 GNUNET_GETOPT_option_string (
936 'N',
937 "next",
938 "ID",
939 gettext_noop ("specify ID of an updated version to be "
940 "published in the future (for namespace insertions only)"),
941 &next_id),
942 GNUNET_GETOPT_option_uint ('p',
943 "priority",
944 "PRIORITY",
945 gettext_noop (
946 "specify the priority of the content"),
947 &bo.content_priority),
948 GNUNET_GETOPT_option_string ('P',
949 "pseudonym",
950 "NAME",
951 gettext_noop (
952 "publish the files under the pseudonym "
953 "NAME (place file into namespace)"),
954 &pseudonym),
955 GNUNET_GETOPT_option_uint ('r',
956 "replication",
957 "LEVEL",
958 gettext_noop (
959 "set the desired replication LEVEL"),
960 &bo.replication_level),
961 GNUNET_GETOPT_option_flag ('s',
962 "simulate-only",
963 gettext_noop (
964 "only simulate the process but do not do "
965 "any actual publishing (useful to compute URIs)"),
966 &do_simulate),
967 GNUNET_GETOPT_option_string ('t',
968 "this",
969 "ID",
970 gettext_noop (
971 "set the ID of this version of the publication "
972 "(for namespace insertions only)"),
973 &this_id),
974 GNUNET_GETOPT_option_string (
975 'u',
976 "uri",
977 "URI",
978 gettext_noop (
979 "URI to be published (can be used instead of passing a "
980 "file to add keywords to the file with the respective URI)"),
981 &uri_string),
982
983 GNUNET_GETOPT_option_verbose (&verbose),
984
985 GNUNET_GETOPT_OPTION_END };
986
987 bo.expiration_time =
988 GNUNET_TIME_year_to_time (GNUNET_TIME_get_current_year () + 2);
989
990 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
991 return 2;
992 ret =
993 (GNUNET_OK ==
994 GNUNET_PROGRAM_run (argc,
995 argv,
996 "gnunet-publish [OPTIONS] FILENAME",
997 gettext_noop ("Publish a file or directory on GNUnet"),
998 options,
999 &run,
1000 NULL))
1001 ? ret
1002 : 1;
1003 GNUNET_free_nz ((void *) argv);
1004 return ret;
1005}
1006
1007
1008/* end of gnunet-publish.c */