Line data Source code
1 : /* t-gpgconf.c - Regression test.
2 : Copyright (C) 2001, 2004, 2007 g10 Code GmbH
3 :
4 : This file is part of GPGME.
5 :
6 : GPGME is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU Lesser General Public License as
8 : published by the Free Software Foundation; either version 2.1 of
9 : the License, or (at your option) any later version.
10 :
11 : GPGME is distributed in the hope that it will be useful, but
12 : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should have received a copy of the GNU Lesser General Public
17 : License along with this program; if not, write to the Free Software
18 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 : 02111-1307, USA. */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include <config.h>
23 : #endif
24 :
25 : #include <unistd.h>
26 : #include <errno.h>
27 : #include <stdlib.h>
28 : #include <locale.h>
29 : #include <string.h>
30 :
31 : #ifdef HAVE_W32_SYSTEM
32 : #include <windows.h>
33 : #endif
34 :
35 : #include <gpgme.h>
36 :
37 : #include "t-support.h"
38 :
39 : static char *
40 146 : spaces (char *str, int extra)
41 : {
42 : static char buf[80];
43 146 : int len = str ? strlen (str) : 0;
44 : int n;
45 :
46 : #define TABSTOP 30
47 146 : n = TABSTOP - len - extra;
48 :
49 146 : memset (buf, ' ', sizeof (buf));
50 146 : if (n < 1 || n > (sizeof (buf) - 1))
51 : {
52 7 : buf[0] = '\n';
53 7 : n = TABSTOP + 1;
54 : }
55 :
56 146 : buf[n] = '\0';
57 146 : return buf;
58 : }
59 :
60 :
61 : void
62 27 : dump_arg (int type, gpgme_conf_arg_t arg)
63 : {
64 27 : if (!arg)
65 : {
66 4 : printf ("(none)");
67 4 : return;
68 : }
69 :
70 70 : while (arg)
71 : {
72 24 : switch (type)
73 : {
74 : case GPGME_CONF_STRING:
75 : case GPGME_CONF_PATHNAME:
76 : case GPGME_CONF_LDAP_SERVER:
77 : case GPGME_CONF_KEY_FPR:
78 : case GPGME_CONF_PUB_KEY:
79 : case GPGME_CONF_SEC_KEY:
80 : case GPGME_CONF_ALIAS_LIST:
81 11 : printf ("`%s'", arg->value.string);
82 11 : break;
83 :
84 : case GPGME_CONF_UINT32:
85 11 : printf ("%u", arg->value.uint32);
86 11 : break;
87 :
88 : case GPGME_CONF_INT32:
89 2 : printf ("%i", arg->value.int32);
90 2 : break;
91 :
92 : case GPGME_CONF_NONE:
93 0 : printf ("%i (times)", arg->value.count);
94 0 : break;
95 :
96 : default:
97 0 : printf ("(unknown type)");
98 : }
99 :
100 24 : arg = arg->next;
101 24 : if (arg)
102 1 : printf (" ");
103 : }
104 : }
105 :
106 :
107 : void
108 119 : dump_opt (gpgme_conf_opt_t opt)
109 : {
110 : char level;
111 119 : char runtime = (opt->flags & GPGME_CONF_RUNTIME) ? 'r' : ' ';
112 :
113 119 : switch (opt->level)
114 : {
115 : case GPGME_CONF_BASIC:
116 54 : level = 'b';
117 54 : break;
118 : case GPGME_CONF_ADVANCED:
119 41 : level = 'a';
120 41 : break;
121 : case GPGME_CONF_EXPERT:
122 15 : level = 'e';
123 15 : break;
124 : case GPGME_CONF_INVISIBLE:
125 9 : level = 'i';
126 9 : break;
127 : case GPGME_CONF_INTERNAL:
128 0 : level = '#';
129 0 : break;
130 : default:
131 0 : level = '?';
132 : }
133 :
134 119 : if (opt->flags & GPGME_CONF_GROUP)
135 : {
136 27 : printf ("\n");
137 27 : printf ("%c%c [%s]%s%s\n", level, runtime, opt->name, spaces (opt->name, 5),
138 27 : opt->description
139 : ? opt->description : "");
140 : }
141 : else
142 : {
143 92 : if (opt->argname)
144 : {
145 41 : const char *more = (opt->flags & GPGME_CONF_LIST) ? "..." : "";
146 :
147 41 : if (opt->flags & GPGME_CONF_OPTIONAL)
148 : {
149 5 : printf ("%c%c --%s [%s%s] %s", level, runtime, opt->name, opt->argname, more,
150 5 : spaces (opt->name, 9 + strlen (opt->argname) + strlen (more)));
151 : }
152 : else
153 : {
154 36 : printf ("%c%c --%s %s%s %s", level, runtime, opt->name, opt->argname, more,
155 36 : spaces (opt->name, 7 + strlen (opt->argname) + strlen (more)));
156 : }
157 : }
158 : else
159 51 : printf ("%c%c --%s%s", level, runtime, opt->name, spaces (opt->name, 5));
160 :
161 92 : if (opt->description)
162 83 : printf ("%s", opt->description);
163 92 : printf ("\n");
164 :
165 92 : if (opt->flags & GPGME_CONF_DEFAULT)
166 : {
167 27 : printf ("%s%s = ", spaces (NULL, 0), opt->argname ? opt->argname : "(default)");
168 27 : dump_arg (opt->type, opt->default_value);
169 27 : printf ("\n");
170 : }
171 65 : else if (opt->flags & GPGME_CONF_DEFAULT_DESC)
172 0 : printf ("%s%s = %s\n", spaces (NULL, 0), opt->argname ? opt->argname : "(default)",
173 : opt->default_description);
174 :
175 92 : if (opt->no_arg_value)
176 : {
177 0 : printf ("%sNo Arg Def = ", spaces (NULL, 0));
178 0 : dump_arg (opt->type, opt->no_arg_value);
179 0 : printf ("\n");
180 : }
181 92 : if (opt->value)
182 : {
183 0 : printf ("%sCurrent = ", spaces (NULL, 0));
184 0 : dump_arg (opt->type, opt->value);
185 0 : printf ("\n");
186 : }
187 : }
188 :
189 : #if 0
190 : arg = comp->options;
191 : while (opt)
192 : {
193 : dump_opt (opt);
194 : opt = opt->next;
195 : }
196 : #endif
197 119 : }
198 :
199 :
200 : void
201 6 : dump_comp (gpgme_conf_comp_t comp)
202 : {
203 : gpgme_conf_opt_t opt;
204 :
205 6 : printf ("COMPONENT\n");
206 6 : printf ("=========\n");
207 6 : printf (" Name: %s\n", comp->name);
208 6 : if (comp->description)
209 6 : printf (" Desc: %s\n", comp->description);
210 6 : if (comp->program_name)
211 6 : printf (" Path: %s\n", comp->program_name);
212 6 : printf ("\n");
213 :
214 6 : opt = comp->options;
215 131 : while (opt)
216 : {
217 119 : dump_opt (opt);
218 119 : opt = opt->next;
219 : }
220 6 : }
221 :
222 :
223 : int
224 40 : lookup (gpgme_conf_comp_t conf,
225 : const char *component,
226 : const char *option,
227 : gpgme_conf_comp_t *comp,
228 : gpgme_conf_opt_t *opt)
229 : {
230 40 : *comp = conf;
231 160 : while (*comp && strcmp ((*comp)->name, component))
232 80 : *comp = (*comp)->next;
233 :
234 40 : if (*comp)
235 : {
236 40 : *opt = (*comp)->options;
237 380 : while (*opt && strcmp ((*opt)->name, option))
238 300 : *opt = (*opt)->next;
239 :
240 : /* Allow for the option not to be there. */
241 40 : if (*opt)
242 40 : return 1; /* Found. */
243 : }
244 :
245 0 : return 0; /* Not found. */
246 : }
247 :
248 : #include <assert.h>
249 :
250 :
251 : int
252 1 : main (void)
253 : {
254 : gpgme_ctx_t ctx;
255 : gpgme_error_t err;
256 : gpgme_conf_comp_t conf;
257 : gpgme_conf_comp_t comp;
258 : int first;
259 1 : int i, N = 10;
260 :
261 1 : init_gpgme (GPGME_PROTOCOL_GPGCONF);
262 :
263 1 : err = gpgme_new (&ctx);
264 1 : fail_if_err (err);
265 :
266 1 : err = gpgme_op_conf_load (ctx, &conf);
267 1 : fail_if_err (err);
268 :
269 1 : comp = conf;
270 1 : first = 1;
271 8 : while (comp)
272 : {
273 6 : if (!first)
274 5 : printf ("\n");
275 : else
276 1 : first = 0;
277 6 : dump_comp (comp);
278 6 : comp = comp->next;
279 : }
280 :
281 : /* Now change something. */
282 1 : fprintf (stderr, " dirmngr.verbose ");
283 11 : for (i = 0; i < N; i++) {
284 10 : unsigned int count = i % 4 + 1; /* counts must not be zero */
285 : gpgme_conf_arg_t arg;
286 : gpgme_conf_opt_t opt;
287 :
288 10 : err = gpgme_conf_arg_new (&arg, GPGME_CONF_NONE, &count);
289 10 : fail_if_err (err);
290 :
291 10 : if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
292 : {
293 : /* Found. */
294 10 : err = gpgme_conf_opt_change (opt, 0, arg);
295 10 : fail_if_err (err);
296 :
297 10 : err = gpgme_op_conf_save (ctx, comp);
298 10 : fail_if_err (err);
299 : }
300 : else
301 : {
302 0 : fprintf (stderr, "Skipping test, option dirmngr.verbose not found.\n");
303 0 : break;
304 : }
305 :
306 : /* Reload config and verify that the value was updated. */
307 10 : gpgme_conf_release (conf);
308 10 : err = gpgme_op_conf_load (ctx, &conf);
309 10 : fail_if_err (err);
310 10 : if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
311 : {
312 : /* Found. */
313 10 : test (opt->alt_type == GPGME_CONF_NONE);
314 10 : test (opt->value);
315 10 : test ((unsigned long) opt->value->value.count == count);
316 : }
317 :
318 10 : fprintf (stderr, ".");
319 10 : fflush (stderr);
320 : }
321 :
322 : /* Now change something else. */
323 1 : fprintf (stderr, " gpg.keyserver ");
324 11 : for (i = 0; i < N; i++) {
325 10 : const char *values[2] = { "hkp://foo.bar", "hkps://bar.foo" };
326 : gpgme_conf_arg_t arg;
327 : gpgme_conf_opt_t opt;
328 :
329 10 : err = gpgme_conf_arg_new (&arg, GPGME_CONF_STRING, values[i%2]);
330 10 : fail_if_err (err);
331 :
332 10 : if (lookup (conf, "gpg", "keyserver", &comp, &opt))
333 : {
334 : /* Found. */
335 10 : test (opt->alt_type == GPGME_CONF_STRING);
336 10 : err = gpgme_conf_opt_change (opt, 0, arg);
337 10 : fail_if_err (err);
338 :
339 10 : err = gpgme_op_conf_save (ctx, comp);
340 10 : fail_if_err (err);
341 : }
342 : else
343 : {
344 0 : fprintf (stderr, "Skipping test, option gpg.keyserver not found.\n");
345 0 : break;
346 : }
347 :
348 : /* Reload config and verify that the value was updated. */
349 10 : gpgme_conf_release (conf);
350 10 : err = gpgme_op_conf_load (ctx, &conf);
351 10 : fail_if_err (err);
352 10 : if (lookup (conf, "gpg", "keyserver", &comp, &opt))
353 : {
354 : /* Found. */
355 10 : test (opt->alt_type == GPGME_CONF_STRING);
356 10 : test (opt->value);
357 10 : test (opt->value->value.string);
358 10 : test (strcmp (opt->value->value.string, values[i%2]) == 0);
359 : }
360 :
361 10 : fprintf (stderr, ".");
362 10 : fflush (stderr);
363 : }
364 1 : fprintf (stderr, "\n");
365 :
366 1 : gpgme_conf_release (conf);
367 1 : gpgme_release (ctx);
368 1 : return 0;
369 : }
|