fs tools
authorChristian Grothoff <christian@grothoff.org>
Sun, 6 Sep 2009 21:03:16 +0000 (21:03 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sun, 6 Sep 2009 21:03:16 +0000 (21:03 +0000)
17 files changed:
TODO
doc/man/Makefile.am
doc/man/gnunet-download.1 [new file with mode: 0644]
doc/man/gnunet-peerinfo.1
doc/man/gnunet-publish.1
doc/man/gnunet-search.1 [new file with mode: 0644]
doc/man/gnunet-statistics.1
doc/man/gnunet-unindex.1 [new file with mode: 0644]
src/fs/fs.c
src/fs/fs.h
src/fs/fs_download.c
src/fs/fs_publish.c
src/fs/gnunet-download.c
src/fs/gnunet-publish.c
src/fs/gnunet-search.c
src/fs/gnunet-unindex.c
src/include/gnunet_fs_service.h

diff --git a/TODO b/TODO
index 24c12a1bf64d151ebe61a0cc7781f4247d9aaa69..fe9f791c4c404285cdbbc813d3862c7e6bbe4b99 100644 (file)
--- a/TODO
+++ b/TODO
@@ -36,11 +36,6 @@ Urgent items (before announcing ng.gnunet.org):
 * HOSTLIST:
   - implement testcases
 * FS (basic anonymous FS only)
-  - implement basic FS library
-    - gnunet-publish (progress CB, shutdown, URI args)
-    - gnunet-unindex (progress CB, shutdown, error checking)
-    - gnunet-search (start search, progress CB, shutdown, options)
-    - gnunet-download (start download, progress CB, shutdown, options)
   - design network structs (P2P)
     + query
     + response
@@ -80,6 +75,10 @@ Urgent items (before announcing ng.gnunet.org):
     + indexing: index-failure-cleanup
     + download: management/bounding of parallel downloads (for recursive dl.)
     + datastore reservation (publishing)
+    + gnunet-publish (URI args)
+    + gnunet-download (directory)
+    + gnunet-search (options, incl. namespace search)
+    - gnunet-download (many options)
   - implement adv. FS testcases 
     + insert: sblocks, loc uris
     + download: loc uris
index b5af700e0ff40449307dfa5c68d01448537b9966..aa8c737d7ca81e1311d079cba39049032b543f3e 100644 (file)
@@ -1,8 +1,11 @@
 man_MANS = \
   gnunet-arm.1 \
+  gnunet-download.1 \
   gnunet-peerinfo.1 \
   gnunet-publish.1 \
+  gnunet-search.1 \
   gnunet-statistics.1 \
-  gnunet-transport.c
+  gnunet-transport.1 \
+  gnunet-unindex.1
 
 EXTRA_DIST = ${man_MANS}
diff --git a/doc/man/gnunet-download.1 b/doc/man/gnunet-download.1
new file mode 100644 (file)
index 0000000..c729683
--- /dev/null
@@ -0,0 +1,68 @@
+.TH GNUNET-DOWNLOAD "1" "6 Sep 2009" "GNUnet"
+.SH NAME
+gnunet\-download \- a command line interface for downloading files from GNUnet
+.SH SYNOPSIS
+.B gnunet\-download
+[\fIOPTIONS\fR] \-\- GNUNET_URI
+.SH DESCRIPTION
+.PP
+Download files from GNUnet.
+.TP
+\fB\-a \fILEVEL\fR, \fB\-\-anonymity=LEVEL\fR
+set desired level of receiver anonymity.  Default is 1.
+.TP
+\fB\-c \fIFILENAME\fR, \fB\-\-config=FILENAME\fR
+use config file (defaults: ~/.gnunet/gnunet.conf)
+.TP
+\fB\-d, \fB\-\-directory\fR
+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.
+.TP
+\fB\-D, \fB\-\-delete\-incomplete\fR
+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.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print help page
+.TP
+\fB\-H \fIHOSTNAME\fR, \fB\-\-host=\fIHOSTNAME\fR
+on which host is gnunetd running (default: localhost).  You can also specify a port using the syntax HOSTNAME:PORT.  The default port is 2087.
+.TP
+\fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=LOGLEVEL\fR
+Change the loglevel.  Possible values for LOGLEVEL are 
+ERROR, WARNING, INFO and DEBUG. 
+.TP
+\fB\-o \fIFILENAME\fR, \fB\-\-output=FILENAME\fR
+write the file to FILENAME.  Hint: when recursively downloading a directory, append a '/' to the end of the FILENAME to create a directory of that name.  If no FILENAME is specified, gnunet\-download constructs a temporary ID from the URI of the file.  The final filename is constructed based on meta\-data extracted using libextractor (if available).
+.TP
+\fB\-p \fIDOWNLOADS\fR, \fB\-\-parallelism=DOWNLOADS\fR
+set the maximum number of parallel downloads that is allowed.  More parallel downloads can, to some extent, improve the overall time to download content.  However, parallel downloads also take more memory.  The specified number is the number of files that are downloaded in parallel, not the number of blocks that are concurrently requested.  As a result, the number only matters for recursive downloads.  The default value is 32.
+.TP
+\fB\-R\fR, \fB\-\-recursive\fR
+download directories recursively (and in parallel); note that the URI must belong to a GNUnet directory and that the filename given must end with a '/' \-\- otherwise, only the file corresponding to the URI will be downloaded.
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version number
+.TP
+\fB\-V\fR, \fB\-\-verbose\fR
+print progress information
+.SH NOTES
+The GNUNET_URI is typically obtained from gnunet\-search. gnunet\-gtk can also be used instead of gnunet\-download.
+If you ever have to abort a download, you can at any time continue it by re\-issuing gnunet\-download with the same filename. In that case GNUnet will not download blocks again that are already present. GNUnets file\-encoding will ensure file integrity, even if the existing file was not downloaded from GNUnet in the first place. Temporary information will be appended to the target file until the download is completed. 
+
+.SH SETTING ANONYMITY LEVEL
+
+The \fB\-a\fR option can be used to specify additional anonymity constraints. If set to 0, GNUnet will try to download the file as fast as possible without any additional slowdown by the anonymity code. Note that you will still have a fair degree of anonymity depending on the current network load and the power of the adversary. The download is still unlikely to be terribly fast since the sender may have requested sender\-anonymity and since in addition to that, GNUnet will still do the anonymous routing.
+
+This option can be used to limit requests further than that. In particular, you can require GNUnet to receive certain amounts of traffic from other peers before sending your queries. This way, you can gain very high levels of anonymity \- at the expense of much more traffic and much higher latency. So set it only if you really believe you need it.
+
+The definition of ANONYMITY\-RECEIVE is the following: If the value v is < 1000, it means that if GNUnet routes n bytes of messages from foreign peers, it may originate n/v bytes of queries in the same time\-period. The time\-period is twice the average delay that GNUnet deferrs forwarded queries. If the value v is >= 1000, it means that if GNUnet routes n bytes of QUERIES from at least (v % 1000) peers, it may originate n/v/1000 bytes of queries in the same time\-period.
+
+The default is 0 and this should be fine for most users. Also notice that if you choose values above 1000, you may end up having no throughput at all, especially if many of your fellow GNUnet\-peers do the same.
+
+.SH FILES
+.TP
+~/.gnunet/gnunet.conf
+GNUnet configuration file
+.SH "REPORTING BUGS"
+Report bugs to <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org>
+.SH "SEE ALSO"
+\fBgnunet\-gtk\fP(1), \fBgnunet\-publish\fP(1), \fBgnunet\-gtk\fP(1), \fBgnunet\-search\fP(1), \fBgnunet\-download\fP(1), \fBgnunet.conf\fP(5), \fBgnunetd\fP(1)
index 2980d35446a8aaef69299dbdc7ace87a65fe8666..d25dfa3d38d3eaffd778472ec953a3dae0d68846 100644 (file)
@@ -1,4 +1,4 @@
-.TH GNUNET-PEERINFO 1 "Mar 15, 2009" "GNUnet"
+.TH GNUNET\-PEERINFO 1 "Mar 15, 2009" "GNUnet"
 
 .SH NAME
 gnunet\-peerinfo \- Display information about other peers.
index 4926295cf6d65c90d2d9f89fdfd2cbf04b985197..df20596297034b9db7964776f4548dbbbabdf80d 100644 (file)
@@ -50,10 +50,8 @@ additional key to index the content with (to add multiple keys, specify multiple
 
 .TP
 \fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=\fILOGLEVEL\fR
-Change the loglevel.  Possible values for LOGLEVEL are NOTHING, FATAL,
-ERROR, WARNING, INFO, STATUS and DEBUG.  Note that options in the 
-configuration file take precedence over this option (the argument 
-will be ignored in that case).
+Change the loglevel.  Possible values for LOGLEVEL are 
+ERROR, WARNING, INFO and DEBUG. 
 
 .TP
 \fB\-m \fITYPE:VALUE\fR, \fB\-\-meta=\fITYPE:VALUE\fR
@@ -161,6 +159,6 @@ Update the previous entry, do not allow any future updates:
 ~/.gnunet/gnunet.conf
 GNUnet configuration file
 .SH "REPORTING BUGS"
-Report bugs by using mantis <https://gnunet.org/mantis/> or by sending electronic mail to <gnunet\-developers@gnu.org>
+Report bugs to <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org>
 .SH "SEE ALSO"
 \fBgnunet\-auto\-share\fP(1), \fBgnunet\-gtk\fP(1), \fBgnunet\-pseudonym\fP(1), \fBgnunet\-search\fP(1), \fBgnunet\-download\fP(1), \fBgnunet.conf\fP(5), \fBgnunetd\fP(1), \fBextract\fP(1)
diff --git a/doc/man/gnunet-search.1 b/doc/man/gnunet-search.1
new file mode 100644 (file)
index 0000000..5f6fffe
--- /dev/null
@@ -0,0 +1,72 @@
+.TH GNUNET-SEARCH "1" "6 Sep 2009" "GNUnet"
+.SH NAME
+gnunet\-search \- a command line interface to search for content on GNUnet
+.SH SYNOPSIS
+.B gnunet\-search
+[\fIOPTIONS\fR] [+]\fIKEYWORD\fR [[+]\fIKEYWORD\fR]*
+
+.B gnunet\-search
+[\fIOPTIONS\fR] [+]\fIURI\fR
+.SH DESCRIPTION
+.PP
+Search for content on GNUnet. The keywords are case\-sensitive.  gnunet\-search can be used both for a search in the global namespace as well as for searching a private subspace.
+.TP
+\fB\-a \fILEVEL\fR, \fB\-\-anonymity=\fILEVEL\fR
+The \fB-a\fR option can be used to specify additional anonymity constraints.  If set to 0, GNUnet will try to download the file as fast as possible without any additional slowdown for anonymous routing.  Note that you may still have some amount of anonymity depending on the current network load and the power of the adversary.  Use at least 1 to force GNUnet to use anonymous routing.
+
+This option can be used to limit requests further than that. In particular, you can require GNUnet to have a certain amount of cover traffic from other peers before sending your queries. This way, you can gain very high levels of anonymity \- at the expense of much more traffic and much higher latency. So set this option to values beyond 1 only if you really believe you need it.
+
+The definition of ANONYMITY\-RECEIVE is the following: If the value v is 0, anonymous routing is not required.  For 1, anonymous routing is required, but there is no lower bound on how much cover traffic must be present.  For values > 1 and < 1000, it means that if GNUnet routes n bytes of messages from foreign peers, it may originate n/v bytes of queries in the same time\-period. The time\-period is twice the average delay that GNUnet deferrs forwarded queries. If the value v is >= 1000, it means that if GNUnet routes n bytes of QUERIES from at least (v % 1000) peers, it may originate n/v/1000 bytes of queries in the same time\-period.
+
+The default is 1 and this should be fine for most users.  Also notice that if you choose values above 1000, you may end up having no throughput at all, especially if many of your fellow GNUnet\-peers do the same.
+
+.TP
+\fB\-c \fIFILENAME\fR, \fB\-\-config=\fIFILENAME\fR
+use config file (defaults: ~/.gnunet/gnunet.conf)
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print help page
+.TP
+\fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=\fILOGLEVEL\fR
+Change the loglevel.  Possible values for LOGLEVEL are 
+ERROR, WARNING, INFO and DEBUG. 
+.TP
+\fB\-o \fIPREFIX\fR, \fB\-\-output=\fIPREFIX\fR
+Writes the encountered (unencrypted) RBlocks or SBlocks to files with name PREFIX.XXX, where XXX is a number. This is useful to keep search results around.
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version number
+.SH NOTES
+
+You can run gnunet\-search with an URI instead of a keyword.  The URI can have the format for a namespace search or for a keyword search.  For a namespace search, the format is gnunet://fs/sks/NAMESPACE/IDENTIFIER.  For a keyword search, use gnunet://ecrs/ksk/KEYWORD[+KEYWORD]*.  If the format does not correspond to a GNUnet URI, GNUnet will automatically assume that keywords are supplied directly.  
+
+If multiple keywords are passed, gnunet-search will look for content matching any of the keywords.  The prefix "+" makes a keyword mandatory.  
+
+# gnunet\-search "Das Kapital"
+
+searches for content matching the keyword "Das Kapital".  Whereas
+
+# gnunet\-search +Das +Kapital
+
+Searches for content matching both mandatory keywords "Das" and "Kapital".
+
+Search results are printed by gnunet\-search like this:
+.P
+.ad l
+       gnunet\-download \-o "COPYING" gnunet://fs/chk/HASH1.HASH2.SIZE
+
+               Description: The GNU Public License
+
+               Mime-type: text/plain
+.ad b
+
+The first line contains the command to run to download the file.  The suggested filename in the example is COPYING.  The GNUnet URI consists of the key and query hash of the file and finally the size of the file.  After the command to download the file GNUnet will print meta\-data about the file as advertised in the search result, here "The GNU Public License" and the mime\-type (see the options for gnunet\-insert on how to supply meta-data by hand).
+
+.SH FILES
+.TP
+~/.gnunet/gnunet.conf
+GNUnet configuration file; specifies the default value for the timeout
+.SH "REPORTING BUGS"
+Report bugs to <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet-developers@gnu.org>
+.SH "SEE ALSO"
+\fBgnunet\-gtk\fP(1), \fBgnunet\-publish\fP(1), \fBgnunet\-download\fP(1), \fBgnunet\-pseudonym\fP(1), \fBgnunet.conf\fP(5), \fBgnunetd\fP(1)
index 8a23e01e0f5b61557f1c65a9cb3517135d667ed8..25f548ef6d891d1af11bdfe510f629bde97d0ab8 100644 (file)
@@ -4,7 +4,7 @@
 gnunet\-statistics \- Display statistics about your GNUnet system
 
 .SH SYNOPSIS
-.B gnunet-statistics
+.B gnunet\-statistics
 .RI [ options ] [ VALUE ]
 .br
 
diff --git a/doc/man/gnunet-unindex.1 b/doc/man/gnunet-unindex.1
new file mode 100644 (file)
index 0000000..be478ea
--- /dev/null
@@ -0,0 +1,37 @@
+.TH GNUNET-UNINDEX "1" "6 Sep 2009" "GNUnet"
+.SH NAME
+gnunet\-unindex \- a command line interface for deleting indexed files from GNUnet
+.SH SYNOPSIS
+.B gnunet\-unindex
+[\fIOPTIONS\fR] FILENAME
+.SH DESCRIPTION
+.PP
+gnunet\-unindex is used for deleting indexed files from GNUnet.
+.TP
+\fB\-c \fIFILENAME\fR, \fB\-\-config=FILENAME\fR
+use config file (defaults: ~/.gnunet/gnunet.conf)
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print help page
+.TP
+\fB\-L \fILOGLEVEL\fR, \fB\-\-loglevel=LOGLEVEL\fR
+Change the loglevel.  Possible values for LOGLEVEL are NOTHING,
+ERROR, WARNING, INFO and DEBUG. 
+
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version number
+.TP
+\fB\-V\fR, \fB\-\-verbose\fR
+be verbose
+.SH NOTES
+You can only unindex files that you indexed and that you still have available locally in full.  You should use gnunet\-unindex on files that you indexed (not inserted) and that you are going to delete or move locally.
+.TP
+.SH FILES
+.TP
+~/.gnunet/gnunet.conf
+GNUnet configuration file
+.SH "REPORTING BUGS"
+Report bugs to <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org>
+.SH "SEE ALSO"
+\fBgnunet\-gtk\fP(1), \fBgnunet\-publish\fP(1), \fBgnunet\-gtk\fP(1), \fBgnunet\-search\fP(1), \fBgnunet\-download\fP(1), \fBgnunet.conf\fP(5), \fBgnunetd\fP(1)
index 66699507b197efa726acf18949bb41b49c40220c..8396fc18f87983e78ad6d7a61ff7d513bb61754f 100644 (file)
  * @param client_name unique identifier for this client 
  * @param upcb function to call to notify about FS actions
  * @param upcb_cls closure for upcb
+ * @param flags specific attributes for fs-operations
+ * @param ... list of optional options, terminated with GNUNET_FS_OPTIONS_END
+ * @return NULL on error
  */
 struct GNUNET_FS_Handle *
 GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched,
                 const struct GNUNET_CONFIGURATION_Handle *cfg,
                 const char *client_name,
                 GNUNET_FS_ProgressCallback upcb,
-                void *upcb_cls)
+                void *upcb_cls,
+                enum GNUNET_FS_Flags flags,
+                ...)
 {
   struct GNUNET_FS_Handle *ret;
   struct GNUNET_CLIENT_Connection *client;
@@ -60,6 +65,8 @@ GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched,
   ret->upcb = upcb;
   ret->upcb_cls = upcb_cls;
   ret->client = client;
+  ret->flags = flags;
+  // FIXME: process varargs!
   // FIXME: setup receive-loop with client
 
   // FIXME: deserialize state; use client-name to find master-directory!
index 70e02360c5d7f25745d817e51d5504e5132a2e23..c2a2e7d032ff0e069ef5d50508e1d39c15afca79 100644 (file)
@@ -389,6 +389,11 @@ struct GNUNET_FS_Handle
    */
   unsigned int active_probes;
 
+  /**
+   * General flags.
+   */
+  enum GNUNET_FS_Flags flags;
+
 };
 
 
