GNUnet 0.21.0
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
32static int ret;
33
34static unsigned int verbose;
35
37
38static const struct GNUNET_CONFIGURATION_Handle *cfg;
39
40static struct GNUNET_FS_Handle *ctx;
41
43
44static unsigned int anonymity = 1;
45
46static unsigned int parallelism = 16;
47
48static unsigned int request_parallelism = 4092;
49
50static int do_recursive;
51
52static char *filename;
53
54static int local_only;
55
56
57static void
58cleanup_task (void *cls)
59{
61 ctx = NULL;
62}
63
64
65static void
66shutdown_task (void *cls)
67{
68 if (NULL != dc)
69 {
71 dc = NULL;
72 }
73}
74
75
83static void
84display_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
119static void *
120progress_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
222static void
223run (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",
263 NULL,
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
311int
312main (int argc, char *const *argv)
313{
316 "anonymity",
317 "LEVEL",
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",
343 "set the maximum number of parallel downloads that is allowed"),
344 &parallelism),
346 'r',
347 "request-parallelism",
348 "REQUESTS",
350 "set the maximum number of parallel requests for blocks that is allowed"),
353 "recursive",
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",
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 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 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 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 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.
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
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:2099
int GNUNET_FS_uri_test_loc(const struct GNUNET_FS_Uri *uri)
Is this a location URI?
Definition: fs_uri.c:1384
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
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:677
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:2253
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
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_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_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
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
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:1230
#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:570
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
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.