Add gpgconf related dummy options default_pubkey_algo.
[gnupg.git] / tools / gpgconf-comp.c
blobf8de9d650e7489c4944f53ae8ea6a31d9a86596a
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 },
670 { "default_pubkey_algo",
671 (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
672 NULL, NULL,
673 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
676 { "Debug",
677 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
678 "gnupg", N_("Options useful for debugging") },
679 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
680 "gnupg", "|LEVEL|set the debugging level to LEVEL",
681 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
682 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
683 "gnupg", N_("|FILE|write server mode logs to FILE"),
684 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
685 /* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */
686 /* NULL, NULL, */
687 /* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */
689 { "Keyserver",
690 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
691 "gnupg", N_("Configuration for Keyservers") },
692 { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
693 "gnupg", N_("|URL|use keyserver at URL"),
694 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
695 { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
696 "gnupg", N_("allow PKA lookups (DNS requests)"),
697 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
698 { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
699 "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
700 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
705 GC_OPTION_NULL
710 /* The options of the GC_COMPONENT_GPGSM component. */
711 static gc_option_t gc_options_gpgsm[] =
713 /* The configuration file to which we write the changes. */
714 { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
715 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
717 { "Monitor",
718 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
719 "gnupg", N_("Options controlling the diagnostic output") },
720 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
721 "gnupg", "verbose",
722 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
723 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
724 "gnupg", "be somewhat more quiet",
725 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
726 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
727 NULL, NULL,
728 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
730 { "Configuration",
731 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
732 "gnupg", N_("Options controlling the configuration") },
733 { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
734 "gnupg", N_("|NAME|use NAME as default secret key"),
735 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
736 { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
737 "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
738 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
739 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
740 "gnupg", "|FILE|read options from FILE",
741 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
742 { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
743 "gnupg", "use system's dirmngr if available",
744 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
745 { "disable-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
746 "gnupg", N_("disable all access to the dirmngr"),
747 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
748 { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
749 "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"),
750 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
751 { "keyserver", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
752 "gnupg", N_("|SPEC|use this keyserver to lookup keys"),
753 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_GPGSM },
754 { "default_pubkey_algo",
755 (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
756 NULL, NULL,
757 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
759 { "Debug",
760 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
761 "gnupg", N_("Options useful for debugging") },
762 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
763 "gnupg", "|LEVEL|set the debugging level to LEVEL",
764 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
765 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
766 "gnupg", N_("|FILE|write server mode logs to FILE"),
767 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
768 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
769 NULL, NULL,
770 GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
772 { "Security",
773 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
774 "gnupg", N_("Options controlling the security") },
775 { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
776 "gnupg", "never consult a CRL",
777 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
778 { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
779 "gnupg", N_("do not check CRLs for root certificates"),
780 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
781 { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
782 "gnupg", "check validity using OCSP",
783 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
784 { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
785 "gnupg", "|N|number of certificates to include",
786 GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
787 { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
788 "gnupg", "do not check certificate policies",
789 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
790 { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
791 "gnupg", "fetch missing issuer certificates",
792 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
793 { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
794 "gnupg", "|NAME|use cipher algorithm NAME",
795 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
797 GC_OPTION_NULL
801 /* The options of the GC_COMPONENT_DIRMNGR component. */
802 static gc_option_t gc_options_dirmngr[] =
804 /* The configuration file to which we write the changes. */
805 { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
806 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
808 { "Monitor",
809 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
810 "gnupg", N_("Options controlling the diagnostic output") },
811 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
812 "dirmngr", "verbose",
813 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
814 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
815 "dirmngr", "be somewhat more quiet",
816 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
817 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
818 NULL, NULL,
819 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
821 { "Format",
822 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
823 "gnupg", N_("Options controlling the format of the output") },
824 { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
825 "dirmngr", "sh-style command output",
826 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
827 { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
828 "dirmngr", "csh-style command output",
829 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
831 { "Configuration",
832 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
833 "gnupg", N_("Options controlling the configuration") },
834 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
835 "dirmngr", "|FILE|read options from FILE",
836 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
838 { "Debug",
839 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
840 "gnupg", N_("Options useful for debugging") },
841 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
842 "dirmngr", "|LEVEL|set the debugging level to LEVEL",
843 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
844 { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
845 "dirmngr", "do not detach from the console",
846 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
847 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
848 "dirmngr", N_("|FILE|write server mode logs to FILE"),
849 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
850 { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
851 NULL, NULL,
852 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
853 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
854 NULL, NULL,
855 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
857 { "Enforcement",
858 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
859 "gnupg", N_("Options controlling the interactivity and enforcement") },
860 { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
861 "dirmngr", "run without asking a user",
862 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
863 { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
864 "dirmngr", "force loading of outdated CRLs",
865 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
867 { "HTTP",
868 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
869 "gnupg", N_("Configuration for HTTP servers") },
870 { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
871 "dirmngr", "inhibit the use of HTTP",
872 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
873 { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
874 "dirmngr", "ignore HTTP CRL distribution points",
875 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
876 { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
877 "dirmngr", "|URL|redirect all HTTP requests to URL",
878 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
879 { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
880 "gnupg", N_("use system's HTTP proxy setting"),
881 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
883 { "LDAP",
884 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
885 "gnupg", N_("Configuration of LDAP servers to use") },
886 { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
887 "dirmngr", "inhibit the use of LDAP",
888 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
889 { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
890 "dirmngr", "ignore LDAP CRL distribution points",
891 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
892 { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
893 "dirmngr", "|HOST|use HOST for LDAP queries",
894 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
895 { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
896 "dirmngr", "do not use fallback hosts with --ldap-proxy",
897 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
898 { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
899 "dirmngr", "add new servers discovered in CRL distribution points"
900 " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
901 { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
902 "dirmngr", "|N|set LDAP timeout to N seconds",
903 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
904 /* The following entry must not be removed, as it is required for
905 the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */
906 { "ldapserverlist-file",
907 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
908 "dirmngr", "|FILE|read LDAP server list from FILE",
909 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
910 /* This entry must come after at least one entry for
911 GC_BACKEND_DIRMNGR in this component, so that the entry for
912 "ldapserverlist-file will be initialized before this one. */
913 { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
914 "gnupg", N_("LDAP server list"),
915 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
916 { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
917 "dirmngr", "|N|do not return more than N items in one query",
918 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
920 { "OCSP",
921 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
922 "gnupg", N_("Configuration for OCSP") },
923 { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
924 "dirmngr", "allow sending OCSP requests",
925 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
926 { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
927 "dirmngr", "ignore certificate contained OCSP service URLs",
928 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
929 { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
930 "dirmngr", "|URL|use OCSP responder at URL",
931 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
932 { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
933 "dirmngr", "|FPR|OCSP response signed by FPR",
934 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
937 GC_OPTION_NULL
941 /* Component system. Each component is a set of options that can be
942 configured at the same time. If you change this, don't forget to
943 update GC_COMPONENT below. */
944 typedef enum
946 /* The classic GPG for OpenPGP. */
947 GC_COMPONENT_GPG,
949 /* The GPG Agent. */
950 GC_COMPONENT_GPG_AGENT,
952 /* The Smardcard Daemon. */
953 GC_COMPONENT_SCDAEMON,
955 /* GPG for S/MIME. */
956 GC_COMPONENT_GPGSM,
958 /* The LDAP Directory Manager for CRLs. */
959 GC_COMPONENT_DIRMNGR,
961 /* The number of components. */
962 GC_COMPONENT_NR
963 } gc_component_t;
966 /* The information associated with each component. */
967 static struct
969 /* The name of this component. Must not contain a colon (':')
970 character. */
971 const char *name;
973 /* The gettext domain for the description DESC. If this is NULL,
974 then the description is not translated. */
975 const char *desc_domain;
977 /* The description for this domain. */
978 const char *desc;
980 /* The list of options for this component, terminated by
981 GC_OPTION_NULL. */
982 gc_option_t *options;
983 } gc_component[] =
985 { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg },
986 { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
987 { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
988 { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
989 { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }
994 /* Structure used to collect error output of the backend programs. */
995 struct error_line_s;
996 typedef struct error_line_s *error_line_t;
997 struct error_line_s
999 error_line_t next; /* Link to next item. */
1000 const char *fname; /* Name of the config file (points into BUFFER). */
1001 unsigned int lineno; /* Line number of the config file. */
1002 const char *errtext; /* Text of the error message (points into BUFFER). */
1003 char buffer[1]; /* Helper buffer. */
1008 /* Engine specific support. */
1009 static void
1010 gpg_agent_runtime_change (void)
1012 #ifndef HAVE_W32_SYSTEM
1013 char *agent = getenv ("GPG_AGENT_INFO");
1014 char *pid_str;
1015 unsigned long pid_long;
1016 char *tail;
1017 pid_t pid;
1019 if (!agent)
1020 return;
1022 pid_str = strchr (agent, ':');
1023 if (!pid_str)
1024 return;
1026 pid_str++;
1027 errno = 0;
1028 pid_long = strtoul (pid_str, &tail, 0);
1029 if (errno || (*tail != ':' && *tail != '\0'))
1030 return;
1032 pid = (pid_t) pid_long;
1034 /* Check for overflow. */
1035 if (pid_long != (unsigned long) pid)
1036 return;
1038 /* Ignore any errors here. */
1039 kill (pid, SIGHUP);
1040 #else
1041 gpg_error_t err;
1042 const char *pgmname;
1043 const char *argv[2];
1044 pid_t pid;
1046 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1047 argv[0] = "reloadagent";
1048 argv[1] = NULL;
1050 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1051 if (!err)
1052 err = gnupg_wait_process (pgmname, pid, NULL);
1053 if (err)
1054 gc_error (0, 0, "error running `%s%s': %s",
1055 pgmname, " reloadagent", gpg_strerror (err));
1056 #endif /*!HAVE_W32_SYSTEM*/
1060 static void
1061 scdaemon_runtime_change (void)
1063 gpg_error_t err;
1064 const char *pgmname;
1065 const char *argv[6];
1066 pid_t pid;
1068 /* We use "GETINFO app_running" to see whether the agent is already
1069 running and kill it only in this case. This avoids an explicit
1070 starting of the agent in case it is not yet running. There is
1071 obviously a race condition but that should not harm too much. */
1073 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1074 argv[0] = "-s";
1075 argv[1] = "GETINFO scd_running";
1076 argv[2] = "/if ${! $?}";
1077 argv[3] = "scd killscd";
1078 argv[4] = "/end";
1079 argv[5] = NULL;
1081 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1082 if (!err)
1083 err = gnupg_wait_process (pgmname, pid, NULL);
1084 if (err)
1085 gc_error (0, 0, "error running `%s%s': %s",
1086 pgmname, " scd killscd", gpg_strerror (err));
1090 /* Unconditionally reload COMPONENT or all components if COMPONENT is -1. */
1091 void
1092 gc_component_reload (int component)
1094 int runtime[GC_BACKEND_NR];
1095 gc_option_t *option;
1096 gc_backend_t backend;
1098 /* Set a flag for the backends to be reloaded. */
1099 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1100 runtime[backend] = 0;
1102 if (component == -1)
1104 for (component = 0; component < GC_COMPONENT_NR; component++)
1106 option = gc_component[component].options;
1107 for (; option && option->name; option++)
1108 runtime[option->backend] = 1;
1111 else
1113 assert (component < GC_COMPONENT_NR);
1114 option = gc_component[component].options;
1115 for (; option && option->name; option++)
1116 runtime[option->backend] = 1;
1119 /* Do the reload for all selected backends. */
1120 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1122 if (runtime[backend] && gc_backend[backend].runtime_change)
1123 (*gc_backend[backend].runtime_change) ();
1129 /* More or less Robust version of dgettext. It has the side effect of
1130 switching the codeset to utf-8 because this is what we want to
1131 output. In theory it is posible to keep the orginal code set and
1132 switch back for regular disgnostic output (redefine "_(" for that)
1133 but given the natur of this tool, being something invoked from
1134 other pograms, it does not make much sense. */
1135 static const char *
1136 my_dgettext (const char *domain, const char *msgid)
1138 #ifdef USE_SIMPLE_GETTEXT
1139 if (domain)
1141 static int switched_codeset;
1142 char *text;
1144 if (!switched_codeset)
1146 switched_codeset = 1;
1147 gettext_select_utf8 (1);
1150 if (!strcmp (domain, "gnupg"))
1151 domain = PACKAGE_GT;
1153 /* FIXME: we have no dgettext, thus we can't switch. */
1155 text = (char*)gettext (msgid);
1156 return text ? text : msgid;
1158 #elif defined(ENABLE_NLS)
1159 if (domain)
1161 static int switched_codeset;
1162 char *text;
1164 if (!switched_codeset)
1166 switched_codeset = 1;
1167 bind_textdomain_codeset (PACKAGE_GT, "utf-8");
1169 bindtextdomain ("dirmngr", LOCALEDIR);
1170 bind_textdomain_codeset ("dirmngr", "utf-8");
1174 /* Note: This is a hack to actually use the gnupg2 domain as
1175 long we are in a transition phase where gnupg 1.x and 1.9 may
1176 coexist. */
1177 if (!strcmp (domain, "gnupg"))
1178 domain = PACKAGE_GT;
1180 text = dgettext (domain, msgid);
1181 return text ? text : msgid;
1183 else
1184 #endif
1185 return msgid;
1189 /* Percent-Escape special characters. The string is valid until the
1190 next invocation of the function. */
1191 char *
1192 gc_percent_escape (const char *src)
1194 static char *esc_str;
1195 static int esc_str_len;
1196 int new_len = 3 * strlen (src) + 1;
1197 char *dst;
1199 if (esc_str_len < new_len)
1201 char *new_esc_str = realloc (esc_str, new_len);
1202 if (!new_esc_str)
1203 gc_error (1, errno, "can not escape string");
1204 esc_str = new_esc_str;
1205 esc_str_len = new_len;
1208 dst = esc_str;
1209 while (*src)
1211 if (*src == '%')
1213 *(dst++) = '%';
1214 *(dst++) = '2';
1215 *(dst++) = '5';
1217 else if (*src == ':')
1219 /* The colon is used as field separator. */
1220 *(dst++) = '%';
1221 *(dst++) = '3';
1222 *(dst++) = 'a';
1224 else if (*src == ',')
1226 /* The comma is used as list separator. */
1227 *(dst++) = '%';
1228 *(dst++) = '2';
1229 *(dst++) = 'c';
1231 else
1232 *(dst++) = *(src);
1233 src++;
1235 *dst = '\0';
1236 return esc_str;
1241 /* Percent-Deescape special characters. The string is valid until the
1242 next invocation of the function. */
1243 static char *
1244 percent_deescape (const char *src)
1246 static char *str;
1247 static int str_len;
1248 int new_len = 3 * strlen (src) + 1;
1249 char *dst;
1251 if (str_len < new_len)
1253 char *new_str = realloc (str, new_len);
1254 if (!new_str)
1255 gc_error (1, errno, "can not deescape string");
1256 str = new_str;
1257 str_len = new_len;
1260 dst = str;
1261 while (*src)
1263 if (*src == '%')
1265 int val = hextobyte (src + 1);
1267 if (val < 0)
1268 gc_error (1, 0, "malformed end of string %s", src);
1270 *(dst++) = (char) val;
1271 src += 3;
1273 else
1274 *(dst++) = *(src++);
1276 *dst = '\0';
1277 return str;
1281 /* List all components that are available. */
1282 void
1283 gc_component_list_components (FILE *out)
1285 gc_component_t component;
1286 gc_option_t *option;
1287 gc_backend_t backend;
1288 int backend_seen[GC_BACKEND_NR];
1289 const char *desc;
1290 const char *pgmname;
1292 for (component = 0; component < GC_COMPONENT_NR; component++)
1294 option = gc_component[component].options;
1295 if (option)
1297 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1298 backend_seen[backend] = 0;
1300 pgmname = "";
1301 for (; option && option->name; option++)
1303 if ((option->flags & GC_OPT_FLAG_GROUP))
1304 continue;
1305 backend = option->backend;
1306 if (backend_seen[backend])
1307 continue;
1308 backend_seen[backend] = 1;
1309 assert (backend != GC_BACKEND_ANY);
1310 if (gc_backend[backend].program
1311 && !gc_backend[backend].module_name)
1312 continue;
1313 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1314 break;
1317 desc = gc_component[component].desc;
1318 desc = my_dgettext (gc_component[component].desc_domain, desc);
1319 fprintf (out, "%s:%s:",
1320 gc_component[component].name, gc_percent_escape (desc));
1321 fprintf (out, "%s\n", gc_percent_escape (pgmname));
1328 static int
1329 all_digits_p (const char *p, size_t len)
1331 if (!len)
1332 return 0; /* No. */
1333 for (; len; len--, p++)
1334 if (!isascii (*p) || !isdigit (*p))
1335 return 0; /* No. */
1336 return 1; /* Yes. */
1340 /* Collect all error lines from file descriptor FD. Only lines
1341 prefixed with TAG are considered. Close that file descriptor
1342 then. Returns a list of error line items (which may be empty).
1343 There is no error return. */
1344 static error_line_t
1345 collect_error_output (int fd, const char *tag)
1347 FILE *fp;
1348 char buffer[1024];
1349 char *p, *p2, *p3;
1350 int c, cont_line;
1351 unsigned int pos;
1352 error_line_t eitem, errlines, *errlines_tail;
1353 size_t taglen = strlen (tag);
1355 fp = fdopen (fd, "r");
1356 if (!fp)
1357 gc_error (1, errno, "can't fdopen pipe for reading");
1359 errlines = NULL;
1360 errlines_tail = &errlines;
1361 pos = 0;
1362 cont_line = 0;
1363 while ((c=getc (fp)) != EOF)
1365 buffer[pos++] = c;
1366 if (pos >= sizeof buffer - 5 || c == '\n')
1368 buffer[pos - (c == '\n')] = 0;
1369 if (cont_line)
1370 ; /*Ignore continuations of previous line. */
1371 else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
1373 /* "gpgsm: foo:4: bla" */
1374 /* Yep, we are interested in this line. */
1375 p = buffer + taglen + 1;
1376 while (*p == ' ' || *p == '\t')
1377 p++;
1378 if (!*p)
1379 ; /* Empty lines are ignored. */
1380 else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
1381 && all_digits_p (p2+1, p3 - (p2+1)))
1383 /* Line in standard compiler format. */
1384 p3++;
1385 while (*p3 == ' ' || *p3 == '\t')
1386 p3++;
1387 eitem = xmalloc (sizeof *eitem + strlen (p));
1388 eitem->next = NULL;
1389 strcpy (eitem->buffer, p);
1390 eitem->fname = eitem->buffer;
1391 eitem->buffer[p2-p] = 0;
1392 eitem->errtext = eitem->buffer + (p3 - p);
1393 /* (we already checked that there are only ascii
1394 digits followed by a colon) */
1395 eitem->lineno = 0;
1396 for (p2++; isdigit (*p2); p2++)
1397 eitem->lineno = eitem->lineno*10 + (*p2 - '0');
1398 *errlines_tail = eitem;
1399 errlines_tail = &eitem->next;
1401 else
1403 /* Other error output. */
1404 eitem = xmalloc (sizeof *eitem + strlen (p));
1405 eitem->next = NULL;
1406 strcpy (eitem->buffer, p);
1407 eitem->fname = NULL;
1408 eitem->errtext = eitem->buffer;
1409 eitem->lineno = 0;
1410 *errlines_tail = eitem;
1411 errlines_tail = &eitem->next;
1414 pos = 0;
1415 /* If this was not a complete line mark that we are in a
1416 continuation. */
1417 cont_line = (c != '\n');
1421 /* We ignore error lines not terminated by a LF. */
1423 fclose (fp);
1424 return errlines;
1428 /* Check the options of a single component. Returns 0 if everything
1429 is OK. */
1431 gc_component_check_options (int component, FILE *out, const char *conf_file)
1433 gpg_error_t err;
1434 unsigned int result;
1435 int backend_seen[GC_BACKEND_NR];
1436 gc_backend_t backend;
1437 gc_option_t *option;
1438 const char *pgmname;
1439 const char *argv[4];
1440 int i;
1441 pid_t pid;
1442 int exitcode;
1443 int filedes[2];
1444 error_line_t errlines;
1446 /* We use a temporary file to collect the error output. It would be
1447 better to use a pipe here but as of now we have no suitable
1448 fucntion to create a portable pipe outside of exechelp. Thus it
1449 is easier to use the tempfile approach. */
1451 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1452 backend_seen[backend] = 0;
1454 option = gc_component[component].options;
1455 for (; option && option->name; option++)
1457 if ((option->flags & GC_OPT_FLAG_GROUP))
1458 continue;
1459 backend = option->backend;
1460 if (backend_seen[backend])
1461 continue;
1462 backend_seen[backend] = 1;
1463 assert (backend != GC_BACKEND_ANY);
1464 if (!gc_backend[backend].program)
1465 continue;
1466 if (!gc_backend[backend].module_name)
1467 continue;
1469 break;
1471 if (! option || ! option->name)
1472 return 0;
1474 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1475 i = 0;
1476 if (conf_file)
1478 argv[i++] = "--options";
1479 argv[i++] = conf_file;
1481 argv[i++] = "--gpgconf-test";
1482 argv[i++] = NULL;
1484 err = gnupg_create_inbound_pipe (filedes);
1485 if (err)
1486 gc_error (1, 0, _("error creating a pipe: %s\n"),
1487 gpg_strerror (err));
1489 result = 0;
1490 errlines = NULL;
1491 if (gnupg_spawn_process_fd (pgmname, argv, -1, -1, filedes[1], &pid))
1493 close (filedes[0]);
1494 close (filedes[1]);
1495 result |= 1; /* Program could not be run. */
1497 else
1499 close (filedes[1]);
1500 errlines = collect_error_output (filedes[0],
1501 gc_component[component].name);
1502 if (gnupg_wait_process (pgmname, pid, &exitcode))
1504 if (exitcode == -1)
1505 result |= 1; /* Program could not be run or it
1506 terminated abnormally. */
1507 result |= 2; /* Program returned an error. */
1511 /* If the program could not be run, we can't tell whether
1512 the config file is good. */
1513 if (result & 1)
1514 result |= 2;
1516 if (out)
1518 const char *desc;
1519 error_line_t errptr;
1521 desc = gc_component[component].desc;
1522 desc = my_dgettext (gc_component[component].desc_domain, desc);
1523 fprintf (out, "%s:%s:",
1524 gc_component[component].name, gc_percent_escape (desc));
1525 fputs (gc_percent_escape (pgmname), out);
1526 fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
1527 for (errptr = errlines; errptr; errptr = errptr->next)
1529 if (errptr != errlines)
1530 fputs ("\n:::::", out); /* Continuation line. */
1531 if (errptr->fname)
1532 fputs (gc_percent_escape (errptr->fname), out);
1533 putc (':', out);
1534 if (errptr->fname)
1535 fprintf (out, "%u", errptr->lineno);
1536 putc (':', out);
1537 fputs (gc_percent_escape (errptr->errtext), out);
1538 putc (':', out);
1540 putc ('\n', out);
1543 while (errlines)
1545 error_line_t tmp = errlines->next;
1546 xfree (errlines);
1547 errlines = tmp;
1550 return result;
1554 /* Check all components that are available. */
1555 void
1556 gc_check_programs (FILE *out)
1558 gc_component_t component;
1560 for (component = 0; component < GC_COMPONENT_NR; component++)
1561 gc_component_check_options (component, out, NULL);
1566 /* Find the component with the name NAME. Returns -1 if not
1567 found. */
1569 gc_component_find (const char *name)
1571 gc_component_t idx;
1573 for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1575 if (gc_component[idx].options
1576 && !strcmp (name, gc_component[idx].name))
1577 return idx;
1579 return -1;
1583 /* List the option OPTION. */
1584 static void
1585 list_one_option (const gc_option_t *option, FILE *out)
1587 const char *desc = NULL;
1588 char *arg_name = NULL;
1590 if (option->desc)
1592 desc = my_dgettext (option->desc_domain, option->desc);
1594 if (*desc == '|')
1596 const char *arg_tail = strchr (&desc[1], '|');
1598 if (arg_tail)
1600 int arg_len = arg_tail - &desc[1];
1601 arg_name = xmalloc (arg_len + 1);
1602 memcpy (arg_name, &desc[1], arg_len);
1603 arg_name[arg_len] = '\0';
1604 desc = arg_tail + 1;
1610 /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1611 PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY
1612 FIELDS. */
1614 /* The name field. */
1615 fprintf (out, "%s", option->name);
1617 /* The flags field. */
1618 fprintf (out, ":%lu", option->flags);
1619 if (opt.verbose)
1621 putc (' ', out);
1623 if (!option->flags)
1624 fprintf (out, "none");
1625 else
1627 unsigned long flags = option->flags;
1628 unsigned long flag = 0;
1629 unsigned long first = 1;
1631 while (flags)
1633 if (flags & 1)
1635 if (first)
1636 first = 0;
1637 else
1638 putc (',', out);
1639 fprintf (out, "%s", gc_flag[flag].name);
1641 flags >>= 1;
1642 flag++;
1647 /* The level field. */
1648 fprintf (out, ":%u", option->level);
1649 if (opt.verbose)
1650 fprintf (out, " %s", gc_level[option->level].name);
1652 /* The description field. */
1653 fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
1655 /* The type field. */
1656 fprintf (out, ":%u", option->arg_type);
1657 if (opt.verbose)
1658 fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1660 /* The alternate type field. */
1661 fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1662 if (opt.verbose)
1663 fprintf (out, " %s",
1664 gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1666 /* The argument name field. */
1667 fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
1668 if (arg_name)
1669 xfree (arg_name);
1671 /* The default value field. */
1672 fprintf (out, ":%s", option->default_value ? option->default_value : "");
1674 /* The default argument field. */
1675 fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1677 /* The value field. */
1678 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1679 && (option->flags & GC_OPT_FLAG_LIST)
1680 && option->value)
1681 /* The special format "1,1,1,1,...,1" is converted to a number
1682 here. */
1683 fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1684 else
1685 fprintf (out, ":%s", option->value ? option->value : "");
1687 /* ADD NEW FIELDS HERE. */
1689 putc ('\n', out);
1693 /* List all options of the component COMPONENT. */
1694 void
1695 gc_component_list_options (int component, FILE *out)
1697 const gc_option_t *option = gc_component[component].options;
1699 while (option && option->name)
1701 /* Do not output unknown or internal options. */
1702 if (!(option->flags & GC_OPT_FLAG_GROUP)
1703 && (!option->active || option->level == GC_LEVEL_INTERNAL))
1705 option++;
1706 continue;
1709 if (option->flags & GC_OPT_FLAG_GROUP)
1711 const gc_option_t *group_option = option + 1;
1712 gc_expert_level_t level = GC_LEVEL_NR;
1714 /* The manual states that the group level is always the
1715 minimum of the levels of all contained options. Due to
1716 different active options, and because it is hard to
1717 maintain manually, we calculate it here. The value in
1718 the global static table is ignored. */
1720 while (group_option->name)
1722 if (group_option->flags & GC_OPT_FLAG_GROUP)
1723 break;
1724 if (group_option->level < level)
1725 level = group_option->level;
1726 group_option++;
1729 /* Check if group is empty. */
1730 if (level != GC_LEVEL_NR)
1732 gc_option_t opt_copy;
1734 /* Fix up the group level. */
1735 memcpy (&opt_copy, option, sizeof (opt_copy));
1736 opt_copy.level = level;
1737 list_one_option (&opt_copy, out);
1740 else
1741 list_one_option (option, out);
1743 option++;
1748 /* Find the option NAME in component COMPONENT, for the backend
1749 BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */
1750 static gc_option_t *
1751 find_option (gc_component_t component, const char *name,
1752 gc_backend_t backend)
1754 gc_option_t *option = gc_component[component].options;
1755 while (option->name)
1757 if (!(option->flags & GC_OPT_FLAG_GROUP)
1758 && !strcmp (option->name, name)
1759 && (backend == GC_BACKEND_ANY || option->backend == backend))
1760 break;
1761 option++;
1763 return option->name ? option : NULL;
1767 /* Determine the configuration filename for the component COMPONENT
1768 and backend BACKEND. */
1769 static char *
1770 get_config_filename (gc_component_t component, gc_backend_t backend)
1772 char *filename = NULL;
1773 gc_option_t *option = find_option
1774 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
1775 assert (option);
1776 assert (option->arg_type == GC_ARG_TYPE_FILENAME);
1777 assert (!(option->flags & GC_OPT_FLAG_LIST));
1779 if (!option->active || !option->default_value)
1780 gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
1781 gc_backend[backend].option_config_filename,
1782 gc_backend[backend].name);
1784 if (option->value && *option->value)
1785 filename = percent_deescape (&option->value[1]);
1786 else if (option->default_value && *option->default_value)
1787 filename = percent_deescape (&option->default_value[1]);
1788 else
1789 filename = "";
1791 #ifdef HAVE_DOSISH_SYSTEM
1792 if (!(filename[0]
1793 && filename[1] == ':'
1794 && (filename[2] == '/' || filename[2] == '\\')))
1795 #else
1796 if (filename[0] != '/')
1797 #endif
1798 gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
1799 gc_backend[backend].option_config_filename,
1800 gc_backend[backend].name);
1802 return filename;
1806 /* Retrieve the options for the component COMPONENT from backend
1807 BACKEND, which we already know is a program-type backend. */
1808 static void
1809 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
1811 gpg_error_t err;
1812 int filedes[2];
1813 const char *pgmname;
1814 const char *argv[2];
1815 int exitcode;
1816 pid_t pid;
1817 char *line = NULL;
1818 size_t line_len = 0;
1819 ssize_t length;
1820 FILE *config;
1821 char *config_filename;
1823 err = gnupg_create_inbound_pipe (filedes);
1824 if (err)
1825 gc_error (1, 0, _("error creating a pipe: %s\n"), gpg_strerror (err));
1827 pgmname = (gc_backend[backend].module_name
1828 ? gnupg_module_name (gc_backend[backend].module_name)
1829 : gc_backend[backend].program );
1830 argv[0] = "--gpgconf-list";
1831 argv[1] = NULL;
1833 err = gnupg_spawn_process_fd (pgmname, argv, -1, filedes[1], -1, &pid);
1834 if (err)
1836 close (filedes[0]);
1837 close (filedes[1]);
1838 gc_error (1, 0, "could not gather active options from `%s': %s",
1839 pgmname, gpg_strerror (err));
1841 close (filedes[1]);
1842 config = fdopen (filedes[0], "r");
1843 if (!config)
1844 gc_error (1, errno, "can't fdopen pipe for reading");
1846 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1848 gc_option_t *option;
1849 char *linep;
1850 unsigned long flags = 0;
1851 char *default_value = NULL;
1853 /* Strip newline and carriage return, if present. */
1854 while (length > 0
1855 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1856 line[--length] = '\0';
1858 linep = strchr (line, ':');
1859 if (linep)
1860 *(linep++) = '\0';
1862 /* Extract additional flags. Default to none. */
1863 if (linep)
1865 char *end;
1866 char *tail;
1868 end = strchr (linep, ':');
1869 if (end)
1870 *(end++) = '\0';
1872 errno = 0;
1873 flags = strtoul (linep, &tail, 0);
1874 if (errno)
1875 gc_error (1, errno, "malformed flags in option %s from %s",
1876 line, pgmname);
1877 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1878 gc_error (1, 0, "garbage after flags in option %s from %s",
1879 line, pgmname);
1881 linep = end;
1884 /* Extract default value, if present. Default to empty if
1885 not. */
1886 if (linep)
1888 char *end;
1890 end = strchr (linep, ':');
1891 if (end)
1892 *(end++) = '\0';
1894 if (flags & GC_OPT_FLAG_DEFAULT)
1895 default_value = linep;
1897 linep = end;
1900 /* Look up the option in the component and install the
1901 configuration data. */
1902 option = find_option (component, line, backend);
1903 if (option)
1905 if (option->active)
1906 gc_error (1, errno, "option %s returned twice from %s",
1907 line, pgmname);
1908 option->active = 1;
1910 option->flags |= flags;
1911 if (default_value && *default_value)
1912 option->default_value = xstrdup (default_value);
1915 if (length < 0 || ferror (config))
1916 gc_error (1, errno, "error reading from %s",pgmname);
1917 if (fclose (config) && ferror (config))
1918 gc_error (1, errno, "error closing %s", pgmname);
1920 err = gnupg_wait_process (pgmname, pid, &exitcode);
1921 if (err)
1922 gc_error (1, 0, "running %s failed (exitcode=%d): %s",
1923 pgmname, exitcode, gpg_strerror (err));
1926 /* At this point, we can parse the configuration file. */
1927 config_filename = get_config_filename (component, backend);
1929 config = fopen (config_filename, "r");
1930 if (!config)
1931 gc_error (0, errno, "warning: can not open config file %s",
1932 config_filename);
1933 else
1935 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1937 char *name;
1938 char *value;
1939 gc_option_t *option;
1941 name = line;
1942 while (*name == ' ' || *name == '\t')
1943 name++;
1944 if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1945 continue;
1947 value = name;
1948 while (*value && *value != ' ' && *value != '\t'
1949 && *value != '#' && *value != '\r' && *value != '\n')
1950 value++;
1951 if (*value == ' ' || *value == '\t')
1953 char *end;
1955 *(value++) = '\0';
1956 while (*value == ' ' || *value == '\t')
1957 value++;
1959 end = value;
1960 while (*end && *end != '#' && *end != '\r' && *end != '\n')
1961 end++;
1962 while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1963 end--;
1964 *end = '\0';
1966 else
1967 *value = '\0';
1969 /* Look up the option in the component and install the
1970 configuration data. */
1971 option = find_option (component, line, backend);
1972 if (option)
1974 char *opt_value;
1976 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1978 if (*value)
1979 gc_error (0, 0,
1980 "warning: ignoring argument %s for option %s",
1981 value, name);
1982 opt_value = xstrdup ("1");
1984 else if (gc_arg_type[option->arg_type].fallback
1985 == GC_ARG_TYPE_STRING)
1986 opt_value = xasprintf ("\"%s", gc_percent_escape (value));
1987 else
1989 /* FIXME: Verify that the number is sane. */
1990 opt_value = xstrdup (value);
1993 /* Now enter the option into the table. */
1994 if (!(option->flags & GC_OPT_FLAG_LIST))
1996 if (option->value)
1997 free (option->value);
1998 option->value = opt_value;
2000 else
2002 if (!option->value)
2003 option->value = opt_value;
2004 else
2006 char *opt_val = opt_value;
2008 option->value = xasprintf ("%s,%s", option->value,
2009 opt_val);
2010 xfree (opt_value);
2016 if (length < 0 || ferror (config))
2017 gc_error (1, errno, "error reading from %s", config_filename);
2018 if (fclose (config) && ferror (config))
2019 gc_error (1, errno, "error closing %s", config_filename);
2022 xfree (line);
2026 /* Retrieve the options for the component COMPONENT from backend
2027 BACKEND, which we already know is of type file list. */
2028 static void
2029 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
2031 gc_option_t *list_option;
2032 gc_option_t *config_option;
2033 char *list_filename;
2034 FILE *list_file;
2035 char *line = NULL;
2036 size_t line_len = 0;
2037 ssize_t length;
2038 char *list = NULL;
2040 list_option = find_option (component,
2041 gc_backend[backend].option_name, GC_BACKEND_ANY);
2042 assert (list_option);
2043 assert (!list_option->active);
2045 list_filename = get_config_filename (component, backend);
2046 list_file = fopen (list_filename, "r");
2047 if (!list_file)
2048 gc_error (0, errno, "warning: can not open list file %s", list_filename);
2049 else
2052 while ((length = read_line (list_file, &line, &line_len, NULL)) > 0)
2054 char *start;
2055 char *end;
2056 char *new_list;
2058 start = line;
2059 while (*start == ' ' || *start == '\t')
2060 start++;
2061 if (!*start || *start == '#' || *start == '\r' || *start == '\n')
2062 continue;
2064 end = start;
2065 while (*end && *end != '#' && *end != '\r' && *end != '\n')
2066 end++;
2067 /* Walk back to skip trailing white spaces. Looks evil, but
2068 works because of the conditions on START and END imposed
2069 at this point (END is at least START + 1, and START is
2070 not a whitespace character). */
2071 while (*(end - 1) == ' ' || *(end - 1) == '\t')
2072 end--;
2073 *end = '\0';
2074 /* FIXME: Oh, no! This is so lame! Should use realloc and
2075 really append. */
2076 if (list)
2078 new_list = xasprintf ("%s,\"%s", list, gc_percent_escape (start));
2079 xfree (list);
2080 list = new_list;
2082 else
2083 list = xasprintf ("\"%s", gc_percent_escape (start));
2085 if (length < 0 || ferror (list_file))
2086 gc_error (1, errno, "can not read list file %s", list_filename);
2089 list_option->active = 1;
2090 list_option->value = list;
2092 /* Fix up the read-only flag. */
2093 config_option = find_option
2094 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
2095 if (config_option->flags & GC_OPT_FLAG_NO_CHANGE)
2096 list_option->flags |= GC_OPT_FLAG_NO_CHANGE;
2098 if (list_file && fclose (list_file) && ferror (list_file))
2099 gc_error (1, errno, "error closing %s", list_filename);
2100 xfree (line);
2104 /* Retrieve the currently active options and their defaults from all
2105 involved backends for this component. Using -1 for component will
2106 retrieve all options from all components. */
2107 void
2108 gc_component_retrieve_options (int component)
2110 int process_all = 0;
2111 int backend_seen[GC_BACKEND_NR];
2112 gc_backend_t backend;
2113 gc_option_t *option;
2115 for (backend = 0; backend < GC_BACKEND_NR; backend++)
2116 backend_seen[backend] = 0;
2118 if (component == -1)
2120 process_all = 1;
2121 component = 0;
2122 assert (component < GC_COMPONENT_NR);
2127 option = gc_component[component].options;
2129 while (option && option->name)
2131 if (!(option->flags & GC_OPT_FLAG_GROUP))
2133 backend = option->backend;
2135 if (backend_seen[backend])
2137 option++;
2138 continue;
2140 backend_seen[backend] = 1;
2142 assert (backend != GC_BACKEND_ANY);
2144 if (gc_backend[backend].program)
2145 retrieve_options_from_program (component, backend);
2146 else
2147 retrieve_options_from_file (component, backend);
2149 option++;
2152 while (process_all && ++component < GC_COMPONENT_NR);
2158 /* Perform a simple validity check based on the type. Return in
2159 NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
2160 type GC_ARG_TYPE_NONE. */
2161 static void
2162 option_check_validity (gc_option_t *option, unsigned long flags,
2163 char *new_value, unsigned long *new_value_nr)
2165 char *arg;
2167 if (!option->active)
2168 gc_error (1, 0, "option %s not supported by backend %s",
2169 option->name, gc_backend[option->backend].name);
2171 if (option->new_flags || option->new_value)
2172 gc_error (1, 0, "option %s already changed", option->name);
2174 if (flags & GC_OPT_FLAG_DEFAULT)
2176 if (*new_value)
2177 gc_error (1, 0, "argument %s provided for deleted option %s",
2178 new_value, option->name);
2180 return;
2183 /* GC_ARG_TYPE_NONE options have special list treatment. */
2184 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2186 char *tail;
2188 errno = 0;
2189 *new_value_nr = strtoul (new_value, &tail, 0);
2191 if (errno)
2192 gc_error (1, errno, "invalid argument for option %s",
2193 option->name);
2194 if (*tail)
2195 gc_error (1, 0, "garbage after argument for option %s",
2196 option->name);
2198 if (!(option->flags & GC_OPT_FLAG_LIST))
2200 if (*new_value_nr != 1)
2201 gc_error (1, 0, "argument for non-list option %s of type 0 "
2202 "(none) must be 1", option->name);
2204 else
2206 if (*new_value_nr == 0)
2207 gc_error (1, 0, "argument for option %s of type 0 (none) "
2208 "must be positive", option->name);
2211 return;
2214 arg = new_value;
2217 if (*arg == '\0' || *arg == ',')
2219 if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
2220 gc_error (1, 0, "argument required for option %s", option->name);
2222 if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
2223 gc_error (1, 0, "list found for non-list option %s", option->name);
2225 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
2227 if (*arg != '"')
2228 gc_error (1, 0, "string argument for option %s must begin "
2229 "with a quote (\") character", option->name);
2231 /* FIXME: We do not allow empty string arguments for now, as
2232 we do not quote arguments in configuration files, and
2233 thus no argument is indistinguishable from the empty
2234 string. */
2235 if (arg[1] == '\0' || arg[1] == ',')
2236 gc_error (1, 0, "empty string argument for option %s is "
2237 "currently not allowed. Please report this!",
2238 option->name);
2240 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2242 errno = 0;
2243 (void) strtol (arg, &arg, 0);
2245 if (errno)
2246 gc_error (1, errno, "invalid argument for option %s",
2247 option->name);
2249 if (*arg != '\0' && *arg != ',')
2250 gc_error (1, 0, "garbage after argument for option %s",
2251 option->name);
2253 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2255 errno = 0;
2256 (void) strtoul (arg, &arg, 0);
2258 if (errno)
2259 gc_error (1, errno, "invalid argument for option %s",
2260 option->name);
2262 if (*arg != '\0' && *arg != ',')
2263 gc_error (1, 0, "garbage after argument for option %s",
2264 option->name);
2266 arg = strchr (arg, ',');
2267 if (arg)
2268 arg++;
2270 while (arg && *arg);
2273 #ifdef HAVE_W32_SYSTEM
2275 copy_file (const char *src_name, const char *dst_name)
2277 #define BUF_LEN 4096
2278 char buffer[BUF_LEN];
2279 int len;
2280 FILE *src;
2281 FILE *dst;
2283 src = fopen (src_name, "r");
2284 if (src == NULL)
2285 return -1;
2287 dst = fopen (dst_name, "w");
2288 if (dst == NULL)
2290 int saved_err = errno;
2291 fclose (src);
2292 errno = saved_err;
2293 return -1;
2298 int written;
2300 len = fread (buffer, 1, BUF_LEN, src);
2301 if (len == 0)
2302 break;
2303 written = fwrite (buffer, 1, len, dst);
2304 if (written != len)
2305 break;
2307 while (!feof (src) && !ferror (src) && !ferror (dst));
2309 if (ferror (src) || ferror (dst) || !feof (src))
2311 int saved_errno = errno;
2312 fclose (src);
2313 fclose (dst);
2314 unlink (dst_name);
2315 errno = saved_errno;
2316 return -1;
2319 if (fclose (dst) && ferror (dst))
2320 gc_error (1, errno, "error closing %s", dst_name);
2321 if (fclose (src) && ferror (src))
2322 gc_error (1, errno, "error closing %s", src_name);
2324 return 0;
2326 #endif /* HAVE_W32_SYSTEM */
2329 /* Create and verify the new configuration file for the specified
2330 backend and component. Returns 0 on success and -1 on error. */
2331 static int
2332 change_options_file (gc_component_t component, gc_backend_t backend,
2333 char **src_filenamep, char **dest_filenamep,
2334 char **orig_filenamep)
2336 static const char marker[] = "###+++--- GPGConf ---+++###";
2337 /* True if we are within the marker in the config file. */
2338 int in_marker = 0;
2339 gc_option_t *option;
2340 char *line = NULL;
2341 size_t line_len;
2342 ssize_t length;
2343 int res;
2344 int fd;
2345 FILE *src_file = NULL;
2346 FILE *dest_file = NULL;
2347 char *src_filename;
2348 char *dest_filename;
2349 char *orig_filename;
2350 char *arg;
2351 char *cur_arg = NULL;
2353 option = find_option (component,
2354 gc_backend[backend].option_name, GC_BACKEND_ANY);
2355 assert (option);
2356 assert (option->active);
2357 assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
2359 /* FIXME. Throughout the function, do better error reporting. */
2360 /* Note that get_config_filename() calls percent_deescape(), so we
2361 call this before processing the arguments. */
2362 dest_filename = xstrdup (get_config_filename (component, backend));
2363 src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2364 orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2366 arg = option->new_value;
2367 if (arg && arg[0] == '\0')
2368 arg = NULL;
2369 else if (arg)
2371 char *end;
2373 arg++;
2374 end = strchr (arg, ',');
2375 if (end)
2376 *end = '\0';
2378 cur_arg = percent_deescape (arg);
2379 if (end)
2381 *end = ',';
2382 arg = end + 1;
2384 else
2385 arg = NULL;
2388 #ifdef HAVE_W32_SYSTEM
2389 res = copy_file (dest_filename, orig_filename);
2390 #else
2391 res = link (dest_filename, orig_filename);
2392 #endif
2393 if (res < 0 && errno != ENOENT)
2394 return -1;
2395 if (res < 0)
2397 xfree (orig_filename);
2398 orig_filename = NULL;
2401 /* We now initialize the return strings, so the caller can do the
2402 cleanup for us. */
2403 *src_filenamep = src_filename;
2404 *dest_filenamep = dest_filename;
2405 *orig_filenamep = orig_filename;
2407 /* Use open() so that we can use O_EXCL. */
2408 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2409 if (fd < 0)
2410 return -1;
2411 src_file = fdopen (fd, "w");
2412 res = errno;
2413 if (!src_file)
2415 errno = res;
2416 return -1;
2419 /* Only if ORIG_FILENAME is not NULL did the configuration file
2420 exist already. In this case, we will copy its content into the
2421 new configuration file, changing it to our liking in the
2422 process. */
2423 if (orig_filename)
2425 dest_file = fopen (dest_filename, "r");
2426 if (!dest_file)
2427 goto change_file_one_err;
2429 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2431 int disable = 0;
2432 char *start;
2434 if (!strncmp (marker, line, sizeof (marker) - 1))
2436 if (!in_marker)
2437 in_marker = 1;
2438 else
2439 break;
2442 start = line;
2443 while (*start == ' ' || *start == '\t')
2444 start++;
2445 if (*start && *start != '\r' && *start != '\n' && *start != '#')
2447 char *end;
2448 char *endp;
2449 char saved_end;
2451 endp = start;
2452 end = endp;
2454 /* Search for the end of the line. */
2455 while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
2457 endp++;
2458 if (*endp && *endp != ' ' && *endp != '\t'
2459 && *endp != '\r' && *endp != '\n' && *endp != '#')
2460 end = endp + 1;
2462 saved_end = *end;
2463 *end = '\0';
2465 if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2466 || !cur_arg || strcmp (start, cur_arg))
2467 disable = 1;
2468 else
2470 /* Find next argument. */
2471 if (arg)
2473 char *arg_end;
2475 arg++;
2476 arg_end = strchr (arg, ',');
2477 if (arg_end)
2478 *arg_end = '\0';
2480 cur_arg = percent_deescape (arg);
2481 if (arg_end)
2483 *arg_end = ',';
2484 arg = arg_end + 1;
2486 else
2487 arg = NULL;
2489 else
2490 cur_arg = NULL;
2493 *end = saved_end;
2496 if (disable)
2498 if (!in_marker)
2500 fprintf (src_file,
2501 "# GPGConf disabled this option here at %s\n",
2502 asctimestamp (gnupg_get_time ()));
2503 if (ferror (src_file))
2504 goto change_file_one_err;
2505 fprintf (src_file, "# %s", line);
2506 if (ferror (src_file))
2507 goto change_file_one_err;
2510 else
2512 fprintf (src_file, "%s", line);
2513 if (ferror (src_file))
2514 goto change_file_one_err;
2517 if (length < 0 || ferror (dest_file))
2518 goto change_file_one_err;
2521 if (!in_marker)
2523 /* There was no marker. This is the first time we edit the
2524 file. We add our own marker at the end of the file and
2525 proceed. Note that we first write a newline, this guards us
2526 against files which lack the newline at the end of the last
2527 line, while it doesn't hurt us in all other cases. */
2528 fprintf (src_file, "\n%s\n", marker);
2529 if (ferror (src_file))
2530 goto change_file_one_err;
2533 /* At this point, we have copied everything up to the end marker
2534 into the new file, except for the arguments we are going to add.
2535 Now, dump the new arguments and write the end marker, possibly
2536 followed by the rest of the original file. */
2537 while (cur_arg)
2539 fprintf (src_file, "%s\n", cur_arg);
2541 /* Find next argument. */
2542 if (arg)
2544 char *end;
2546 arg++;
2547 end = strchr (arg, ',');
2548 if (end)
2549 *end = '\0';
2551 cur_arg = percent_deescape (arg);
2552 if (end)
2554 *end = ',';
2555 arg = end + 1;
2557 else
2558 arg = NULL;
2560 else
2561 cur_arg = NULL;
2564 fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2565 if (ferror (src_file))
2566 goto change_file_one_err;
2568 if (!in_marker)
2570 fprintf (src_file, "# GPGConf edited this configuration file.\n");
2571 if (ferror (src_file))
2572 goto change_file_one_err;
2573 fprintf (src_file, "# It will disable options before this marked "
2574 "block, but it will\n");
2575 if (ferror (src_file))
2576 goto change_file_one_err;
2577 fprintf (src_file, "# never change anything below these lines.\n");
2578 if (ferror (src_file))
2579 goto change_file_one_err;
2581 if (dest_file)
2583 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2585 fprintf (src_file, "%s", line);
2586 if (ferror (src_file))
2587 goto change_file_one_err;
2589 if (length < 0 || ferror (dest_file))
2590 goto change_file_one_err;
2592 xfree (line);
2593 line = NULL;
2595 res = fclose (src_file);
2596 if (res)
2598 res = errno;
2599 close (fd);
2600 if (dest_file)
2601 fclose (dest_file);
2602 errno = res;
2603 return -1;
2605 close (fd);
2606 if (dest_file)
2608 res = fclose (dest_file);
2609 if (res)
2610 return -1;
2612 return 0;
2614 change_file_one_err:
2615 xfree (line);
2616 res = errno;
2617 if (src_file)
2619 fclose (src_file);
2620 close (fd);
2622 if (dest_file)
2623 fclose (dest_file);
2624 errno = res;
2625 return -1;
2629 /* Create and verify the new configuration file for the specified
2630 backend and component. Returns 0 on success and -1 on error. */
2631 static int
2632 change_options_program (gc_component_t component, gc_backend_t backend,
2633 char **src_filenamep, char **dest_filenamep,
2634 char **orig_filenamep)
2636 static const char marker[] = "###+++--- GPGConf ---+++###";
2637 /* True if we are within the marker in the config file. */
2638 int in_marker = 0;
2639 gc_option_t *option;
2640 char *line = NULL;
2641 size_t line_len;
2642 ssize_t length;
2643 int res;
2644 int fd;
2645 FILE *src_file = NULL;
2646 FILE *dest_file = NULL;
2647 char *src_filename;
2648 char *dest_filename;
2649 char *orig_filename;
2650 /* Special hack for gpg, see below. */
2651 int utf8strings_seen = 0;
2653 /* FIXME. Throughout the function, do better error reporting. */
2654 dest_filename = xstrdup (get_config_filename (component, backend));
2655 src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2656 orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2658 #ifdef HAVE_W32_SYSTEM
2659 res = copy_file (dest_filename, orig_filename);
2660 #else
2661 res = link (dest_filename, orig_filename);
2662 #endif
2663 if (res < 0 && errno != ENOENT)
2664 return -1;
2665 if (res < 0)
2667 xfree (orig_filename);
2668 orig_filename = NULL;
2671 /* We now initialize the return strings, so the caller can do the
2672 cleanup for us. */
2673 *src_filenamep = src_filename;
2674 *dest_filenamep = dest_filename;
2675 *orig_filenamep = orig_filename;
2677 /* Use open() so that we can use O_EXCL. */
2678 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2679 if (fd < 0)
2680 return -1;
2681 src_file = fdopen (fd, "w");
2682 res = errno;
2683 if (!src_file)
2685 errno = res;
2686 return -1;
2689 /* Only if ORIG_FILENAME is not NULL did the configuration file
2690 exist already. In this case, we will copy its content into the
2691 new configuration file, changing it to our liking in the
2692 process. */
2693 if (orig_filename)
2695 dest_file = fopen (dest_filename, "r");
2696 if (!dest_file)
2697 goto change_one_err;
2699 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2701 int disable = 0;
2702 char *start;
2704 if (!strncmp (marker, line, sizeof (marker) - 1))
2706 if (!in_marker)
2707 in_marker = 1;
2708 else
2709 break;
2711 else if (backend == GC_BACKEND_GPG && in_marker
2712 && ! strcmp ("utf8-strings\n", line))
2714 /* Strip duplicated entries. */
2715 if (utf8strings_seen)
2716 disable = 1;
2717 else
2718 utf8strings_seen = 1;
2721 start = line;
2722 while (*start == ' ' || *start == '\t')
2723 start++;
2724 if (*start && *start != '\r' && *start != '\n' && *start != '#')
2726 char *end;
2727 char saved_end;
2729 end = start;
2730 while (*end && *end != ' ' && *end != '\t'
2731 && *end != '\r' && *end != '\n' && *end != '#')
2732 end++;
2733 saved_end = *end;
2734 *end = '\0';
2736 option = find_option (component, start, backend);
2737 *end = saved_end;
2738 if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2739 || option->new_value))
2740 disable = 1;
2742 if (disable)
2744 if (!in_marker)
2746 fprintf (src_file,
2747 "# GPGConf disabled this option here at %s\n",
2748 asctimestamp (gnupg_get_time ()));
2749 if (ferror (src_file))
2750 goto change_one_err;
2751 fprintf (src_file, "# %s", line);
2752 if (ferror (src_file))
2753 goto change_one_err;
2756 else
2758 fprintf (src_file, "%s", line);
2759 if (ferror (src_file))
2760 goto change_one_err;
2763 if (length < 0 || ferror (dest_file))
2764 goto change_one_err;
2767 if (!in_marker)
2769 /* There was no marker. This is the first time we edit the
2770 file. We add our own marker at the end of the file and
2771 proceed. Note that we first write a newline, this guards us
2772 against files which lack the newline at the end of the last
2773 line, while it doesn't hurt us in all other cases. */
2774 fprintf (src_file, "\n%s\n", marker);
2775 if (ferror (src_file))
2776 goto change_one_err;
2778 /* At this point, we have copied everything up to the end marker
2779 into the new file, except for the options we are going to change.
2780 Now, dump the changed options (except for those we are going to
2781 revert to their default), and write the end marker, possibly
2782 followed by the rest of the original file. */
2784 /* We have to turn on UTF8 strings for GnuPG. */
2785 if (backend == GC_BACKEND_GPG && ! utf8strings_seen)
2786 fprintf (src_file, "utf8-strings\n");
2788 option = gc_component[component].options;
2789 while (option->name)
2791 if (!(option->flags & GC_OPT_FLAG_GROUP)
2792 && option->backend == backend
2793 && option->new_value)
2795 char *arg = option->new_value;
2799 if (*arg == '\0' || *arg == ',')
2801 fprintf (src_file, "%s\n", option->name);
2802 if (ferror (src_file))
2803 goto change_one_err;
2805 else if (gc_arg_type[option->arg_type].fallback
2806 == GC_ARG_TYPE_NONE)
2808 assert (*arg == '1');
2809 fprintf (src_file, "%s\n", option->name);
2810 if (ferror (src_file))
2811 goto change_one_err;
2813 arg++;
2815 else if (gc_arg_type[option->arg_type].fallback
2816 == GC_ARG_TYPE_STRING)
2818 char *end;
2820 assert (*arg == '"');
2821 arg++;
2823 end = strchr (arg, ',');
2824 if (end)
2825 *end = '\0';
2827 fprintf (src_file, "%s %s\n", option->name,
2828 percent_deescape (arg));
2829 if (ferror (src_file))
2830 goto change_one_err;
2832 if (end)
2833 *end = ',';
2834 arg = end;
2836 else
2838 char *end;
2840 end = strchr (arg, ',');
2841 if (end)
2842 *end = '\0';
2844 fprintf (src_file, "%s %s\n", option->name, arg);
2845 if (ferror (src_file))
2846 goto change_one_err;
2848 if (end)
2849 *end = ',';
2850 arg = end;
2853 assert (arg == NULL || *arg == '\0' || *arg == ',');
2854 if (arg && *arg == ',')
2855 arg++;
2857 while (arg && *arg);
2859 option++;
2862 fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2863 if (ferror (src_file))
2864 goto change_one_err;
2866 if (!in_marker)
2868 fprintf (src_file, "# GPGConf edited this configuration file.\n");
2869 if (ferror (src_file))
2870 goto change_one_err;
2871 fprintf (src_file, "# It will disable options before this marked "
2872 "block, but it will\n");
2873 if (ferror (src_file))
2874 goto change_one_err;
2875 fprintf (src_file, "# never change anything below these lines.\n");
2876 if (ferror (src_file))
2877 goto change_one_err;
2879 if (dest_file)
2881 while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2883 fprintf (src_file, "%s", line);
2884 if (ferror (src_file))
2885 goto change_one_err;
2887 if (length < 0 || ferror (dest_file))
2888 goto change_one_err;
2890 xfree (line);
2891 line = NULL;
2893 res = fclose (src_file);
2894 if (res)
2896 res = errno;
2897 close (fd);
2898 if (dest_file)
2899 fclose (dest_file);
2900 errno = res;
2901 return -1;
2903 close (fd);
2904 if (dest_file)
2906 res = fclose (dest_file);
2907 if (res)
2908 return -1;
2910 return 0;
2912 change_one_err:
2913 xfree (line);
2914 res = errno;
2915 if (src_file)
2917 fclose (src_file);
2918 close (fd);
2920 if (dest_file)
2921 fclose (dest_file);
2922 errno = res;
2923 return -1;
2927 /* Common code for gc_component_change_options and
2928 gc_process_gpgconf_conf. */
2929 static void
2930 change_one_value (gc_option_t *option, int *runtime,
2931 unsigned long flags, char *new_value)
2933 unsigned long new_value_nr = 0;
2935 option_check_validity (option, flags, new_value, &new_value_nr);
2937 if (option->flags & GC_OPT_FLAG_RUNTIME)
2938 runtime[option->backend] = 1;
2940 option->new_flags = flags;
2941 if (!(flags & GC_OPT_FLAG_DEFAULT))
2943 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2944 && (option->flags & GC_OPT_FLAG_LIST))
2946 char *str;
2948 /* We convert the number to a list of 1's for convenient
2949 list handling. */
2950 assert (new_value_nr > 0);
2951 option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2952 str = option->new_value;
2953 *(str++) = '1';
2954 while (--new_value_nr > 0)
2956 *(str++) = ',';
2957 *(str++) = '1';
2959 *(str++) = '\0';
2961 else
2962 option->new_value = xstrdup (new_value);
2967 /* Read the modifications from IN and apply them. If IN is NULL the
2968 modifications are expected to already have been set to the global
2969 table. */
2970 void
2971 gc_component_change_options (int component, FILE *in, FILE *out)
2973 int err = 0;
2974 int runtime[GC_BACKEND_NR];
2975 char *src_filename[GC_BACKEND_NR];
2976 char *dest_filename[GC_BACKEND_NR];
2977 char *orig_filename[GC_BACKEND_NR];
2978 gc_backend_t backend;
2979 gc_option_t *option;
2980 char *line = NULL;
2981 size_t line_len = 0;
2982 ssize_t length;
2984 for (backend = 0; backend < GC_BACKEND_NR; backend++)
2986 runtime[backend] = 0;
2987 src_filename[backend] = NULL;
2988 dest_filename[backend] = NULL;
2989 orig_filename[backend] = NULL;
2992 if (in)
2994 /* Read options from the file IN. */
2995 while ((length = read_line (in, &line, &line_len, NULL)) > 0)
2997 char *linep;
2998 unsigned long flags = 0;
2999 char *new_value = "";
3001 /* Strip newline and carriage return, if present. */
3002 while (length > 0
3003 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
3004 line[--length] = '\0';
3006 linep = strchr (line, ':');
3007 if (linep)
3008 *(linep++) = '\0';
3010 /* Extract additional flags. Default to none. */
3011 if (linep)
3013 char *end;
3014 char *tail;
3016 end = strchr (linep, ':');
3017 if (end)
3018 *(end++) = '\0';
3020 errno = 0;
3021 flags = strtoul (linep, &tail, 0);
3022 if (errno)
3023 gc_error (1, errno, "malformed flags in option %s", line);
3024 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
3025 gc_error (1, 0, "garbage after flags in option %s", line);
3027 linep = end;
3030 /* Don't allow setting of the no change flag. */
3031 flags &= ~GC_OPT_FLAG_NO_CHANGE;
3033 /* Extract default value, if present. Default to empty if not. */
3034 if (linep)
3036 char *end;
3037 end = strchr (linep, ':');
3038 if (end)
3039 *(end++) = '\0';
3040 new_value = linep;
3041 linep = end;
3044 option = find_option (component, line, GC_BACKEND_ANY);
3045 if (!option)
3046 gc_error (1, 0, "unknown option %s", line);
3048 if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
3050 gc_error (0, 0, "ignoring new value for option %s",
3051 option->name);
3052 continue;
3055 change_one_value (option, runtime, flags, new_value);
3059 /* Now that we have collected and locally verified the changes,
3060 write them out to new configuration files, verify them
3061 externally, and then commit them. */
3062 option = gc_component[component].options;
3063 while (option && option->name)
3065 /* Go on if we have already seen this backend, or if there is
3066 nothing to do. */
3067 if (src_filename[option->backend]
3068 || !(option->new_flags || option->new_value))
3070 option++;
3071 continue;
3074 if (gc_backend[option->backend].program)
3076 err = change_options_program (component, option->backend,
3077 &src_filename[option->backend],
3078 &dest_filename[option->backend],
3079 &orig_filename[option->backend]);
3080 if (! err)
3082 /* External verification. */
3083 err = gc_component_check_options (component, out,
3084 src_filename[option->backend]);
3085 if (err)
3087 gc_error (0, 0,
3088 _("External verification of component %s failed"),
3089 gc_component[component].name);
3090 errno = EINVAL;
3095 else
3096 err = change_options_file (component, option->backend,
3097 &src_filename[option->backend],
3098 &dest_filename[option->backend],
3099 &orig_filename[option->backend]);
3101 if (err)
3102 break;
3104 option++;
3107 if (! err && ! opt.dry_run)
3109 int i;
3111 for (i = 0; i < GC_BACKEND_NR; i++)
3113 if (src_filename[i])
3115 /* FIXME: Make a verification here. */
3117 assert (dest_filename[i]);
3119 if (orig_filename[i])
3121 #ifdef HAVE_W32_SYSTEM
3122 /* There is no atomic update on W32. */
3123 err = unlink (dest_filename[i]);
3124 #endif /* HAVE_W32_SYSTEM */
3125 if (!err)
3126 err = rename (src_filename[i], dest_filename[i]);
3128 else
3130 #ifdef HAVE_W32_SYSTEM
3131 /* We skip the unlink if we expect the file not to
3132 be there. */
3133 err = rename (src_filename[i], dest_filename[i]);
3134 #else /* HAVE_W32_SYSTEM */
3135 /* This is a bit safer than rename() because we
3136 expect DEST_FILENAME not to be there. If it
3137 happens to be there, this will fail. */
3138 err = link (src_filename[i], dest_filename[i]);
3139 if (!err)
3140 err = unlink (src_filename[i]);
3141 #endif /* !HAVE_W32_SYSTEM */
3143 if (err)
3144 break;
3145 src_filename[i] = NULL;
3150 if (err || opt.dry_run)
3152 int i;
3153 int saved_errno = errno;
3155 /* An error occured or a dry-run is requested. */
3156 for (i = 0; i < GC_BACKEND_NR; i++)
3158 if (src_filename[i])
3160 /* The change was not yet committed. */
3161 unlink (src_filename[i]);
3162 if (orig_filename[i])
3163 unlink (orig_filename[i]);
3165 else
3167 /* The changes were already committed. FIXME: This is a
3168 tad dangerous, as we don't know if we don't overwrite
3169 a version of the file that is even newer than the one
3170 we just installed. */
3171 if (orig_filename[i])
3173 #ifdef HAVE_W32_SYSTEM
3174 /* There is no atomic update on W32. */
3175 unlink (dest_filename[i]);
3176 #endif /* HAVE_W32_SYSTEM */
3177 rename (orig_filename[i], dest_filename[i]);
3179 else
3180 unlink (dest_filename[i]);
3183 if (err)
3184 gc_error (1, saved_errno, "could not commit changes");
3186 /* Fall-through for dry run. */
3187 goto leave;
3190 /* If it all worked, notify the daemons of the changes. */
3191 if (opt.runtime)
3192 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3194 if (runtime[backend] && gc_backend[backend].runtime_change)
3195 (*gc_backend[backend].runtime_change) ();
3198 /* Move the per-process backup file into its place. */
3199 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3200 if (orig_filename[backend])
3202 char *backup_filename;
3204 assert (dest_filename[backend]);
3206 backup_filename = xasprintf ("%s.gpgconf.bak", dest_filename[backend]);
3208 #ifdef HAVE_W32_SYSTEM
3209 /* There is no atomic update on W32. */
3210 unlink (backup_filename);
3211 #endif /* HAVE_W32_SYSTEM */
3212 rename (orig_filename[backend], backup_filename);
3215 leave:
3216 xfree (line);
3220 /* Check whether USER matches the current user of one of its group.
3221 This function may change USER. Returns true is there is a
3222 match. */
3223 static int
3224 key_matches_user_or_group (char *user)
3226 char *group;
3228 if (*user == '*' && user[1] == 0)
3229 return 1; /* A single asterisk matches all users. */
3231 group = strchr (user, ':');
3232 if (group)
3233 *group++ = 0;
3235 #ifdef HAVE_W32_SYSTEM
3236 /* Under Windows we don't support groups. */
3237 if (group && *group)
3238 gc_error (0, 0, _("Note that group specifications are ignored\n"));
3239 if (*user)
3241 static char *my_name;
3243 if (!my_name)
3245 char tmp[1];
3246 DWORD size = 1;
3248 GetUserNameA (tmp, &size);
3249 my_name = xmalloc (size);
3250 if (!GetUserNameA (my_name, &size))
3251 gc_error (1,0, "error getting current user name: %s",
3252 w32_strerror (-1));
3255 if (!strcmp (user, my_name))
3256 return 1; /* Found. */
3258 #else /*!HAVE_W32_SYSTEM*/
3259 /* First check whether the user matches. */
3260 if (*user)
3262 static char *my_name;
3264 if (!my_name)
3266 struct passwd *pw = getpwuid ( getuid () );
3267 if (!pw)
3268 gc_error (1, errno, "getpwuid failed for current user");
3269 my_name = xstrdup (pw->pw_name);
3271 if (!strcmp (user, my_name))
3272 return 1; /* Found. */
3275 /* If that failed, check whether a group matches. */
3276 if (group && *group)
3278 static char *my_group;
3279 static char **my_supgroups;
3280 int n;
3282 if (!my_group)
3284 struct group *gr = getgrgid ( getgid () );
3285 if (!gr)
3286 gc_error (1, errno, "getgrgid failed for current user");
3287 my_group = xstrdup (gr->gr_name);
3289 if (!strcmp (group, my_group))
3290 return 1; /* Found. */
3292 if (!my_supgroups)
3294 int ngids;
3295 gid_t *gids;
3297 ngids = getgroups (0, NULL);
3298 gids = xcalloc (ngids+1, sizeof *gids);
3299 ngids = getgroups (ngids, gids);
3300 if (ngids < 0)
3301 gc_error (1, errno, "getgroups failed for current user");
3302 my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
3303 for (n=0; n < ngids; n++)
3305 struct group *gr = getgrgid ( gids[n] );
3306 if (!gr)
3307 gc_error (1, errno, "getgrgid failed for supplementary group");
3308 my_supgroups[n] = xstrdup (gr->gr_name);
3310 xfree (gids);
3313 for (n=0; my_supgroups[n]; n++)
3314 if (!strcmp (group, my_supgroups[n]))
3315 return 1; /* Found. */
3317 #endif /*!HAVE_W32_SYSTEM*/
3318 return 0; /* No match. */
3323 /* Read and process the global configuration file for gpgconf. This
3324 optional file is used to update our internal tables at runtime and
3325 may also be used to set new default values. If FNAME is NULL the
3326 default name will be used. With UPDATE set to true the internal
3327 tables are actually updated; if not set, only a syntax check is
3328 done. If DEFAULTS is true the global options are written to the
3329 configuration files. If LISTFP is set, no changes are done but the
3330 configuration file is printed to LISTFP in a colon separated format.
3332 Returns 0 on success or if the config file is not present; -1 is
3333 returned on error. */
3335 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
3336 FILE *listfp)
3338 int result = 0;
3339 char *line = NULL;
3340 size_t line_len = 0;
3341 ssize_t length;
3342 FILE *config;
3343 int lineno = 0;
3344 int in_rule = 0;
3345 int got_match = 0;
3346 int runtime[GC_BACKEND_NR];
3347 int used_components[GC_COMPONENT_NR];
3348 int backend_id, component_id;
3349 char *fname;
3351 if (fname_arg)
3352 fname = xstrdup (fname_arg);
3353 else
3354 fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
3356 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3357 runtime[backend_id] = 0;
3358 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3359 used_components[component_id] = 0;
3361 config = fopen (fname, "r");
3362 if (!config)
3364 /* Do not print an error if the file is not available, except
3365 when running in syntax check mode. */
3366 if (errno != ENOENT || !update)
3368 gc_error (0, errno, "can not open global config file `%s'", fname);
3369 result = -1;
3371 xfree (fname);
3372 return result;
3375 while ((length = read_line (config, &line, &line_len, NULL)) > 0)
3377 char *key, *component, *option, *flags, *value;
3378 char *empty;
3379 gc_option_t *option_info = NULL;
3380 char *p;
3381 int is_continuation;
3383 lineno++;
3384 key = line;
3385 while (*key == ' ' || *key == '\t')
3386 key++;
3387 if (!*key || *key == '#' || *key == '\r' || *key == '\n')
3388 continue;
3390 is_continuation = (key != line);
3392 /* Parse the key field. */
3393 if (!is_continuation && got_match)
3394 break; /* Finish after the first match. */
3395 else if (!is_continuation)
3397 in_rule = 0;
3398 for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
3400 if (!*p)
3402 gc_error (0, 0, "missing rule at `%s', line %d", fname, lineno);
3403 result = -1;
3404 continue;
3406 *p++ = 0;
3407 component = p;
3409 else if (!in_rule)
3411 gc_error (0, 0, "continuation but no rule at `%s', line %d",
3412 fname, lineno);
3413 result = -1;
3414 continue;
3416 else
3418 component = key;
3419 key = NULL;
3422 in_rule = 1;
3424 /* Parse the component. */
3425 while (*component == ' ' || *component == '\t')
3426 component++;
3427 for (p=component; *p && !strchr (" \t\r\n", *p); p++)
3429 if (p == component)
3431 gc_error (0, 0, "missing component at `%s', line %d",
3432 fname, lineno);
3433 result = -1;
3434 continue;
3436 empty = p;
3437 *p++ = 0;
3438 option = p;
3439 component_id = gc_component_find (component);
3440 if (component_id < 0)
3442 gc_error (0, 0, "unknown component at `%s', line %d",
3443 fname, lineno);
3444 result = -1;
3447 /* Parse the option name. */
3448 while (*option == ' ' || *option == '\t')
3449 option++;
3450 for (p=option; *p && !strchr (" \t\r\n", *p); p++)
3452 if (p == option)
3454 gc_error (0, 0, "missing option at `%s', line %d",
3455 fname, lineno);
3456 result = -1;
3457 continue;
3459 *p++ = 0;
3460 flags = p;
3461 if ( component_id != -1)
3463 option_info = find_option (component_id, option, GC_BACKEND_ANY);
3464 if (!option_info)
3466 gc_error (0, 0, "unknown option at `%s', line %d",
3467 fname, lineno);
3468 result = -1;
3473 /* Parse the optional flags. */
3474 while (*flags == ' ' || *flags == '\t')
3475 flags++;
3476 if (*flags == '[')
3478 flags++;
3479 p = strchr (flags, ']');
3480 if (!p)
3482 gc_error (0, 0, "syntax error in rule at `%s', line %d",
3483 fname, lineno);
3484 result = -1;
3485 continue;
3487 *p++ = 0;
3488 value = p;
3490 else /* No flags given. */
3492 value = flags;
3493 flags = NULL;
3496 /* Parse the optional value. */
3497 while (*value == ' ' || *value == '\t')
3498 value++;
3499 for (p=value; *p && !strchr ("\r\n", *p); p++)
3501 if (p == value)
3502 value = empty; /* No value given; let it point to an empty string. */
3503 else
3505 /* Strip trailing white space. */
3506 *p = 0;
3507 for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
3508 *p = 0;
3511 /* Check flag combinations. */
3512 if (!flags)
3514 else if (!strcmp (flags, "default"))
3516 if (*value)
3518 gc_error (0, 0, "flag \"default\" may not be combined "
3519 "with a value at `%s', line %d",
3520 fname, lineno);
3521 result = -1;
3524 else if (!strcmp (flags, "change"))
3526 else if (!strcmp (flags, "no-change"))
3528 else
3530 gc_error (0, 0, "unknown flag at `%s', line %d",
3531 fname, lineno);
3532 result = -1;
3535 /* In list mode we print out all records. */
3536 if (listfp && !result)
3538 /* If this is a new ruleset, print a key record. */
3539 if (!is_continuation)
3541 char *group = strchr (key, ':');
3542 if (group)
3544 *group++ = 0;
3545 if ((p = strchr (group, ':')))
3546 *p = 0; /* We better strip any extra stuff. */
3549 fprintf (listfp, "k:%s:", gc_percent_escape (key));
3550 fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
3553 /* All other lines are rule records. */
3554 fprintf (listfp, "r:::%s:%s:%s:",
3555 gc_component[component_id].name,
3556 option_info->name? option_info->name : "",
3557 flags? flags : "");
3558 if (value != empty)
3559 fprintf (listfp, "\"%s", gc_percent_escape (value));
3561 putc ('\n', listfp);
3564 /* Check whether the key matches but do this only if we are not
3565 running in syntax check mode. */
3566 if ( update
3567 && !result && !listfp
3568 && (got_match || (key && key_matches_user_or_group (key))) )
3570 int newflags = 0;
3572 got_match = 1;
3574 /* Apply the flags from gpgconf.conf. */
3575 if (!flags)
3577 else if (!strcmp (flags, "default"))
3578 newflags |= GC_OPT_FLAG_DEFAULT;
3579 else if (!strcmp (flags, "no-change"))
3580 option_info->flags |= GC_OPT_FLAG_NO_CHANGE;
3581 else if (!strcmp (flags, "change"))
3582 option_info->flags &= ~GC_OPT_FLAG_NO_CHANGE;
3584 if (defaults)
3586 assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
3587 used_components[component_id] = 1;
3589 /* Here we explicitly allow to update the value again. */
3590 if (newflags)
3592 option_info->new_flags = 0;
3594 if (*value)
3596 xfree (option_info->new_value);
3597 option_info->new_value = NULL;
3599 change_one_value (option_info, runtime, newflags, value);
3604 if (length < 0 || ferror (config))
3606 gc_error (0, errno, "error reading from `%s'", fname);
3607 result = -1;
3609 if (fclose (config) && ferror (config))
3610 gc_error (0, errno, "error closing `%s'", fname);
3612 xfree (line);
3614 /* If it all worked, process the options. */
3615 if (!result && update && defaults && !listfp)
3617 /* We need to switch off the runtime update, so that we can do
3618 it later all at once. */
3619 int save_opt_runtime = opt.runtime;
3620 opt.runtime = 0;
3622 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3624 gc_component_change_options (component_id, NULL, NULL);
3626 opt.runtime = save_opt_runtime;
3628 if (opt.runtime)
3630 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3631 if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
3632 (*gc_backend[backend_id].runtime_change) ();
3636 xfree (fname);
3637 return result;