index 145e16818c53bd6049d429d574370f9123a17e17..77fbb11399113a78fa0fa5feeab2da9d6f050a0e 100644 (file)
@@ -142,6 +142,8 @@ make_download_status (struct GNUNET_FS_ProgressInfo *pi,
     = (dc->parent == NULL) ? NULL : dc->parent->client_info;
   pi->value.download.uri 
     = dc->uri;
+  pi->value.download.filename
+    = dc->filename;
   pi->value.download.length
     = dc->length;
   pi->value.download.duration
index d58ea3f377a07808d5bf4e4981bd5ffff14cceb5..db38b76daced2313064c02574fd62c14fe0ac9ad 100644 (file)
@@ -111,6 +111,8 @@ make_publish_status (struct GNUNET_FS_ProgressInfo *pi,
     = p->client_info;
   pi->value.publish.pctx
     = (NULL == p->dir) ? NULL : p->dir->client_info;
+  pi->value.publish.filename
+    = (p->is_directory) ? p->data.dir.dirname : p->data.file.filename;
   pi->value.publish.size
     = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size;
   pi->value.publish.eta 
index c6bb7c115bcca096ce85acca755446a7a9542469..681608d6bb7b22cf6cf60311222b0e0ddf70164f 100644 (file)
  * @author Igor Wronsky
  *
  * TODO:
- * - all
+ * - many command-line options
  */
 #include "platform.h"
 #include "gnunet_fs_service.h"
 
 static int ret;
 
+static int verbose;
+
+static int delete_incomplete;
+
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 static struct GNUNET_FS_Handle *ctx;
 
-static struct GNUNET_TIME_Absolute start_time;
+static struct GNUNET_FS_DownloadContext *dc;
 
 static unsigned int anonymity = 1;
 
+static char *filename;
 
 /**
  * Called by FS client to give information about the progress of an 
@@ -59,6 +64,44 @@ static void *
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
 {
+  switch (info->status)
+    {
+    case GNUNET_FS_STATUS_DOWNLOAD_START:
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
+      if (verbose)
+       fprintf (stdout,
+                _("Downloading `%s' at %llu/%llu (%s remaining, %s/s)\n"),
+                info->value.download.filename,
+                (unsigned long long) info->value.download.completed,
+                (unsigned long long) info->value.download.length,
+                GNUNET_STRINGS_relative_time_to_string(info->value.download.eta),
+                GNUNET_STRINGS_byte_size_fancy(info->value.download.completed * 1000 / (info->value.download.duration.value + 1)));
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
+      fprintf (stderr,
+              _("Error downloading: %s.\n"),
+              info->value.download.specifics.error.message);
+      GNUNET_FS_file_download_stop (dc, delete_incomplete); 
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
+      fprintf (stdout,
+              _("Downloading `%s' done (%s/s).\n"),
+              info->value.download.filename,
+              GNUNET_STRINGS_byte_size_fancy(info->value.download.completed * 1000 / (info->value.download.duration.value + 1)));
+      if (info->value.download.dc == dc)
+       GNUNET_FS_file_download_stop (dc, delete_incomplete);
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: 
+      if (info->value.download.dc == dc)
+       GNUNET_FS_stop (ctx);
+      break;      
+    default:
+      fprintf (stderr,
+              _("Unexpected status: %d\n"),
+              info->status);
+      break;
+    }
   return NULL;
 }
 
@@ -79,23 +122,66 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
+  struct GNUNET_FS_Uri *uri;
+  char *emsg;
+  enum GNUNET_FS_DownloadOptions options;
+
   /* FIXME: check arguments */
+  uri = GNUNET_FS_uri_parse (args[0],
+                            &emsg);
+  if (NULL == uri)
+    {
+      fprintf (stderr,
+              _("Failed to parse URI: %s\n"),
+              emsg);
+      GNUNET_free (emsg);
+      ret = 1;
+      return;
+    }
+  if (! GNUNET_FS_uri_test_chk (uri))
+    {
+      fprintf (stderr,
+              "Only CHK URIs supported right now.\n");
+      ret = 1;
+      GNUNET_FS_uri_destroy (uri);
+      return;           
+    }
+  if (NULL == filename)
+    {
+      fprintf (stderr,
+              "Target filename must be specified.\n");
+      ret = 1;
+      GNUNET_FS_uri_destroy (uri);
+      return;           
+    }
   cfg = c;
   ctx = GNUNET_FS_start (sched,
                         cfg,
                         "gnunet-download",
                         &progress_cb,
-                        NULL);
+                        NULL,
+                        GNUNET_FS_FLAGS_NONE,
+                        GNUNET_FS_OPTIONS_END);
   if (NULL == ctx)
     {
       fprintf (stderr,
               _("Could not initialize `%s' subsystem.\n"),
               "FS");
+      GNUNET_FS_uri_destroy (uri);
       ret = 1;
       return;
     }
-  start_time = GNUNET_TIME_absolute_get ();
-  // FIXME: start download
+  options = GNUNET_FS_DOWNLOAD_OPTION_NONE;
+  dc = GNUNET_FS_file_download_start (ctx,
+                                     uri,
+                                     NULL,
+                                     filename,
+                                     0,
+                                     GNUNET_FS_uri_chk_get_file_size (uri),
+                                     anonymity,
+                                     options,
+                                     NULL);
+  GNUNET_FS_uri_destroy (uri);
 }
 
 
