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