aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-search.c')
-rw-r--r--src/fs/gnunet-search.c382
1 files changed, 0 insertions, 382 deletions
diff --git a/src/fs/gnunet-search.c b/src/fs/gnunet-search.c
deleted file mode 100644
index 3bf013650..000000000
--- a/src/fs/gnunet-search.c
+++ /dev/null
@@ -1,382 +0,0 @@
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 */
20/**
21 * @file fs/gnunet-search.c
22 * @brief searching for files on GNUnet
23 * @author Christian Grothoff
24 * @author Krista Bennett
25 * @author James Blackwell
26 * @author Igor Wronsky
27 */
28#include "platform.h"
29#include "gnunet_fs_service.h"
30
31static int ret;
32
33static const struct GNUNET_CONFIGURATION_Handle *cfg;
34
35static struct GNUNET_FS_Handle *ctx;
36
37static struct GNUNET_FS_SearchContext *sc;
38
39static char *output_filename;
40
41static struct GNUNET_FS_DirectoryBuilder *db;
42
43static unsigned int anonymity = 1;
44
45/**
46 * Timeout for the search, 0 means to wait for CTRL-C.
47 */
48static struct GNUNET_TIME_Relative timeout;
49
50static unsigned int results_limit;
51
52static unsigned int results;
53
54static unsigned int verbose;
55
56static int local_only;
57
58static struct GNUNET_SCHEDULER_Task *tt;
59
60
61/**
62 * Type of a function that libextractor calls for each
63 * meta data item found.
64 *
65 * @param cls closure (user-defined, unused)
66 * @param plugin_name name of the plugin that produced this value;
67 * special values can be used (e.g. '&lt;zlib&gt;' for zlib being
68 * used in the main libextractor library and yielding
69 * meta data).
70 * @param type libextractor-type describing the meta data
71 * @param format basic format information about data
72 * @param data_mime_type mime-type of data (not of the original file);
73 * can be NULL (if mime-type is not known)
74 * @param data actual meta-data found
75 * @param data_size number of bytes in @a data
76 * @return 0 to continue extracting, 1 to abort
77 */
78static int
79item_printer (void *cls,
80 const char *plugin_name,
81 enum EXTRACTOR_MetaType type,
82 enum EXTRACTOR_MetaFormat format,
83 const char *data_mime_type,
84 const char *data,
85 size_t data_size)
86{
87 if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
88 (format != EXTRACTOR_METAFORMAT_C_STRING))
89 return 0;
90 if (type == EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME)
91 return 0;
92#if HAVE_LIBEXTRACTOR
93 printf ("\t%20s: %s\n",
94 dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN,
95 EXTRACTOR_metatype_to_string (type)),
96 data);
97#else
98 printf ("\t%20d: %s\n", type, data);
99#endif
100 return 0;
101}
102
103
104static void
105clean_task (void *cls)
106{
107 size_t dsize;
108 void *ddata;
109
110 GNUNET_FS_stop (ctx);
111 ctx = NULL;
112 if (output_filename == NULL)
113 return;
114 if (GNUNET_OK !=
115 GNUNET_FS_directory_builder_finish (db, &dsize, &ddata))
116 {
117 GNUNET_break (0);
118 GNUNET_free (output_filename);
119 return;
120 }
121 (void) GNUNET_DISK_directory_remove (output_filename);
122 if (GNUNET_OK !=
123 GNUNET_DISK_fn_write (output_filename,
124 ddata,
125 dsize,
126 GNUNET_DISK_PERM_USER_READ
127 | GNUNET_DISK_PERM_USER_WRITE))
128 {
129 fprintf (stderr,
130 _ ("Failed to write directory with search results to `%s'\n"),
131 output_filename);
132 }
133 GNUNET_free (ddata);
134 GNUNET_free (output_filename);
135}
136
137
138/**
139 * Called by FS client to give information about the progress of an
140 * operation.
141 *
142 * @param cls closure
143 * @param info details about the event, specifying the event type
144 * and various bits about the event
145 * @return client-context (for the next progress call
146 * for this operation; should be set to NULL for
147 * SUSPEND and STOPPED events). The value returned
148 * will be passed to future callbacks in the respective
149 * field in the GNUNET_FS_ProgressInfo struct.
150 */
151static void *
152progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
153{
154 static unsigned int cnt;
155 int is_directory;
156 char *uri;
157 char *filename;
158
159 switch (info->status)
160 {
161 case GNUNET_FS_STATUS_SEARCH_START:
162 break;
163
164 case GNUNET_FS_STATUS_SEARCH_RESULT:
165 if (db != NULL)
166 GNUNET_FS_directory_builder_add (db,
167 info->value.search.specifics.result.uri,
168 info->value.search.specifics.result.meta,
169 NULL);
170 uri = GNUNET_FS_uri_to_string (info->value.search.specifics.result.uri);
171 printf ("#%u:\n", ++cnt);
172 filename = GNUNET_CONTAINER_meta_data_get_by_type (
173 info->value.search.specifics.result.meta,
174 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
175 is_directory = GNUNET_FS_meta_data_test_for_directory (
176 info->value.search.specifics.result.meta);
177 if (NULL != filename)
178 {
179 while ((filename[0] != '\0') && ('/' == filename[strlen (filename) - 1]))
180 filename[strlen (filename) - 1] = '\0';
181 GNUNET_DISK_filename_canonicalize (filename);
182 if (GNUNET_YES == is_directory)
183 printf ("gnunet-download -o \"%s%s\" -R %s\n",
184 filename,
185 GNUNET_FS_DIRECTORY_EXT,
186 uri);
187 else
188 printf ("gnunet-download -o \"%s\" %s\n", filename, uri);
189 }
190 else if (GNUNET_YES == is_directory)
191 printf ("gnunet-download -o \"collection%s\" -R %s\n",
192 GNUNET_FS_DIRECTORY_EXT,
193 uri);
194 else
195 printf ("gnunet-download %s\n", uri);
196 if (verbose)
197 GNUNET_CONTAINER_meta_data_iterate (info->value.search.specifics.result
198 .meta,
199 &item_printer,
200 NULL);
201 printf ("\n");
202 fflush (stdout);
203 GNUNET_free (filename);
204 GNUNET_free (uri);
205 results++;
206 if ((results_limit > 0) && (results >= results_limit))
207 GNUNET_SCHEDULER_shutdown ();
208 break;
209
210 case GNUNET_FS_STATUS_SEARCH_UPDATE:
211 break;
212
213 case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
214 /* ignore */
215 break;
216
217 case GNUNET_FS_STATUS_SEARCH_ERROR:
218 fprintf (stderr,
219 _ ("Error searching: %s.\n"),
220 info->value.search.specifics.error.message);
221 GNUNET_SCHEDULER_shutdown ();
222 break;
223
224 case GNUNET_FS_STATUS_SEARCH_STOPPED:
225 GNUNET_SCHEDULER_add_now (&clean_task, NULL);
226 break;
227
228 default:
229 fprintf (stderr, _ ("Unexpected status: %d\n"), info->status);
230 break;
231 }
232 return NULL;
233}
234
235
236static void
237shutdown_task (void *cls)
238{
239 if (sc != NULL)
240 {
241 GNUNET_FS_search_stop (sc);
242 sc = NULL;
243 }
244}
245
246
247static void
248timeout_task (void *cls)
249{
250 tt = NULL;
251 GNUNET_SCHEDULER_shutdown ();
252}
253
254
255/**
256 * Main function that will be run by the scheduler.
257 *
258 * @param cls closure
259 * @param args remaining command-line arguments
260 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
261 * @param c configuration
262 */
263static void
264run (void *cls,
265 char *const *args,
266 const char *cfgfile,
267 const struct GNUNET_CONFIGURATION_Handle *c)
268{
269 struct GNUNET_FS_Uri *uri;
270 unsigned int argc;
271 enum GNUNET_FS_SearchOptions options;
272
273 argc = 0;
274 while (NULL != args[argc])
275 argc++;
276 uri = GNUNET_FS_uri_ksk_create_from_args (argc, (const char **) args);
277 if (NULL == uri)
278 {
279 fprintf (stderr,
280 "%s",
281 _ ("Could not create keyword URI from arguments.\n"));
282 ret = 1;
283 return;
284 }
285 cfg = c;
286 ctx = GNUNET_FS_start (cfg,
287 "gnunet-search",
288 &progress_cb,
289 NULL,
290 GNUNET_FS_FLAGS_NONE,
291 GNUNET_FS_OPTIONS_END);
292 if (NULL == ctx)
293 {
294 fprintf (stderr, _ ("Could not initialize `%s' subsystem.\n"), "FS");
295 GNUNET_FS_uri_destroy (uri);
296 ret = 1;
297 return;
298 }
299 if (output_filename != NULL)
300 db = GNUNET_FS_directory_builder_create (NULL);
301 options = GNUNET_FS_SEARCH_OPTION_NONE;
302 if (local_only)
303 options |= GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY;
304 sc = GNUNET_FS_search_start (ctx, uri, anonymity, options, NULL);
305 GNUNET_FS_uri_destroy (uri);
306 if (NULL == sc)
307 {
308 fprintf (stderr, "%s", _ ("Could not start searching.\n"));
309 GNUNET_FS_stop (ctx);
310 ret = 1;
311 return;
312 }
313 if (0 != timeout.rel_value_us)
314 tt = GNUNET_SCHEDULER_add_delayed (timeout, &timeout_task, NULL);
315 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
316}
317
318
319/**
320 * The main function to search GNUnet.
321 *
322 * @param argc number of arguments from the command line
323 * @param argv command line arguments
324 * @return 0 ok, 1 on error
325 */
326int
327main (int argc, char *const *argv)
328{
329 struct GNUNET_GETOPT_CommandLineOption options[] =
330 { GNUNET_GETOPT_option_uint ('a',
331 "anonymity",
332 "LEVEL",
333 gettext_noop (
334 "set the desired LEVEL of receiver-anonymity"),
335 &anonymity),
336 GNUNET_GETOPT_option_flag (
337 'n',
338 "no-network",
339 gettext_noop ("only search the local peer (no P2P network search)"),
340 &local_only),
341 GNUNET_GETOPT_option_string (
342 'o',
343 "output",
344 "PREFIX",
345 gettext_noop ("write search results to file starting with PREFIX"),
346 &output_filename),
347 GNUNET_GETOPT_option_relative_time (
348 't',
349 "timeout",
350 "DELAY",
351 gettext_noop ("automatically terminate search after DELAY"),
352 &timeout),
353 GNUNET_GETOPT_option_verbose (&verbose),
354 GNUNET_GETOPT_option_uint ('N',
355 "results",
356 "VALUE",
357 gettext_noop ("automatically terminate search "
358 "after VALUE results are found"),
359 &results_limit),
360 GNUNET_GETOPT_OPTION_END };
361
362 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
363 return 2;
364
365 ret =
366 (GNUNET_OK ==
367 GNUNET_PROGRAM_run (argc,
368 argv,
369 "gnunet-search [OPTIONS] KEYWORD",
370 gettext_noop (
371 "Search GNUnet for files that were published on GNUnet"),
372 options,
373 &run,
374 NULL))
375 ? ret
376 : 1;
377 GNUNET_free_nz ((void *) argv);
378 return ret;
379}
380
381
382/* end of gnunet-search.c */