@@ -106,7 +192,31 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
   {'a', "anonymity", "LEVEL",
    gettext_noop ("set the desired LEVEL of receiver-anonymity"),
    1, &GNUNET_GETOPT_set_uint, &anonymity},
+#if 0
   // FIXME: options!
+  {'d', "directory", NULL,
+   gettext_noop
+   ("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."),
+   0, &GNUNET_getopt_configure_set_one, &do_directory},
+  {'D', "delete-incomplete", NULL,
+   gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"),
+   0, &GNUNET_getopt_configure_set_one, &do_delete_incomplete},
+#endif
+  {'o', "output", "FILENAME",
+   gettext_noop ("write the file to FILENAME"),
+   1, &GNUNET_GETOPT_set_string, &filename},
+#if 0
+  {'p', "parallelism", "DOWNLOADS",
+   gettext_noop
+   ("set the maximum number of parallel downloads that are allowed"),
+   1, &GNUNET_getopt_configure_set_uint, &parallelism},
+  {'R', "recursive", NULL,
+   gettext_noop ("download a GNUnet directory recursively"),
+   0, &GNUNET_getopt_configure_set_one, &do_recursive},
+#endif
+  {'V', "verbose", NULL,
+   gettext_noop ("be verbose (print progress information)"),
+   0, &GNUNET_GETOPT_set_one, &verbose},
   GNUNET_GETOPT_OPTION_END
 };
 
