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