plane hacking
[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 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_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 "fs.h"
29
30 /* ******************** command-line option parsing API ******************** */
31
32 /**
33  * Command-line option parser function that allows the user
34  * to specify one or more '-k' options with keywords.  Each
35  * specified keyword will be added to the URI.  A pointer to
36  * the URI must be passed as the "scls" argument.
37  *
38  * @param ctx command line processor context
39  * @param scls must be of type "struct GNUNET_FS_Uri **"
40  * @param option name of the option (typically 'k')
41  * @param value command line argument given
42  * @return GNUNET_OK on success
43  */
44 int
45 GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext* ctx, 
46                                          void *scls,
47                                          const char *option,
48                                          const char *value)
49 {
50   struct GNUNET_FS_Uri **uri = scls;
51   struct GNUNET_FS_Uri *u = *uri;
52   char *val;
53   size_t slen;
54
55   if (u == NULL)
56     {
57       u = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
58       *uri = u;
59       u->type = ksk;
60       u->data.ksk.keywordCount = 0;
61       u->data.ksk.keywords = NULL;
62     }
63   else
64     {
65       GNUNET_assert (u->type == ksk);
66     }
67   slen = strlen (value);
68   if (slen == 0)
69     return GNUNET_SYSERR;       /* cannot be empty */
70   if (value[0] == '+')
71     {
72       /* simply preserve the "mandatory" flag */
73       if (slen < 2)
74         return GNUNET_SYSERR;   /* empty keywords not allowed */
75       if ((value[1] == '"') && (slen > 3) && (value[slen - 1] == '"'))
76         {
77           /* remove the quotes, keep the '+' */
78           val = GNUNET_malloc (slen - 1);
79           val[0] = '+';
80           memcpy (&val[1], &value[2], slen - 3);
81           val[slen - 2] = '\0';
82         }
83       else
84         {
85           /* no quotes, just keep the '+' */
86           val = GNUNET_strdup (value);
87         }
88     }
89   else
90     {
91       if ((value[0] == '"') && (slen > 2) && (value[slen - 1] == '"'))
92         {
93           /* remove the quotes, add a space */
94           val = GNUNET_malloc (slen);
95           val[0] = ' ';
96           memcpy (&val[1], &value[1], slen - 2);
97           val[slen - 1] = '\0';
98         }
99       else
100         {
101           /* add a space to indicate "not mandatory" */
102           val = GNUNET_malloc (slen + 2);
103           strcpy (val, " ");
104           strcat (val, value);
105         }
106     }
107   GNUNET_array_append (u->data.ksk.keywords,
108                        u->data.ksk.keywordCount,
109                        val);
110   return GNUNET_OK;
111 }
112
113
114 /**
115  * Command-line option parser function that allows the user to specify
116  * one or more '-m' options with metadata.  Each specified entry of
117  * the form "type=value" will be added to the metadata.  A pointer to
118  * the metadata must be passed as the "scls" argument.
119  *
120  * @param ctx command line processor context
121  * @param scls must be of type "struct GNUNET_MetaData **"
122  * @param option name of the option (typically 'k')
123  * @param value command line argument given
124  * @return GNUNET_OK on success
125  */
126 int
127 GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext* ctx, 
128                                          void *scls,
129                                          const char *option,
130                                          const char *value)
131
132 {
133   struct GNUNET_CONTAINER_MetaData **mm = scls;
134   enum EXTRACTOR_MetaType type;
135   const char *typename;
136   const char *typename_i18n;
137   struct GNUNET_CONTAINER_MetaData *meta;
138   char *tmp;
139
140   meta = *mm;
141   if (meta == NULL)
142     {
143       meta = GNUNET_CONTAINER_meta_data_create ();
144       *mm = meta;
145     }
146
147   tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value),
148 #if ENABLE_NLS
149                                 nl_langinfo (CODESET)
150 #else
151                                 "utf-8"
152 #endif
153     );
154   type = EXTRACTOR_metatype_get_max ();
155   while (type > 0)
156     {
157       type--;
158       typename = EXTRACTOR_metatype_to_string (type);
159       typename_i18n = dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, typename);
160       if ((strlen (tmp) >= strlen (typename) + 1) &&
161           (tmp[strlen (typename)] == ':') &&
162           (0 == strncmp (typename, tmp, strlen (typename))))
163         {
164           GNUNET_CONTAINER_meta_data_insert (meta, 
165                                              "<gnunet>",
166                                              type,
167                                              EXTRACTOR_METAFORMAT_UTF8,
168                                              "text/plain",
169                                              &tmp[strlen (typename) + 1],
170                                              strlen (&tmp[strlen (typename) + 1])+1);
171           GNUNET_free (tmp);
172           tmp = NULL;
173           break;
174         }
175       if ((strlen (tmp) >= strlen (typename_i18n) + 1) &&
176           (tmp[strlen (typename_i18n)] == ':') &&
177           (0 == strncmp (typename_i18n, tmp, strlen (typename_i18n))))
178         {
179           GNUNET_CONTAINER_meta_data_insert (meta,
180                                              "<gnunet>",
181                                              type,
182                                              EXTRACTOR_METAFORMAT_UTF8,
183                                              "text/plain",
184                                              &tmp[strlen (typename_i18n) + 1],
185                                              strlen (&tmp[strlen (typename_i18n) + 1]) + 1);
186           GNUNET_free (tmp);
187           tmp = NULL;
188           break;
189         }
190     }
191   if (tmp != NULL)
192     {
193       GNUNET_CONTAINER_meta_data_insert (meta, 
194                                          "<gnunet>",
195                                          EXTRACTOR_METATYPE_UNKNOWN, 
196                                          EXTRACTOR_METAFORMAT_UTF8,
197                                          "text/plain",
198                                          tmp,
199                                          strlen(tmp) + 1);
200       GNUNET_free (tmp);
201       printf (_
202               ("Unknown metadata type in metadata option `%s'.  Using metadata type `unknown' instead.\n"),
203               value);
204     }
205   return GNUNET_OK;
206 }
207
208 /* end of fs_getopt.c */