index b6b9199d0e6f41b4d6c2ca56c2b1f415833e6a80..a30b36c9eafe77c6609771b609f7f9bcb6697af0 100644 (file)
@@ -27,8 +27,6 @@
  *
  * TODO:
  * - support for some options is still missing (uri argument)
- * - progress callbacks not implemented (and need verbosity option)
- * - clean shutdown is not implemented (stop ctx, etc.)
  */
 #include "platform.h"
 #include "gnunet_fs_service.h"
 
 static int ret;
 
+static int verbose;
+
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 static struct GNUNET_FS_Handle *ctx;
 
 static struct GNUNET_FS_PublishContext *pc;
 
-static struct GNUNET_TIME_Absolute start_time;
-
 static struct GNUNET_CONTAINER_MetaData *meta;
 
 static struct GNUNET_FS_Uri *topKeywords;
@@ -89,7 +87,43 @@ static void *
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
 {
-  return NULL;
+  switch (info->status)
+    {
+    case GNUNET_FS_STATUS_PUBLISH_START:
+      break;
+    case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
+      if (verbose)
+       fprintf (stdout,
+                _("Publishing `%s' at %llu/%llu (%s remaining)\n"),
+                info->value.publish.filename,
+                (unsigned long long) info->value.publish.completed,
+                (unsigned long long) info->value.publish.size,
+                GNUNET_STRINGS_relative_time_to_string(info->value.publish.eta));
+      break;
+    case GNUNET_FS_STATUS_PUBLISH_ERROR:
+      fprintf (stderr,
+              _("Error publishing: %s.\n"),
+              info->value.publish.specifics.error.message);
+      GNUNET_FS_publish_stop (pc);      
+      break;
+    case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
+      fprintf (stdout,
+              _("Publishing `%s' done.\n"),
+              info->value.publish.filename);
+      if (info->value.publish.pctx == NULL)
+       GNUNET_FS_publish_stop (pc);
+      break;
+    case GNUNET_FS_STATUS_PUBLISH_STOPPED: 
+      if (info->value.publish.sc == pc)
+       GNUNET_FS_stop (ctx);
+      return NULL;      
+    default:
+      fprintf (stderr,
+              _("Unexpected status: %d\n"),
+              info->status);
+      return NULL;
+    }
+  return ""; /* non-null */
 }
 
 
