uncrustify as demanded.
[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
169 #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
170   enum EXTRACTOR_MetaType type;
171   const char *typename;
172   const char *typename_i18n;
173 #endif
174   struct GNUNET_CONTAINER_MetaData *meta;
175   char *tmp;
176
177   meta = *mm;
178   if (meta == NULL)
179     {
180       meta = GNUNET_CONTAINER_meta_data_create();
181       *mm = meta;
182     }
183
184   /* Use GNUNET_STRINGS_get_utf8_args() in main() to acquire utf-8-encoded
185    * commandline arguments, so that the following line is not needed.
186    */
187   /*tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), locale_charset ());*/
188   tmp = GNUNET_strdup(value);
189 #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
190   type = EXTRACTOR_metatype_get_max();
191   while (type > 0)
192     {
193       type--;
194       typename = EXTRACTOR_metatype_to_string(type);
195       typename_i18n = dgettext(LIBEXTRACTOR_GETTEXT_DOMAIN, typename);
196       if ((strlen(tmp) >= strlen(typename) + 1) &&
197           (tmp[strlen(typename)] == ':') &&
198           (0 == strncmp(typename, tmp, strlen(typename))))
199         {
200           GNUNET_CONTAINER_meta_data_insert(meta, "<gnunet>", type,
201                                             EXTRACTOR_METAFORMAT_UTF8,
202                                             "text/plain",
203                                             &tmp[strlen(typename) + 1],
204                                             strlen(&tmp[strlen(typename) + 1]) +
205                                             1);
206           GNUNET_free(tmp);
207           tmp = NULL;
208           break;
209         }
210       if ((strlen(tmp) >= strlen(typename_i18n) + 1) &&
211           (tmp[strlen(typename_i18n)] == ':') &&
212           (0 == strncmp(typename_i18n, tmp, strlen(typename_i18n))))
213         {
214           GNUNET_CONTAINER_meta_data_insert(meta, "<gnunet>", type,
215                                             EXTRACTOR_METAFORMAT_UTF8,
216                                             "text/plain",
217                                             &tmp[strlen(typename_i18n) + 1],
218                                             strlen(&tmp
219                                                    [strlen(typename_i18n) + 1]) +
220                                             1);
221           GNUNET_free(tmp);
222           tmp = NULL;
223           break;
224         }
225     }
226 #endif
227
228   if (NULL != tmp)
229     {
230       GNUNET_CONTAINER_meta_data_insert(meta, "<gnunet>",
231                                         EXTRACTOR_METATYPE_UNKNOWN,
232                                         EXTRACTOR_METAFORMAT_UTF8, "text/plain",
233                                         tmp, strlen(tmp) + 1);
234       GNUNET_free(tmp);
235       printf(_
236                ("Unknown metadata type in metadata option `%s'.  Using metadata type `unknown' instead.\n"),
237              value);
238     }
239   return GNUNET_OK;
240 }
241
242 /**
243  * Allow user to specify metadata.
244  *
245  * @param shortName short name of the option
246  * @param name long name of the option
247  * @param argumentHelp help text for the option argument
248  * @param description long help text for the option
249  * @param[out] metadata set to the desired value
250  */
251 struct GNUNET_GETOPT_CommandLineOption
252 GNUNET_FS_GETOPT_METADATA(char shortName,
253                           const char *name,
254                           const char *argumentHelp,
255                           const char *description,
256                           struct GNUNET_CONTAINER_MetaData **meta)
257 {
258   struct GNUNET_GETOPT_CommandLineOption clo = {
259     .shortName = shortName,
260     .name = name,
261     .argumentHelp = argumentHelp,
262     .description = description,
263     .require_argument = 1,
264     .processor = &getopt_set_metadata,
265     .scls = (void *)meta
266   };
267
268   return clo;
269 }
270
271
272
273
274 /* end of fs_getopt.c */