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 159 : spaces (char *str, int extra)
41 : {
42 : static char buf[80];
43 159 : int len = str ? strlen (str) : 0;
44 : int n;
45 :
46 : #define TABSTOP 30
47 159 : n = TABSTOP - len - extra;
48 :
49 159 : memset (buf, ' ', sizeof (buf));
50 159 : if (n < 1 || n > (sizeof (buf) - 1))
51 : {
52 9 : buf[0] = '\n';
53 9 : n = TABSTOP + 1;
54 : }
55 :
56 159 : buf[n] = '\0';
57 159 : return buf;
58 : }
59 :
60 :
61 : void
62 31 : dump_arg (int type, gpgme_conf_arg_t arg)
63 : {
64 31 : if (!arg)
65 : {
66 4 : printf ("(none)");
67 4 : return;
68 : }
69 :
70 81 : while (arg)
71 : {
72 27 : 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 13 : printf ("`%s'", arg->value.string);
82 13 : 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 1 : printf ("%i (times)", arg->value.count);
94 1 : break;
95 :
96 : default:
97 0 : printf ("(unknown type)");
98 : }
99 :
100 27 : arg = arg->next;
101 27 : if (arg)
102 0 : printf (" ");
103 : }
104 : }
105 :
106 :
107 : void
108 128 : dump_opt (gpgme_conf_opt_t opt)
109 : {
110 : char level;
111 128 : char runtime = (opt->flags & GPGME_CONF_RUNTIME) ? 'r' : ' ';
112 :
113 128 : 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 20 : level = 'e';
123 20 : break;
124 : case GPGME_CONF_INVISIBLE:
125 13 : level = 'i';
126 13 : break;
127 : case GPGME_CONF_INTERNAL:
128 0 : level = '#';
129 0 : break;
130 : default:
131 0 : level = '?';
132 : }
133 :
134 128 : 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 101 : if (opt->argname)
144 : {
145 42 : const char *more = (opt->flags & GPGME_CONF_LIST) ? "..." : "";
146 :
147 42 : 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 37 : printf ("%c%c --%s %s%s %s", level, runtime, opt->name, opt->argname, more,
155 37 : spaces (opt->name, 7 + strlen (opt->argname) + strlen (more)));
156 : }
157 : }
158 : else
159 59 : printf ("%c%c --%s%s", level, runtime, opt->name, spaces (opt->name, 5));
160 :
161 101 : if (opt->description)
162 84 : printf ("%s", opt->description);
163 101 : printf ("\n");
164 :
165 101 : if (opt->flags & GPGME_CONF_DEFAULT)
166 : {
167 30 : printf ("%s%s = ", spaces (NULL, 0), opt->argname ? opt->argname : "(default)");
168 30 : dump_arg (opt->type, opt->default_value);
169 30 : printf ("\n");
170 : }
171 71 : 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 101 : 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 101 : if (opt->value)
182 : {
183 1 : printf ("%sCurrent = ", spaces (NULL, 0));
184 1 : dump_arg (opt->type, opt->value);
185 1 : 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 128 : }
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 140 : while (opt)
216 : {
217 128 : dump_opt (opt);
218 128 : 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 400 : while (*opt && strcmp ((*opt)->name, option))
238 320 : *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 : {
267 : /* Let's check getting the agent-socket directory for different homedirs. */
268 1 : char *result1 = NULL;
269 1 : char *result2 = NULL;
270 1 : err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, "/tmp/foo");
271 1 : fail_if_err (err);
272 1 : err = gpgme_op_conf_dir (ctx, "agent-socket", &result1);
273 1 : fail_if_err (err);
274 :
275 1 : err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, NULL);
276 1 : fail_if_err (err);
277 1 : err = gpgme_op_conf_dir (ctx, "agent-socket", &result2);
278 1 : fail_if_err (err);
279 :
280 : /* They have to be different. */
281 1 : test (strcmp(result1, result2));
282 1 : gpgme_free (result1);
283 1 : gpgme_free (result2);
284 : }
285 :
286 1 : err = gpgme_op_conf_load (ctx, &conf);
287 1 : fail_if_err (err);
288 :
289 1 : comp = conf;
290 1 : first = 1;
291 8 : while (comp)
292 : {
293 6 : if (!first)
294 5 : printf ("\n");
295 : else
296 1 : first = 0;
297 6 : dump_comp (comp);
298 6 : comp = comp->next;
299 : }
300 :
301 : /* Now change something. */
302 1 : fprintf (stderr, " dirmngr.verbose ");
303 11 : for (i = 0; i < N; i++) {
304 10 : unsigned int count = i % 4 + 1; /* counts must not be zero */
305 : gpgme_conf_arg_t arg;
306 : gpgme_conf_opt_t opt;
307 :
308 10 : err = gpgme_conf_arg_new (&arg, GPGME_CONF_NONE, &count);
309 10 : fail_if_err (err);
310 :
311 10 : if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
312 : {
313 : /* Found. */
314 10 : err = gpgme_conf_opt_change (opt, 0, arg);
315 10 : fail_if_err (err);
316 :
317 10 : err = gpgme_op_conf_save (ctx, comp);
318 10 : fail_if_err (err);
319 : }
320 : else
321 : {
322 0 : fprintf (stderr, "Skipping test, option dirmngr.verbose not found.\n");
323 0 : break;
324 : }
325 :
326 : /* Reload config and verify that the value was updated. */
327 10 : gpgme_conf_release (conf);
328 10 : err = gpgme_op_conf_load (ctx, &conf);
329 10 : fail_if_err (err);
330 10 : if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
331 : {
332 : /* Found. */
333 10 : test (opt->alt_type == GPGME_CONF_NONE);
334 10 : test (opt->value);
335 10 : test ((unsigned long) opt->value->value.count == count);
336 : }
337 :
338 10 : fprintf (stderr, ".");
339 10 : fflush (stderr);
340 : }
341 :
342 : /* Now change something else. */
343 1 : fprintf (stderr, " gpg.keyserver ");
344 11 : for (i = 0; i < N; i++) {
345 10 : const char *values[2] = { "hkp://foo.bar", "hkps://bar.foo" };
346 : gpgme_conf_arg_t arg;
347 : gpgme_conf_opt_t opt;
348 :
349 10 : err = gpgme_conf_arg_new (&arg, GPGME_CONF_STRING, values[i%2]);
350 10 : fail_if_err (err);
351 :
352 10 : if (lookup (conf, "gpg", "keyserver", &comp, &opt))
353 : {
354 : /* Found. */
355 10 : test (opt->alt_type == GPGME_CONF_STRING);
356 10 : err = gpgme_conf_opt_change (opt, 0, arg);
357 10 : fail_if_err (err);
358 :
359 10 : err = gpgme_op_conf_save (ctx, comp);
360 10 : fail_if_err (err);
361 : }
362 : else
363 : {
364 0 : fprintf (stderr, "Skipping test, option gpg.keyserver not found.\n");
365 0 : break;
366 : }
367 :
368 : /* Reload config and verify that the value was updated. */
369 10 : gpgme_conf_release (conf);
370 10 : err = gpgme_op_conf_load (ctx, &conf);
371 10 : fail_if_err (err);
372 10 : if (lookup (conf, "gpg", "keyserver", &comp, &opt))
373 : {
374 : /* Found. */
375 10 : test (opt->alt_type == GPGME_CONF_STRING);
376 10 : test (opt->value);
377 10 : test (opt->value->value.string);
378 10 : test (strcmp (opt->value->value.string, values[i%2]) == 0);
379 : }
380 :
381 10 : fprintf (stderr, ".");
382 10 : fflush (stderr);
383 : }
384 1 : fprintf (stderr, "\n");
385 :
386 1 : gpgme_conf_release (conf);
387 1 : gpgme_release (ctx);
388 1 : return 0;
389 : }
|