@@ -302,7 +336,9 @@ run (void *cls,
                         cfg,
                         "gnunet-publish",
                         &progress_cb,
-                        NULL);
+                        NULL,
+                        GNUNET_FS_FLAGS_NONE,
+                        GNUNET_FS_OPTIONS_END);
   if (NULL == ctx)
     {
       fprintf (stderr,
@@ -331,7 +367,6 @@ run (void *cls,
       // FIXME -- implement!
       return;
     }
-  start_time = GNUNET_TIME_absolute_get ();
 
   l = NULL;
   if (! disable_extractor)
@@ -389,6 +424,14 @@ run (void *cls,
                                (do_simulate) 
                                ? GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY
                                : GNUNET_FS_PUBLISH_OPTION_NONE);
+  if (NULL == pc)
+    {
+      fprintf (stderr,
+              _("Could not start publishing.\n"));
+      GNUNET_FS_stop (ctx);
+      ret = 1;
+      return;
+    }
 }
 
 
@@ -449,7 +492,10 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
   {'u', "uri", "URI",
    gettext_noop ("URI to be published (can be used instead of passing a "
                  "file to add keywords to the file with the respective URI)"),
-   1, &GNUNET_GETOPT_set_string, &uri_string},
+   1, &GNUNET_GETOPT_set_string, &uri_string}, 
+  {'V', "verbose", NULL,
+   gettext_noop ("be verbose (print progress information)"),
+   0, &GNUNET_GETOPT_set_one, &verbose},
   GNUNET_GETOPT_OPTION_END
 };
 
