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