8afe498523c7c390ba0a7e5a7becf9087d5b0d0c
[oweals/gnunet.git] / src / fs / fs_getopt.c
1 /*
2      This file is part of GNUnet.
3      (C) 2003, 2004, 2005, 2006, 2007, 2008, 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 2, 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_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_lib.h"
28
29
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 int
46 GNUNET_FS_getopt_configure_set_keywords (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 (u == NULL)
57     {
58       u = GNUNET_malloc (sizeof (struct GNUNET_ECRS_URI));
59       *uri = u;
60       u->type = ksk;
61       u->data.ksk.keywordCount = 0;
62       u->data.ksk.keywords = NULL;
63     }
64   else
65     {
66       GNUNET_assert (u->type == ksk);
67     }
68   slen = strlen (value);
69   if (slen == 0)
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           memcpy (&val[1], &value[2], slen - 3);
82           val[slen - 2] = '\0';
83         }
84       else
85         {
86           /* no quotes, just keep the '+' */
87           val = GNUNET_strdup (value);
88         }
89     }
90   else
91     {
92       if ((value[0] == '"') && (slen > 2) && (value[slen - 1] == '"'))
93         {
94           /* remove the quotes, add a space */
95           val = GNUNET_malloc (slen);
96           val[0] = ' ';
97           memcpy (&val[1], &value[1], slen - 2);
98           val[slen - 1] = '\0';
99         }
100       else
101         {
102           /* add a space to indicate "not mandatory" */
103           val = GNUNET_malloc (slen + 2);
104           strcpy (val, " ");
105           strcat (val, value);
106         }
107     }
108   GNUNET_array_grow (u->data.ksk.keywords,
109                      u->data.ksk.keywordCount, u->data.ksk.keywordCount + 1);
110   u->data.ksk.keywords[u->data.ksk.keywordCount - 1] = val;
111   return GNUNET_OK;
112 }
113
114
115 /**
116  * Command-line option parser function that allows the user to specify
117  * one or more '-m' options with metadata.  Each specified entry of
118  * the form "type=value" will be added to the metadata.  A pointer to
119  * the metadata must be passed as the "scls" argument.
120  *
121  * @param ctx command line processor context
122  * @param scls must be of type "struct GNUNET_MetaData **"
123  * @param option name of the option (typically 'k')
124  * @param value command line argument given
125  * @return GNUNET_OK on success
126  */
127 int
128 GNUNET_FS_getopt_configure_set_metadata (GNUNET_GETOPT_CommandLineProcessorContext* ctx, 
129                                          void *scls,
130                                          const char *option,
131                                          const char *value)
132
133 {
134   struct GNUNET_CONTAINER_MetaData **mm = scls;
135   EXTRACTOR_KeywordType type;
136   const char *typename;
137   const char *typename_i18n;
138   struct GNUNET_CONTAINER_MetaData *meta;
139   char *tmp;
140
141   meta = *mm;
142   if (meta == NULL)
143     {
144       meta = GNUNET_CONTAINER_meta_data_create ();
145       *mm = meta;
146     }
147
148   tmp = GNUNET_STRINGS_to_utf8 (NULL, value, strlen (value),
149 #if ENABLE_NLS
150                                 nl_langinfo (CODESET)
151 #else
152                                 "utf-8"
153 #endif
154     );
155   type = EXTRACTOR_getHighestKeywordTypeNumber ();
156   while (type > 0)
157     {
158       type--;
159       typename = EXTRACTOR_getKeywordTypeAsString (type);
160       typename_i18n = dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, typename);
161       if ((strlen (tmp) >= strlen (typename) + 1) &&
162           (tmp[strlen (typename)] == ':') &&
163           (0 == strncmp (typename, tmp, strlen (typename))))
164         {
165           GNUNET_CONTAINER_meta_data_insert (meta, type, &tmp[strlen (typename) + 1]);
166           GNUNET_free (tmp);
167           tmp = NULL;
168           break;
169         }
170       if ((strlen (tmp) >= strlen (typename_i18n) + 1) &&
171           (tmp[strlen (typename_i18n)] == ':') &&
172           (0 == strncmp (typename_i18n, tmp, strlen (typename_i18n))))
173         {
174           GNUNET_CONTAINER_meta_data_insert (meta, type,
175                                              &tmp[strlen (typename_i18n) + 1]);
176           GNUNET_free (tmp);
177           tmp = NULL;
178           break;
179         }
180     }
181   if (tmp != NULL)
182     {
183       GNUNET_CONTAINER_meta_data_insert (meta, EXTRACTOR_UNKNOWN, tmp);
184       GNUNET_free (tmp);
185       printf (_
186               ("Unknown metadata type in metadata option `%s'.  Using metadata type `unknown' instead.\n"),
187               value);
188     }
189   return GNUNET_OK;
190 }
191
192 /* end of fs_getopt.c */