f1d8fb56e15528da49dac991d86f5e1df62a91eb
[oweals/gnunet.git] / src / dht / gnunet-dht-put.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 3, 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 dht/gnunet-dht-put.c
22  * @brief search for data in DHT
23  * @author Christian Grothoff
24  * @author Nathan Evans
25  */
26 #include "platform.h"
27 #include "gnunet_dht_service.h"
28
29 /**
30  * The type of the query
31  */
32 static unsigned int query_type;
33
34 /**
35  * The key used in the DHT
36  */
37 struct GNUNET_HashCode key;
38
39 /**
40  * The key for the query
41  */
42 static char *query_key;
43
44 /**
45  * User supplied timeout value
46  */
47 static unsigned long long timeout_request = 5;
48
49 /**
50  * User supplied expiration value
51  */
52 static unsigned long long expiration_seconds = 3600;
53
54 /**
55  * Desired replication level.
56  */
57 static unsigned int replication = 5;
58
59 /**
60  * Be verbose
61  */
62 static int verbose;
63
64 /**
65  * Handle to the DHT
66  */
67 static struct GNUNET_DHT_Handle *dht_handle;
68
69
70 /**
71  * Global handle of the configuration
72  */
73 static const struct GNUNET_CONFIGURATION_Handle *cfg;
74
75 /**
76  * Global status value
77  */
78 static int ret;
79
80 /**
81  * The data to insert into the dht
82  */
83 static char *data;
84
85 static void
86 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
87 {
88   if (NULL != dht_handle)
89   {
90     GNUNET_DHT_disconnect (dht_handle);
91     dht_handle = NULL;
92   }
93 }
94
95 /**
96  * Signature of the main function of a task.
97  *
98  * @param cls closure
99  * @param success GNUNET_OK if the PUT was transmitted,
100  *                GNUNET_NO on timeout,
101  *                GNUNET_SYSERR on disconnect from service
102  *                after the PUT message was transmitted
103  *                (so we don't know if it was received or not)
104  */
105 static void
106 message_sent_cont (void *cls, int success)
107 {
108   if (verbose)
109   {
110     switch (success)
111     {
112     case GNUNET_OK:
113       FPRINTF (stderr, "%s `%s'!\n",  _("PUT request sent with key"), GNUNET_h2s_full(&key));
114       break;
115     case GNUNET_NO:
116       FPRINTF (stderr, "%s",  _("Timeout sending PUT request!\n"));
117       break;
118     case GNUNET_SYSERR:
119       FPRINTF (stderr, "%s",  _("PUT request not confirmed!\n"));
120       break;
121     default:
122       GNUNET_break (0);
123       break;
124     }
125   }
126   GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
127 }
128
129 /**
130  * Main function that will be run by the scheduler.
131  *
132  * @param cls closure
133  * @param args remaining command-line arguments
134  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
135  * @param c configuration
136  */
137 static void
138 run (void *cls, char *const *args, const char *cfgfile,
139      const struct GNUNET_CONFIGURATION_Handle *c)
140 {
141   struct GNUNET_TIME_Relative timeout;
142   struct GNUNET_TIME_Absolute expiration;
143
144   cfg = c;
145
146   if ((query_key == NULL) || (data == NULL))
147   {
148     FPRINTF (stderr, "%s",  _("Must provide KEY and DATA for DHT put!\n"));
149     ret = 1;
150     return;
151   }
152
153   dht_handle = GNUNET_DHT_connect (cfg, 1);
154   if (dht_handle == NULL)
155   {
156     FPRINTF (stderr, _("Could not connect to %s service!\n"), "DHT");
157     ret = 1;
158     return;
159   }
160   else if (verbose)
161     FPRINTF (stderr, _("Connected to %s service!\n"), "DHT");
162
163   if (query_type == GNUNET_BLOCK_TYPE_ANY)      /* Type of data not set */
164     query_type = GNUNET_BLOCK_TYPE_TEST;
165
166   GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key);
167
168   timeout =
169       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_request);
170   expiration =
171       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply
172                                         (GNUNET_TIME_UNIT_SECONDS,
173                                          expiration_seconds));
174
175   if (verbose)
176     FPRINTF (stderr, _("Issuing put request for `%s' with data `%s'!\n"),
177              query_key, data);
178   GNUNET_DHT_put (dht_handle, &key, replication, GNUNET_DHT_RO_NONE, query_type,
179                   strlen (data), data, expiration, timeout, &message_sent_cont,
180                   NULL);
181
182 }
183
184
185 /**
186  * gnunet-dht-put command line options
187  */
188 static struct GNUNET_GETOPT_CommandLineOption options[] = {
189   {'d', "data", "DATA",
190    gettext_noop ("the data to insert under the key"),
191    1, &GNUNET_GETOPT_set_string, &data},
192   {'e', "expiration", "EXPIRATION",
193    gettext_noop ("how long to store this entry in the dht (in seconds)"),
194    1, &GNUNET_GETOPT_set_ulong, &expiration_seconds},
195   {'k', "key", "KEY",
196    gettext_noop ("the query key"),
197    1, &GNUNET_GETOPT_set_string, &query_key},
198   {'r', "replication", "LEVEL",
199    gettext_noop ("how many replicas to create"),
200    1, &GNUNET_GETOPT_set_uint, &replication},
201   {'t', "type", "TYPE",
202    gettext_noop ("the type to insert data as"),
203    1, &GNUNET_GETOPT_set_uint, &query_type},
204   {'T', "timeout", "TIMEOUT",
205    gettext_noop ("how long to execute this query before giving up?"),
206    1, &GNUNET_GETOPT_set_ulong, &timeout_request},
207   {'V', "verbose", NULL,
208    gettext_noop ("be verbose (print progress information)"),
209    0, &GNUNET_GETOPT_set_one, &verbose},
210   GNUNET_GETOPT_OPTION_END
211 };
212
213
214 /**
215  * Entry point for gnunet-dht-put
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   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
225     return 2;
226
227   return (GNUNET_OK ==
228           GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-put",
229                               gettext_noop
230                               ("Issue a PUT request to the GNUnet DHT insert DATA under KEY."),
231                               options, &run, NULL)) ? ret : 1;
232 }
233
234 /* end of gnunet-dht-put.c */