index 10a3c82fd3265dee09b8cf7497d56cc967fdf55a..b744d2e1ad6681896ccd128b8579896c1c7dcc88 100644 (file)
@@ -26,7 +26,7 @@
  * @author Igor Wronsky
  *
  * TODO:
- * - all
+ * - add many options (timeout, namespace search, etc.)
  */
 #include "platform.h"
 #include "gnunet_fs_service.h"
@@ -37,10 +37,24 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 static struct GNUNET_FS_Handle *ctx;
 
-static struct GNUNET_TIME_Absolute start_time;
+static struct GNUNET_FS_SearchContext *sc;
 
 static unsigned int anonymity = 1;
 
+static int verbose;
+
+static int
+item_printer (void *cls,
+             EXTRACTOR_KeywordType type, 
+             const char *data)
+{
+  printf ("\t%20s: %s\n",
+          dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN,
+                    EXTRACTOR_getKeywordTypeAsString (type)),
+         data);
+  return GNUNET_OK;
+}
+
 
 /**
  * Called by FS client to give information about the progress of an 
@@ -59,6 +73,56 @@ static void *
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
 {
+  char *uri;
+  char *dotdot;
+  char *filename;
+
+  switch (info->status)
+    {
+    case GNUNET_FS_STATUS_SEARCH_START:
+      break;
+    case GNUNET_FS_STATUS_SEARCH_RESULT:
+      uri = GNUNET_FS_uri_to_string (info->value.search.specifics.result.uri);
+      printf ("%s:\n", uri);
+      filename =
+        GNUNET_CONTAINER_meta_data_get_by_type (info->value.search.specifics.result.meta,
+                                               EXTRACTOR_FILENAME);
+      if (filename != NULL)
+        {
+          while (NULL != (dotdot = strstr (filename, "..")))
+            dotdot[0] = dotdot[1] = '_';
+          printf ("gnunet-download -o \"%s\" %s\n", 
+                 filename, 
+                 uri);
+        }
+      else
+        printf ("gnunet-download %s\n", uri);
+      if (verbose)
+       GNUNET_CONTAINER_meta_data_get_contents (info->value.search.specifics.result.meta, 
+                                                &item_printer,
+                                                NULL);
+      printf ("\n");
+      fflush(stdout);
+      GNUNET_free_non_null (filename);
+      GNUNET_free (uri);
+      break;
+    case GNUNET_FS_STATUS_SEARCH_UPDATE:
+      break;
+    case GNUNET_FS_STATUS_SEARCH_ERROR:
+      fprintf (stderr,
+              _("Error searching: %s.\n"),
+              info->value.search.specifics.error.message);
+      GNUNET_FS_search_stop (sc);      
+      break;
+    case GNUNET_FS_STATUS_SEARCH_STOPPED: 
+      GNUNET_FS_stop (ctx);
+      break;      
+    default:
+      fprintf (stderr,
+              _("Unexpected status: %d\n"),
+              info->status);
+      break;
+    }
   return NULL;
 }
 
@@ -79,23 +143,51 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
-  /* FIXME: check arguments */
+  struct GNUNET_FS_Uri *uri;
+  unsigned int argc;
+
+  argc = 0;
+  while (NULL != args[argc])
+    argc++;
+  uri = GNUNET_FS_uri_ksk_create_from_args (argc,
+                                           (const char **) args);
+  if (NULL == uri)
+    {
+      fprintf (stderr,
+              _("Could not create keyword URI from arguments.\n"));
+      ret = 1;
+      GNUNET_FS_uri_destroy (uri);
+      return;
+    }
   cfg = c;
   ctx = GNUNET_FS_start (sched,
                         cfg,
                         "gnunet-search",
                         &progress_cb,
-                        NULL);
+                        NULL,
+                        GNUNET_FS_FLAGS_NONE,
+                        GNUNET_FS_OPTIONS_END);
   if (NULL == ctx)
     {
       fprintf (stderr,
               _("Could not initialize `%s' subsystem.\n"),
               "FS");
+      GNUNET_FS_uri_destroy (uri);
+      GNUNET_FS_stop (ctx);
+      ret = 1;
+      return;
+    }
+  sc = GNUNET_FS_search_start (ctx,
+                              uri,
+                              anonymity);
+  GNUNET_FS_uri_destroy (uri);
+  if (NULL == sc)
+    {
+      fprintf (stderr,
+              _("Could not start searching.\n"));
       ret = 1;
       return;
     }
