GNUnet  0.11.x
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 #include "gnunet_fs_service.h"
30 
31 static int ret;
32 
33 static unsigned int verbose;
34 
35 static int delete_incomplete;
36 
37 static const struct GNUNET_CONFIGURATION_Handle *cfg;
38 
39 static struct GNUNET_FS_Handle *ctx;
40 
42 
43 static unsigned int anonymity = 1;
44 
45 static unsigned int parallelism = 16;
46 
47 static unsigned int request_parallelism = 4092;
48 
49 static int do_recursive;
50 
51 static char *filename;
52 
53 static int local_only;
54 
55 
56 static void
57 cleanup_task (void *cls)
58 {
60  ctx = NULL;
61 }
62 
63 
64 static void
65 shutdown_task (void *cls)
66 {
67  if (NULL != dc)
68  {
70  dc = NULL;
71  }
72 }
73 
74 
82 static void
83 display_bar (unsigned long long x, unsigned long long n, unsigned int w)
84 {
85  char buf[w + 20];
86  unsigned int p;
87  unsigned int endeq;
88  float ratio_complete;
89 
90  if (0 == isatty (1))
91  return;
92  ratio_complete = x / (float) n;
93  endeq = ratio_complete * w;
94  GNUNET_snprintf (buf, sizeof(buf), "%3d%% [", (int) (ratio_complete * 100));
95  for (p = 0; p < endeq; p++)
96  strcat (buf, "=");
97  for (p = endeq; p < w; p++)
98  strcat (buf, " ");
99  strcat (buf, "]\r");
100  printf ("%s", buf);
101  fflush (stdout);
102 }
103 
104 
118 static void *
119 progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
120 {
121  char *s;
122  const char *s2;
123  char *t;
124 
125  switch (info->status)
126  {
128  if (verbose > 1)
129  fprintf (stderr,
130  _ ("Starting download `%s'.\n"),
131  info->value.download.filename);
132  break;
133 
135  if (verbose)
136  {
137  s = GNUNET_strdup (
139  GNUNET_YES));
140  if (info->value.download.specifics.progress.block_download_duration
141  .rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
142  s2 = _ ("<unknown time>");
143  else
145  .specifics.progress
146  .block_download_duration,
147  GNUNET_YES);
149  info->value.download.completed * 1000LL
150  / (info->value.download.duration.rel_value_us + 1));
151  fprintf (
152  stdout,
153  _ (
154  "Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to download\n"),
155  info->value.download.filename,
156  (unsigned long long) info->value.download.completed,
157  (unsigned long long) info->value.download.size,
158  s,
159  t,
160  s2);
161  GNUNET_free (s);
162  GNUNET_free (t);
163  }
164  else
165  {
166  display_bar (info->value.download.completed,
167  info->value.download.size,
168  60);
169  }
170  break;
171 
173  if (0 != isatty (1))
174  fprintf (stdout, "\n");
175  fprintf (stderr,
176  _ ("Error downloading: %s.\n"),
177  info->value.download.specifics.error.message);
179  break;
180 
183  info->value.download.completed * 1000
184  / (info->value.download.duration.rel_value_us + 1));
185  if (0 != isatty (1))
186  fprintf (stdout, "\n");
187  fprintf (stdout,
188  _ ("Downloading `%s' done (%s/s).\n"),
189  info->value.download.filename,
190  s);
191  GNUNET_free (s);
192  if (info->value.download.dc == dc)
194  break;
195 
197  if (info->value.download.dc == dc)
199  break;
200 
203  break;
204 
205  default:
206  fprintf (stderr, _ ("Unexpected status: %d\n"), info->status);
207  break;
208  }
209  return NULL;
210 }
211 
212 
221 static void
222 run (void *cls,
223  char *const *args,
224  const char *cfgfile,
225  const struct GNUNET_CONFIGURATION_Handle *c)
226 {
227  struct GNUNET_FS_Uri *uri;
228  char *emsg;
230 
231  if (NULL == args[0])
232  {
233  fprintf (stderr, "%s", _ ("You need to specify a URI argument.\n"));
234  return;
235  }
236  uri = GNUNET_FS_uri_parse (args[0], &emsg);
237  if (NULL == uri)
238  {
239  fprintf (stderr, _ ("Failed to parse URI: %s\n"), emsg);
240  GNUNET_free (emsg);
241  ret = 1;
242  return;
243  }
245  {
246  fprintf (stderr, "%s", _ ("Only CHK or LOC URIs supported.\n"));
247  ret = 1;
249  return;
250  }
251  if (NULL == filename)
252  {
253  fprintf (stderr, "%s", _ ("Target filename must be specified.\n"));
254  ret = 1;
256  return;
257  }
258  cfg = c;
260  "gnunet-download",
261  &progress_cb,
262  NULL,
265  parallelism,
269  if (NULL == ctx)
270  {
271  fprintf (stderr, _ ("Could not initialize `%s' subsystem.\n"), "FS");
273  ret = 1;
274  return;
275  }
277  if (do_recursive)
279  if (local_only)
282  uri,
283  NULL,
284  filename,
285  NULL,
286  0,
288  anonymity,
289  options,
290  NULL,
291  NULL);
293  if (dc == NULL)
294  {
296  ctx = NULL;
297  return;
298  }
300 }
301 
302 
310 int
311 main (int argc, char *const *argv)
312 {
315  "anonymity",
316  "LEVEL",
317  gettext_noop (
318  "set the desired LEVEL of receiver-anonymity"),
319  &anonymity),
320 
322  'D',
323  "delete-incomplete",
324  gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"),
326 
328  'n',
329  "no-network",
330  gettext_noop ("only search the local peer (no P2P network search)"),
331  &local_only),
333  "output",
334  "FILENAME",
335  gettext_noop ("write the file to FILENAME"),
336  &filename),
338  'p',
339  "parallelism",
340  "DOWNLOADS",
341  gettext_noop (
342  "set the maximum number of parallel downloads that is allowed"),
343  &parallelism),
345  'r',
346  "request-parallelism",
347  "REQUESTS",
348  gettext_noop (
349  "set the maximum number of parallel requests for blocks that is allowed"),
352  "recursive",
353  gettext_noop (
354  "download a GNUnet directory recursively"),
355  &do_recursive),
357  'V',
358  "verbose",
359  gettext_noop ("be verbose (print progress information)"),
360  &verbose),
362 
363  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
364  return 2;
365 
366  ret =
367  (GNUNET_OK ==
369  argc,
370  argv,
371  "gnunet-download [OPTIONS] URI",
372  gettext_noop (
373  "Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/chk/...)"),
374  options,
375  &run,
376  NULL))
377  ? ret
378  : 1;
379  GNUNET_free_nz ((void *) argv);
380  return ret;
381 }
382 
383 
384 /* 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:69
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 ...
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static char buf[2048]
static struct GNUNET_SCHEDULER_Task * t
Main task.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
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:644
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:1370
struct GNUNET_FS_DownloadContext * GNUNET_FS_download_start(struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_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:2145
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition: fs_uri.c:1394
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:678
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:2333
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:3263
int GNUNET_FS_uri_test_chk(const struct GNUNET_FS_Uri *uri)
Is this a file (or directory) URI?
Definition: fs_uri.c:1356
void GNUNET_FS_stop(struct GNUNET_FS_Handle *h)
Close our connection with the file-sharing service.
Definition: fs_api.c:3338
@ 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.
#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:364
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
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:1296
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:1331
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
Definition: strings.c:130
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:1209
#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:557
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Context for controlling a download.
Definition: fs_api.h:1743
Master context for most FS operations.
Definition: fs_api.h:1069
Argument given to the progress callback with information about what is going on.
struct GNUNET_FS_ProgressInfo::@25::GNUNET_FS_DownloadStatusEvent download
union GNUNET_FS_ProgressInfo::@25 value
Values that depend on the event type.
enum GNUNET_FS_Status status
Specific status code (determines the event type).
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:166
Definition of a command line option.