GNUnet  0.19.4
gnunet-download.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
28 #include "platform.h"
29 
30 #include "gnunet_fs_service.h"
31 
32 static int ret;
33 
34 static unsigned int verbose;
35 
36 static int delete_incomplete;
37 
38 static const struct GNUNET_CONFIGURATION_Handle *cfg;
39 
40 static struct GNUNET_FS_Handle *ctx;
41 
43 
44 static unsigned int anonymity = 1;
45 
46 static unsigned int parallelism = 16;
47 
48 static unsigned int request_parallelism = 4092;
49 
50 static int do_recursive;
51 
52 static char *filename;
53 
54 static int local_only;
55 
56 
57 static void
58 cleanup_task (void *cls)
59 {
61  ctx = NULL;
62 }
63 
64 
65 static void
66 shutdown_task (void *cls)
67 {
68  if (NULL != dc)
69  {
71  dc = NULL;
72  }
73 }
74 
75 
83 static void
84 display_bar (unsigned long long x, unsigned long long n, unsigned int w)
85 {
86  char buf[w + 20];
87  unsigned int p;
88  unsigned int endeq;
89  float ratio_complete;
90 
91  if (0 == isatty (1))
92  return;
93  ratio_complete = x / (float) n;
94  endeq = ratio_complete * w;
95  GNUNET_snprintf (buf, sizeof(buf), "%3d%% [", (int) (ratio_complete * 100));
96  for (p = 0; p < endeq; p++)
97  strcat (buf, "=");
98  for (p = endeq; p < w; p++)
99  strcat (buf, " ");
100  strcat (buf, "]\r");
101  printf ("%s", buf);
102  fflush (stdout);
103 }
104 
105 
119 static void *
120 progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
121 {
122  char *s;
123  const char *s2;
124  char *t;
125 
126  switch (info->status)
127  {
129  if (verbose > 1)
130  fprintf (stderr,
131  _ ("Starting download `%s'.\n"),
132  info->value.download.filename);
133  break;
134 
136  if (verbose)
137  {
138  s = GNUNET_strdup (
139  GNUNET_STRINGS_relative_time_to_string (info->value.download.eta,
140  GNUNET_YES));
141  if (info->value.download.specifics.progress.block_download_duration
142  .rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
143  s2 = _ ("<unknown time>");
144  else
145  s2 = GNUNET_STRINGS_relative_time_to_string (info->value.download
146  .specifics.progress
147  .block_download_duration,
148  GNUNET_YES);
150  info->value.download.completed * 1000LL
151  / (info->value.download.duration.rel_value_us + 1));
152  fprintf (
153  stdout,
154  _ (
155  "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to download\n"),
156  info->value.download.filename,
157  (unsigned long long) info->value.download.completed,
158  (unsigned long long) info->value.download.size,
159  s,
160  t,
161  s2);
162  GNUNET_free (s);
163  GNUNET_free (t);
164  }
165  else
166  {
167  display_bar (info->value.download.completed,
168  info->value.download.size,
169  60);
170  }
171  break;
172 
174  if (0 != isatty (1))
175  fprintf (stdout, "\n");
176  fprintf (stderr,
177  _ ("Error downloading: %s.\n"),
178  info->value.download.specifics.error.message);
180  break;
181 
184  info->value.download.completed * 1000
185  / (info->value.download.duration.rel_value_us + 1));
186  if (0 != isatty (1))
187  fprintf (stdout, "\n");
188  fprintf (stdout,
189  _ ("Downloading `%s' done (%s/s).\n"),
190  info->value.download.filename,
191  s);
192  GNUNET_free (s);
193  if (info->value.download.dc == dc)
195  break;
196 
198  if (info->value.download.dc == dc)
200  break;
201 
204  break;
205 
206  default:
207  fprintf (stderr, _ ("Unexpected status: %d\n"), info->status);
208  break;
209  }
210  return NULL;
211 }
212 
213 
222 static void
223 run (void *cls,
224  char *const *args,
225  const char *cfgfile,
226  const struct GNUNET_CONFIGURATION_Handle *c)
227 {
228  struct GNUNET_FS_Uri *uri;
229  char *emsg;
231 
232  if (NULL == args[0])
233  {
234  fprintf (stderr, "%s", _ ("You need to specify a URI argument.\n"));
235  return;
236  }
237  uri = GNUNET_FS_uri_parse (args[0], &emsg);
238  if (NULL == uri)
239  {
240  fprintf (stderr, _ ("Failed to parse URI: %s\n"), emsg);
241  GNUNET_free (emsg);
242  ret = 1;
243  return;
244  }
246  {
247  fprintf (stderr, "%s", _ ("Only CHK or LOC URIs supported.\n"));
248  ret = 1;
250  return;
251  }
252  if (NULL == filename)
253  {
254  fprintf (stderr, "%s", _ ("Target filename must be specified.\n"));
255  ret = 1;
257  return;
258  }
259  cfg = c;
261  "gnunet-download",
262  &progress_cb,
263  NULL,
266  parallelism,
270  if (NULL == ctx)
271  {
272  fprintf (stderr, _ ("Could not initialize `%s' subsystem.\n"), "FS");
274  ret = 1;
275  return;
276  }
278  if (do_recursive)
280  if (local_only)
283  uri,
284  NULL,
285  filename,
286  NULL,
287  0,
289  anonymity,
290  options,
291  NULL,
292  NULL);
294  if (dc == NULL)
295  {
297  ctx = NULL;
298  return;
299  }
301 }
302 
303 
311 int
312 main (int argc, char *const *argv)
313 {
316  "anonymity",
317  "LEVEL",
318  gettext_noop (
319  "set the desired LEVEL of receiver-anonymity"),
320  &anonymity),
321 
323  'D',
324  "delete-incomplete",
325  gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"),
327 
329  'n',
330  "no-network",
331  gettext_noop ("only search the local peer (no P2P network search)"),
332  &local_only),
334  "output",
335  "FILENAME",
336  gettext_noop ("write the file to FILENAME"),
337  &filename),
339  'p',
340  "parallelism",
341  "DOWNLOADS",
342  gettext_noop (
343  "set the maximum number of parallel downloads that is allowed"),
344  &parallelism),
346  'r',
347  "request-parallelism",
348  "REQUESTS",
349  gettext_noop (
350  "set the maximum number of parallel requests for blocks that is allowed"),
353  "recursive",
354  gettext_noop (
355  "download a GNUnet directory recursively"),
356  &do_recursive),
358  'V',
359  "verbose",
360  gettext_noop ("be verbose (print progress information)"),
361  &verbose),
363 
364  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
365  return 2;
366 
367  ret =
368  (GNUNET_OK ==
370  argc,
371  argv,
372  "gnunet-download [OPTIONS] URI",
373  gettext_noop (
374  "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/chk/...)"),
375  options,
376  &run,
377  NULL))
378  ? ret
379  : 1;
380  GNUNET_free_nz ((void *) argv);
381  return ret;
382 }
383 
384 
385 /* end of gnunet-download.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:70
static unsigned int verbose
static unsigned int anonymity
static int do_recursive
static void display_bar(unsigned long long x, unsigned long long n, unsigned int w)
Display progress bar (if tty).
static const struct GNUNET_CONFIGURATION_Handle * cfg
static void cleanup_task(void *cls)
static void shutdown_task(void *cls)
static int ret
static unsigned int request_parallelism
static struct GNUNET_FS_Handle * ctx
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run by the scheduler.
static void * progress_cb(void *cls, const struct GNUNET_FS_ProgressInfo *info)
Called by FS client to give information about the progress of an operation.
static unsigned int parallelism
static int local_only
int main(int argc, char *const *argv)
The main function to download GNUnet.
static struct GNUNET_FS_DownloadContext * dc
static int delete_incomplete
static char * filename
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
#define info
static char buf[2048]
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
static struct GNUNET_SCHEDULER_Task * t
Main task.
API for file sharing via GNUnet.
struct GNUNET_FS_Uri * GNUNET_FS_uri_parse(const char *uri, char **emsg)
Convert a UTF-8 String to a URI.
Definition: fs_uri.c:637
GNUNET_FS_DownloadOptions
Options for downloading.
uint64_t GNUNET_FS_uri_chk_get_file_size(const struct GNUNET_FS_Uri *uri)
What is the size of the file that this URI refers to?
Definition: fs_uri.c:1360
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition: fs_uri.c:1384
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:677
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_MetaData *meta, const char *filename, const char *tempname, uint64_t offset, uint64_t length, uint32_t anonymity, enum GNUNET_FS_DownloadOptions options, void *cctx, struct GNUNET_FS_DownloadContext *parent)
Download parts of a file.
Definition: fs_download.c:2100
void GNUNET_FS_download_stop(struct GNUNET_FS_DownloadContext *dc, int do_delete)
Stop a download (aborts if download is incomplete).
Definition: fs_download.c:2254
struct GNUNET_FS_Handle * GNUNET_FS_start(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *client_name, GNUNET_FS_ProgressCallback upcb, void *upcb_cls, enum GNUNET_FS_Flags flags,...)
Setup a connection to the file-sharing service.
Definition: fs_api.c:3244
int GNUNET_FS_uri_test_chk(const struct GNUNET_FS_Uri *uri)
Is this a file (or directory) URI?
Definition: fs_uri.c:1346
void GNUNET_FS_stop(struct GNUNET_FS_Handle *h)
Close our connection with the file-sharing service.
Definition: fs_api.c:3310
@ GNUNET_FS_FLAGS_NONE
No special flags set.
@ GNUNET_FS_DOWNLOAD_OPTION_NONE
No options (use defaults for everything).
@ GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE
Do a recursive download (that is, automatically trigger the download of files in directories).
@ GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY
Only download from the local host, do not access remote systems (no P2P)
@ GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM
Select the desired amount of parallelism (this option should be followed by an "unsigned int" giving ...
@ GNUNET_FS_OPTIONS_END
Last option in the VARARG list.
@ GNUNET_FS_OPTIONS_REQUEST_PARALLELISM
Maximum number of requests that should be pending at a given point in time (invidivual downloads may ...
@ GNUNET_FS_STATUS_DOWNLOAD_INACTIVE
Notification that this download is no longer actively being pursued (back in the queue).
@ GNUNET_FS_STATUS_DOWNLOAD_ERROR
Notification that this download encountered an error.
@ GNUNET_FS_STATUS_DOWNLOAD_COMPLETED
Notification that this download completed.
@ GNUNET_FS_STATUS_DOWNLOAD_START
Notification that we have started this download.
@ GNUNET_FS_STATUS_DOWNLOAD_PROGRESS
Notification about progress with this download.
@ GNUNET_FS_STATUS_DOWNLOAD_ACTIVE
Notification that this download is now actively being pursued (as opposed to waiting in the queue).
@ GNUNET_FS_STATUS_DOWNLOAD_STOPPED
Notification that this download was stopped (final event with respect to this action).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_increment_uint(char shortName, const char *name, const char *description, unsigned int *val)
Increment val each time the option flag is given by one.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
@ GNUNET_OK
@ GNUNET_YES
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
Definition: strings.c:106
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1222
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:569
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Context for controlling a download.
Definition: fs_api.h:1744
Master context for most FS operations.
Definition: fs_api.h:1070
Argument given to the progress callback with information about what is going on.
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:167
Definition of a command line option.