fixing drq code
[oweals/gnunet.git] / src / fs / gnunet-search.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
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  * TODO:
29  * - add many options (timeout, namespace search, etc.)
30  */
31 #include "platform.h"
32 #include "gnunet_fs_service.h"
33
34 static int ret;
35
36 static const struct GNUNET_CONFIGURATION_Handle *cfg;
37
38 static struct GNUNET_FS_Handle *ctx;
39
40 static struct GNUNET_FS_SearchContext *sc;
41
42 static unsigned int anonymity = 1;
43
44 static int verbose;
45
46 static int
47 item_printer (void *cls,
48               const char *plugin_name,
49               enum EXTRACTOR_MetaType type, 
50               enum EXTRACTOR_MetaFormat format,
51               const char *data_mime_type,
52               const char *data,
53               size_t data_size)
54 {
55   if ( (format != EXTRACTOR_METAFORMAT_UTF8) &&
56        (format != EXTRACTOR_METAFORMAT_C_STRING) )
57     return 0;
58   printf ("\t%20s: %s\n",
59           dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN,
60                     EXTRACTOR_metatype_to_string (type)),
61           data);
62   return GNUNET_OK;
63 }
64
65
66 /**
67  * Called by FS client to give information about the progress of an 
68  * operation.
69  *
70  * @param cls closure
71  * @param info details about the event, specifying the event type
72  *        and various bits about the event
73  * @return client-context (for the next progress call
74  *         for this operation; should be set to NULL for
75  *         SUSPEND and STOPPED events).  The value returned
76  *         will be passed to future callbacks in the respective
77  *         field in the GNUNET_FS_ProgressInfo struct.
78  */
79 static void *
80 progress_cb (void *cls,
81              const struct GNUNET_FS_ProgressInfo *info)
82 {
83   char *uri;
84   char *dotdot;
85   char *filename;
86
87   switch (info->status)
88     {
89     case GNUNET_FS_STATUS_SEARCH_START:
90       break;
91     case GNUNET_FS_STATUS_SEARCH_RESULT:
92       uri = GNUNET_FS_uri_to_string (info->value.search.specifics.result.uri);
93       printf ("%s:\n", uri);
94       filename =
95         GNUNET_CONTAINER_meta_data_get_by_type (info->value.search.specifics.result.meta,
96                                                 EXTRACTOR_METATYPE_FILENAME);
97       if (filename != NULL)
98         {
99           while (NULL != (dotdot = strstr (filename, "..")))
100             dotdot[0] = dotdot[1] = '_';
101           printf ("gnunet-download -o \"%s\" %s\n", 
102                   filename, 
103                   uri);
104         }
105       else
106         printf ("gnunet-download %s\n", uri);
107       if (verbose)
108         GNUNET_CONTAINER_meta_data_iterate (info->value.search.specifics.result.meta, 
109                                             &item_printer,
110                                             NULL);
111       printf ("\n");
112       fflush(stdout);
113       GNUNET_free_non_null (filename);
114       GNUNET_free (uri);
115       break;
116     case GNUNET_FS_STATUS_SEARCH_UPDATE:
117       break;
118     case GNUNET_FS_STATUS_SEARCH_ERROR:
119       fprintf (stderr,
120                _("Error searching: %s.\n"),
121                info->value.search.specifics.error.message);
122       GNUNET_FS_search_stop (sc);      
123       break;
124     case GNUNET_FS_STATUS_SEARCH_STOPPED: 
125       GNUNET_FS_stop (ctx);
126       break;      
127     default:
128       fprintf (stderr,
129                _("Unexpected status: %d\n"),
130                info->status);
131       break;
132     }
133   return NULL;
134 }
135
136
137 /**
138  * Main function that will be run by the scheduler.
139  *
140  * @param cls closure
141  * @param sched the scheduler to use
142  * @param args remaining command-line arguments
143  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
144  * @param c configuration
145  */
146 static void
147 run (void *cls,
148      struct GNUNET_SCHEDULER_Handle *sched,
149      char *const *args,
150      const char *cfgfile,
151      const struct GNUNET_CONFIGURATION_Handle *c)
152 {
153   struct GNUNET_FS_Uri *uri;
154   unsigned int argc;
155
156   argc = 0;
157   while (NULL != args[argc])
158     argc++;
159   uri = GNUNET_FS_uri_ksk_create_from_args (argc,
160                                             (const char **) args);
161   if (NULL == uri)
162     {
163       fprintf (stderr,
164                _("Could not create keyword URI from arguments.\n"));
165       ret = 1;
166       GNUNET_FS_uri_destroy (uri);
167       return;
168     }
169   cfg = c;
170   ctx = GNUNET_FS_start (sched,
171                          cfg,
172                          "gnunet-search",
173                          &progress_cb,
174                          NULL,
175                          GNUNET_FS_FLAGS_NONE,
176                          GNUNET_FS_OPTIONS_END);
177   if (NULL == ctx)
178     {
179       fprintf (stderr,
180                _("Could not initialize `%s' subsystem.\n"),
181                "FS");
182       GNUNET_FS_uri_destroy (uri);
183       GNUNET_FS_stop (ctx);
184       ret = 1;
185       return;
186     }
187   sc = GNUNET_FS_search_start (ctx,
188                                uri,
189                                anonymity,
190                                NULL);
191   GNUNET_FS_uri_destroy (uri);
192   if (NULL == sc)
193     {
194       fprintf (stderr,
195                _("Could not start searching.\n"));
196       ret = 1;
197       return;
198     }
199 }
200
201
202 /**
203  * gnunet-search command line options
204  */
205 static struct GNUNET_GETOPT_CommandLineOption options[] = {
206   {'a', "anonymity", "LEVEL",
207    gettext_noop ("set the desired LEVEL of receiver-anonymity"),
208    1, &GNUNET_GETOPT_set_uint, &anonymity},
209   // FIXME: options!
210   GNUNET_GETOPT_OPTION_END
211 };
212
213
214 /**
215  * The main function to search GNUnet.
216  *
217  * @param argc number of arguments from the command line
218  * @param argv command line arguments
219  * @return 0 ok, 1 on error
220  */
221 int
222 main (int argc, char *const *argv)
223 {
224   return (GNUNET_OK ==
225           GNUNET_PROGRAM_run (argc,
226                               argv,
227                               "gnunet-search",
228                               gettext_noop
229                               ("Search GNUnet."),
230                               options, &run, NULL)) ? ret : 1;
231 }
232
233 /* end of gnunet-search.c */
234