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