diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-03-31 19:29:36 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-03-31 19:29:36 +0000 |
commit | 4ef94875c1e50499513fd50f6a0feee479a07812 (patch) | |
tree | 88b4d5628c2b6b8127ac0828a246d992b1aa4362 | |
parent | 5b6955a12b801a06f428acf8ba2cd651cd294912 (diff) | |
download | gnunet-4ef94875c1e50499513fd50f6a0feee479a07812.tar.gz gnunet-4ef94875c1e50499513fd50f6a0feee479a07812.zip |
stuff
-rw-r--r-- | TODO | 36 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | doc/man/gnunet-download.1 | 3 | ||||
-rw-r--r-- | src/arm/Makefile.am | 3 | ||||
-rw-r--r-- | src/fs/fs.h | 27 | ||||
-rw-r--r-- | src/fs/fs_download.c | 197 | ||||
-rw-r--r-- | src/fs/gnunet-download.c | 94 | ||||
-rw-r--r-- | src/fs/gnunet-publish.c | 35 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_indexing.c | 21 | ||||
-rw-r--r-- | src/include/gnunet_disk_lib.h | 2 |
10 files changed, 301 insertions, 124 deletions
@@ -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 | ||
164 | 0.9.0: | 173 | 0.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 | ||
184 | 0.9.x: | 188 | 0.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]) |
589 | AC_SUBST(GN_DAEMON_CONFIG_DIR, $gn_daemon_config_dir) | 589 | AC_SUBST(GN_DAEMON_CONFIG_DIR, $gn_daemon_config_dir) |
590 | gn_daemon_pidfile="/var/run/gnunetd/pid" | ||
591 | AC_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]) | ||
596 | AC_SUBST(GN_DAEMON_PIDFILE, $gn_daemon_pidfile) | ||
597 | 590 | ||
598 | GN_INTLINCL="" | 591 | GN_INTLINCL="" |
599 | GN_LIBINTL="$LTLIBINTL" | 592 | GN_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 |
15 | use config file (defaults: ~/.gnunet/gnunet.conf) | 15 | use config file (defaults: ~/.gnunet/gnunet.conf) |
16 | .TP | 16 | .TP |
17 | \fB\-d, \fB\-\-directory\fR | ||
18 | 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. | ||
19 | .TP | ||
20 | \fB\-D, \fB\-\-delete\-incomplete\fR | 17 | \fB\-D, \fB\-\-delete\-incomplete\fR |
21 | causes 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. | 18 | causes 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 = \ | |||
53 | check_SCRIPTS = \ | 53 | check_SCRIPTS = \ |
54 | test_gnunet_arm.sh | 54 | test_gnunet_arm.sh |
55 | 55 | ||
56 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) | 56 | TESTS = $(check_PROGRAMS) |
57 | #$(check_SCRIPTS) | ||
57 | 58 | ||
58 | test_arm_api_SOURCES = \ | 59 | test_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 | */ | ||
352 | static void | ||
353 | trigger_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 | */ | ||
401 | static void | ||
402 | full_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 | ||
52 | static int do_recursive; | 49 | static int do_recursive; |
53 | 50 | ||
54 | static int do_directory; | ||
55 | |||
56 | static char *filename; | 51 | static 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 | ||
69 | static int do_disable_creation_time; | 69 | static int do_disable_creation_time; |
70 | 70 | ||
71 | static GNUNET_SCHEDULER_TaskIdentifier kill_task; | ||
72 | |||
71 | 73 | ||
72 | static void | 74 | static void |
73 | do_stop_task (void *cls, | 75 | do_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 | */ |