aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-03-31 19:29:36 +0000
committerChristian Grothoff <christian@grothoff.org>2010-03-31 19:29:36 +0000
commit4ef94875c1e50499513fd50f6a0feee479a07812 (patch)
tree88b4d5628c2b6b8127ac0828a246d992b1aa4362
parent5b6955a12b801a06f428acf8ba2cd651cd294912 (diff)
downloadgnunet-4ef94875c1e50499513fd50f6a0feee479a07812.tar.gz
gnunet-4ef94875c1e50499513fd50f6a0feee479a07812.zip
stuff
-rw-r--r--TODO36
-rw-r--r--configure.ac7
-rw-r--r--doc/man/gnunet-download.13
-rw-r--r--src/arm/Makefile.am3
-rw-r--r--src/fs/fs.h27
-rw-r--r--src/fs/fs_download.c197
-rw-r--r--src/fs/gnunet-download.c94
-rw-r--r--src/fs/gnunet-publish.c35
-rw-r--r--src/fs/gnunet-service-fs_indexing.c21
-rw-r--r--src/include/gnunet_disk_lib.h2
10 files changed, 301 insertions, 124 deletions
diff --git a/TODO b/TODO
index a460da778..e0b730dbd 100644
--- a/TODO
+++ b/TODO
@@ -26,17 +26,18 @@ away), in order in which they will likely be done:
26 - utilization can (easily, restart?) go out of control (very large), causing 26 - utilization can (easily, restart?) go out of control (very large), causing
27 content expiration job to go crazy and delete everything! 27 content expiration job to go crazy and delete everything!
28* FS: [CG] 28* FS: [CG]
29 T gnunet-publish cannot be aborted using CTRL-C
30 - on some systems, keyword search does not find locally published content 29 - on some systems, keyword search does not find locally published content
31 (need testcase of command-line tools! - also good to cover getopt API!) 30 (need testcase of command-line tools! - also good to cover getopt API!)
32 [could be related to datastore issue above!] 31 [could be related to datastore issue above!]
33 - 2-peer download is still too slow (why?) 32 - 2-peer download is still too slow (why?)
34 - advanced FS API parts 33 - advanced FS API parts
35 T gnunet-download (directory-file download [easy]) 34 + pick correct filenames for recursive downloads (mkdir, .gnd)
36 T fs_download (recursive download; bounded parallelism) 35 + support recursive download even if filename is NULL and we hence
37 T indexing: index-failure-cleanup [easy] 36 do not generate files on disk (use temp_filename)
38 + gnunet-service-fs (remove failing on-demand blocks, hot-path routing, 37 + bound parallelism (# fs downloads)
39 load-based routing, nitpicks) 38 + distinguish in performance tracking and event signalling between
39 downloads that are actually running and those that are merely in the queue
40 + gnunet-service-fs (hot-path routing, load-based routing, nitpicks)
40 - [gnunet-service-fs.c:208]: member 'LocalGetContext::results_bf_size' is never used 41 - [gnunet-service-fs.c:208]: member 'LocalGetContext::results_bf_size' is never used
41 - [gnunet-service-fs.c:501]: member 'PendingRequest::used_pids_size' is never used 42 - [gnunet-service-fs.c:501]: member 'PendingRequest::used_pids_size' is never used
42 - [gnunet-service-fs.c:654]: member 'ConnectedPeer::last_client_replies' is never used 43 - [gnunet-service-fs.c:654]: member 'ConnectedPeer::last_client_replies' is never used
@@ -160,6 +161,14 @@ away), in order in which they will likely be done:
160 - test churn generation 161 - test churn generation
161 - consider changing API for peer-group termination to 162 - consider changing API for peer-group termination to
162 call continuation when done 163 call continuation when done
164* NAT/UPNP: [MW]
165 - finalize API design
166 - code clean up
167 - testing
168 - integration with transport service
169* MYSQL database backends: [CG]
170 - datacache
171 - datastore
163 172
1640.9.0: 1730.9.0:
165* new webpage: 174* new webpage:
@@ -171,14 +180,9 @@ away), in order in which they will likely be done:
171 enable developers to publish TGZs nicely 180 enable developers to publish TGZs nicely
172 - port "contact" page 181 - port "contact" page
173 - add content type for "todo" items? 182 - add content type for "todo" items?
174* Plugins to implement: [CG] 183* POSTGRES database backends: [CG]
175 - MySQL database backends 184 - datacache
176 + datacache 185 - datastore
177 + datastore
178 - Postgres database backends
179 + datacache
180 + datastore
181* VPN
182* Determine RC bugs and fix those! 186* Determine RC bugs and fix those!
183 187
1840.9.x: 1880.9.x:
@@ -214,6 +218,7 @@ away), in order in which they will likely be done:
214 we have not 'used' (for their public keys) in a while; need a way 218 we have not 'used' (for their public keys) in a while; need a way
215 to track actual 'use') 219 to track actual 'use')
216 - make sue we also trigger notifications whenever HELLOs expire 220 - make sue we also trigger notifications whenever HELLOs expire
221* VPN
217 222
218 223
219 224
@@ -246,4 +251,5 @@ Minor features:
246 - [./transport/gnunet-service-transport.c:173]: (style) struct or union member 'TransportPlugin::rebuild' is never used (related to TCP not refreshing external addresses?) 251 - [./transport/gnunet-service-transport.c:173]: (style) struct or union member 'TransportPlugin::rebuild' is never used (related to TCP not refreshing external addresses?)
247* DATACACHE: 252* DATACACHE:
248 - add stats (# bytes available, # bytes used, # PUTs, # GETs, # GETs satisfied) 253 - add stats (# bytes available, # bytes used, # PUTs, # GETs, # GETs satisfied)
249 254* FS:
255 - support inline data in directories for recursive file downloads (fs_download)
diff --git a/configure.ac b/configure.ac
index 4251e329c..aad6e44a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -587,13 +587,6 @@ AC_ARG_WITH(daemon-config-dir,
587 [default daemon config directory (/etc)]), 587 [default daemon config directory (/etc)]),
588 [gn_daemon_config_dir=$withval]) 588 [gn_daemon_config_dir=$withval])
589AC_SUBST(GN_DAEMON_CONFIG_DIR, $gn_daemon_config_dir) 589AC_SUBST(GN_DAEMON_CONFIG_DIR, $gn_daemon_config_dir)
590gn_daemon_pidfile="/var/run/gnunetd/pid"
591AC_ARG_WITH(daemon-pidfile,
592 AC_HELP_STRING(
593 [--with-daemon-pidfile=FILE],
594 [default daemon pidfile (/var/run/gnunetd/pid)]),
595 [gn_daemon_pidfile=$withval])
596AC_SUBST(GN_DAEMON_PIDFILE, $gn_daemon_pidfile)
597 590
598GN_INTLINCL="" 591GN_INTLINCL=""
599GN_LIBINTL="$LTLIBINTL" 592GN_LIBINTL="$LTLIBINTL"
diff --git a/doc/man/gnunet-download.1 b/doc/man/gnunet-download.1
index c729683e9..0db45aeb0 100644
--- a/doc/man/gnunet-download.1
+++ b/doc/man/gnunet-download.1
@@ -14,9 +14,6 @@ set desired level of receiver anonymity. Default is 1.
14\fB\-c \fIFILENAME\fR, \fB\-\-config=FILENAME\fR 14\fB\-c \fIFILENAME\fR, \fB\-\-config=FILENAME\fR
15use config file (defaults: ~/.gnunet/gnunet.conf) 15use config file (defaults: ~/.gnunet/gnunet.conf)
16.TP 16.TP
17\fB\-d, \fB\-\-directory\fR
18download a GNUnet directory that has already been downloaded. Requires that a filename of an existing file is specified instead of the URI. The download will only download the top\-level files in the directory unless the `\-R' option is also specified.
19.TP
20\fB\-D, \fB\-\-delete\-incomplete\fR 17\fB\-D, \fB\-\-delete\-incomplete\fR
21causes gnunet\-download to delete incomplete downloads when aborted with CTRL\-C. Note that complete files that are part of an incomplete recursive download will not be deleted even with this option. Without this option, terminating gnunet\-download with a signal will cause incomplete downloads to stay on disk. If gnunet\-download runs to (normal) completion finishing the download, this option has no effect. 18causes gnunet\-download to delete incomplete downloads when aborted with CTRL\-C. Note that complete files that are part of an incomplete recursive download will not be deleted even with this option. Without this option, terminating gnunet\-download with a signal will cause incomplete downloads to stay on disk. If gnunet\-download runs to (normal) completion finishing the download, this option has no effect.
22.TP 19.TP
diff --git a/src/arm/Makefile.am b/src/arm/Makefile.am
index f9c2a3289..0f6ef4237 100644
--- a/src/arm/Makefile.am
+++ b/src/arm/Makefile.am
@@ -53,7 +53,8 @@ check_PROGRAMS = \
53check_SCRIPTS = \ 53check_SCRIPTS = \
54 test_gnunet_arm.sh 54 test_gnunet_arm.sh
55 55
56TESTS = $(check_PROGRAMS) $(check_SCRIPTS) 56TESTS = $(check_PROGRAMS)
57#$(check_SCRIPTS)
57 58
58test_arm_api_SOURCES = \ 59test_arm_api_SOURCES = \
59 test_arm_api.c 60 test_arm_api.c
diff --git a/src/fs/fs.h b/src/fs/fs.h
index e3b3bc99d..77a73c3d6 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -955,6 +955,26 @@ struct GNUNET_FS_DownloadContext
955 struct GNUNET_FS_DownloadContext *parent; 955 struct GNUNET_FS_DownloadContext *parent;
956 956
957 /** 957 /**
958 * Head of list of child downloads.
959 */
960 struct GNUNET_FS_DownloadContext *child_head;
961
962 /**
963 * Tail of list of child downloads.
964 */
965 struct GNUNET_FS_DownloadContext *child_tail;
966
967 /**
968 * Previous download belonging to the same parent.
969 */
970 struct GNUNET_FS_DownloadContext *prev;
971
972 /**
973 * Next download belonging to the same parent.
974 */
975 struct GNUNET_FS_DownloadContext *next;
976
977 /**
958 * Context kept for the client. 978 * Context kept for the client.
959 */ 979 */
960 void *client_info; 980 void *client_info;
@@ -982,6 +1002,13 @@ struct GNUNET_FS_DownloadContext
982 char *filename; 1002 char *filename;
983 1003
984 /** 1004 /**
1005 * Where are we writing the data temporarily (name of the
1006 * file, can be NULL!); used if we do not have a permanent
1007 * name and we are a directory and we do a recursive download.
1008 */
1009 char *temp_filename;
1010
1011 /**
985 * Map of active requests (those waiting 1012 * Map of active requests (those waiting
986 * for a response). The key is the hash 1013 * for a response). The key is the hash
987 * of the encryped block (aka query). 1014 * of the encryped block (aka query).
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index 3de192e12..46759f495 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -25,6 +25,8 @@
25 * TODO: 25 * TODO:
26 * - handle recursive downloads (need directory & 26 * - handle recursive downloads (need directory &
27 * fs-level download-parallelism management) 27 * fs-level download-parallelism management)
28 * - handle recursive downloads where directory file is
29 * NOT saved on disk (need temporary file instead then!)
28 * - location URI suppport (can wait, easy) 30 * - location URI suppport (can wait, easy)
29 * - check if blocks exist already (can wait, easy) 31 * - check if blocks exist already (can wait, easy)
30 * - check if iblocks can be computed from existing blocks (can wait, hard) 32 * - check if iblocks can be computed from existing blocks (can wait, hard)
@@ -39,15 +41,12 @@
39#define DEBUG_DOWNLOAD GNUNET_NO 41#define DEBUG_DOWNLOAD GNUNET_NO
40 42
41/** 43/**
42 * We're storing the IBLOCKS after the 44 * We're storing the IBLOCKS after the DBLOCKS on disk (so that we
43 * DBLOCKS on disk (so that we only have 45 * only have to truncate the file once we're done).
44 * to truncate the file once we're done).
45 * 46 *
46 * Given the offset of a block (with respect 47 * Given the offset of a block (with respect to the DBLOCKS) and its
47 * to the DBLOCKS) and its depth, return the 48 * depth, return the offset where we would store this block in the
48 * offset where we would store this block 49 * file.
49 * in the file.
50
51 * 50 *
52 * @param fsize overall file size 51 * @param fsize overall file size
53 * @param off offset of the block in the file 52 * @param off offset of the block in the file
@@ -245,8 +244,7 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc,
245 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 244 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
246 GNUNET_NO, 245 GNUNET_NO,
247 &transmit_download_request, 246 &transmit_download_request,
248 dc); 247 dc);
249
250} 248}
251 249
252 250
@@ -341,6 +339,129 @@ struct ProcessResultClosure
341 339
342 340
343/** 341/**
342 * We found an entry in a directory. Check if the respective child
343 * already exists and if not create the respective child download.
344 *
345 * @param cls the parent download
346 * @param filename name of the file in the directory
347 * @param uri URI of the file (CHK or LOC)
348 * @param meta meta data of the file
349 * @param length number of bytes in data
350 * @param data contents of the file (or NULL if they were not inlined)
351 */
352static void
353trigger_recursive_download (void *cls,
354 const char *filename,
355 const struct GNUNET_FS_Uri *uri,
356 const struct GNUNET_CONTAINER_MetaData *meta,
357 size_t length,
358 const void *data)
359{
360 struct GNUNET_FS_DownloadContext *dc = cls;
361 struct GNUNET_FS_DownloadContext *cpos;
362
363 cpos = dc->child_head;
364 while (cpos != NULL)
365 {
366 if (0 == strcmp (cpos->filename,
367 filename))
368 {
369 GNUNET_break_op (GNUNET_FS_uri_test_equal (uri,
370 cpos->uri));
371 break;
372 }
373 cpos = cpos->next;
374 }
375 if (cpos != NULL)
376 return; /* already exists */
377 if (data != NULL)
378 {
379 /* determine on-disk filename, write data! */
380 GNUNET_break (0); // FIXME: not implemented
381 }
382 GNUNET_FS_download_start (dc->h,
383 uri,
384 meta,
385 filename, /* FIXME: prepend directory name! */
386 0,
387 GNUNET_FS_uri_chk_get_file_size (uri),
388 dc->anonymity,
389 dc->options,
390 NULL,
391 dc);
392}
393
394
395/**
396 * We're done downloading a directory. Open the file and
397 * trigger all of the (remaining) child downloads.
398 *
399 * @param dc context of download that just completed
400 */
401static void
402full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
403{
404 size_t size;
405 uint64_t size64;
406 void *data;
407 struct GNUNET_DISK_FileHandle *h;
408 struct GNUNET_DISK_MapHandle *m;
409
410 size64 = GNUNET_FS_uri_chk_get_file_size (dc->uri);
411 size = (size_t) size64;
412 if (size64 != (uint64_t) size)
413 {
414 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
415 _("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
416 return;
417 }
418 if (dc->filename != NULL)
419 {
420 h = GNUNET_DISK_file_open (dc->filename,
421 GNUNET_DISK_OPEN_READ,
422 GNUNET_DISK_PERM_NONE);
423 }
424 else
425 {
426 /* FIXME: need to initialize (and use) temp_filename
427 in various places in order for this assertion to
428 not fail; right now, it will always fail! */
429 GNUNET_assert (dc->temp_filename != NULL);
430 h = GNUNET_DISK_file_open (dc->temp_filename,
431 GNUNET_DISK_OPEN_READ,
432 GNUNET_DISK_PERM_NONE);
433 }
434 if (h == NULL)
435 return; /* oops */
436 data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size);
437 if (data == NULL)
438 {
439 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
440 _("Directory too large for system address space\n"));
441 }
442 else
443 {
444 GNUNET_FS_directory_list_contents (size,
445 data,
446 0,
447 &trigger_recursive_download,
448 dc);
449 GNUNET_DISK_file_unmap (m);
450 }
451 GNUNET_DISK_file_close (h);
452 if (dc->filename == NULL)
453 {
454 if (0 != UNLINK (dc->temp_filename))
455 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
456 "unlink",
457 dc->temp_filename);
458 GNUNET_free (dc->temp_filename);
459 dc->temp_filename = NULL;
460 }
461}
462
463
464/**
344 * Iterator over entries in the pending requests in the 'active' map for the 465 * Iterator over entries in the pending requests in the 'active' map for the
345 * reply that we just got. 466 * reply that we just got.
346 * 467 *
@@ -484,6 +605,17 @@ process_result_with_request (void *cls,
484 app -= (sm->offset + prc->size) - (dc->offset + dc->length); 605 app -= (sm->offset + prc->size) - (dc->offset + dc->length);
485 } 606 }
486 dc->completed += app; 607 dc->completed += app;
608
609 if ( (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
610 (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) )
611 {
612 GNUNET_FS_directory_list_contents (prc->size,
613 pt,
614 off,
615 &trigger_recursive_download,
616 dc);
617 }
618
487 } 619 }
488 620
489 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS; 621 pi.status = GNUNET_FS_STATUS_DOWNLOAD_PROGRESS;
@@ -513,11 +645,18 @@ process_result_with_request (void *cls,
513 "truncate", 645 "truncate",
514 dc->filename); 646 dc->filename);
515 } 647 }
516 /* signal completion */ 648
517 pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED; 649 if ( (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
518 make_download_status (&pi, dc); 650 (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) )
519 dc->client_info = dc->h->upcb (dc->h->upcb_cls, 651 full_recursive_download (dc);
520 &pi); 652 if (dc->child_head == NULL)
653 {
654 /* signal completion */
655 pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED;
656 make_download_status (&pi, dc);
657 dc->client_info = dc->h->upcb (dc->h->upcb_cls,
658 &pi);
659 }
521 GNUNET_assert (sm->depth == dc->treedepth); 660 GNUNET_assert (sm->depth == dc->treedepth);
522 } 661 }
523 // FIXME: make persistent 662 // FIXME: make persistent
@@ -836,11 +975,6 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
836 GNUNET_break (0); 975 GNUNET_break (0);
837 return NULL; 976 return NULL;
838 } 977 }
839 client = GNUNET_CLIENT_connect (h->sched,
840 "fs",
841 h->cfg);
842 if (NULL == client)
843 return NULL;
844 // FIXME: add support for "loc" URIs! 978 // FIXME: add support for "loc" URIs!
845#if DEBUG_DOWNLOAD 979#if DEBUG_DOWNLOAD
846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 980 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -850,8 +984,13 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
850#endif 984#endif
851 dc = GNUNET_malloc (sizeof(struct GNUNET_FS_DownloadContext)); 985 dc = GNUNET_malloc (sizeof(struct GNUNET_FS_DownloadContext));
852 dc->h = h; 986 dc->h = h;
853 dc->client = client;
854 dc->parent = parent; 987 dc->parent = parent;
988 if (parent != NULL)
989 {
990 GNUNET_CONTAINER_DLL_insert (parent->child_head,
991 parent->child_tail,
992 dc);
993 }
855 dc->uri = GNUNET_FS_uri_dup (uri); 994 dc->uri = GNUNET_FS_uri_dup (uri);
856 dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); 995 dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
857 dc->client_info = cctx; 996 dc->client_info = cctx;
@@ -897,6 +1036,12 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
897 dc->treedepth); 1036 dc->treedepth);
898#endif 1037#endif
899 // FIXME: make persistent 1038 // FIXME: make persistent
1039
1040 // FIXME: bound parallelism here!
1041 client = GNUNET_CLIENT_connect (h->sched,
1042 "fs",
1043 h->cfg);
1044 dc->client = client;
900 schedule_block_download (dc, 1045 schedule_block_download (dc,
901 &dc->uri->data.chk.chk, 1046 &dc->uri->data.chk.chk,
902 0, 1047 0,
@@ -945,7 +1090,15 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc,
945{ 1090{
946 struct GNUNET_FS_ProgressInfo pi; 1091 struct GNUNET_FS_ProgressInfo pi;
947 1092
1093 while (NULL != dc->child_head)
1094 GNUNET_FS_download_stop (dc->child_head,
1095 do_delete);
948 // FIXME: make unpersistent 1096 // FIXME: make unpersistent
1097 if (dc->parent != NULL)
1098 GNUNET_CONTAINER_DLL_remove (dc->parent->child_head,
1099 dc->parent->child_tail,
1100 dc);
1101
949 pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; 1102 pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED;
950 make_download_status (&pi, dc); 1103 make_download_status (&pi, dc);
951 dc->client_info = dc->h->upcb (dc->h->upcb_cls, 1104 dc->client_info = dc->h->upcb (dc->h->upcb_cls,
diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c
index 63895d4b2..6f50922be 100644
--- a/src/fs/gnunet-download.c
+++ b/src/fs/gnunet-download.c
@@ -24,9 +24,6 @@
24 * @author Krista Bennett 24 * @author Krista Bennett
25 * @author James Blackwell 25 * @author James Blackwell
26 * @author Igor Wronsky 26 * @author Igor Wronsky
27 *
28 * TODO:
29 * - download-directory option support (do_directory)
30 */ 27 */
31#include "platform.h" 28#include "platform.h"
32#include "gnunet_fs_service.h" 29#include "gnunet_fs_service.h"
@@ -51,8 +48,6 @@ static unsigned int parallelism = 16;
51 48
52static int do_recursive; 49static int do_recursive;
53 50
54static int do_directory;
55
56static char *filename; 51static char *filename;
57 52
58 53
@@ -133,15 +128,8 @@ progress_cb (void *cls,
133 info->value.download.filename, 128 info->value.download.filename,
134 s); 129 s);
135 GNUNET_free (s); 130 GNUNET_free (s);
136 if (do_directory) 131 if (info->value.download.dc == dc)
137 { 132 GNUNET_SCHEDULER_shutdown (sched);
138 GNUNET_break (0); //FIXME: not implemented
139 }
140 else
141 {
142 if (info->value.download.dc == dc)
143 GNUNET_SCHEDULER_shutdown (sched);
144 }
145 break; 133 break;
146 case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: 134 case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
147 if (info->value.download.dc == dc) 135 if (info->value.download.dc == dc)
@@ -181,31 +169,24 @@ run (void *cls,
181 enum GNUNET_FS_DownloadOptions options; 169 enum GNUNET_FS_DownloadOptions options;
182 170
183 sched = s; 171 sched = s;
184 if (do_directory) 172 uri = GNUNET_FS_uri_parse (args[0],
173 &emsg);
174 if (NULL == uri)
185 { 175 {
186 GNUNET_break (0); //FIXME: not implemented 176 fprintf (stderr,
177 _("Failed to parse URI: %s\n"),
178 emsg);
179 GNUNET_free (emsg);
180 ret = 1;
181 return;
187 } 182 }
188 else 183 if (! GNUNET_FS_uri_test_chk (uri))
189 { 184 {
190 uri = GNUNET_FS_uri_parse (args[0], 185 fprintf (stderr,
191 &emsg); 186 "Only CHK URIs supported right now.\n");
192 if (NULL == uri) 187 ret = 1;
193 { 188 GNUNET_FS_uri_destroy (uri);
194 fprintf (stderr, 189 return;
195 _("Failed to parse URI: %s\n"),
196 emsg);
197 GNUNET_free (emsg);
198 ret = 1;
199 return;
200 }
201 if (! GNUNET_FS_uri_test_chk (uri))
202 {
203 fprintf (stderr,
204 "Only CHK URIs supported right now.\n");
205 ret = 1;
206 GNUNET_FS_uri_destroy (uri);
207 return;
208 }
209 } 190 }
210 if (NULL == filename) 191 if (NULL == filename)
211 { 192 {
@@ -237,29 +218,22 @@ run (void *cls,
237 options = GNUNET_FS_DOWNLOAD_OPTION_NONE; 218 options = GNUNET_FS_DOWNLOAD_OPTION_NONE;
238 if (do_recursive) 219 if (do_recursive)
239 options |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE; 220 options |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE;
240 if (do_directory) 221 dc = GNUNET_FS_download_start (ctx,
222 uri,
223 NULL,
224 filename,
225 0,
226 GNUNET_FS_uri_chk_get_file_size (uri),
227 anonymity,
228 options,
229 NULL,
230 NULL);
231 GNUNET_FS_uri_destroy (uri);
232 if (dc == NULL)
241 { 233 {
242 GNUNET_break (0); //FIXME: not implemented 234 GNUNET_FS_stop (ctx);
243 } 235 ctx = NULL;
244 else 236 return;
245 {
246 dc = GNUNET_FS_download_start (ctx,
247 uri,
248 NULL,
249 filename,
250 0,
251 GNUNET_FS_uri_chk_get_file_size (uri),
252 anonymity,
253 options,
254 NULL,
255 NULL);
256 GNUNET_FS_uri_destroy (uri);
257 if (dc == NULL)
258 {
259 GNUNET_FS_stop (ctx);
260 ctx = NULL;
261 return;
262 }
263 } 237 }
264 GNUNET_SCHEDULER_add_delayed (sched, 238 GNUNET_SCHEDULER_add_delayed (sched,
265 GNUNET_TIME_UNIT_FOREVER_REL, 239 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -275,10 +249,6 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
275 {'a', "anonymity", "LEVEL", 249 {'a', "anonymity", "LEVEL",
276 gettext_noop ("set the desired LEVEL of receiver-anonymity"), 250 gettext_noop ("set the desired LEVEL of receiver-anonymity"),
277 1, &GNUNET_GETOPT_set_uint, &anonymity}, 251 1, &GNUNET_GETOPT_set_uint, &anonymity},
278 {'d', "directory", NULL,
279 gettext_noop
280 ("download a GNUnet directory that has already been downloaded. Requires that a filename of an existing file is specified instead of the URI. The download will only download the top-level files in the directory unless the `-R' option is also specified."),
281 0, &GNUNET_GETOPT_set_one, &do_directory},
282 {'D', "delete-incomplete", NULL, 252 {'D', "delete-incomplete", NULL,
283 gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"), 253 gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"),
284 0, &GNUNET_GETOPT_set_one, &delete_incomplete}, 254 0, &GNUNET_GETOPT_set_one, &delete_incomplete},
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 1e0884361..70964590d 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -68,6 +68,8 @@ static int extract_only;
68 68
69static int do_disable_creation_time; 69static int do_disable_creation_time;
70 70
71static GNUNET_SCHEDULER_TaskIdentifier kill_task;
72
71 73
72static void 74static void
73do_stop_task (void *cls, 75do_stop_task (void *cls,
@@ -124,6 +126,12 @@ progress_cb (void *cls,
124 fprintf (stderr, 126 fprintf (stderr,
125 _("Error publishing: %s.\n"), 127 _("Error publishing: %s.\n"),
126 info->value.publish.specifics.error.message); 128 info->value.publish.specifics.error.message);
129 if (kill_task != GNUNET_SCHEDULER_NO_TASK)
130 {
131 GNUNET_SCHEDULER_cancel (sched,
132 kill_task);
133 kill_task = GNUNET_SCHEDULER_NO_TASK;
134 }
127 GNUNET_SCHEDULER_add_continuation (sched, 135 GNUNET_SCHEDULER_add_continuation (sched,
128 &do_stop_task, 136 &do_stop_task,
129 NULL, 137 NULL,
@@ -133,11 +141,24 @@ progress_cb (void *cls,
133 fprintf (stdout, 141 fprintf (stdout,
134 _("Publishing `%s' done.\n"), 142 _("Publishing `%s' done.\n"),
135 info->value.publish.filename); 143 info->value.publish.filename);
144 s = GNUNET_FS_uri_to_string (info->value.publish.specifics.completed.chk_uri);
145 fprintf (stdout,
146 _("URI is `%s'.\n"),
147 s);
148 GNUNET_free (s);
136 if (info->value.publish.pctx == NULL) 149 if (info->value.publish.pctx == NULL)
137 GNUNET_SCHEDULER_add_continuation (sched, 150 {
138 &do_stop_task, 151 if (kill_task != GNUNET_SCHEDULER_NO_TASK)
139 NULL, 152 {
140 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 153 GNUNET_SCHEDULER_cancel (sched,
154 kill_task);
155 kill_task = GNUNET_SCHEDULER_NO_TASK;
156 }
157 GNUNET_SCHEDULER_add_continuation (sched,
158 &do_stop_task,
159 NULL,
160 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
161 }
141 break; 162 break;
142 case GNUNET_FS_STATUS_PUBLISH_STOPPED: 163 case GNUNET_FS_STATUS_PUBLISH_STOPPED:
143 GNUNET_break (NULL == pc); 164 GNUNET_break (NULL == pc);
@@ -547,6 +568,10 @@ run (void *cls,
547 ret = 1; 568 ret = 1;
548 return; 569 return;
549 } 570 }
571 kill_task = GNUNET_SCHEDULER_add_delayed (sched,
572 GNUNET_TIME_UNIT_FOREVER_REL,
573 &do_stop_task,
574 NULL);
550} 575}
551 576
552 577
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index ca9a226a2..525da1a91 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -22,9 +22,6 @@
22 * @file fs/gnunet-service-fs_indexing.c 22 * @file fs/gnunet-service-fs_indexing.c
23 * @brief program that provides indexing functions of the file-sharing service 23 * @brief program that provides indexing functions of the file-sharing service
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - indexed files/blocks not removed on errors
28 */ 25 */
29#include "platform.h" 26#include "platform.h"
30#include <float.h> 27#include <float.h>
@@ -180,7 +177,7 @@ read_index_list ()
180 } 177 }
181 if (GNUNET_NO == GNUNET_DISK_file_test (fn)) 178 if (GNUNET_NO == GNUNET_DISK_file_test (fn))
182 { 179 {
183 /* no index info yet */ 180 /* no index info yet */
184 GNUNET_free (fn); 181 GNUNET_free (fn);
185 return; 182 return;
186 } 183 }
@@ -596,8 +593,12 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key,
596 STRERROR (errno)); 593 STRERROR (errno));
597 if (fh != NULL) 594 if (fh != NULL)
598 GNUNET_DISK_file_close (fh); 595 GNUNET_DISK_file_close (fh);
599 /* FIXME: if this happens often, we need 596 GNUNET_FS_drq_remove (key,
600 to remove the OnDemand block from the DS! */ 597 size,
598 data,
599 &remove_cont,
600 NULL,
601 GNUNET_TIME_UNIT_FOREVER_REL);
601 return GNUNET_SYSERR; 602 return GNUNET_SYSERR;
602 } 603 }
603 GNUNET_DISK_file_close (fh); 604 GNUNET_DISK_file_close (fh);
@@ -621,8 +622,12 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key,
621 _("Indexed file `%s' changed at offset %llu\n"), 622 _("Indexed file `%s' changed at offset %llu\n"),
622 fn, 623 fn,
623 (unsigned long long) off); 624 (unsigned long long) off);
624 /* FIXME: if this happens often, we need 625 GNUNET_FS_drq_remove (key,
625 to remove the OnDemand block from the DS! */ 626 size,
627 data,
628 &remove_cont,
629 NULL,
630 GNUNET_TIME_UNIT_FOREVER_REL);
626 return GNUNET_SYSERR; 631 return GNUNET_SYSERR;
627 } 632 }
628#if DEBUG_FS 633#if DEBUG_FS
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
index 7b6898293..fcb58ffef 100644
--- a/src/include/gnunet_disk_lib.h
+++ b/src/include/gnunet_disk_lib.h
@@ -312,7 +312,7 @@ GNUNET_DISK_mktemp (const char *t);
312 * @param fn file name to be opened 312 * @param fn file name to be opened
313 * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags 313 * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags
314 * @param perm permissions for the newly created file, use 314 * @param perm permissions for the newly created file, use
315 * GNUNET_DISK_PERM_USER_NONE if a file could not be created by this 315 * GNUNET_DISK_PERM_NONE if a file could not be created by this
316 * call (because of flags) 316 * call (because of flags)
317 * @return IO handle on success, NULL on error 317 * @return IO handle on success, NULL on error
318 */ 318 */