Initialize opt.session_env.
[gnupg.git] / tools / gpgconf-comp.c
blob7ba526f695569e05338bb96ab83efbf263f966b3
1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2 * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG 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 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GnuPG; if not, see <http://www.gnu.org/licenses/>.
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <assert.h>
30 #include <errno.h>
31 #include <time.h>
32 #include <stdarg.h>
33 #include <signal.h>
34 #include <ctype.h>
35 #ifdef HAVE_W32_SYSTEM
36 # define WIN32_LEAN_AND_MEAN 1
37 # include <windows.h>
38 #else
39 # include <pwd.h>
40 # include <grp.h>
41 #endif
43 /* For log_logv(), asctimestamp(), gnupg_get_time (). */
44 #define JNLIB_NEED_LOG_LOGV
45 #include "util.h"
46 #include "i18n.h"
47 #include "exechelp.h"
49 #include "gc-opt-flags.h"
50 #include "gpgconf.h"
53 /* There is a problem with gpg 1.4 under Windows: --gpgconf-list
54 returns a plain filename without escaping. As long as we have not
55 fixed that we need to use gpg2 - it might actually be better to use
56 gpg2 in any case. */
57 #ifdef HAVE_W32_SYSTEM
58 #define GPGNAME "gpg2"
59 #else
60 #define GPGNAME "gpg"
61 #endif
64 /* TODO:
65 Components: Add more components and their options.
66 Robustness: Do more validation. Call programs to do validation for us.
67 Add options to change backend binary path.
68 Extract binary path for some backends from gpgsm/gpg config.
72 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
73 void gc_error (int status, int errnum, const char *fmt, ...) \
74 __attribute__ ((format (printf, 3, 4)));
75 #endif
77 /* Output a diagnostic message. If ERRNUM is not 0, then the output
78 is followed by a colon, a white space, and the error string for the
79 error number ERRNUM. In any case the output is finished by a
80 newline. The message is prepended by the program name, a colon,
81 and a whitespace. The output may be further formatted or
82 redirected by the jnlib logging facility. */
83 void
84 gc_error (int status, int errnum, const char *fmt, ...)
86 va_list arg_ptr;
88 va_start (arg_ptr, fmt);
89 log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
90 va_end (arg_ptr);
92 if (errnum)
93 log_printf (": %s\n", strerror (errnum));
94 else
95 log_printf ("\n");
97 if (status)
99 log_printf (NULL);
100 log_printf ("fatal error (exit status %i)\n", status);
101 exit (status);
106 /* Forward declaration. */
107 static void gpg_agent_runtime_change (void);
108 static void scdaemon_runtime_change (void);
110 /* Backend configuration. Backends are used to decide how the default
111 and current value of an option can be determined, and how the
112 option can be changed. To every option in every component belongs
113 exactly one backend that controls and determines the option. Some
114 backends are programs from the GPG system. Others might be
115 implemented by GPGConf itself. If you change this enum, don't
116 forget to update GC_BACKEND below. */
117 typedef enum
119 /* Any backend, used for find_option (). */
120 GC_BACKEND_ANY,
122 /* The Gnu Privacy Guard. */
123 GC_BACKEND_GPG,
125 /* The Gnu Privacy Guard for S/MIME. */
126 GC_BACKEND_GPGSM,
128 /* The GPG Agent. */
129 GC_BACKEND_GPG_AGENT,
131 /* The GnuPG SCDaemon. */
132 GC_BACKEND_SCDAEMON,
134 /* The Aegypten directory manager. */
135 GC_BACKEND_DIRMNGR,
137 /* The LDAP server list file for the Aegypten director manager. */
138 GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
140 /* The number of the above entries. */
141 GC_BACKEND_NR
142 } gc_backend_t;
145 /* To be able to implement generic algorithms for the various
146 backends, we collect all information about them in this struct. */
147 static struct
149 /* The name of the backend. */
150 const char *name;
152 /* The name of the program that acts as the backend. Some backends
153 don't have an associated program, but are implemented directly by
154 GPGConf. In this case, PROGRAM is NULL. */
155 char *program;
157 /* The module name (GNUPG_MODULE_NAME_foo) as defined by
158 ../common/util.h. This value is used to get the actual installed
159 path of the program. 0 is used if no backedn program is
160 available. */
161 char module_name;
163 /* The runtime change callback. */
164 void (*runtime_change) (void);
166 /* The option name for the configuration filename of this backend.
167 This must be an absolute filename. It can be an option from a
168 different backend (but then ordering of the options might
169 matter). Note: This must be unique among all components. */
170 const char *option_config_filename;
172 /* If this is a file backend rather than a program backend, then
173 this is the name of the option associated with the file. */
174 const char *option_name;
175 } gc_backend[GC_BACKEND_NR] =
177 { NULL }, /* GC_BACKEND_ANY dummy entry. */
178 { "GnuPG", GPGNAME, GNUPG_MODULE_NAME_GPG,
179 NULL, "gpgconf-gpg.conf" },
180 { "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
181 NULL, "gpgconf-gpgsm.conf" },
182 { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT,
183 gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
184 { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
185 scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
186 { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
187 NULL, "gpgconf-dirmngr.conf" },
188 { "DirMngr LDAP Server List", NULL, 0,
189 NULL, "ldapserverlist-file", "LDAP Server" },
193 /* Option configuration. */
195 /* An option might take an argument, or not. Argument types can be
196 basic or complex. Basic types are generic and easy to validate.
197 Complex types provide more specific information about the intended
198 use, but can be difficult to validate. If you add to this enum,
199 don't forget to update GC_ARG_TYPE below. YOU MUST NOT CHANGE THE
200 NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
201 INTERFACE. */
202 typedef enum
204 /* Basic argument types. */
206 /* No argument. */
207 GC_ARG_TYPE_NONE = 0,
209 /* A String argument. */
210 GC_ARG_TYPE_STRING = 1,
212 /* A signed integer argument. */
213 GC_ARG_TYPE_INT32 = 2,
215 /* An unsigned integer argument. */
216 GC_ARG_TYPE_UINT32 = 3,
218 /* ADD NEW BASIC TYPE ENTRIES HERE. */
220 /* Complex argument types. */
222 /* A complete filename. */
223 GC_ARG_TYPE_FILENAME = 32,
225 /* An LDAP server in the format
226 HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */
227 GC_ARG_TYPE_LDAP_SERVER = 33,
229 /* A 40 character fingerprint. */
230 GC_ARG_TYPE_KEY_FPR = 34,
232 /* A user ID or key ID or fingerprint for a certificate. */
233 GC_ARG_TYPE_PUB_KEY = 35,
235 /* A user ID or key ID or fingerprint for a certificate with a key. */
236 GC_ARG_TYPE_SEC_KEY = 36,
238 /* A alias list made up of a key, an equal sign and a space
239 separated list of values. */
240 GC_ARG_TYPE_ALIAS_LIST = 37,
242 /* ADD NEW COMPLEX TYPE ENTRIES HERE. */
244 /* The number of the above entries. */
245 GC_ARG_TYPE_NR
246 } gc_arg_type_t;
249 /* For every argument, we record some information about it in the
250 following struct. */
251 static struct
253 /* For every argument type exists a basic argument type that can be
254 used as a fallback for input and validation purposes. */
255 gc_arg_type_t fallback;
257 /* Human-readable name of the type. */
258 const char *name;
259 } gc_arg_type[GC_ARG_TYPE_NR] =
261 /* The basic argument types have their own types as fallback. */
262 { GC_ARG_TYPE_NONE, "none" },
263 { GC_ARG_TYPE_STRING, "string" },
264 { GC_ARG_TYPE_INT32, "int32" },
265 { GC_ARG_TYPE_UINT32, "uint32" },
267 /* Reserved basic type entries for future extension. */
268 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
269 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
270 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
271 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
272 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
273 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
274 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
275 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
276 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
277 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
278 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
279 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
280 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
281 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
283 /* The complex argument types have a basic type as fallback. */
284 { GC_ARG_TYPE_STRING, "filename" },
285 { GC_ARG_TYPE_STRING, "ldap server" },
286 { GC_ARG_TYPE_STRING, "key fpr" },
287 { GC_ARG_TYPE_STRING, "pub key" },
288 { GC_ARG_TYPE_STRING, "sec key" },
289 { GC_ARG_TYPE_STRING, "alias list" },
293 /* Every option has an associated expert level, than can be used to
294 hide advanced and expert options from beginners. If you add to
295 this list, don't forget to update GC_LEVEL below. YOU MUST NOT
296 CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
297 EXTERNAL INTERFACE. */
298 typedef enum
300 /* The basic options should always be displayed. */
301 GC_LEVEL_BASIC,
303 /* The advanced options may be hidden from beginners. */
304 GC_LEVEL_ADVANCED,
306 /* The expert options should only be displayed to experts. */
307 GC_LEVEL_EXPERT,
309 /* The invisible options should normally never be displayed. */
310 GC_LEVEL_INVISIBLE,
312 /* The internal options are never exported, they mark options that
313 are recorded for internal use only. */
314 GC_LEVEL_INTERNAL,
316 /* ADD NEW ENTRIES HERE. */
318 /* The number of the above entries. */
319 GC_LEVEL_NR
320 } gc_expert_level_t;
322 /* A description for each expert level. */
323 static struct
325 const char *name;
326 } gc_level[] =
328 { "basic" },
329 { "advanced" },
330 { "expert" },
331 { "invisible" },
332 { "internal" }
336 /* Option flags. The flags which are used by the backends are defined
337 by gc-opt-flags.h, included above.
339 YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING FLAGS, AS THEY ARE
340 PART OF THE EXTERNAL INTERFACE. */
342 /* Some entries in the option list are not options, but mark the
343 beginning of a new group of options. These entries have the GROUP
344 flag set. */
345 #define GC_OPT_FLAG_GROUP (1UL << 0)
346 /* The ARG_OPT flag for an option indicates that the argument is
347 optional. This is never set for GC_ARG_TYPE_NONE options. */
348 #define GC_OPT_FLAG_ARG_OPT (1UL << 1)
349 /* The LIST flag for an option indicates that the option can occur
350 several times. A comma separated list of arguments is used as the
351 argument value. */
352 #define GC_OPT_FLAG_LIST (1UL << 2)
353 /* The NO_CHANGE flag for an option indicates that the user should not
354 be allowed to change this option using the standard gpgconf method.
355 Frontends using gpgconf should grey out such options, so that only
356 the current value is displayed. */
357 #define GC_OPT_FLAG_NO_CHANGE (1UL <<7)
360 /* A human-readable description for each flag. */
361 static struct
363 const char *name;
364 } gc_flag[] =
366 { "group" },
367 { "optional arg" },
368 { "list" },
369 { "runtime" },
370 { "default" },
371 { "default desc" },
372 { "no arg desc" },
373 { "no change" }
377 /* To each option, or group marker, the information in the GC_OPTION
378 struct is provided. If you change this, don't forget to update the
379 option list of each component. */
380 struct gc_option
382 /* If this is NULL, then this is a terminator in an array of unknown
383 length. Otherwise, if this entry is a group marker (see FLAGS),
384 then this is the name of the group described by this entry.
385 Otherwise it is the name of the option described by this
386 entry. The name must not contain a colon. */
387 const char *name;
389 /* The option flags. If the GROUP flag is set, then this entry is a
390 group marker, not an option, and only the fields LEVEL,
391 DESC_DOMAIN and DESC are valid. In all other cases, this entry
392 describes a new option and all fields are valid. */
393 unsigned long flags;
395 /* The expert level. This field is valid for options and groups. A
396 group has the expert level of the lowest-level option in the
397 group. */
398 gc_expert_level_t level;
400 /* A gettext domain in which the following description can be found.
401 If this is NULL, then DESC is not translated. Valid for groups
402 and options.
404 Note that we try to keep the description of groups within the
405 gnupg domain.
407 IMPORTANT: If you add a new domain please make sure to add a code
408 set switching call to the function my_dgettext further below. */
409 const char *desc_domain;
411 /* A gettext description for this group or option. If it starts
412 with a '|', then the string up to the next '|' describes the
413 argument, and the description follows the second '|'.
415 In general enclosing these description in N_() is not required
416 because the description should be identical to the one in the
417 help menu of the respective program. */
418 const char *desc;
420 /* The following fields are only valid for options. */
422 /* The type of the option argument. */
423 gc_arg_type_t arg_type;
425 /* The backend that implements this option. */
426 gc_backend_t backend;
428 /* The following fields are set to NULL at startup (because all
429 option's are declared as static variables). They are at the end
430 of the list so that they can be omitted from the option
431 declarations. */
433 /* This is true if the option is supported by this version of the
434 backend. */
435 int active;
437 /* The default value for this option. This is NULL if the option is
438 not present in the backend, the empty string if no default is
439 available, and otherwise a quoted string. */
440 char *default_value;
442 /* The default argument is only valid if the "optional arg" flag is
443 set, and specifies the default argument (value) that is used if
444 the argument is omitted. */
445 char *default_arg;
447 /* The current value of this option. */
448 char *value;
450 /* The new flags for this option. The only defined flag is actually
451 GC_OPT_FLAG_DEFAULT, and it means that the option should be
452 deleted. In this case, NEW_VALUE is NULL. */
453 unsigned long new_flags;
455 /* The new value of this option. */
456 char *new_value;
458 typedef struct gc_option gc_option_t;
460 /* Use this macro to terminate an option list. */
461 #define GC_OPTION_NULL { NULL }
464 /* The options of the GC_COMPONENT_GPG_AGENT component. */
465 static gc_option_t gc_options_gpg_agent[] =
467 /* The configuration file to which we write the changes. */
468 { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
469 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
471 { "Monitor",
472 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
473 "gnupg", N_("Options controlling the diagnostic output") },
474 { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
475 "gnupg", "verbose",
476 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
477 { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
478 "gnupg", "be somewhat more quiet",
479 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
480 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
481 NULL, NULL,
482 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
484 { "Configuration",
485 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
486 "gnupg", N_("Options controlling the configuration") },
487 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
488 "gnupg", "|FILE|read options from FILE",
489 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
490 { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
491 "gnupg", "do not use the SCdaemon",
492 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
494 { "Debug",
495 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
496 "gnupg", N_("Options useful for debugging") },
497 { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
498 "gnupg", "|LEVEL|set the debugging level to LEVEL",
499 GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
500 { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
501 "gnupg", N_("|FILE|write server mode logs to FILE"),
502 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
503 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
504 NULL, NULL,
505 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
507 { "Security",
508 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
509 "gnupg", N_("Options controlling the security") },
510 { "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
511 GC_LEVEL_BASIC, "gnupg",
512 "|N|expire cached PINs after N seconds",
513 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
514 { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
515 GC_LEVEL_ADVANCED, "gnupg",
516 N_("|N|expire SSH keys after N seconds"),
517 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
518 { "max-cache-ttl", GC_OPT_FLAG_RUNTIME,
519 GC_LEVEL_EXPERT, "gnupg",
520 N_("|N|set maximum PIN cache lifetime to N seconds"),
521 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
522 { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
523 GC_LEVEL_EXPERT, "gnupg",
524 N_("|N|set maximum SSH key lifetime to N seconds"),
525 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
526 { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
527 GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
528 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
529 { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
530 GC_LEVEL_ADVANCED, "gnupg", "allow clients to mark keys as \"trusted\"",
531 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
532 { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
533 "gnupg", "do not grab keyboard and mouse",
534 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
536 { "Passphrase policy",
537 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
538 "gnupg", N_("Options enforcing a passphrase policy") },
539 { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME,
540 GC_LEVEL_EXPERT, "gnupg",
541 N_("do not allow to bypass the passphrase policy"),
542 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
543 { "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
544 GC_LEVEL_ADVANCED, "gnupg",
545 N_("|N|set minimal required length for new passphrases to N"),
546 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
547 { "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
548 GC_LEVEL_EXPERT, "gnupg",
549 N_("|N|require at least N non-alpha characters for a new passphrase"),
550 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
551 { "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
552 GC_LEVEL_EXPERT,
553 "gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
554 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
555 { "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
556 GC_LEVEL_EXPERT, "gnupg",
557 N_("|N|expire the passphrase after N days"),
558 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
559 { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME,
560 GC_LEVEL_EXPERT, "gnupg",
561 N_("do not allow the reuse of old passphrases"),
562 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
564 GC_OPTION_NULL
568 /* The options of the GC_COMPONENT_SCDAEMON component. */
569 static gc_option_t gc_options_scdaemon[] =
571 /* The configuration file to which we write the changes. */
572 { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
573 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
575 { "Monitor",
576 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
577 "gnupg", N_("Options controlling the diagnostic output") },
578 { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
579 "gnupg", "verbose",
580 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
581 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
582 "gnupg", "be somewhat more quiet",
583 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
584 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
585 NULL, NULL,
586 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
588 { "Configuration",
589 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
590 "gnupg", N_("Options controlling the configuration") },
591 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
592 "gnupg", "|FILE|read options from FILE",
593 GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
594 { "reader-port", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
595 "gnupg", "|N|connect to reader at port N",
596 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
597 { "ctapi-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
598 "gnupg", "|NAME|use NAME as ct-API driver",
599 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
600 { "pcsc-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
601 "gnupg", "|NAME|use NAME as PC/SC driver",
602 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
603 { "disable-ccid", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
604 "gnupg", "do not use the internal CCID driver",
605 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
606 { "disable-keypad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
607 "gnupg", "do not use a reader's keypad",
608 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
609 { "card-timeout", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
610 "gnupg", "|N|disconnect the card after N seconds of inactivity",
611 GC_ARG_TYPE_UINT32, GC_BACKEND_SCDAEMON },
613 { "Debug",
614 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
615 "gnupg", N_("Options useful for debugging") },
616 { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
617 "gnupg", "|LEVEL|set the debugging level to LEVEL",
618 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
619 { "log-file", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
620 "gnupg", N_("|FILE|write a log to FILE"),
621 GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
623 { "Security",
624 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
625 "gnupg", N_("Options controlling the security") },
626 { "deny-admin", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
627 "gnupg", "deny the use of admin card commands",
628 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
631 GC_OPTION_NULL
635 /* The options of the GC_COMPONENT_GPG component. */
636 static gc_option_t gc_options_gpg[] =
638 /* The configuration file to which we write the changes. */
639 { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
640 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
642 { "Monitor",
643 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
644 "gnupg", N_("Options controlling the diagnostic output") },
645 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
646 "gnupg", "verbose",
647 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
648 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
649 "gnupg", "be somewhat more quiet",
650 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
651 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
652 NULL, NULL,
653 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
655 { "Configuration",
656 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
657 "gnupg", N_("Options controlling the configuration") },
658 { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
659 "gnupg", N_("|NAME|use NAME as default secret key"),
660 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
661 { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
662 "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
663 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
664 { "group", GC_OPT_FLAG_LIST, GC_LEVEL_ADVANCED,
665 "gnupg", N_("|SPEC|set up email aliases"),
666 GC_ARG_TYPE_ALIAS_LIST, GC_BACKEND_GPG },
667 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
668 "gnupg", "|FILE|read options from FILE",
669 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
671 { "Debug",
672 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
673 "gnupg", N_("Options useful for debugging") },
674 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
675 "gnupg", "|LEVEL|set the debugging level to LEVEL",
676 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
677 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
678 "gnupg", N_("|FILE|write server mode logs to FILE"),
679 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
680 /* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */
681 /* NULL, NULL, */
682 /* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */
684 { "Keyserver",
685 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
686 "gnupg", N_("Configuration for Keyservers") },
687 { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
688 "gnupg", N_("|URL|use keyserver at URL"),
689 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
690 { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
691 "gnupg", N_("allow PKA lookups (DNS requests)"),
692 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
693 { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
694 "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
695 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
698 GC_OPTION_NULL
703 /* The options of the GC_COMPONENT_GPGSM component. */
704 static gc_option_t gc_options_gpgsm[] =
706 /* The configuration file to which we write the changes. */
707 { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
708 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
710 { "Monitor",
711 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
712 "gnupg", N_("Options controlling the diagnostic output") },
713 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
714 "gnupg", "verbose",
715 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
716 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
717 "gnupg", "be somewhat more quiet",
718 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
719 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
720 NULL, NULL,
721 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
723 { "Configuration",
724 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
725 "gnupg", N_("Options controlling the configuration") },
726 { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
727 "gnupg", N_("|NAME|use NAME as default secret key"),
728 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
729 { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
730 "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
731 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
732 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
733 "gnupg", "|FILE|read options from FILE",
734 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
735 { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
736 "gnupg", "use system's dirmngr if available",
737 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
738 { "disable-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
739 "gnupg", N_("disable all access to the dirmngr"),
740 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
741 { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
742 "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"),
743 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
744 { "keyserver", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
745 "gnupg", N_("|SPEC|use this keyserver to lookup keys"),
746 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_GPGSM },
748 { "Debug",
749 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
750 "gnupg", N_("Options useful for debugging") },
751 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
752 "gnupg", "|LEVEL|set the debugging level to LEVEL",
753 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
754 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
755 "gnupg", N_("|FILE|write server mode logs to FILE"),
756 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
757 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
758 NULL, NULL,
759 GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
761 { "Security",
762 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
763 "gnupg", N_("Options controlling the security") },
764 { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
765 "gnupg", "never consult a CRL",
766 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
767 { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
768 "gnupg", N_("do not check CRLs for root certificates"),
769 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
770 { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
771 "gnupg", "check validity using OCSP",
772 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
773 { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
774 "gnupg", "|N|number of certificates to include",
775 GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
776 { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
777 "gnupg", "do not check certificate policies",
778 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
779 { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
780 "gnupg", "fetch missing issuer certificates",
781 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
782 { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
783 "gnupg", "|NAME|use cipher algorithm NAME",
784 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
786 GC_OPTION_NULL
790 /* The options of the GC_COMPONENT_DIRMNGR component. */
791 static gc_option_t gc_options_dirmngr[] =
793 /* The configuration file to which we write the changes. */
794 { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
795 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
797 { "Monitor",
798 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
799 "gnupg", N_("Options controlling the diagnostic output") },
800 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
801 "dirmngr", "verbose",
802 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
803 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
804 "dirmngr", "be somewhat more quiet",
805 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
806 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
807 NULL, NULL,
808 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
810 { "Format",
811 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
812 "gnupg", N_("Options controlling the format of the output") },
813 { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
814 "dirmngr", "sh-style command output",
815 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
816 { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
817 "dirmngr", "csh-style command output",
818 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
820 { "Configuration",
821 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
822 "gnupg", N_("Options controlling the configuration") },
823 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
824 "dirmngr", "|FILE|read options from FILE",
825 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
827 { "Debug",
828 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
829 "gnupg", N_("Options useful for debugging") },
830 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
831 "dirmngr", "|LEVEL|set the debugging level to LEVEL",
832 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
833 { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
834 "dirmngr", "do not detach from the console",
835 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
836 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
837 "dirmngr", N_("|FILE|write server mode logs to FILE"),
838 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
839 { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
840 NULL, NULL,
841 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
842 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
843 NULL, NULL,
844 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
846 { "Enforcement",
847 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
848 "gnupg", N_("Options controlling the interactivity and enforcement") },
849 { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
850 "dirmngr", "run without asking a user",
851 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
852 { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
853 "dirmngr", "force loading of outdated CRLs",
854 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
856 { "HTTP",
857 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
858 "gnupg", N_("Configuration for HTTP servers") },
859 { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
860 "dirmngr", "inhibit the use of HTTP",
861 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
862 { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
863 "dirmngr", "ignore HTTP CRL distribution points",
864 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
865 { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
866 "dirmngr", "|URL|redirect all HTTP requests to URL",
867 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
868 { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
869 "gnupg", N_("use system's HTTP proxy setting"),
870 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
872 { "LDAP",
873 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
874 "gnupg", N_("Configuration of LDAP servers to use") },
875 { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
876 "dirmngr", "inhibit the use of LDAP",
877 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
878 { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
879 "dirmngr", "ignore LDAP CRL distribution points",
880 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
881 { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
882 "dirmngr", "|HOST|use HOST for LDAP queries",
883 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
884 { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
885 "dirmngr", "do not use fallback hosts with --ldap-proxy",
886 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
887 { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
888 "dirmngr", "add new servers discovered in CRL distribution points"
889 " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
890 { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
891 "dirmngr", "|N|set LDAP timeout to N seconds",
892 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
893 /* The following entry must not be removed, as it is required for
894 the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */
895 { "ldapserverlist-file",
896 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
897 "dirmngr", "|FILE|read LDAP server list from FILE",
898 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
899 /* This entry must come after at least one entry for
900 GC_BACKEND_DIRMNGR in this component, so that the entry for
901 "ldapserverlist-file will be initialized before this one. */
902 { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
903 "gnupg", N_("LDAP server list"),
904 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
905 { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
906 "dirmngr", "|N|do not return more than N items in one query",
907 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
909 { "OCSP",
910 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
911 "gnupg", N_("Configuration for OCSP") },
912 { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
913 "dirmngr", "allow sending OCSP requests",
914 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
915 { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
916 "dirmngr", "ignore certificate contained OCSP service URLs",
917 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
918 { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
919 "dirmngr", "|URL|use OCSP responder at URL",
920 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
921 { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
922 "dirmngr", "|FPR|OCSP response signed by FPR",
923 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
926 GC_OPTION_NULL
930 /* Component system. Each component is a set of options that can be
931 configured at the same time. If you change this, don't forget to
932 update GC_COMPONENT below. */
933 typedef enum
935 /* The classic GPG for OpenPGP. */
936 GC_COMPONENT_GPG,
938 /* The GPG Agent. */
939 GC_COMPONENT_GPG_AGENT,
941 /* The Smardcard Daemon. */
942 GC_COMPONENT_SCDAEMON,
944 /* GPG for S/MIME. */
945 GC_COMPONENT_GPGSM,
947 /* The LDAP Directory Manager for CRLs. */
948 GC_COMPONENT_DIRMNGR,
950 /* The number of components. */
951 GC_COMPONENT_NR
952 } gc_component_t;
955 /* The information associated with each component. */
956 static struct
958 /* The name of this component. Must not contain a colon (':')
959 character. */
960 const char *name;
962 /* The gettext domain for the description DESC. If this is NULL,
963 then the description is not translated. */
964 const char *desc_domain;
966 /* The description for this domain. */
967 const char *desc;
969 /* The list of options for this component, terminated by
970 GC_OPTION_NULL. */
971 gc_option_t *options;
972 } gc_component[] =
974 { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg },
975 { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
976 { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
977 { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
978 { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }
983 /* Structure used to collect error output of the backend programs. */
984 struct error_line_s;
985 typedef struct error_line_s *error_line_t;
986 struct error_line_s
988 error_line_t next; /* Link to next item. */
989 const char *fname; /* Name of the config file (points into BUFFER). */
990 unsigned int lineno; /* Line number of the config file. */
991 const char *errtext; /* Text of the error message (points into BUFFER). */
992 char buffer[1]; /* Helper buffer. */
997 /* Engine specific support. */
998 static void
999 gpg_agent_runtime_change (void)
1001 #ifndef HAVE_W32_SYSTEM
1002 char *agent = getenv ("GPG_AGENT_INFO");
1003 char *pid_str;
1004 unsigned long pid_long;
1005 char *tail;
1006 pid_t pid;
1008 if (!agent)
1009 return;
1011 pid_str = strchr (agent, ':');
1012 if (!pid_str)
1013 return;
1015 pid_str++;
1016 errno = 0;
1017 pid_long = strtoul (pid_str, &tail, 0);
1018 if (errno || (*tail != ':' && *tail != '\0'))
1019 return;
1021 pid = (pid_t) pid_long;
1023 /* Check for overflow. */
1024 if (pid_long != (unsigned long) pid)
1025 return;
1027 /* Ignore any errors here. */
1028 kill (pid, SIGHUP);
1029 #else
1030 gpg_error_t err;
1031 const char *pgmname;
1032 const char *argv[2];
1033 pid_t pid;
1035 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1036 argv[0] = "reloadagent";
1037 argv[1] = NULL;
1039 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1040 if (!err)
1041 err = gnupg_wait_process (pgmname, pid, NULL);
1042 if (err)
1043 gc_error (0, 0, "error running `%s%s': %s",
1044 pgmname, " reloadagent", gpg_strerror (err));
1045 #endif /*!HAVE_W32_SYSTEM*/
1049 static void
1050 scdaemon_runtime_change (void)
1052 gpg_error_t err;
1053 const char *pgmname;
1054 const char *argv[6];
1055 pid_t pid;
1057 /* We use "GETINFO app_running" to see whether the agent is already
1058 running and kill it only in this case. This avoids an explicit
1059 starting of the agent in case it is not yet running. There is
1060 obviously a race condition but that should not harm too much. */
1062 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1063 argv[0] = "-s";
1064 argv[1] = "GETINFO scd_running";
1065 argv[2] = "/if ${! $?}";
1066 argv[3] = "scd killscd";
1067 argv[4] = "/end";
1068 argv[5] = NULL;
1070 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1071 if (!err)
1072 err = gnupg_wait_process (pgmname, pid, NULL);
1073 if (err)
1074 gc_error (0, 0, "error running `%s%s': %s",
1075 pgmname, " scd killscd", gpg_strerror (err));
1079 /* Unconditionally reload COMPONENT or all components if COMPONENT is -1. */
1080 void
1081 gc_component_reload (int component)
1083 int runtime[GC_BACKEND_NR];
1084 gc_option_t *option;
1085 gc_backend_t backend;
1087 /* Set a flag for the backends to be reloaded. */
1088 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1089 runtime[backend] = 0;
1091 if (component == -1)
1093 for (component = 0; component < GC_COMPONENT_NR; component++)
1095 option = gc_component[component].options;
1096 for (; option && option->name; option++)
1097 runtime[option->backend] = 1;
1100 else
1102 assert (component < GC_COMPONENT_NR);
1103 option = gc_component[component].options;
1104 for (; option && option->name; option++)
1105 runtime[option->backend] = 1;
1108 /* Do the reload for all selected backends. */
1109 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1111 if (runtime[backend] && gc_backend[backend].runtime_change)
1112 (*gc_backend[backend].runtime_change) ();
1118 /* More or less Robust version of dgettext. It has the side effect of
1119 switching the codeset to utf-8 because this is what we want to
1120 output. In theory it is posible to keep the orginal code set and
1121 switch back for regular disgnostic output (redefine "_(" for that)
1122 but given the natur of this tool, being something invoked from
1123 other pograms, it does not make much sense. */
1124 static const char *
1125 my_dgettext (const char *domain, const char *msgid)
1127 #ifdef USE_SIMPLE_GETTEXT
1128 if (domain)
1130 static int switched_codeset;
1131 char *text;
1133 if (!switched_codeset)
1135 switched_codeset = 1;
1136 gettext_select_utf8 (1);
1139 if (!strcmp (domain, "gnupg"))
1140 domain = PACKAGE_GT;
1142 /* FIXME: we have no dgettext, thus we can't switch. */
1144 text = (char*)gettext (msgid);
1145 return text ? text : msgid;
1147 #elif defined(ENABLE_NLS)
1148 if (domain)
1150 static int switched_codeset;
1151 char *text;
1153 if (!switched_codeset)
1155 switched_codeset = 1;
1156 bind_textdomain_codeset (PACKAGE_GT, "utf-8");
1158 bindtextdomain ("dirmngr", LOCALEDIR);
1159 bind_textdomain_codeset ("dirmngr", "utf-8");
1163 /* Note: This is a hack to actually use the gnupg2 domain as
1164 long we are in a transition phase where gnupg 1.x and 1.9 may
1165 coexist. */
1166 if (!strcmp (domain, "gnupg"))
1167 domain = PACKAGE_GT;
1169 text = dgettext (domain, msgid);
1170 return text ? text : msgid;
1172 else
1173 #endif
1174 return msgid;
1178 /* Percent-Escape special characters. The string is valid until the
1179 next invocation of the function. */
1180 char *
1181 gc_percent_escape (const char *src)
1183 static char *esc_str;
1184 static int esc_str_len;
1185 int new_len = 3 * strlen (src) + 1;
1186 char *dst;
1188 if (esc_str_len < new_len)
1190 char *new_esc_str = realloc (esc_str, new_len);
1191 if (!new_esc_str)
1192 gc_error (1, errno, "can not escape string");
1193 esc_str = new_esc_str;
1194 esc_str_len = new_len;
1197 dst = esc_str;
1198 while (*src)
1200 if (*src == '%')
1202 *(dst++) = '%';
1203 *(dst++) = '2';
1204 *(dst++) = '5';
1206 else if (*src == ':')
1208 /* The colon is used as field separator. */
1209 *(dst++) = '%';
1210 *(dst++) = '3';
1211 *(dst++) = 'a';
1213 else if (*src == ',')
1215 /* The comma is used as list separator. */
1216 *(dst++) = '%';
1217 *(dst++) = '2';
1218 *(dst++) = 'c';
1220 else
1221 *(dst++) = *(src);
1222 src++;
1224 *dst = '\0';
1225 return esc_str;
1230 /* Percent-Deescape special characters. The string is valid until the
1231 next invocation of the function. */
1232 static char *
1233 percent_deescape (const char *src)
1235 static char *str;
1236 static int str_len;
1237 int new_len = 3 * strlen (src) + 1;
1238 char *dst;
1240 if (str_len < new_len)
1242 char *new_str = realloc (str, new_len);
1243 if (!new_str)
1244 gc_error (1, errno, "can not deescape string");
1245 str = new_str;
1246 str_len = new_len;
1249 dst = str;
1250 while (*src)
1252 if (*src == '%')
1254 int val = hextobyte (src + 1);
1256 if (val < 0)
1257 gc_error (1, 0, "malformed end of string %s", src);
1259 *(dst++) = (char) val;
1260 src += 3;
1262 else
1263 *(dst++) = *(src++);
1265 *dst = '\0';
1266 return str;
1270 /* List all components that are available. */
1271 void
1272 gc_component_list_components (FILE *out)
1274 gc_component_t component;
1275 gc_option_t *option;
1276 gc_backend_t backend;
1277 int backend_seen[GC_BACKEND_NR];
1278 const char *desc;
1279 const char *pgmname;
1281 for (component = 0; component < GC_COMPONENT_NR; component++)
1283 option = gc_component[component].options;
1284 if (option)
1286 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1287 backend_seen[backend] = 0;
1289 pgmname = "";
1290 for (; option && option->name; option++)
1292 if ((option->flags & GC_OPT_FLAG_GROUP))
1293 continue;
1294 backend = option->backend;
1295 if (backend_seen[backend])
1296 continue;
1297 backend_seen[backend] = 1;
1298 assert (backend != GC_BACKEND_ANY);
1299 if (gc_backend[backend].program
1300 && !gc_backend[backend].module_name)
1301 continue;
1302 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1303 break;
1306 desc = gc_component[component].desc;
1307 desc = my_dgettext (gc_component[component].desc_domain, desc);
1308 fprintf (out, "%s:%s:",
1309 gc_component[component].name, gc_percent_escape (desc));
1310 fprintf (out, "%s\n", gc_percent_escape (pgmname));
1317 static int
1318 all_digits_p (const char *p, size_t len)
1320 if (!len)
1321 return 0; /* No. */
1322 for (; len; len--, p++)
1323 if (!isascii (*p) || !isdigit (*p))
1324 return 0; /* No. */
1325 return 1; /* Yes. */
1329 /* Collect all error lines from file descriptor FD. Only lines
1330 prefixed with TAG are considered. Close that file descriptor
1331 then. Returns a list of error line items (which may be empty).
1332 There is no error return. */
1333 static error_line_t
1334 collect_error_output (int fd, const char *tag)
1336 FILE *fp;
1337 char buffer[1024];
1338 char *p, *p2, *p3;
1339 int c, cont_line;
1340 unsigned int pos;
1341 error_line_t eitem, errlines, *errlines_tail;
1342 size_t taglen = strlen (tag);
1344 fp = fdopen (fd, "r");
1345 if (!fp)
1346 gc_error (1, errno, "can't fdopen pipe for reading");
1348 errlines = NULL;
1349 errlines_tail = &errlines;
1350 pos = 0;
1351 cont_line = 0;
1352 while ((c=getc (fp)) != EOF)
1354 buffer[pos++] = c;
1355 if (pos >= sizeof buffer - 5 || c == '\n')
1357 buffer[pos - (c == '\n')] = 0;
1358 if (cont_line)
1359 ; /*Ignore continuations of previous line. */
1360 else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
1362 /* "gpgsm: foo:4: bla" */
1363 /* Yep, we are interested in this line. */
1364 p = buffer + taglen + 1;
1365 while (*p == ' ' || *p == '\t')
1366 p++;
1367 if (!*p)
1368 ; /* Empty lines are ignored. */
1369 else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
1370 && all_digits_p (p2+1, p3 - (p2+1)))
1372 /* Line in standard compiler format. */
1373 p3++;
1374 while (*p3 == ' ' || *p3 == '\t')
1375 p3++;
1376 eitem = xmalloc (sizeof *eitem + strlen (p));
1377 eitem->next = NULL;
1378 strcpy (eitem->buffer, p);
1379 eitem->fname = eitem->buffer;
1380 eitem->buffer[p2-p] = 0;
1381 eitem->errtext = eitem->buffer + (p3 - p);
1382 /* (we already checked that there are only ascii
1383 digits followed by a colon) */
1384 eitem->lineno = 0;
1385 for (p2++; isdigit (*p2); p2++)
1386 eitem->lineno = eitem->lineno*10 + (*p2 - '0');
1387 *errlines_tail = eitem;
1388 errlines_tail = &eitem->next;
1390 else
1392 /* Other error output. */
1393 eitem = xmalloc (sizeof *eitem + strlen (p));
1394 eitem->next = NULL;
1395 strcpy (eitem->buffer, p);
1396 eitem->fname = NULL;
1397 eitem->errtext = eitem->buffer;
1398 eitem->lineno = 0;
1399 *errlines_tail = eitem;
1400 errlines_tail = &eitem->next;
1403 pos = 0;
1404 /* If this was not a complete line mark that we are in a
1405 continuation. */
1406 cont_line = (c != '\n');
1410 /* We ignore error lines not terminated by a LF. */
1412 fclose (fp);
1413 return errlines;
1417 /* Check the options of a single component. Returns 0 if everything
1418 is OK. */
1420 gc_component_check_options (int component, FILE *out, const char *conf_file)
1422 gpg_error_t err;
1423 unsigned int result;
1424 int backend_seen[GC_BACKEND_NR];
1425 gc_backend_t backend;
1426 gc_option_t *option;
1427 const char *pgmname;
1428 const char *argv[4];
1429 int i;
1430 pid_t pid;
1431 int exitcode;
1432 int filedes[2];
1433 error_line_t errlines;
1435 /* We use a temporary file to collect the error output. It would be
1436 better to use a pipe here but as of now we have no suitable
1437 fucntion to create a portable pipe outside of exechelp. Thus it
1438 is easier to use the tempfile approach. */
1440 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1441 backend_seen[backend] = 0;
1443 option = gc_component[component].options;
1444 for (; option && option->name; option++)
1446 if ((option->flags & GC_OPT_FLAG_GROUP))
1447 continue;
1448 backend = option->backend;
1449 if (backend_seen[backend])
1450 continue;
1451 backend_seen[backend] = 1;
1452 assert (backend != GC_BACKEND_ANY);
1453 if (!gc_backend[backend].program)
1454 continue;
1455 if (!gc_backend[backend].module_name)
1456 continue;
1458 break;
1460 if (! option || ! option->name)
1461 return 0;
1463 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1464 i = 0;
1465 if (conf_file)
1467 argv[i++] = "--options";
1468 argv[i++] = conf_file;
1470 argv[i++] = "--gpgconf-test";
1471 argv[i++] = NULL;
1473 err = gnupg_create_inbound_pipe (filedes);
1474 if (err)
1475 gc_error (1, 0, _("error creating a pipe: %s\n"),
1476 gpg_strerror (err));
1478 result = 0;
1479 errlines = NULL;
1480 if (gnupg_spawn_process_fd (pgmname, argv, -1, -1, filedes[1], &pid))
1482 close (filedes[0]);
1483 close (filedes[1]);
1484 result |= 1; /* Program could not be run. */
1486 else
1488 close (filedes[1]);
1489 errlines = collect_error_output (filedes[0],
1490 gc_component[component].name);
1491 if (gnupg_wait_process (pgmname, pid, &exitcode))
1493 if (exitcode == -1)
1494 result |= 1; /* Program could not be run or it
1495 terminated abnormally. */
1496 result |= 2; /* Program returned an error. */
1500 /* If the program could not be run, we can't tell whether
1501 the config file is good. */
1502 if (result & 1)
1503 result |= 2;
1505 if (out)
1507 const char *desc;
1508 error_line_t errptr;
1510 desc = gc_component[component].desc;
1511 desc = my_dgettext (gc_component[component].desc_domain, desc);
1512 fprintf (out, "%s:%s:",
1513 gc_component[component].name, gc_percent_escape (desc));
1514 fputs (gc_percent_escape (pgmname), out);
1515 fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
1516 for (errptr = errlines; errptr; errptr = errptr->next)
1518 if (errptr != errlines)
1519 fputs ("\n:::::", out); /* Continuation line. */
1520 if (errptr->fname)
1521 fputs (gc_percent_escape (errptr->fname), out);
1522 putc (':', out);
1523 if (errptr->fname)
1524 fprintf (out, "%u", errptr->lineno);
1525 putc (':', out);
1526 fputs (gc_percent_escape (errptr->errtext), out);
1527 putc (':', out);
1529 putc ('\n', out);
1532 while (errlines)
1534 error_line_t tmp = errlines->next;
1535 xfree (errlines);
1536 errlines = tmp;
1539 return result;
1543 /* Check all components that are available. */
1544 void
1545 gc_check_programs (FILE *out)
1547 gc_component_t component;
1549 for (component = 0; component < GC_COMPONENT_NR; component++)
1550 gc_component_check_options (component, out, NULL);
1555 /* Find the component with the name NAME. Returns -1 if not
1556 found. */
1558 gc_component_find (const char *name)
1560 gc_component_t idx;
1562 for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1564 if (gc_component[idx].options
1565 && !strcmp (name, gc_component[idx].name))
1566 return idx;
1568 return -1;
1572 /* List the option OPTION. */
1573 static void
1574 list_one_option (const gc_option_t *option, FILE *out)
1576 const char *desc = NULL;
1577 char *arg_name = NULL;
1579 if (option->desc)
1581 desc = my_dgettext (option->desc_domain, option->desc);
1583 if (*desc == '|')
1585 const char *arg_tail = strchr (&desc[1], '|');
1587 if (arg_tail)
1589 int arg_len = arg_tail - &desc[1];
1590 arg_name = xmalloc (arg_len + 1);
1591 memcpy (arg_name, &desc[1], arg_len);
1592 arg_name[arg_len] = '\0';
1593 desc = arg_tail + 1;
1599 /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1600 PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY
1601 FIELDS. */
1603 /* The name field. */
1604 fprintf (out, "%s", option->name);
1606 /* The flags field. */
1607 fprintf (out, ":%lu", option->flags);
1608 if (opt.verbose)
1610 putc (' ', out);
1612 if (!option->flags)
1613 fprintf (out, "none");
1614 else
1616 unsigned long flags = option->flags;
1617 unsigned long flag = 0;
1618 unsigned long first = 1;
1620 while (flags)
1622 if (flags & 1)
1624 if (first)
1625 first = 0;
1626 else
1627 putc (',', out);
1628 fprintf (out, "%s", gc_flag[flag].name);
1630 flags >>= 1;
1631 flag++;
1636 /* The level field. */
1637 fprintf (out, ":%u", option->level);
1638 if (opt.verbose)
1639 fprintf (out, " %s", gc_level[option->level].name);
1641 /* The description field. */
1642 fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
1644 /* The type field. */
1645 fprintf (out, ":%u", option->arg_type);
1646 if (opt.verbose)
1647 fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1649 /* The alternate type field. */
1650 fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1651 if (opt.verbose)
1652 fprintf (out, " %s",
1653 gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1655 /* The argument name field. */
1656 fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
1657 if (arg_name)
1658 xfree (arg_name);
1660 /* The default value field. */
1661 fprintf (out, ":%s", option->default_value ? option->default_value : "");
1663 /* The default argument field. */
1664 fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1666 /* The value field. */
1667 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1668 && (option->flags & GC_OPT_FLAG_LIST)
1669 && option->value)
1670 /* The special format "1,1,1,1,...,1" is converted to a number
1671 here. */
1672 fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1673 else
1674 fprintf (out, ":%s", option->value ? option->value : "");
1676 /* ADD NEW FIELDS HERE. */
1678 putc ('\n', out);
1682 /* List all options of the component COMPONENT. */
1683 void
1684 gc_component_list_options (int component, FILE *out)
1686 const gc_option_t *option = gc_component[component].options;
1688 while (option && option->name)
1690 /* Do not output unknown or internal options. */
1691 if (!(option->flags & GC_OPT_FLAG_GROUP)
1692 && (!option->active || option->level == GC_LEVEL_INTERNAL))
1694 option++;
1695 continue;
1698 if (option->flags & GC_OPT_FLAG_GROUP)
1700 const gc_option_t *group_option = option + 1;
1701 gc_expert_level_t level = GC_LEVEL_NR;
1703 /* The manual states that the group level is always the
1704 minimum of the levels of all contained options. Due to
1705 different active options, and because it is hard to
1706 maintain manually, we calculate it here. The value in
1707 the global static table is ignored. */
1709 while (group_option->name)
1711 if (group_option->flags & GC_OPT_FLAG_GROUP)
1712 break;
1713 if (group_option->level < level)
1714 level = group_option->level;
1715 group_option++;
1718 /* Check if group is empty. */
1719 if (level != GC_LEVEL_NR)
1721 gc_option_t opt_copy;
1723 /* Fix up the group level. */
1724 memcpy (&opt_copy, option, sizeof (opt_copy));
1725 opt_copy.level = level;
1726 list_one_option (&opt_copy, out);
1729 else
1730 list_one_option (option, out);
1732 option++;
1737 /* Find the option NAME in component COMPONENT, for the backend
1738 BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */
1739 static gc_option_t *
1740 find_option (gc_component_t component, const char *name,
1741 gc_backend_t backend)
1743 gc_option_t *option = gc_component[component].options;
1744 while (option->name)
1746 if (!(option->flags & GC_OPT_FLAG_GROUP)
1747 && !strcmp (option->name, name)
1748 && (backend == GC_BACKEND_ANY || option->backend == backend))
1749 break;
1750 option++;
1752 return option->name ? option : NULL;
1756 /* Determine the configuration filename for the component COMPONENT
1757 and backend BACKEND. */
1758 static char *
1759 get_config_filename (gc_component_t component, gc_backend_t backend)
1761 char *filename = NULL;
1762 gc_option_t *option = find_option
1763 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
1764 assert (option);
1765 assert (option->arg_type == GC_ARG_TYPE_FILENAME);
1766 assert (!(option->flags & GC_OPT_FLAG_LIST));
1768 if (!option->active || !option->default_value)
1769 gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
1770 gc_backend[backend].option_config_filename,
1771 gc_backend[backend].name);
1773 if (option->value && *option->value)
1774 filename = percent_deescape (&option->value[1]);
1775 else if (option->default_value && *option->default_value)
1776 filename = percent_deescape (&option->default_value[1]);
1777 else
1778 filename = "";
1780 #ifdef HAVE_DOSISH_SYSTEM
1781 if (!(filename[0]
1782 && filename[1] == ':'
1783 && (filename[2] == '/' || filename[2] == '\\')))
1784 #else
1785 if (filename[0] != '/')
1786 #endif
1787 gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
1788 gc_backend[backend].option_config_filename,
1789 gc_backend[backend].name);
1791 return filename;
1795 /* Retrieve the options for the component COMPONENT from backend
1796 BACKEND, which we already know is a program-type backend. */
1797 static void
1798 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
1800 gpg_error_t err;
1801 int filedes[2];
1802 const char *pgmname;
1803 const char *argv[2];
1804 int exitcode;
1805 pid_t pid;
1806 char *line = NULL;
1807 size_t line_len = 0;
1808 ssize_t length;
1809 FILE *config;
1810 char *config_filename;
1812 err = gnupg_create_inbound_pipe (filedes);
1813 if (err)
1814 gc_error (1, 0, _("error creating a pipe: %s\n"), gpg_strerror (err));
1816 pgmname = (gc_backend[backend].module_name
1817 ? gnupg_module_name (gc_backend[backend].module_name)
1818 : gc_backend[backend].program );
1819 argv[0] = "--gpgconf-list";
1820 argv[1] = NULL;
1822 err = gnupg_spawn_process_fd (pgmname, argv, -1, filedes[1], -1, &pid);
1823 if (err)
1825 close (filedes[0]);
1826 close (filedes[1]);
1827 gc_error (1, 0, "could not gather active options from `%s': %s",
1828 pgmname, gpg_strerror (err));
1830 close (filedes[1]);
1831 config = fdopen (filedes[0], "r");
1832 if (!config)
1833 gc_error (1, errno, "can't fdopen pipe for reading");
1835 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1837 gc_option_t *option;
1838 char *linep;
1839 unsigned long flags = 0;
1840 char *default_value = NULL;
1842 /* Strip newline and carriage return, if present. */
1843 while (length > 0
1844 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1845 line[--length] = '\0';
1847 linep = strchr (line, ':');
1848 if (linep)
1849 *(linep++) = '\0';
1851 /* Extract additional flags. Default to none. */
1852 if (linep)
1854 char *end;
1855 char *tail;
1857 end = strchr (linep, ':');
1858 if (end)
1859 *(end++) = '\0';
1861 errno = 0;
1862 flags = strtoul (linep, &tail, 0);
1863 if (errno)
1864 gc_error (1, errno, "malformed flags in option %s from %s",
1865 line, pgmname);
1866 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1867 gc_error (1, 0, "garbage after flags in option %s from %s",
1868 line, pgmname);
1870 linep = end;
1873 /* Extract default value, if present. Default to empty if
1874 not. */
1875 if (linep)
1877 char *end;
1879 end = strchr (linep, ':');
1880 if (end)
1881 *(end++) = '\0';
1883 if (flags & GC_OPT_FLAG_DEFAULT)
1884 default_value = linep;
1886 linep = end;
1889 /* Look up the option in the component and install the
1890 configuration data. */
1891 option = find_option (component, line, backend);
1892 if (option)
1894 if (option->active)
1895 gc_error (1, errno, "option %s returned twice from %s",
1896 line, pgmname);
1897 option->active = 1;
1899 option->flags |= flags;
1900 if (default_value && *default_value)
1901 option->default_value = xstrdup (default_value);
1904 if (length < 0 || ferror (config))
1905 gc_error (1, errno, "error reading from %s",pgmname);
1906 if (fclose (config) && ferror (config))
1907 gc_error (1, errno, "error closing %s", pgmname);
1909 err = gnupg_wait_process (pgmname, pid, &exitcode);
1910 if (err)
1911 gc_error (1, 0, "running %s failed (exitcode=%d): %s",
1912 pgmname, exitcode, gpg_strerror (err));
1915 /* At this point, we can parse the configuration file. */
1916 config_filename = get_config_filename (component, backend);
1918 config = fopen (config_filename, "r");
1919 if (!config)
1920 gc_error (0, errno, "warning: can not open config file %s",
1921 config_filename);
1922 else
1924 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1926 char *name;
1927 char *value;
1928 gc_option_t *option;
1930 name = line;
1931 while (*name == ' ' || *name == '\t')
1932 name++;
1933 if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1934 continue;
1936 value = name;
1937 while (*value && *value != ' ' && *value != '\t'
1938 && *value != '#' && *value != '\r' && *value != '\n')
1939 value++;
1940 if (*value == ' ' || *value == '\t')
1942 char *end;
1944 *(value++) = '\0';
1945 while (*value == ' ' || *value == '\t')
1946 value++;
1948 end = value;
1949 while (*end && *end != '#' && *end != '\r' && *end != '\n')
1950 end++;
1951 while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1952 end--;
1953 *end = '\0';
1955 else
1956 *value = '\0';
1958 /* Look up the option in the component and install the
1959 configuration data. */
1960 option = find_option (component, line, backend);
1961 if (option)
1963 char *opt_value;
1965 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1967 if (*value)
1968 gc_error (0, 0,
1969 "warning: ignoring argument %s for option %s",
1970 value, name);
1971 opt_value = xstrdup ("1");
1973 else if (gc_arg_type[option->arg_type].fallback
1974 == GC_ARG_TYPE_STRING)
1975 opt_value = xasprintf ("\"%s", gc_percent_escape (value));
1976 else
1978 /* FIXME: Verify that the number is sane. */
1979 opt_value = xstrdup (value);
1982 /* Now enter the option into the table. */
1983 if (!(option->flags & GC_OPT_FLAG_LIST))
1985 if (option->value)
1986 free (option->value);
1987 option->value = opt_value;
1989 else
1991 if (!option->value)
1992 option->value = opt_value;
1993 else
1995 char *opt_val = opt_value;
1997 option->value = xasprintf ("%s,%s", option->value,
1998 opt_val);
1999 xfree (opt_value);
2005 if (length < 0 || ferror (config))
2006 gc_error (1, errno, "error reading from %s", config_filename);
2007 if (fclose (config) && ferror (config))
2008 gc_error (1, errno, "error closing %s", config_filename);
2011 xfree (line);
2015 /* Retrieve the options for the component COMPONENT from backend
2016 BACKEND, which we already know is of type file list. */
2017 static void
2018 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
2020 gc_option_t *list_option;
2021 gc_option_t *config_option;
2022 char *list_filename;
2023 FILE *list_file;
2024 char *line = NULL;
2025 size_t line_len = 0;
2026 ssize_t length;
2027 char *list = NULL;
2029 list_option = find_option (component,
2030 gc_backend[backend].option_name, GC_BACKEND_ANY);
2031 assert (list_option);
2032 assert (!list_option->active);
2034 list_filename = get_config_filename (component, backend);
2035 list_file = fopen (list_filename, "r");
2036 if (!list_file)
2037 gc_error (0, errno, "warning: can not open list file %s", list_filename);
2038 else
2041 while ((length = read_line (list_file, &line, &line_len, NULL)) > 0)
2043 char *start;
2044 char *end;
2045 char *new_list;
2047 start = line;
2048 while (*start == ' ' || *start == '\t')
2049 start++;
2050 if (!*start || *start == '#' || *start == '\r' || *start == '\n')
2051 continue;
2053 end = start;
2054 while (*end && *end != '#' && *end != '\r' && *end != '\n')
2055 end++;
2056 /* Walk back to skip trailing white spaces. Looks evil, but
2057 works because of the conditions on START and END imposed
2058 at this point (END is at least START + 1, and START is
2059 not a whitespace character). */
2060 while (*(end - 1) == ' ' || *(end - 1) == '\t')
2061 end--;
2062 *end = '\0';
2063 /* FIXME: Oh, no! This is so lame! Should use realloc and
2064 really append. */
2065 if (list)
2067 new_list = xasprintf ("%s,\"%s", list, gc_percent_escape (start));
2068 xfree (list);
2069 list = new_list;
2071 else
2072 list = xasprintf ("\"%s", gc_percent_escape (start));
2074 if (length < 0 || ferror (list_file))
2075 gc_error (1, errno, "can not read list file %s", list_filename);
2078 list_option->active = 1;
2079 list_option->value = list;
2081 /* Fix up the read-only flag. */
2082 config_option = find_option
2083 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
2084 if (config_option->flags & GC_OPT_FLAG_NO_CHANGE)
2085 list_option->flags |= GC_OPT_FLAG_NO_CHANGE;
2087 if (list_file && fclose (list_file) && ferror (list_file))
2088 gc_error (1, errno, "error closing %s", list_filename);
2089 xfree (line);
2093 /* Retrieve the currently active options and their defaults from all
2094 involved backends for this component. Using -1 for component will
2095 retrieve all options from all components. */
2096 void
2097 gc_component_retrieve_options (int component)
2099 int process_all = 0;
2100 int backend_seen[GC_BACKEND_NR];
2101 gc_backend_t backend;
2102 gc_option_t *option;
2104 for (backend = 0; backend < GC_BACKEND_NR; backend++)
2105 backend_seen[backend] = 0;
2107 if (component == -1)
2109 process_all = 1;
2110 component = 0;
2111 assert (component < GC_COMPONENT_NR);
2116 option = gc_component[component].options;
2118 while (option && option->name)
2120 if (!(option->flags & GC_OPT_FLAG_GROUP))
2122 backend = option->backend;
2124 if (backend_seen[backend])
2126 option++;
2127 continue;
2129 backend_seen[backend] = 1;
2131 assert (backend != GC_BACKEND_ANY);
2133 if (gc_backend[backend].program)
2134 retrieve_options_from_program (component, backend);
2135 else
2136 retrieve_options_from_file (component, backend);
2138 option++;
2141 while (process_all && ++component < GC_COMPONENT_NR);
2147 /* Perform a simple validity check based on the type. Return in
2148 NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
2149 type GC_ARG_TYPE_NONE. */
2150 static void
2151 option_check_validity (gc_option_t *option, unsigned long flags,
2152 char *new_value, unsigned long *new_value_nr)
2154 char *arg;
2156 if (!option->active)
2157 gc_error (1, 0, "option %s not supported by backend %s",
2158 option->name, gc_backend[option->backend].name);
2160 if (option->new_flags || option->new_value)
2161 gc_error (1, 0, "option %s already changed", option->name);
2163 if (flags & GC_OPT_FLAG_DEFAULT)
2165 if (*new_value)
2166 gc_error (1, 0, "argument %s provided for deleted option %s",
2167 new_value, option->name);
2169 return;
2172 /* GC_ARG_TYPE_NONE options have special list treatment. */
2173 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2175 char *tail;
2177 errno = 0;
2178 *new_value_nr = strtoul (new_value, &tail, 0);
2180 if (errno)
2181 gc_error (1, errno, "invalid argument for option %s",
2182 option->name);
2183 if (*tail)
2184 gc_error (1, 0, "garbage after argument for option %s",
2185 option->name);
2187 if (!(option->flags & GC_OPT_FLAG_LIST))
2189 if (*new_value_nr != 1)
2190 gc_error (1, 0, "argument for non-list option %s of type 0 "
2191 "(none) must be 1", option->name);
2193 else
2195 if (*new_value_nr == 0)
2196 gc_error (1, 0, "argument for option %s of type 0 (none) "
2197 "must be positive", option->name);
2200 return;
2203 arg = new_value;
2206 if (*arg == '\0' || *arg == ',')
2208 if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
2209 gc_error (1, 0, "argument required for option %s", option->name);
2211 if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
2212 gc_error (1, 0, "list found for non-list option %s", option->name);
2214 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
2216 if (*arg != '"')
2217 gc_error (1, 0, "string argument for option %s must begin "
2218 "with a quote (\") character", option->name);
2220 /* FIXME: We do not allow empty string arguments for now, as
2221 we do not quote arguments in configuration files, and
2222 thus no argument is indistinguishable from the empty
2223 string. */
2224 if (arg[1] == '\0' || arg[1] == ',')
2225 gc_error (1, 0, "empty string argument for option %s is "
2226 "currently not allowed. Please report this!",
2227 option->name);
2229 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2231 errno = 0;
2232 (void) strtol (arg, &arg, 0);
2234 if (errno)
2235 gc_error (1, errno, "invalid argument for option %s",
2236 option->name);
2238 if (*arg != '\0' && *arg != ',')
2239 gc_error (1, 0, "garbage after argument for option %s",
2240 option->name);
2242 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2244 errno = 0;
2245 (void) strtoul (arg, &arg, 0);
2247 if (errno)
2248 gc_error (1, errno, "invalid argument for option %s",
2249 option->name);
2251 if (*arg != '\0' && *arg != ',')
2252 gc_error (1, 0, "garbage after argument for option %s",
2253 option->name);
2255 arg = strchr (arg, ',');
2256 if (arg)
2257 arg++;
2259 while (arg && *arg);
2262 #ifdef HAVE_W32_SYSTEM
2264 copy_file (const char *src_name, const char *dst_name)
2266 #define BUF_LEN 4096
2267 char buffer[BUF_LEN];
2268 int len;
2269 FILE *src;
2270 FILE *dst;
2272 src = fopen (src_name, "r");
2273 if (src == NULL)
2274 return -1;
2276 dst = fopen (dst_name, "w");
2277 if (dst == NULL)
2279 int saved_err = errno;
2280 fclose (src);
2281 errno = saved_err;
2282 return -1;
2287 int written;
2289 len = fread (buffer, 1, BUF_LEN, src);
2290 if (len == 0)
2291 break;
2292 written = fwrite (buffer, 1, len, dst);
2293 if (written != len)
2294 break;
2296 while (!feof (src) && !ferror (src) && !ferror (dst));
2298 if (ferror (src) || ferror (dst) || !feof (src))
2300 int saved_errno = errno;
2301 fclose (src);
2302 fclose (dst);
2303 unlink (dst_name);
2304 errno = saved_errno;
2305 return -1;
2308 if (fclose (dst) && ferror (dst))
2309 gc_error (1, errno, "error closing %s", dst_name);
2310 if (fclose (src) && ferror (src))
2311 gc_error (1, errno, "error closing %s", src_name);
2313 return 0;
2315 #endif /* HAVE_W32_SYSTEM */
2318 /* Create and verify the new configuration file for the specified
2319 backend and component. Returns 0 on success and -1 on error. */
2320 static int
2321 change_options_file (gc_component_t component, gc_backend_t backend,
2322 char **src_filenamep, char **dest_filenamep,
2323 char **orig_filenamep)
2325 static const char marker[] = "###+++--- GPGConf ---+++###";
2326 /* True if we are within the marker in the config file. */
2327 int in_marker = 0;
2328 gc_option_t *option;
2329 char *line = NULL;
2330 size_t line_len;
2331 ssize_t length;
2332 int res;
2333 int fd;
2334 FILE *src_file = NULL;
2335 FILE *dest_file = NULL;
2336 char *src_filename;
2337 char *dest_filename;
2338 char *orig_filename;
2339 char *arg;
2340 char *cur_arg = NULL;
2342 option = find_option (component,
2343 gc_backend[backend].option_name, GC_BACKEND_ANY);
2344 assert (option);
2345 assert (option->active);
2346 assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
2348 /* FIXME. Throughout the function, do better error reporting. */
2349 /* Note that get_config_filename() calls percent_deescape(), so we
2350 call this before processing the arguments. */
2351 dest_filename = xstrdup (get_config_filename (component, backend));
2352 src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2353 orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2355 arg = option->new_value;
2356 if (arg && arg[0] == '\0')
2357 arg = NULL;
2358 else if (arg)
2360 char *end;
2362 arg++;
2363 end = strchr (arg, ',');
2364 if (end)
2365 *end = '\0';
2367 cur_arg = percent_deescape (arg);
2368 if (end)
2370 *end = ',';
2371 arg = end + 1;
2373 else
2374 arg = NULL;
2377 #ifdef HAVE_W32_SYSTEM
2378 res = copy_file (dest_filename, orig_filename);
2379 #else
2380 res = link (dest_filename, orig_filename);
2381 #endif
2382 if (res < 0 && errno != ENOENT)
2383 return -1;
2384 if (res < 0)
2386 xfree (orig_filename);
2387 orig_filename = NULL;
2390 /* We now initialize the return strings, so the caller can do the
2391 cleanup for us. */
2392 *src_filenamep = src_filename;
2393 *dest_filenamep = dest_filename;
2394 *orig_filenamep = orig_filename;
2396 /* Use open() so that we can use O_EXCL. */
2397 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2398 if (fd < 0)
2399 return -1;
2400 src_file = fdopen (fd, "w");
2401 res = errno;
2402 if (!src_file)
2404 errno = res;
2405 return -1;
2408 /* Only if ORIG_FILENAME is not NULL did the configuration file
2409 exist already. In this case, we will copy its content into the
2410 new configuration file, changing it to our liking in the
2411 process. */
2412 if (orig_filename)
2414 dest_file = fopen (dest_filename, "r");
2415 if (!dest_file)
2416 goto change_file_one_err;
2418 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2420 int disable = 0;
2421 char *start;
2423 if (!strncmp (marker, line, sizeof (marker) - 1))
2425 if (!in_marker)
2426 in_marker = 1;
2427 else
2428 break;
2431 start = line;
2432 while (*start == ' ' || *start == '\t')
2433 start++;
2434 if (*start && *start != '\r' && *start != '\n' && *start != '#')
2436 char *end;
2437 char *endp;
2438 char saved_end;
2440 endp = start;
2441 end = endp;
2443 /* Search for the end of the line. */
2444 while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
2446 endp++;
2447 if (*endp && *endp != ' ' && *endp != '\t'
2448 && *endp != '\r' && *endp != '\n' && *endp != '#')
2449 end = endp + 1;
2451 saved_end = *end;
2452 *end = '\0';
2454 if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2455 || !cur_arg || strcmp (start, cur_arg))
2456 disable = 1;
2457 else
2459 /* Find next argument. */
2460 if (arg)
2462 char *arg_end;
2464 arg++;
2465 arg_end = strchr (arg, ',');
2466 if (arg_end)
2467 *arg_end = '\0';
2469 cur_arg = percent_deescape (arg);
2470 if (arg_end)
2472 *arg_end = ',';
2473 arg = arg_end + 1;
2475 else
2476 arg = NULL;
2478 else
2479 cur_arg = NULL;
2482 *end = saved_end;
2485 if (disable)
2487 if (!in_marker)
2489 fprintf (src_file,
2490 "# GPGConf disabled this option here at %s\n",
2491 asctimestamp (gnupg_get_time ()));
2492 if (ferror (src_file))
2493 goto change_file_one_err;
2494 fprintf (src_file, "# %s", line);
2495 if (ferror (src_file))
2496 goto change_file_one_err;
2499 else
2501 fprintf (src_file, "%s", line);
2502 if (ferror (src_file))
2503 goto change_file_one_err;
2506 if (length < 0 || ferror (dest_file))
2507 goto change_file_one_err;
2510 if (!in_marker)
2512 /* There was no marker. This is the first time we edit the
2513 file. We add our own marker at the end of the file and
2514 proceed. Note that we first write a newline, this guards us
2515 against files which lack the newline at the end of the last
2516 line, while it doesn't hurt us in all other cases. */
2517 fprintf (src_file, "\n%s\n", marker);
2518 if (ferror (src_file))
2519 goto change_file_one_err;
2522 /* At this point, we have copied everything up to the end marker
2523 into the new file, except for the arguments we are going to add.
2524 Now, dump the new arguments and write the end marker, possibly
2525 followed by the rest of the original file. */
2526 while (cur_arg)
2528 fprintf (src_file, "%s\n", cur_arg);
2530 /* Find next argument. */
2531 if (arg)
2533 char *end;
2535 arg++;
2536 end = strchr (arg, ',');
2537 if (end)
2538 *end = '\0';
2540 cur_arg = percent_deescape (arg);
2541 if (end)
2543 *end = ',';
2544 arg = end + 1;
2546 else
2547 arg = NULL;
2549 else
2550 cur_arg = NULL;
2553 fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2554 if (ferror (src_file))
2555 goto change_file_one_err;
2557 if (!in_marker)
2559 fprintf (src_file, "# GPGConf edited this configuration file.\n");
2560 if (ferror (src_file))
2561 goto change_file_one_err;
2562 fprintf (src_file, "# It will disable options before this marked "
2563 "block, but it will\n");
2564 if (ferror (src_file))
2565 goto change_file_one_err;
2566 fprintf (src_file, "# never change anything below these lines.\n");
2567 if (ferror (src_file))
2568 goto change_file_one_err;
2570 if (dest_file)
2572 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2574 fprintf (src_file, "%s", line);
2575 if (ferror (src_file))
2576 goto change_file_one_err;
2578 if (length < 0 || ferror (dest_file))
2579 goto change_file_one_err;
2581 xfree (line);
2582 line = NULL;
2584 res = fclose (src_file);
2585 if (res)
2587 res = errno;
2588 close (fd);
2589 if (dest_file)
2590 fclose (dest_file);
2591 errno = res;
2592 return -1;
2594 close (fd);
2595 if (dest_file)
2597 res = fclose (dest_file);
2598 if (res)
2599 return -1;
2601 return 0;
2603 change_file_one_err:
2604 xfree (line);
2605 res = errno;
2606 if (src_file)
2608 fclose (src_file);
2609 close (fd);
2611 if (dest_file)
2612 fclose (dest_file);
2613 errno = res;
2614 return -1;
2618 /* Create and verify the new configuration file for the specified
2619 backend and component. Returns 0 on success and -1 on error. */
2620 static int
2621 change_options_program (gc_component_t component, gc_backend_t backend,
2622 char **src_filenamep, char **dest_filenamep,
2623 char **orig_filenamep)
2625 static const char marker[] = "###+++--- GPGConf ---+++###";
2626 /* True if we are within the marker in the config file. */
2627 int in_marker = 0;
2628 gc_option_t *option;
2629 char *line = NULL;
2630 size_t line_len;
2631 ssize_t length;
2632 int res;
2633 int fd;
2634 FILE *src_file = NULL;
2635 FILE *dest_file = NULL;
2636 char *src_filename;
2637 char *dest_filename;
2638 char *orig_filename;
2639 /* Special hack for gpg, see below. */
2640 int utf8strings_seen = 0;
2642 /* FIXME. Throughout the function, do better error reporting. */
2643 dest_filename = xstrdup (get_config_filename (component, backend));
2644 src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2645 orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2647 #ifdef HAVE_W32_SYSTEM
2648 res = copy_file (dest_filename, orig_filename);
2649 #else
2650 res = link (dest_filename, orig_filename);
2651 #endif
2652 if (res < 0 && errno != ENOENT)
2653 return -1;
2654 if (res < 0)
2656 xfree (orig_filename);
2657 orig_filename = NULL;
2660 /* We now initialize the return strings, so the caller can do the
2661 cleanup for us. */
2662 *src_filenamep = src_filename;
2663 *dest_filenamep = dest_filename;
2664 *orig_filenamep = orig_filename;
2666 /* Use open() so that we can use O_EXCL. */
2667 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2668 if (fd < 0)
2669 return -1;
2670 src_file = fdopen (fd, "w");
2671 res = errno;
2672 if (!src_file)
2674 errno = res;
2675 return -1;
2678 /* Only if ORIG_FILENAME is not NULL did the configuration file
2679 exist already. In this case, we will copy its content into the
2680 new configuration file, changing it to our liking in the
2681 process. */
2682 if (orig_filename)
2684 dest_file = fopen (dest_filename, "r");
2685 if (!dest_file)
2686 goto change_one_err;
2688 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2690 int disable = 0;
2691 char *start;
2693 if (!strncmp (marker, line, sizeof (marker) - 1))
2695 if (!in_marker)
2696 in_marker = 1;
2697 else
2698 break;
2700 else if (backend == GC_BACKEND_GPG && in_marker
2701 && ! strcmp ("utf8-strings\n", line))
2703 /* Strip duplicated entries. */
2704 if (utf8strings_seen)
2705 disable = 1;
2706 else
2707 utf8strings_seen = 1;
2710 start = line;
2711 while (*start == ' ' || *start == '\t')
2712 start++;
2713 if (*start && *start != '\r' && *start != '\n' && *start != '#')
2715 char *end;
2716 char saved_end;
2718 end = start;
2719 while (*end && *end != ' ' && *end != '\t'
2720 && *end != '\r' && *end != '\n' && *end != '#')
2721 end++;
2722 saved_end = *end;
2723 *end = '\0';
2725 option = find_option (component, start, backend);
2726 *end = saved_end;
2727 if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2728 || option->new_value))
2729 disable = 1;
2731 if (disable)
2733 if (!in_marker)
2735 fprintf (src_file,
2736 "# GPGConf disabled this option here at %s\n",
2737 asctimestamp (gnupg_get_time ()));
2738 if (ferror (src_file))
2739 goto change_one_err;
2740 fprintf (src_file, "# %s", line);
2741 if (ferror (src_file))
2742 goto change_one_err;
2745 else
2747 fprintf (src_file, "%s", line);
2748 if (ferror (src_file))
2749 goto change_one_err;
2752 if (length < 0 || ferror (dest_file))
2753 goto change_one_err;
2756 if (!in_marker)
2758 /* There was no marker. This is the first time we edit the
2759 file. We add our own marker at the end of the file and
2760 proceed. Note that we first write a newline, this guards us
2761 against files which lack the newline at the end of the last
2762 line, while it doesn't hurt us in all other cases. */
2763 fprintf (src_file, "\n%s\n", marker);
2764 if (ferror (src_file))
2765 goto change_one_err;
2767 /* At this point, we have copied everything up to the end marker
2768 into the new file, except for the options we are going to change.
2769 Now, dump the changed options (except for those we are going to
2770 revert to their default), and write the end marker, possibly
2771 followed by the rest of the original file. */
2773 /* We have to turn on UTF8 strings for GnuPG. */
2774 if (backend == GC_BACKEND_GPG && ! utf8strings_seen)
2775 fprintf (src_file, "utf8-strings\n");
2777 option = gc_component[component].options;
2778 while (option->name)
2780 if (!(option->flags & GC_OPT_FLAG_GROUP)
2781 && option->backend == backend
2782 && option->new_value)
2784 char *arg = option->new_value;
2788 if (*arg == '\0' || *arg == ',')
2790 fprintf (src_file, "%s\n", option->name);
2791 if (ferror (src_file))
2792 goto change_one_err;
2794 else if (gc_arg_type[option->arg_type].fallback
2795 == GC_ARG_TYPE_NONE)
2797 assert (*arg == '1');
2798 fprintf (src_file, "%s\n", option->name);
2799 if (ferror (src_file))
2800 goto change_one_err;
2802 arg++;
2804 else if (gc_arg_type[option->arg_type].fallback
2805 == GC_ARG_TYPE_STRING)
2807 char *end;
2809 assert (*arg == '"');
2810 arg++;
2812 end = strchr (arg, ',');
2813 if (end)
2814 *end = '\0';
2816 fprintf (src_file, "%s %s\n", option->name,
2817 percent_deescape (arg));
2818 if (ferror (src_file))
2819 goto change_one_err;
2821 if (end)
2822 *end = ',';
2823 arg = end;
2825 else
2827 char *end;
2829 end = strchr (arg, ',');
2830 if (end)
2831 *end = '\0';
2833 fprintf (src_file, "%s %s\n", option->name, arg);
2834 if (ferror (src_file))
2835 goto change_one_err;
2837 if (end)
2838 *end = ',';
2839 arg = end;
2842 assert (arg == NULL || *arg == '\0' || *arg == ',');
2843 if (arg && *arg == ',')
2844 arg++;
2846 while (arg && *arg);
2848 option++;
2851 fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2852 if (ferror (src_file))
2853 goto change_one_err;
2855 if (!in_marker)
2857 fprintf (src_file, "# GPGConf edited this configuration file.\n");
2858 if (ferror (src_file))
2859 goto change_one_err;
2860 fprintf (src_file, "# It will disable options before this marked "
2861 "block, but it will\n");
2862 if (ferror (src_file))
2863 goto change_one_err;
2864 fprintf (src_file, "# never change anything below these lines.\n");
2865 if (ferror (src_file))
2866 goto change_one_err;
2868 if (dest_file)
2870 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2872 fprintf (src_file, "%s", line);
2873 if (ferror (src_file))
2874 goto change_one_err;
2876 if (length < 0 || ferror (dest_file))
2877 goto change_one_err;
2879 xfree (line);
2880 line = NULL;
2882 res = fclose (src_file);
2883 if (res)
2885 res = errno;
2886 close (fd);
2887 if (dest_file)
2888 fclose (dest_file);
2889 errno = res;
2890 return -1;
2892 close (fd);
2893 if (dest_file)
2895 res = fclose (dest_file);
2896 if (res)
2897 return -1;
2899 return 0;
2901 change_one_err:
2902 xfree (line);
2903 res = errno;
2904 if (src_file)
2906 fclose (src_file);
2907 close (fd);
2909 if (dest_file)
2910 fclose (dest_file);
2911 errno = res;
2912 return -1;
2916 /* Common code for gc_component_change_options and
2917 gc_process_gpgconf_conf. */
2918 static void
2919 change_one_value (gc_option_t *option, int *runtime,
2920 unsigned long flags, char *new_value)
2922 unsigned long new_value_nr = 0;
2924 option_check_validity (option, flags, new_value, &new_value_nr);
2926 if (option->flags & GC_OPT_FLAG_RUNTIME)
2927 runtime[option->backend] = 1;
2929 option->new_flags = flags;
2930 if (!(flags & GC_OPT_FLAG_DEFAULT))
2932 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2933 && (option->flags & GC_OPT_FLAG_LIST))
2935 char *str;
2937 /* We convert the number to a list of 1's for convenient
2938 list handling. */
2939 assert (new_value_nr > 0);
2940 option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2941 str = option->new_value;
2942 *(str++) = '1';
2943 while (--new_value_nr > 0)
2945 *(str++) = ',';
2946 *(str++) = '1';
2948 *(str++) = '\0';
2950 else
2951 option->new_value = xstrdup (new_value);
2956 /* Read the modifications from IN and apply them. If IN is NULL the
2957 modifications are expected to already have been set to the global
2958 table. */
2959 void
2960 gc_component_change_options (int component, FILE *in, FILE *out)
2962 int err = 0;
2963 int runtime[GC_BACKEND_NR];
2964 char *src_filename[GC_BACKEND_NR];
2965 char *dest_filename[GC_BACKEND_NR];
2966 char *orig_filename[GC_BACKEND_NR];
2967 gc_backend_t backend;
2968 gc_option_t *option;
2969 char *line = NULL;
2970 size_t line_len = 0;
2971 ssize_t length;
2973 for (backend = 0; backend < GC_BACKEND_NR; backend++)
2975 runtime[backend] = 0;
2976 src_filename[backend] = NULL;
2977 dest_filename[backend] = NULL;
2978 orig_filename[backend] = NULL;
2981 if (in)
2983 /* Read options from the file IN. */
2984 while ((length = read_line (in, &line, &line_len, NULL)) > 0)
2986 char *linep;
2987 unsigned long flags = 0;
2988 char *new_value = "";
2990 /* Strip newline and carriage return, if present. */
2991 while (length > 0
2992 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2993 line[--length] = '\0';
2995 linep = strchr (line, ':');
2996 if (linep)
2997 *(linep++) = '\0';
2999 /* Extract additional flags. Default to none. */
3000 if (linep)
3002 char *end;
3003 char *tail;
3005 end = strchr (linep, ':');
3006 if (end)
3007 *(end++) = '\0';
3009 errno = 0;
3010 flags = strtoul (linep, &tail, 0);
3011 if (errno)
3012 gc_error (1, errno, "malformed flags in option %s", line);
3013 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
3014 gc_error (1, 0, "garbage after flags in option %s", line);
3016 linep = end;
3019 /* Don't allow setting of the no change flag. */
3020 flags &= ~GC_OPT_FLAG_NO_CHANGE;
3022 /* Extract default value, if present. Default to empty if not. */
3023 if (linep)
3025 char *end;
3026 end = strchr (linep, ':');
3027 if (end)
3028 *(end++) = '\0';
3029 new_value = linep;
3030 linep = end;
3033 option = find_option (component, line, GC_BACKEND_ANY);
3034 if (!option)
3035 gc_error (1, 0, "unknown option %s", line);
3037 if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
3039 gc_error (0, 0, "ignoring new value for option %s",
3040 option->name);
3041 continue;
3044 change_one_value (option, runtime, flags, new_value);
3048 /* Now that we have collected and locally verified the changes,
3049 write them out to new configuration files, verify them
3050 externally, and then commit them. */
3051 option = gc_component[component].options;
3052 while (option && option->name)
3054 /* Go on if we have already seen this backend, or if there is
3055 nothing to do. */
3056 if (src_filename[option->backend]
3057 || !(option->new_flags || option->new_value))
3059 option++;
3060 continue;
3063 if (gc_backend[option->backend].program)
3065 err = change_options_program (component, option->backend,
3066 &src_filename[option->backend],
3067 &dest_filename[option->backend],
3068 &orig_filename[option->backend]);
3069 if (! err)
3071 /* External verification. */
3072 err = gc_component_check_options (component, out,
3073 src_filename[option->backend]);
3074 if (err)
3076 gc_error (0, 0,
3077 _("External verification of component %s failed"),
3078 gc_component[component].name);
3079 errno = EINVAL;
3084 else
3085 err = change_options_file (component, option->backend,
3086 &src_filename[option->backend],
3087 &dest_filename[option->backend],
3088 &orig_filename[option->backend]);
3090 if (err)
3091 break;
3093 option++;
3096 if (! err && ! opt.dry_run)
3098 int i;
3100 for (i = 0; i < GC_BACKEND_NR; i++)
3102 if (src_filename[i])
3104 /* FIXME: Make a verification here. */
3106 assert (dest_filename[i]);
3108 if (orig_filename[i])
3110 #ifdef HAVE_W32_SYSTEM
3111 /* There is no atomic update on W32. */
3112 err = unlink (dest_filename[i]);
3113 #endif /* HAVE_W32_SYSTEM */
3114 if (!err)
3115 err = rename (src_filename[i], dest_filename[i]);
3117 else
3119 #ifdef HAVE_W32_SYSTEM
3120 /* We skip the unlink if we expect the file not to
3121 be there. */
3122 err = rename (src_filename[i], dest_filename[i]);
3123 #else /* HAVE_W32_SYSTEM */
3124 /* This is a bit safer than rename() because we
3125 expect DEST_FILENAME not to be there. If it
3126 happens to be there, this will fail. */
3127 err = link (src_filename[i], dest_filename[i]);
3128 if (!err)
3129 err = unlink (src_filename[i]);
3130 #endif /* !HAVE_W32_SYSTEM */
3132 if (err)
3133 break;
3134 src_filename[i] = NULL;
3139 if (err || opt.dry_run)
3141 int i;
3142 int saved_errno = errno;
3144 /* An error occured or a dry-run is requested. */
3145 for (i = 0; i < GC_BACKEND_NR; i++)
3147 if (src_filename[i])
3149 /* The change was not yet committed. */
3150 unlink (src_filename[i]);
3151 if (orig_filename[i])
3152 unlink (orig_filename[i]);
3154 else
3156 /* The changes were already committed. FIXME: This is a
3157 tad dangerous, as we don't know if we don't overwrite
3158 a version of the file that is even newer than the one
3159 we just installed. */
3160 if (orig_filename[i])
3162 #ifdef HAVE_W32_SYSTEM
3163 /* There is no atomic update on W32. */
3164 unlink (dest_filename[i]);
3165 #endif /* HAVE_W32_SYSTEM */
3166 rename (orig_filename[i], dest_filename[i]);
3168 else
3169 unlink (dest_filename[i]);
3172 if (err)
3173 gc_error (1, saved_errno, "could not commit changes");
3175 /* Fall-through for dry run. */
3176 goto leave;
3179 /* If it all worked, notify the daemons of the changes. */
3180 if (opt.runtime)
3181 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3183 if (runtime[backend] && gc_backend[backend].runtime_change)
3184 (*gc_backend[backend].runtime_change) ();
3187 /* Move the per-process backup file into its place. */
3188 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3189 if (orig_filename[backend])
3191 char *backup_filename;
3193 assert (dest_filename[backend]);
3195 backup_filename = xasprintf ("%s.gpgconf.bak", dest_filename[backend]);
3197 #ifdef HAVE_W32_SYSTEM
3198 /* There is no atomic update on W32. */
3199 unlink (backup_filename);
3200 #endif /* HAVE_W32_SYSTEM */
3201 rename (orig_filename[backend], backup_filename);
3204 leave:
3205 xfree (line);
3209 /* Check whether USER matches the current user of one of its group.
3210 This function may change USER. Returns true is there is a
3211 match. */
3212 static int
3213 key_matches_user_or_group (char *user)
3215 char *group;
3217 if (*user == '*' && user[1] == 0)
3218 return 1; /* A single asterisk matches all users. */
3220 group = strchr (user, ':');
3221 if (group)
3222 *group++ = 0;
3224 #ifdef HAVE_W32_SYSTEM
3225 /* Under Windows we don't support groups. */
3226 if (group && *group)
3227 gc_error (0, 0, _("Note that group specifications are ignored\n"));
3228 if (*user)
3230 static char *my_name;
3232 if (!my_name)
3234 char tmp[1];
3235 DWORD size = 1;
3237 GetUserNameA (tmp, &size);
3238 my_name = xmalloc (size);
3239 if (!GetUserNameA (my_name, &size))
3240 gc_error (1,0, "error getting current user name: %s",
3241 w32_strerror (-1));
3244 if (!strcmp (user, my_name))
3245 return 1; /* Found. */
3247 #else /*!HAVE_W32_SYSTEM*/
3248 /* First check whether the user matches. */
3249 if (*user)
3251 static char *my_name;
3253 if (!my_name)
3255 struct passwd *pw = getpwuid ( getuid () );
3256 if (!pw)
3257 gc_error (1, errno, "getpwuid failed for current user");
3258 my_name = xstrdup (pw->pw_name);
3260 if (!strcmp (user, my_name))
3261 return 1; /* Found. */
3264 /* If that failed, check whether a group matches. */
3265 if (group && *group)
3267 static char *my_group;
3268 static char **my_supgroups;
3269 int n;
3271 if (!my_group)
3273 struct group *gr = getgrgid ( getgid () );
3274 if (!gr)
3275 gc_error (1, errno, "getgrgid failed for current user");
3276 my_group = xstrdup (gr->gr_name);
3278 if (!strcmp (group, my_group))
3279 return 1; /* Found. */
3281 if (!my_supgroups)
3283 int ngids;
3284 gid_t *gids;
3286 ngids = getgroups (0, NULL);
3287 gids = xcalloc (ngids+1, sizeof *gids);
3288 ngids = getgroups (ngids, gids);
3289 if (ngids < 0)
3290 gc_error (1, errno, "getgroups failed for current user");
3291 my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
3292 for (n=0; n < ngids; n++)
3294 struct group *gr = getgrgid ( gids[n] );
3295 if (!gr)
3296 gc_error (1, errno, "getgrgid failed for supplementary group");
3297 my_supgroups[n] = xstrdup (gr->gr_name);
3299 xfree (gids);
3302 for (n=0; my_supgroups[n]; n++)
3303 if (!strcmp (group, my_supgroups[n]))
3304 return 1; /* Found. */
3306 #endif /*!HAVE_W32_SYSTEM*/
3307 return 0; /* No match. */
3312 /* Read and process the global configuration file for gpgconf. This
3313 optional file is used to update our internal tables at runtime and
3314 may also be used to set new default values. If FNAME is NULL the
3315 default name will be used. With UPDATE set to true the internal
3316 tables are actually updated; if not set, only a syntax check is
3317 done. If DEFAULTS is true the global options are written to the
3318 configuration files. If LISTFP is set, no changes are done but the
3319 configuration file is printed to LISTFP in a colon separated format.
3321 Returns 0 on success or if the config file is not present; -1 is
3322 returned on error. */
3324 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
3325 FILE *listfp)
3327 int result = 0;
3328 char *line = NULL;
3329 size_t line_len = 0;
3330 ssize_t length;
3331 FILE *config;
3332 int lineno = 0;
3333 int in_rule = 0;
3334 int got_match = 0;
3335 int runtime[GC_BACKEND_NR];
3336 int used_components[GC_COMPONENT_NR];
3337 int backend_id, component_id;
3338 char *fname;
3340 if (fname_arg)
3341 fname = xstrdup (fname_arg);
3342 else
3343 fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
3345 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3346 runtime[backend_id] = 0;
3347 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3348 used_components[component_id] = 0;
3350 config = fopen (fname, "r");
3351 if (!config)
3353 /* Do not print an error if the file is not available, except
3354 when running in syntax check mode. */
3355 if (errno != ENOENT || !update)
3357 gc_error (0, errno, "can not open global config file `%s'", fname);
3358 result = -1;
3360 xfree (fname);
3361 return result;
3364 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
3366 char *key, *component, *option, *flags, *value;
3367 char *empty;
3368 gc_option_t *option_info = NULL;
3369 char *p;
3370 int is_continuation;
3372 lineno++;
3373 key = line;
3374 while (*key == ' ' || *key == '\t')
3375 key++;
3376 if (!*key || *key == '#' || *key == '\r' || *key == '\n')
3377 continue;
3379 is_continuation = (key != line);
3381 /* Parse the key field. */
3382 if (!is_continuation && got_match)
3383 break; /* Finish after the first match. */
3384 else if (!is_continuation)
3386 in_rule = 0;
3387 for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
3389 if (!*p)
3391 gc_error (0, 0, "missing rule at `%s', line %d", fname, lineno);
3392 result = -1;
3393 continue;
3395 *p++ = 0;
3396 component = p;
3398 else if (!in_rule)
3400 gc_error (0, 0, "continuation but no rule at `%s', line %d",
3401 fname, lineno);
3402 result = -1;
3403 continue;
3405 else
3407 component = key;
3408 key = NULL;
3411 in_rule = 1;
3413 /* Parse the component. */
3414 while (*component == ' ' || *component == '\t')
3415 component++;
3416 for (p=component; *p && !strchr (" \t\r\n", *p); p++)
3418 if (p == component)
3420 gc_error (0, 0, "missing component at `%s', line %d",
3421 fname, lineno);
3422 result = -1;
3423 continue;
3425 empty = p;
3426 *p++ = 0;
3427 option = p;
3428 component_id = gc_component_find (component);
3429 if (component_id < 0)
3431 gc_error (0, 0, "unknown component at `%s', line %d",
3432 fname, lineno);
3433 result = -1;
3436 /* Parse the option name. */
3437 while (*option == ' ' || *option == '\t')
3438 option++;
3439 for (p=option; *p && !strchr (" \t\r\n", *p); p++)
3441 if (p == option)
3443 gc_error (0, 0, "missing option at `%s', line %d",
3444 fname, lineno);
3445 result = -1;
3446 continue;
3448 *p++ = 0;
3449 flags = p;
3450 if ( component_id != -1)
3452 option_info = find_option (component_id, option, GC_BACKEND_ANY);
3453 if (!option_info)
3455 gc_error (0, 0, "unknown option at `%s', line %d",
3456 fname, lineno);
3457 result = -1;
3462 /* Parse the optional flags. */
3463 while (*flags == ' ' || *flags == '\t')
3464 flags++;
3465 if (*flags == '[')
3467 flags++;
3468 p = strchr (flags, ']');
3469 if (!p)
3471 gc_error (0, 0, "syntax error in rule at `%s', line %d",
3472 fname, lineno);
3473 result = -1;
3474 continue;
3476 *p++ = 0;
3477 value = p;
3479 else /* No flags given. */
3481 value = flags;
3482 flags = NULL;
3485 /* Parse the optional value. */
3486 while (*value == ' ' || *value == '\t')
3487 value++;
3488 for (p=value; *p && !strchr ("\r\n", *p); p++)
3490 if (p == value)
3491 value = empty; /* No value given; let it point to an empty string. */
3492 else
3494 /* Strip trailing white space. */
3495 *p = 0;
3496 for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
3497 *p = 0;
3500 /* Check flag combinations. */
3501 if (!flags)
3503 else if (!strcmp (flags, "default"))
3505 if (*value)
3507 gc_error (0, 0, "flag \"default\" may not be combined "
3508 "with a value at `%s', line %d",
3509 fname, lineno);
3510 result = -1;
3513 else if (!strcmp (flags, "change"))
3515 else if (!strcmp (flags, "no-change"))
3517 else
3519 gc_error (0, 0, "unknown flag at `%s', line %d",
3520 fname, lineno);
3521 result = -1;
3524 /* In list mode we print out all records. */
3525 if (listfp && !result)
3527 /* If this is a new ruleset, print a key record. */
3528 if (!is_continuation)
3530 char *group = strchr (key, ':');
3531 if (group)
3533 *group++ = 0;
3534 if ((p = strchr (group, ':')))
3535 *p = 0; /* We better strip any extra stuff. */
3538 fprintf (listfp, "k:%s:", gc_percent_escape (key));
3539 fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
3542 /* All other lines are rule records. */
3543 fprintf (listfp, "r:::%s:%s:%s:",
3544 gc_component[component_id].name,
3545 option_info->name? option_info->name : "",
3546 flags? flags : "");
3547 if (value != empty)
3548 fprintf (listfp, "\"%s", gc_percent_escape (value));
3550 putc ('\n', listfp);
3553 /* Check whether the key matches but do this only if we are not
3554 running in syntax check mode. */
3555 if ( update
3556 && !result && !listfp
3557 && (got_match || (key && key_matches_user_or_group (key))) )
3559 int newflags = 0;
3561 got_match = 1;
3563 /* Apply the flags from gpgconf.conf. */
3564 if (!flags)
3566 else if (!strcmp (flags, "default"))
3567 newflags |= GC_OPT_FLAG_DEFAULT;
3568 else if (!strcmp (flags, "no-change"))
3569 option_info->flags |= GC_OPT_FLAG_NO_CHANGE;
3570 else if (!strcmp (flags, "change"))
3571 option_info->flags &= ~GC_OPT_FLAG_NO_CHANGE;
3573 if (defaults)
3575 assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
3576 used_components[component_id] = 1;
3578 /* Here we explicitly allow to update the value again. */
3579 if (newflags)
3581 option_info->new_flags = 0;
3583 if (*value)
3585 xfree (option_info->new_value);
3586 option_info->new_value = NULL;
3588 change_one_value (option_info, runtime, newflags, value);
3593 if (length < 0 || ferror (config))
3595 gc_error (0, errno, "error reading from `%s'", fname);
3596 result = -1;
3598 if (fclose (config) && ferror (config))
3599 gc_error (0, errno, "error closing `%s'", fname);
3601 xfree (line);
3603 /* If it all worked, process the options. */
3604 if (!result && update && defaults && !listfp)
3606 /* We need to switch off the runtime update, so that we can do
3607 it later all at once. */
3608 int save_opt_runtime = opt.runtime;
3609 opt.runtime = 0;
3611 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3613 gc_component_change_options (component_id, NULL, NULL);
3615 opt.runtime = save_opt_runtime;
3617 if (opt.runtime)
3619 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3620 if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
3621 (*gc_backend[backend_id].runtime_change) ();
3625 xfree (fname);
3626 return result;