fix test case, implement base32 argument parser logic
[oweals/gnunet.git] / src / util / gnunet-config.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file util/gnunet-config.c
23  * @brief tool to access and manipulate GNUnet configuration files
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28
29
30 /**
31  * Name of the section
32  */
33 static char *section;
34
35 /**
36  * Name of the option
37  */
38 static char *option;
39
40 /**
41  * Value to set
42  */
43 static char *value;
44
45 /**
46  * Treat option as a filename.
47  */
48 static int is_filename;
49
50 /**
51  * Whether to show the sections.
52  */
53 static int list_sections;
54
55 /**
56  * Return value from 'main'.
57  */
58 static int ret;
59
60 /**
61  * Should we generate a configuration file that is clean and
62  * only contains the deltas to the defaults?
63  */
64 static int rewrite;
65
66 /**
67  * Print each option in a given section.
68  *
69  * @param cls closure
70  * @param section name of the section
71  * @param option name of the option
72  * @param value value of the option
73  */
74 static void
75 print_option (void *cls, const char *section,
76               const char *option,
77               const char *value)
78 {
79   fprintf (stdout,
80            "%s = %s\n", option, value);
81 }
82
83
84 /**
85  * Print out given section name.
86  *
87  * @param cls unused
88  * @param section a section in the configuration file
89  */
90 static void
91 print_section_name (void *cls,
92                     const char *section)
93 {
94   fprintf (stdout, "%s\n", section);
95 }
96
97
98 /**
99  * Main function that will be run by the scheduler.
100  *
101  * @param cls closure
102  * @param args remaining command-line arguments
103  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
104  * @param cfg configuration
105  */
106 static void
107 run (void *cls,
108      char *const *args,
109      const char *cfgfile,
110      const struct GNUNET_CONFIGURATION_Handle *cfg)
111 {
112   struct GNUNET_CONFIGURATION_Handle *out = NULL;
113   struct GNUNET_CONFIGURATION_Handle *diff = NULL;
114
115   if (rewrite)
116   {
117     struct GNUNET_CONFIGURATION_Handle *def;
118
119     def = GNUNET_CONFIGURATION_create ();
120     if (GNUNET_OK !=
121         GNUNET_CONFIGURATION_load (def, NULL))
122     {
123       fprintf (stderr,
124                _("failed to load configuration defaults"));
125       ret = 1;
126       return;
127     }
128     diff = GNUNET_CONFIGURATION_get_diff (def,
129                                           cfg);
130     cfg = diff;
131   }
132   if ( ((! rewrite) && (NULL == section)) || list_sections)
133   {
134     if (! list_sections)
135     {
136       fprintf (stderr,
137                _("--section argument is required\n"));
138     }
139     fprintf (stderr,
140              _("The following sections are available:\n"));
141     GNUNET_CONFIGURATION_iterate_sections (cfg,
142                                            &print_section_name,
143                                            NULL);
144     ret = 1;
145     goto cleanup;
146   }
147
148   if ( (NULL != section) && (NULL == value) )
149   {
150     if (NULL == option)
151     {
152       GNUNET_CONFIGURATION_iterate_section_values (cfg,
153                                                    section,
154                                                    &print_option,
155                                                    NULL);
156     }
157     else
158     {
159       if (is_filename)
160       {
161         if (GNUNET_OK !=
162             GNUNET_CONFIGURATION_get_value_filename (cfg,
163                                                      section,
164                                                      option,
165                                                      &value))
166         {
167           GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
168                                      section, option);
169           ret = 3;
170           goto cleanup;
171         }
172       }
173       else
174       {
175         if (GNUNET_OK !=
176             GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &value))
177         {
178           GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
179                                      section, option);
180           ret = 3;
181           goto cleanup;
182         }
183       }
184       fprintf (stdout, "%s\n", value);
185     }
186   }
187   else if (NULL != section)
188   {
189     if (NULL == option)
190     {
191       fprintf (stderr, _("--option argument required to set value\n"));
192       ret = 1;
193       goto cleanup;
194     }
195     out = GNUNET_CONFIGURATION_dup (cfg);
196     GNUNET_CONFIGURATION_set_value_string (out,
197                                            section,
198                                            option,
199                                            value);
200   }
201   if ( (NULL != diff) || (NULL != out) )
202   {
203     if (GNUNET_OK !=
204         GNUNET_CONFIGURATION_write ((NULL == out) ? diff : out,
205                                     cfgfile))
206       ret = 2;
207   }
208   if (NULL != out)
209     GNUNET_CONFIGURATION_destroy (out);
210  cleanup:
211   if (NULL != diff)
212     GNUNET_CONFIGURATION_destroy (diff);
213 }
214
215
216 /**
217  * Program to manipulate configuration files.
218  *
219  * @param argc number of arguments from the command line
220  * @param argv command line arguments
221  * @return 0 ok, 1 on error
222  */
223 int
224 main (int argc, char *const *argv)
225 {
226   struct GNUNET_GETOPT_CommandLineOption options[] = {
227     GNUNET_GETOPT_OPTION_SET_ONE ('f',
228                                   "filename",
229                                   gettext_noop ("obtain option of value as a filename (with $-expansion)"),
230                                   &is_filename),
231     GNUNET_GETOPT_OPTION_STRING ('s',
232                                      "section",
233                                      "SECTION",
234                                      gettext_noop ("name of the section to access"),
235                                      &section),
236     GNUNET_GETOPT_OPTION_STRING ('o',
237                                      "option",
238                                      "OPTION",
239                                      gettext_noop ("name of the option to access"),
240                                      &option),
241     GNUNET_GETOPT_OPTION_STRING ('V',
242                                      "value",
243                                      "VALUE",
244                                      gettext_noop ("value to set"),
245                                      &value),
246     GNUNET_GETOPT_OPTION_SET_ONE ('S',
247                                   "list-sections",
248                                   gettext_noop ("print available configuration sections"),
249                                   &list_sections),
250     GNUNET_GETOPT_OPTION_SET_ONE ('w',
251                                   "rewrite",
252                                   gettext_noop ("write configuration file that only contains delta to defaults"),
253                                   &rewrite),
254     GNUNET_GETOPT_OPTION_END
255   };
256   if (GNUNET_OK !=
257       GNUNET_STRINGS_get_utf8_args (argc, argv,
258                                     &argc, &argv))
259     return 2;
260
261   ret = (GNUNET_OK ==
262          GNUNET_PROGRAM_run (argc,
263                              argv,
264                              "gnunet-config [OPTIONS]",
265                              gettext_noop ("Manipulate GNUnet configuration files"),
266                              options,
267                              &run, NULL)) ? 0 : ret;
268   GNUNET_free ((void*) argv);
269   return ret;
270 }
271
272 /* end of gnunet-config.c */