GNUnet  0.10.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 {
59  GNUNET_FS_stop(ctx);
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  }
244  if ((!GNUNET_FS_uri_test_chk(uri)) && (!GNUNET_FS_uri_test_loc(uri)))
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;
259  ctx = GNUNET_FS_start(cfg,
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)
281  dc = GNUNET_FS_download_start(ctx,
282  uri,
283  NULL,
284  filename,
285  NULL,
286  0,
288  anonymity,
289  options,
290  NULL,
291  NULL);
293  if (dc == NULL)
294  {
295  GNUNET_FS_stop(ctx);
296  ctx = NULL;
297  return;
298  }
300 }
301 
302 
310 int
311 main(int argc, char *const *argv)
312 {
313  struct GNUNET_GETOPT_CommandLineOption options[] =
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((void *)argv);
380  return ret;
381 }
382 
383 /* end of gnunet-download.c */
static unsigned int parallelism
Notification that we have started this download.
static int ret
static const struct GNUNET_CONFIGURATION_Handle * cfg
Context for controlling a download.
Definition: fs_api.h:1722
int main(int argc, char *const *argv)
The main function to download GNUnet.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static unsigned int verbose
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
char * GNUNET_STRINGS_byte_size_fancy(unsigned long long size)
Convert a given filesize into a fancy human-readable format.
Definition: strings.c:175
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:641
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1284
Master context for most FS operations.
Definition: fs_api.h:1056
static struct GNUNET_FS_Handle * ctx
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1439
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_FS_ProgressInfo::@28::@30 download
Values for all "GNUNET_FS_STATUS_DOWNLOAD_*" events.
static void cleanup_task(void *cls)
Last option in the VARARG list.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Definition of a command line option.
static struct GNUNET_SCHEDULER_Task * t
Main task.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
void GNUNET_FS_stop(struct GNUNET_FS_Handle *h)
Close our connection with the file-sharing service.
Definition: fs_api.c:3215
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
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:3140
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.
No special flags set.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition: fs_uri.c:1392
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
Notification that this download completed.
static unsigned int request_parallelism
union GNUNET_FS_ProgressInfo::@28 value
Values that depend on the event type.
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 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 struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
Only download from the local host, do not access remote systems (no P2P)
static int local_only
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:1264
enum GNUNET_FS_Status status
Specific status code (determines the event type).
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:686
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:2332
static char buf[2048]
static char * filename
No options (use defaults for everything).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:675
int GNUNET_FS_uri_test_chk(const struct GNUNET_FS_Uri *uri)
Is this a file (or directory) URI?
Definition: fs_uri.c:1354
static int delete_incomplete
Notification that this download is no longer actively being pursued (back in the queue).
Notification about progress with this download.
GNUNET_FS_DownloadOptions
Options for downloading.
Select the desired amount of parallelism (this option should be followed by an "unsigned int" giving ...
Notification that this download is now actively being pursued (as opposed to waiting in the queue)...
static void shutdown_task(void *cls)
Maximum number of requests that should be pending at a given point in time (invidivual downloads may ...
Do a recursive download (that is, automatically trigger the download of files in directories).
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:1368
configuration data
Definition: configuration.c:83
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:162
static int do_recursive
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.
int 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, parse options).
Definition: program.c:367
#define GNUNET_YES
Definition: gnunet_common.h:77
static unsigned int anonymity
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.
Notification that this download was stopped (final event with respect to this action).
static void display_bar(unsigned long long x, unsigned long long n, unsigned int w)
Display progress bar (if tty).
Notification that this download encountered an error.
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
Argument given to the progress callback with information about what is going on.
#define gettext_noop(String)
Definition: gettext.h:69