-  start_time = GNUNET_TIME_absolute_get ();
-  // FIXME: start search
 }
 
 
index 2dfef9432eb93a602236246e84762cc89141a09b..9b335eec0102a38f56829dfa61adbb8093ebf722 100644 (file)
  * @author Krista Bennett
  * @author James Blackwell
  * @author Igor Wronsky
- *
- * TODO:
- * - progress callback
- * - error checking
  */
 #include "platform.h"
 #include "gnunet_fs_service.h"
 
 static int ret;
 
+static int verbose;
+
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 static struct GNUNET_FS_Handle *ctx;
 
 static struct GNUNET_FS_UnindexContext *uc;
 
-static struct GNUNET_TIME_Absolute start_time;
-
 
 /**
  * Called by FS client to give information about the progress of an 
@@ -60,6 +56,38 @@ static void *
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
 {
+  switch (info->status)
+    {
+    case GNUNET_FS_STATUS_UNINDEX_START:
+      break;
+    case GNUNET_FS_STATUS_UNINDEX_PROGRESS:
+      if (verbose)
+       fprintf (stdout,
+                _("Unindexing at %llu/%llu (%s remaining)\n"),
+                (unsigned long long) info->value.unindex.completed,
+                (unsigned long long) info->value.unindex.size,
+                GNUNET_STRINGS_relative_time_to_string(info->value.unindex.eta));
+      break;
+    case GNUNET_FS_STATUS_UNINDEX_ERROR:
+      fprintf (stderr,
+              _("Error unindexing: %s.\n"),
+              info->value.unindex.specifics.error.message);
+      GNUNET_FS_unindex_stop (uc);      
+      break;
+    case GNUNET_FS_STATUS_UNINDEX_COMPLETED:
+      fprintf (stdout,
+              _("Unindexing done.\n"));
+      GNUNET_FS_unindex_stop (uc);
+      break;
+    case GNUNET_FS_STATUS_UNINDEX_STOPPED:
+      GNUNET_FS_stop (ctx);
+      break;      
+    default:
+      fprintf (stderr,
+              _("Unexpected status: %d\n"),
+              info->status);
+      break;
+    }
   return NULL;
 }
 
@@ -93,7 +121,9 @@ run (void *cls,
                         cfg,
                         "gnunet-unindex",
                         &progress_cb,
-                        NULL);
+                        NULL,
+                        GNUNET_FS_FLAGS_NONE,
+                        GNUNET_FS_OPTIONS_END);
   if (NULL == ctx)
     {
       fprintf (stderr,
@@ -102,9 +132,14 @@ run (void *cls,
       ret = 1;
       return;
     }
-  start_time = GNUNET_TIME_absolute_get ();
   uc = GNUNET_FS_unindex (ctx,
                          args[0]);
+  if (NULL == uc)
+    {
+      fprintf (stderr,
+              _("Could not start unindex operation.\n"));
+      GNUNET_FS_stop (ctx);
+    }
 }
 
 
@@ -112,6 +147,9 @@ run (void *cls,
  * gnunet-unindex command line options
  */
 static struct GNUNET_GETOPT_CommandLineOption options[] = {
+  {'V', "verbose", NULL,
+   gettext_noop ("be verbose (print progress information)"),
+   0, &GNUNET_GETOPT_set_one, &verbose},
   GNUNET_GETOPT_OPTION_END
 };
 
