-fixing main FS build, updating man page of gnunet-pseudonym
[oweals/gnunet.git] / src / fs / fs_publish_ksk.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010, 2012, 2013 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 /**
22  * @file fs/fs_publish_ksk.c
23  * @brief publish a URI under a keyword in GNUnet
24  * @see https://gnunet.org/encoding and #2564 
25  * @author Krista Bennett
26  * @author Christian Grothoff
27  */
28
29 #include "platform.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_signatures.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_fs_service.h"
34 #include "fs_api.h"
35 #include "fs_tree.h"
36 #include "fs_publish_ublock.h"
37
38 /**
39  * Context for the KSK publication.
40  */
41 struct GNUNET_FS_PublishKskContext
42 {
43
44   /**
45    * Keywords to use.
46    */
47   struct GNUNET_FS_Uri *ksk_uri;
48
49   /**
50    * URI to publish.
51    */
52   struct GNUNET_FS_Uri *uri;
53
54   /**
55    * Metadata to use.
56    */
57   struct GNUNET_CONTAINER_MetaData *meta;
58
59   /**
60    * Global FS context.
61    */
62   struct GNUNET_FS_Handle *h;
63
64   /**
65    * UBlock publishing operation that is active.
66    */
67   struct GNUNET_FS_PublishUblockContext *uc;
68
69   /**
70    * Handle to the datastore, NULL if we are just simulating.
71    */
72   struct GNUNET_DATASTORE_Handle *dsh;
73
74   /**
75    * Current task.
76    */
77   GNUNET_SCHEDULER_TaskIdentifier ksk_task;
78
79   /**
80    * Function to call once we're done.
81    */
82   GNUNET_FS_PublishContinuation cont;
83
84   /**
85    * Closure for cont.
86    */
87   void *cont_cls;
88
89   /**
90    * When should the KBlocks expire?
91    */
92   struct GNUNET_FS_BlockOptions bo;
93
94   /**
95    * Options to use.
96    */ 
97   enum GNUNET_FS_PublishOptions options;
98
99   /**
100    * Keyword that we are currently processing.
101    */
102   unsigned int i;
103
104 };
105
106
107 /**
108  * Continuation of "GNUNET_FS_publish_ksk" that performs
109  * the actual publishing operation (iterating over all
110  * of the keywords).
111  *
112  * @param cls closure of type "struct PublishKskContext*"
113  * @param tc unused
114  */
115 static void
116 publish_ksk_cont (void *cls, 
117                   const struct GNUNET_SCHEDULER_TaskContext *tc);
118
119
120 /**
121  * Function called by the datastore API with
122  * the result from the PUT request.
123  *
124  * @param cls closure of type "struct GNUNET_FS_PublishKskContext*"
125  * @param msg error message (or NULL)
126  */
127 static void
128 kb_put_cont (void *cls,
129              const char *msg)
130 {
131   struct GNUNET_FS_PublishKskContext *pkc = cls;
132
133   pkc->uc = NULL;
134   if (NULL != msg)
135   {
136     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
137                 "KBlock PUT operation failed: %s\n", msg);
138     pkc->cont (pkc->cont_cls, NULL, msg);
139     GNUNET_FS_publish_ksk_cancel (pkc);
140     return;
141   }
142   pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc);
143 }
144
145
146 /**
147  * Continuation of "GNUNET_FS_publish_ksk" that performs the actual
148  * publishing operation (iterating over all of the keywords).
149  *
150  * @param cls closure of type "struct GNUNET_FS_PublishKskContext*"
151  * @param tc unused
152  */
153 static void
154 publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
155 {
156   struct GNUNET_FS_PublishKskContext *pkc = cls;
157   const char *keyword;
158
159   pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK;
160   if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
161        (NULL == pkc->dsh) )
162   {
163     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n");
164     pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL);
165     GNUNET_FS_publish_ksk_cancel (pkc);
166     return;
167   }
168   keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
169   pkc->uc = GNUNET_FS_publish_ublock_ (pkc->h,
170                                        pkc->dsh,
171                                        keyword, NULL,
172                                        GNUNET_CRYPTO_ecc_key_get_anonymous (),
173                                        pkc->meta,
174                                        pkc->uri,
175                                        &pkc->bo,
176                                        pkc->options,
177                                        &kb_put_cont, pkc);
178 }
179
180
181 /**
182  * Publish a CHK under various keywords on GNUnet.
183  *
184  * @param h handle to the file sharing subsystem
185  * @param ksk_uri keywords to use
186  * @param meta metadata to use
187  * @param uri URI to refer to in the KBlock
188  * @param bo per-block options
189  * @param options publication options
190  * @param cont continuation
191  * @param cont_cls closure for cont
192  * @return NULL on error ('cont' will still be called)
193  */
194 struct GNUNET_FS_PublishKskContext *
195 GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
196                        const struct GNUNET_FS_Uri *ksk_uri,
197                        const struct GNUNET_CONTAINER_MetaData *meta,
198                        const struct GNUNET_FS_Uri *uri,
199                        const struct GNUNET_FS_BlockOptions *bo,
200                        enum GNUNET_FS_PublishOptions options,
201                        GNUNET_FS_PublishContinuation cont, void *cont_cls)
202 {
203   struct GNUNET_FS_PublishKskContext *pkc;
204
205   GNUNET_assert (NULL != uri);
206   pkc = GNUNET_new (struct GNUNET_FS_PublishKskContext);
207   pkc->h = h;
208   pkc->bo = *bo;
209   pkc->options = options;
210   pkc->cont = cont;
211   pkc->cont_cls = cont_cls;
212   pkc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
213   if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
214   {
215     pkc->dsh = GNUNET_DATASTORE_connect (h->cfg);
216     if (NULL == pkc->dsh)
217     {
218       cont (cont_cls, NULL, _("Could not connect to datastore."));
219       GNUNET_free (pkc);
220       return NULL;
221     }
222   }
223   pkc->uri = GNUNET_FS_uri_dup (uri);
224   pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
225   pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc);
226   return pkc;
227 }
228
229
230 /**
231  * Abort the KSK publishing operation.
232  *
233  * @param pkc context of the operation to abort.
234  */
235 void
236 GNUNET_FS_publish_ksk_cancel (struct GNUNET_FS_PublishKskContext *pkc)
237 {
238   if (GNUNET_SCHEDULER_NO_TASK != pkc->ksk_task)
239   {
240     GNUNET_SCHEDULER_cancel (pkc->ksk_task);
241     pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK;
242   }
243   if (NULL != pkc->uc)
244   {
245     GNUNET_FS_publish_ublock_cancel_ (pkc->uc);
246     pkc->uc = NULL;
247   }
248   if (NULL != pkc->dsh)
249   {
250     GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
251     pkc->dsh = NULL;
252   }
253   GNUNET_CONTAINER_meta_data_destroy (pkc->meta);
254   GNUNET_FS_uri_destroy (pkc->ksk_uri);
255   GNUNET_FS_uri_destroy (pkc->uri);
256   GNUNET_free (pkc);
257 }
258
259
260 /* end of fs_publish_ksk.c */