src: for every AGPL3.0 file, add SPDX identifier.
[oweals/gnunet.git] / src / fs / fs_getopt.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 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 /**
22  * @file fs/fs_getopt.c
23  * @brief helper functions for command-line argument processing
24  * @author Igor Wronsky, Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_fs_service.h"
28 #include "gnunet_getopt_lib.h"
29 #include "fs_api.h"
30
31 /* ******************** command-line option parsing API ******************** */
32
33 /**
34  * Command-line option parser function that allows the user
35  * to specify one or more '-k' options with keywords.  Each
36  * specified keyword will be added to the URI.  A pointer to
37  * the URI must be passed as the "scls" argument.
38  *
39  * @param ctx command line processor context
40  * @param scls must be of type "struct GNUNET_FS_Uri **"
41  * @param option name of the option (typically 'k')
42  * @param value command line argument given
43  * @return #GNUNET_OK on success
44  */
45 static int
46 getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
47                      void *scls,
48                      const char *option,
49                      const char *value)
50 {
51   struct GNUNET_FS_Uri **uri = scls;
52   struct GNUNET_FS_Uri *u = *uri;
53   char *val;
54   size_t slen;
55
56   if (NULL == u)
57   {
58     u = GNUNET_new (struct GNUNET_FS_Uri);
59     *uri = u;
60     u->type = GNUNET_FS_URI_KSK;
61     u->data.ksk.keywordCount = 0;
62     u->data.ksk.keywords = NULL;
63   }
64   else
65   {
66     GNUNET_assert (GNUNET_FS_URI_KSK == u->type);
67   }
68   slen = strlen (value);
69   if (0 == slen)
70     return GNUNET_SYSERR;       /* cannot be empty */
71   if (value[0] == '+')
72   {
73     /* simply preserve the "mandatory" flag */
74     if (slen < 2)
75       return GNUNET_SYSERR;     /* empty keywords not allowed */
76     if ((value[1] == '"') && (slen > 3) && (value[slen - 1] == '"'))
77     {
78       /* remove the quotes, keep the '+' */
79       val = GNUNET_malloc (slen - 1);
80       val[0] = '+';
81       GNUNET_memcpy (&val[1],
82                      &value[2],
83                      slen - 3);
84       val[slen - 2] = '\0';
85     }
86     else
87     {
88       /* no quotes, just keep the '+' */
89       val = GNUNET_strdup (value);
90     }
91   }
92   else
93   {
94     if ((value[0] == '"') && (slen > 2) && (value[slen - 1] == '"'))
95     {
96       /* remove the quotes, add a space */
97       val = GNUNET_malloc (slen);
98       val[0] = ' ';
99       GNUNET_memcpy (&val[1],
100                      &value[1],
101                      slen - 2);
102       val[slen - 1] = '\0';
103     }
104     else
105     {
106       /* add a space to indicate "not mandatory" */
107       val = GNUNET_malloc (slen + 2);
108       strcpy (val, " ");
109       strcat (val, value);
110     }
111   }
112   GNUNET_array_append (u->data.ksk.keywords,
113                        u->data.ksk.keywordCount,
114                        val);
115   return GNUNET_OK;
116 }
117
118
119 /**
120  * Allow user to specify keywords.
121  *
122  * @param shortName short name of the option
123  * @param name long name of the option
124  * @param argumentHelp help text for the option argument
125  * @param description long help text for the option
126  * @param[out] topKeywords set to the desired value
127  */
128 struct GNUNET_GETOPT_CommandLineOption
129 GNUNET_FS_GETOPT_KEYWORDS (char shortName,
130                            const char *name,
131                            const char *argumentHelp,
132                            const char *description,
133                            struct GNUNET_FS_Uri **topKeywords)
134 {
135   struct GNUNET_GETOPT_CommandLineOption clo = {
136     .shortName = shortName,
137     .name = name,
138     .argumentHelp = argumentHelp,
139     .description = description,
140     .require_argument = 1,
141     .processor = &getopt_set_keywords,
142     .scls = (void *) topKeywords  
143   };
144
145   return clo;
146 }
147
148
149 /**
150  * Command-line option parser function that allows the user to specify
151  * one or more '-m' options with metadata.  Each specified entry of
152  * the form "type=value" will be added to the metadata.  A pointer to
153  * the metadata must be passed as the "scls" argument.
154  *
155  * @param ctx command line processor context
156  * @param scls must be of type "struct GNUNET_MetaData **"
157  * @param option name of the option (typically 'k')
158  * @param value command line argument given
159  * @return #GNUNET_OK on success
160  */
161 static int
162 getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
163                      void *scls,
164                      const char *option,
165                      const char *value)
166 {
167   struct GNUNET_CONTAINER_MetaData **mm = scls;
168 #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
169   enum EXTRACTOR_MetaType type;
170   const char *typename;
171   const char *typename_i18n;
172 #endif
173   struct GNUNET_CONTAINER_MetaData *meta;
174   char *tmp;
175
176   meta = *mm;
177   if (meta == NULL)
178   {
179     meta = GNUNET_CONTAINER_meta_data_create ();
180     *mm = meta;
181   }
182
183   /* Use GNUNET_STRINGS_get_utf8_args() in main() to acquire utf-8-encoded
184    * commandline arguments, so that the following line is not needed.
185    */
186   /*tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), locale_charset ());*/
187   tmp = GNUNET_strdup (value);
188 #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
189   type = EXTRACTOR_metatype_get_max ();
190   while (type > 0)
191   {
192     type--;
193     typename = EXTRACTOR_metatype_to_string (type);
194     typename_i18n = dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, typename);
195     if ((strlen (tmp) >= strlen (typename) + 1) &&
196         (tmp[strlen (typename)] == ':') &&
197         (0 == strncmp (typename, tmp, strlen (typename))))
198     {
199       GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", type,
200                                          EXTRACTOR_METAFORMAT_UTF8,
201                                          "text/plain",
202                                          &tmp[strlen (typename) + 1],
203                                          strlen (&tmp[strlen (typename) + 1]) +
204                                          1);
205       GNUNET_free (tmp);
206       tmp = NULL;
207       break;
208     }
209     if ((strlen (tmp) >= strlen (typename_i18n) + 1) &&
210         (tmp[strlen (typename_i18n)] == ':') &&
211         (0 == strncmp (typename_i18n, tmp, strlen (typename_i18n))))
212     {
213       GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", type,
214                                          EXTRACTOR_METAFORMAT_UTF8,
215                                          "text/plain",
216                                          &tmp[strlen (typename_i18n) + 1],
217                                          strlen (&tmp
218                                                  [strlen (typename_i18n) + 1]) +
219                                          1);
220       GNUNET_free (tmp);
221       tmp = NULL;
222       break;
223     }
224   }
225 #endif
226
227   if (NULL != tmp)
228   {
229     GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>",
230                                        EXTRACTOR_METATYPE_UNKNOWN,
231                                        EXTRACTOR_METAFORMAT_UTF8, "text/plain",
232                                        tmp, strlen (tmp) + 1);
233     GNUNET_free (tmp);
234     printf (_
235             ("Unknown metadata type in metadata option `%s'.  Using metadata type `unknown' instead.\n"),
236             value);
237   }
238   return GNUNET_OK;
239 }
240
241 /**
242  * Allow user to specify metadata.
243  *
244  * @param shortName short name of the option
245  * @param name long name of the option
246  * @param argumentHelp help text for the option argument
247  * @param description long help text for the option
248  * @param[out] metadata set to the desired value
249  */
250 struct GNUNET_GETOPT_CommandLineOption
251 GNUNET_FS_GETOPT_METADATA (char shortName,
252                            const char *name,
253                            const char *argumentHelp,
254                            const char *description,
255                            struct GNUNET_CONTAINER_MetaData **meta)
256 {
257   struct GNUNET_GETOPT_CommandLineOption clo = {
258     .shortName = shortName,
259     .name = name,
260     .argumentHelp = argumentHelp,
261     .description = description,
262     .require_argument = 1,
263     .processor = &getopt_set_metadata,
264     .scls = (void *) meta
265   };
266
267   return clo;
268 }
269
270
271
272
273 /* end of fs_getopt.c */