index ee10a0156f5e25ad97af37a206ba6a50a46a72f4..114128823e3d3dbd0d5450fe88f9e08da7483d7e 100644 (file)
@@ -360,7 +360,7 @@ GNUNET_FS_uri_test_chk (const struct GNUNET_FS_Uri *uri);
  * What is the size of the file that this URI
  * refers to?
  *
- * @param uri the CHK URI to inspect
+ * @param uri the CHK (or LOC) URI to inspect
  * @return size of the file as specified in the CHK URI
  */
 uint64_t 
@@ -718,6 +718,11 @@ struct GNUNET_FS_ProgressInfo
        * (if this is a file in a directory or a subdirectory).
        */
       void *pctx;
+
+      /**
+       * Name of the file being published; can be NULL.
+       */
+      const char *filename;
       
       /**
        * How large is the file overall?  For directories,
@@ -862,6 +867,11 @@ struct GNUNET_FS_ProgressInfo
        * URI used for this download.
        */
       const struct GNUNET_FS_Uri *uri;
+
+      /**
+       * Name of the file that we are downloading.
+       */
+      const char *filename;
       
       /**
        * How large is the download overall?  This
@@ -1393,6 +1403,46 @@ typedef void* (*GNUNET_FS_ProgressCallback)
    const struct GNUNET_FS_ProgressInfo *info);
 
 
+/**
+ * General (global) option flags for file-sharing.
+ */
+enum GNUNET_FS_Flags
+  {
+    /**
+     * No special flags set.
+     */
+    GNUNET_FS_FLAGS_NONE = 0,
+
+    /**
+     * Is persistence of operations desired?
+     * (will create SUSPEND/RESUME events).
+     */
+    GNUNET_FS_FLAGS_PERSISTENCE = 1
+
+  };
+
+/**
+ * Options specified in the VARARGs
+ * portion of GNUNET_FS_start.
+ */
+enum GNUNET_FS_OPTIONS
+  {
+    
+    /**
+     * Last option in the VARARG list.
+     */
+    GNUNET_FS_OPTIONS_END = 0,
+
+    /**
+     * Select the desired amount of parallelism (this option should be
+     * followed by an "unsigned int" giving the desired maximum number
+     * of parallel downloads).
+     */
+    GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM = 1
+
+  };
+
+
 /**
  * Handle to the file-sharing service.
  */
@@ -1407,13 +1457,18 @@ struct GNUNET_FS_Handle;
  * @param client_name unique identifier for this client 
  * @param upcb function to call to notify about FS actions
  * @param upcb_cls closure for upcb
+ * @param flags specific attributes for fs-operations
+ * @param ... list of optional options, terminated with GNUNET_FS_OPTIONS_END
+ * @return NULL on error
  */
 struct GNUNET_FS_Handle *
 GNUNET_FS_start (struct GNUNET_SCHEDULER_Handle *sched,
                 const struct GNUNET_CONFIGURATION_Handle *cfg,
                 const char *client_name,
                 GNUNET_FS_ProgressCallback upcb,
-                void *upcb_cls);
+                void *upcb_cls,
+                enum GNUNET_FS_Flags flags,
+                ...);
 
 
 /**