Make gpgconf aware of --p12-charset.
[gnupg.git] / tools / gpgconf-comp.c
1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2  * Copyright (C) 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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 2 of the License, or
9  * (at your option) any later version.
10  *
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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GnuPG; if not, write to the Free Software Foundation,
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <time.h>
34 #include <stdarg.h>
35 #include <signal.h>
36 #include <pwd.h>
37 #include <grp.h>
38
39 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
40 #define JNLIB_NEED_LOG_LOGV
41 #include "util.h"
42 #include "i18n.h"
43
44 #include "gpgconf.h"
45
46
47 \f
48 /* TODO:
49    Components: Add more components and their options.
50    Robustness: Do more validation.  Call programs to do validation for us.
51    Don't use popen, as this will not tell us if the program had a
52    non-zero exit code.
53    Add options to change backend binary path.
54    Extract binary path for some backends from gpgsm/gpg config.
55 */
56
57 \f
58 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
59 void gc_error (int status, int errnum, const char *fmt, ...) \
60   __attribute__ ((format (printf, 3, 4)));
61 #endif
62
63 /* Output a diagnostic message.  If ERRNUM is not 0, then the output
64    is followed by a colon, a white space, and the error string for the
65    error number ERRNUM.  In any case the output is finished by a
66    newline.  The message is prepended by the program name, a colon,
67    and a whitespace.  The output may be further formatted or
68    redirected by the jnlib logging facility.  */
69 void
70 gc_error (int status, int errnum, const char *fmt, ...)
71 {
72   va_list arg_ptr;
73
74   va_start (arg_ptr, fmt);
75   log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
76   va_end (arg_ptr);
77
78   if (errnum)
79     log_printf (": %s\n", strerror (errnum));
80   else
81     log_printf ("\n");
82
83   if (status)
84     {
85       log_printf (NULL);
86       log_printf ("fatal error (exit status %i)\n", status);
87       exit (status);
88     }
89 }
90
91 \f
92 /* Forward declaration.  */
93 void gpg_agent_runtime_change (void);
94
95 /* Backend configuration.  Backends are used to decide how the default
96    and current value of an option can be determined, and how the
97    option can be changed.  To every option in every component belongs
98    exactly one backend that controls and determines the option.  Some
99    backends are programs from the GPG system.  Others might be
100    implemented by GPGConf itself.  If you change this enum, don't
101    forget to update GC_BACKEND below.  */
102 typedef enum
103   {
104     /* Any backend, used for find_option ().  */
105     GC_BACKEND_ANY,
106
107     /* The Gnu Privacy Guard.  */
108     GC_BACKEND_GPG,
109
110     /* The Gnu Privacy Guard for S/MIME.  */
111     GC_BACKEND_GPGSM,
112
113     /* The GPG Agent.  */
114     GC_BACKEND_GPG_AGENT,
115
116     /* The GnuPG SCDaemon.  */
117     GC_BACKEND_SCDAEMON,
118
119     /* The Aegypten directory manager.  */
120     GC_BACKEND_DIRMNGR,
121
122     /* The LDAP server list file for the Aegypten director manager.  */
123     GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
124
125     /* The number of the above entries.  */
126     GC_BACKEND_NR
127   } gc_backend_t;
128
129
130 /* To be able to implement generic algorithms for the various
131    backends, we collect all information about them in this struct.  */
132 static struct
133 {
134   /* The name of the backend.  */
135   const char *name;
136
137   /* The name of the program that acts as the backend.  Some backends
138      don't have an associated program, but are implemented directly by
139      GPGConf.  In this case, PROGRAM is NULL.  */
140   char *program;
141
142   /* The runtime change callback.  */
143   void (*runtime_change) (void);
144
145   /* The option name for the configuration filename of this backend.
146      This must be an absolute pathname.  It can be an option from a
147      different backend (but then ordering of the options might
148      matter).  */
149   const char *option_config_filename;
150
151   /* If this is a file backend rather than a program backend, then
152      this is the name of the option associated with the file.  */
153   const char *option_name;
154 } gc_backend[GC_BACKEND_NR] =
155   {
156     { NULL },           /* GC_BACKEND_ANY dummy entry.  */
157     { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" },
158     { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" },
159     { "GPG Agent", "gpg-agent", gpg_agent_runtime_change,
160       "gpgconf-gpg-agent.conf" },
161     { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" },
162     { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" },
163     { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file",
164       "LDAP Server" },
165   };
166
167 \f
168 /* Option configuration.  */
169
170 /* An option might take an argument, or not.  Argument types can be
171    basic or complex.  Basic types are generic and easy to validate.
172    Complex types provide more specific information about the intended
173    use, but can be difficult to validate.  If you add to this enum,
174    don't forget to update GC_ARG_TYPE below.  YOU MUST NOT CHANGE THE
175    NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
176    INTERFACE.  */
177 typedef enum
178   {
179     /* Basic argument types.  */
180
181     /* No argument.  */
182     GC_ARG_TYPE_NONE = 0,
183
184     /* A String argument.  */
185     GC_ARG_TYPE_STRING = 1,
186
187     /* A signed integer argument.  */
188     GC_ARG_TYPE_INT32 = 2,
189
190     /* An unsigned integer argument.  */
191     GC_ARG_TYPE_UINT32 = 3,
192
193     /* ADD NEW BASIC TYPE ENTRIES HERE.  */
194
195     /* Complex argument types.  */
196
197     /* A complete pathname.  */
198     GC_ARG_TYPE_PATHNAME = 32,
199
200     /* An LDAP server in the format
201        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
202     GC_ARG_TYPE_LDAP_SERVER = 33,
203
204     /* A 40 character fingerprint.  */
205     GC_ARG_TYPE_KEY_FPR = 34,
206
207     /* ADD NEW COMPLEX TYPE ENTRIES HERE.  */
208
209     /* The number of the above entries.  */
210     GC_ARG_TYPE_NR
211   } gc_arg_type_t;
212
213
214 /* For every argument, we record some information about it in the
215    following struct.  */
216 static struct
217 {
218   /* For every argument type exists a basic argument type that can be
219      used as a fallback for input and validation purposes.  */
220   gc_arg_type_t fallback;
221
222   /* Human-readable name of the type.  */
223   const char *name;
224 } gc_arg_type[GC_ARG_TYPE_NR] =
225   {
226     /* The basic argument types have their own types as fallback.  */
227     { GC_ARG_TYPE_NONE, "none" },
228     { GC_ARG_TYPE_STRING, "string" },
229     { GC_ARG_TYPE_INT32, "int32" },
230     { GC_ARG_TYPE_UINT32, "uint32" },
231
232     /* Reserved basic type entries for future extension.  */
233     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
234     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
235     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
236     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
237     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
238     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
239     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
240     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
241     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
242     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
243     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
244     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
245     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
246     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
247
248     /* The complex argument types have a basic type as fallback.  */
249     { GC_ARG_TYPE_STRING, "pathname" },
250     { GC_ARG_TYPE_STRING, "ldap server" },
251     { GC_ARG_TYPE_STRING, "key fpr" },
252   };
253
254
255 /* Every option has an associated expert level, than can be used to
256    hide advanced and expert options from beginners.  If you add to
257    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
258    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
259    EXTERNAL INTERFACE.  */
260 typedef enum
261   {
262     /* The basic options should always be displayed.  */
263     GC_LEVEL_BASIC,
264
265     /* The advanced options may be hidden from beginners.  */
266     GC_LEVEL_ADVANCED,
267
268     /* The expert options should only be displayed to experts.  */
269     GC_LEVEL_EXPERT,
270
271     /* The invisible options should normally never be displayed.  */
272     GC_LEVEL_INVISIBLE,
273
274     /* The internal options are never exported, they mark options that
275        are recorded for internal use only.  */
276     GC_LEVEL_INTERNAL,
277
278     /* ADD NEW ENTRIES HERE.  */
279
280     /* The number of the above entries.  */
281     GC_LEVEL_NR
282   } gc_expert_level_t;
283
284 /* A description for each expert level.  */
285 static struct
286 {
287   const char *name;
288 } gc_level[] =
289   {
290     { "basic" },
291     { "advanced" },
292     { "expert" },
293     { "invisible" },
294     { "internal" }
295   };
296
297
298 /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
299    FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
300 #define GC_OPT_FLAG_NONE        0UL
301 /* Some entries in the option list are not options, but mark the
302    beginning of a new group of options.  These entries have the GROUP
303    flag set.  */
304 #define GC_OPT_FLAG_GROUP       (1UL << 0)
305 /* The ARG_OPT flag for an option indicates that the argument is
306    optional.  This is never set for GC_ARG_TYPE_NONE options.  */
307 #define GC_OPT_FLAG_ARG_OPT     (1UL << 1)
308 /* The LIST flag for an option indicates that the option can occur
309    several times.  A comma separated list of arguments is used as the
310    argument value.  */
311 #define GC_OPT_FLAG_LIST        (1UL << 2)
312 /* The RUNTIME flag for an option indicates that the option can be
313    changed at runtime.  */
314 #define GC_OPT_FLAG_RUNTIME     (1UL << 3)
315
316 /* The following flags are incorporated from the backend.  */
317 /* The DEFAULT flag for an option indicates that the option has a
318    default value.  */
319 #define GC_OPT_FLAG_DEFAULT     (1UL << 4)
320 /* The DEF_DESC flag for an option indicates that the option has a
321    default, which is described by the value of the default field.  */
322 #define GC_OPT_FLAG_DEF_DESC    (1UL << 5)
323 /* The NO_ARG_DESC flag for an option indicates that the argument has
324    a default, which is described by the value of the ARGDEF field.  */
325 #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
326 /* The NO_CHANGE flag for an option indicates that the user should not
327    be allowed to chnage this option using the standard gpgconf method.
328    Frontends using gpgconf should grey out such otions, so that only
329    the current value is displayed.  */
330 #define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
331
332 /* A human-readable description for each flag.  */
333 static struct
334 {
335   const char *name;
336 } gc_flag[] =
337   {
338     { "group" },
339     { "optional arg" },
340     { "list" },
341     { "runtime" },
342     { "default" },
343     { "default desc" },
344     { "no arg desc" },
345     { "no change" }
346   };
347
348
349 /* To each option, or group marker, the information in the GC_OPTION
350    struct is provided.  If you change this, don't forget to update the
351    option list of each component.  */
352 struct gc_option
353 {
354   /* If this is NULL, then this is a terminator in an array of unknown
355      length.  Otherwise, if this entry is a group marker (see FLAGS),
356      then this is the name of the group described by this entry.
357      Otherwise it is the name of the option described by this
358      entry.  The name must not contain a colon.  */
359   const char *name;
360
361   /* The option flags.  If the GROUP flag is set, then this entry is a
362      group marker, not an option, and only the fields LEVEL,
363      DESC_DOMAIN and DESC are valid.  In all other cases, this entry
364      describes a new option and all fields are valid.  */
365   unsigned long flags;
366
367   /* The expert level.  This field is valid for options and groups.  A
368      group has the expert level of the lowest-level option in the
369      group.  */
370   gc_expert_level_t level;
371
372   /* A gettext domain in which the following description can be found.
373      If this is NULL, then DESC is not translated.  Valid for groups
374      and options.
375      
376      Note that we try to keep the description of groups within the
377      gnupg domain. 
378      
379      IMPORTANT: If you add a new domain please make sure to add a code
380      set switching call to the function my_dgettext further below.  */
381   const char *desc_domain;
382
383   /* A gettext description for this group or option.  If it starts
384      with a '|', then the string up to the next '|' describes the
385      argument, and the description follows the second '|'. 
386
387      In general enclosing these description in N_() is not required
388      because the description should be identical to the one in the
389      help menu of the respective program. */
390   const char *desc;
391
392   /* The following fields are only valid for options.  */
393
394   /* The type of the option argument.  */
395   gc_arg_type_t arg_type;
396
397   /* The backend that implements this option.  */
398   gc_backend_t backend;
399
400   /* The following fields are set to NULL at startup (because all
401      option's are declared as static variables).  They are at the end
402      of the list so that they can be omitted from the option
403      declarations.  */
404
405   /* This is true if the option is supported by this version of the
406      backend.  */
407   int active;
408
409   /* The default value for this option.  This is NULL if the option is
410      not present in the backend, the empty string if no default is
411      available, and otherwise a quoted string.  */
412   char *default_value;
413
414   /* The default argument is only valid if the "optional arg" flag is
415      set, and specifies the default argument (value) that is used if
416      the argument is omitted.  */
417   char *default_arg;
418
419   /* The current value of this option.  */
420   char *value;
421
422   /* The new flags for this option.  The only defined flag is actually
423      GC_OPT_FLAG_DEFAULT, and it means that the option should be
424      deleted.  In this case, NEW_VALUE is NULL.  */
425   unsigned long new_flags;
426
427   /* The new value of this option.  */
428   char *new_value;
429 };
430 typedef struct gc_option gc_option_t;
431
432 /* Use this macro to terminate an option list.  */
433 #define GC_OPTION_NULL { NULL }
434
435 \f
436 /* The options of the GC_COMPONENT_GPG_AGENT component.  */
437 static gc_option_t gc_options_gpg_agent[] =
438  {
439    /* The configuration file to which we write the changes.  */
440    { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
441      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
442
443    { "Monitor",
444      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
445      "gnupg", N_("Options controlling the diagnostic output") },
446    { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
447      "gnupg", "verbose",
448      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
449    { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
450      "gnupg", "be somewhat more quiet",
451      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
452    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
453      NULL, NULL,
454      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
455
456    { "Configuration",
457      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
458      "gnupg", N_("Options controlling the configuration") },
459    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
460      "gnupg", "|FILE|read options from FILE",
461      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
462    { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
463      "gnupg", "do not use the SCdaemon",
464      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
465
466    { "Debug",
467      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
468      "gnupg", N_("Options useful for debugging") },
469    { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
470      "gnupg", "|LEVEL|set the debugging level to LEVEL",
471      GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
472    { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
473      "gnupg", N_("|FILE|write server mode logs to FILE"),
474      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT },
475    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
476      NULL, NULL,
477      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
478
479    { "Security",
480      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
481      "gnupg", N_("Options controlling the security") },
482    { "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
483      GC_LEVEL_BASIC, "gnupg", 
484      "|N|expire cached PINs after N seconds",
485      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
486    { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
487      GC_LEVEL_ADVANCED, "gnupg",
488      N_("|N|expire SSH keys after N seconds"),
489      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
490    { "max-cache-ttl", GC_OPT_FLAG_RUNTIME,
491      GC_LEVEL_EXPERT, "gnupg",
492      N_("|N|set maximum PIN cache lifetime to N seconds"),
493      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
494    { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
495      GC_LEVEL_EXPERT, "gnupg", 
496      N_("|N|set maximum SSH key lifetime to N seconds"),
497      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
498    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
499      GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
500      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
501    { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME | GC_OPT_FLAG_NO_CHANGE,
502      GC_LEVEL_ADVANCED, "gnupg", "allow clients to mark keys as \"trusted\"",
503      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
504    { "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
505      GC_LEVEL_EXPERT, "gnupg", 
506      N_("|N|set minimal required length for new passphrases to N"),
507      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
508    { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
509      "gnupg", "do not grab keyboard and mouse",
510      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
511
512    GC_OPTION_NULL
513  };
514
515
516 /* The options of the GC_COMPONENT_SCDAEMON component.  */
517 static gc_option_t gc_options_scdaemon[] =
518  {
519    /* The configuration file to which we write the changes.  */
520    { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
521      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
522
523    { "Monitor",
524      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
525      "gnupg", N_("Options controlling the diagnostic output") },
526    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
527      "gnupg", "verbose",
528      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
529    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
530      "gnupg", "be somewhat more quiet",
531      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
532    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
533      NULL, NULL,
534      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
535
536    { "Configuration",
537      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
538      "gnupg", N_("Options controlling the configuration") },
539    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
540      "gnupg", "|FILE|read options from FILE",
541      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
542    { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
543      "gnupg", "|N|connect to reader at port N",
544      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
545    { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
546      "gnupg", "|NAME|use NAME as ct-API driver",
547      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
548    { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
549      "gnupg", "|NAME|use NAME as PC/SC driver",
550      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
551    { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
552      "gnupg", "do not use the OpenSC layer",
553      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
554    { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
555      "gnupg", "do not use the internal CCID driver",
556      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
557    { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
558      "gnupg", "do not use a reader's keypad",
559      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
560
561    { "Debug",
562      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
563      "gnupg", N_("Options useful for debugging") },
564    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
565      "gnupg", "|LEVEL|set the debugging level to LEVEL",
566      GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
567    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
568      "gnupg", N_("|FILE|write server mode logs to FILE"),
569      GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON },
570
571    { "Security",
572      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
573      "gnupg", N_("Options controlling the security") },
574    { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
575      "gnupg", "allow the use of admin card commands",
576      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
577
578
579    GC_OPTION_NULL
580  };
581
582
583 /* The options of the GC_COMPONENT_GPG component.  */
584 static gc_option_t gc_options_gpg[] =
585  {
586    /* The configuration file to which we write the changes.  */
587    { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
588      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
589
590    { "Monitor",
591      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
592      "gnupg", N_("Options controlling the diagnostic output") },
593    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
594      "gnupg", "verbose",
595      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
596    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
597      "gnupg", "be somewhat more quiet",
598      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
599    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
600      NULL, NULL,
601      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
602
603    { "Configuration",
604      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
605      "gnupg", N_("Options controlling the configuration") },
606    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
607      "gnupg", "|FILE|read options from FILE",
608      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
609
610    { "Debug",
611      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
612      "gnupg", N_("Options useful for debugging") },
613    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
614      "gnupg", "|LEVEL|set the debugging level to LEVEL",
615      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
616    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
617      "gnupg", N_("|FILE|write server mode logs to FILE"),
618      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG },
619 /*    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */
620 /*      NULL, NULL, */
621 /*      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */
622
623    { "Keyserver",
624      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
625      "gnupg", N_("Configuration for Keyservers") },
626    { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
627      "gnupg", "|URL|use keyserver at URL",
628      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
629    { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
630      "gnupg", N_("allow PKA lookups (DNS requests)"),
631      GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
632
633
634    GC_OPTION_NULL
635  };
636
637
638
639 /* The options of the GC_COMPONENT_GPGSM component.  */
640 static gc_option_t gc_options_gpgsm[] =
641  {
642    /* The configuration file to which we write the changes.  */
643    { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
644      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
645
646    { "Monitor",
647      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
648      "gnupg", N_("Options controlling the diagnostic output") },
649    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
650      "gnupg", "verbose",
651      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
652    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
653      "gnupg", "be somewhat more quiet",
654      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
655    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
656      NULL, NULL,
657      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
658
659    { "Configuration",
660      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
661      "gnupg", N_("Options controlling the configuration") },
662    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
663      "gnupg", "|FILE|read options from FILE",
664      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
665    { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
666      "gnupg", "use system's dirmngr if available",
667      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
668    { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
669      "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"),
670      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
671
672    { "Debug",
673      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
674      "gnupg", N_("Options useful for debugging") },
675    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
676      "gnupg", "|LEVEL|set the debugging level to LEVEL",
677      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
678    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
679      "gnupg", N_("|FILE|write server mode logs to FILE"),
680      GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM },
681    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
682      NULL, NULL,
683      GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
684
685    { "Security",
686      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
687      "gnupg", N_("Options controlling the security") },
688    { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
689      "gnupg", "never consult a CRL",
690      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
691    { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
692      "gnupg", N_("do not check CRLs for root certificates"),
693      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
694    { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
695      "gnupg", "check validity using OCSP",
696      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
697    { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
698      "gnupg", "|N|number of certificates to include",
699      GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
700    { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
701      "gnupg", "do not check certificate policies",
702      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
703    { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
704      "gnupg", "fetch missing issuer certificates",
705      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
706    { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
707      "gnupg", "|NAME|use cipher algorithm NAME",
708      GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
709
710    GC_OPTION_NULL
711  };
712
713
714 /* The options of the GC_COMPONENT_DIRMNGR component.  */
715 static gc_option_t gc_options_dirmngr[] =
716  {
717    /* The configuration file to which we write the changes.  */
718    { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
719      NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
720
721    { "Monitor",
722      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
723      "gnupg", N_("Options controlling the diagnostic output") },
724    { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
725      "dirmngr", "verbose",
726      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
727    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
728      "dirmngr", "be somewhat more quiet",
729      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
730    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
731      NULL, NULL,
732      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
733
734    { "Format",
735      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
736      "gnupg", N_("Options controlling the format of the output") },
737    { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
738      "dirmngr", "sh-style command output",
739      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
740    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
741      "dirmngr", "csh-style command output",
742      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
743    
744    { "Configuration",
745      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
746      "gnupg", N_("Options controlling the configuration") },
747    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
748      "dirmngr", "|FILE|read options from FILE",
749      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
750
751    { "Debug",
752      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
753      "gnupg", N_("Options useful for debugging") },
754    { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
755      "dirmngr", "|LEVEL|set the debugging level to LEVEL",
756      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
757    { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
758      "dirmngr", "do not detach from the console",
759      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
760    { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
761      "dirmngr", N_("|FILE|write server mode logs to FILE"),
762      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
763    { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
764      NULL, NULL,
765      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
766    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
767      NULL, NULL,
768      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
769
770    { "Enforcement",
771      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
772      "gnupg", N_("Options controlling the interactivity and enforcement") },
773    { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
774      "dirmngr", "run without asking a user",
775      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
776    { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
777      "dirmngr", "force loading of outdated CRLs",
778      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
779
780    { "HTTP",
781      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
782      "gnupg", N_("Configuration for HTTP servers") },
783    { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
784      "dirmngr", "inhibit the use of HTTP",
785       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
786    { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
787      "dirmngr", "ignore HTTP CRL distribution points",
788       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
789    { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
790      "dirmngr", "|URL|redirect all HTTP requests to URL",
791      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
792    { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
793      "dirmngr", N_("use system's HTTP proxy setting"),
794      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
795
796    { "LDAP",
797      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
798      "gnupg", N_("Configuration of LDAP servers to use") },
799    { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
800      "dirmngr", "inhibit the use of LDAP",
801       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
802    { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
803      "dirmngr", "ignore LDAP CRL distribution points",
804       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
805    { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
806      "dirmngr", "|HOST|use HOST for LDAP queries",
807      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
808    { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
809      "dirmngr", "do not use fallback hosts with --ldap-proxy",
810       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
811    { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
812      "dirmngr", "add new servers discovered in CRL distribution points"
813      " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
814    { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
815      "dirmngr", "|N|set LDAP timeout to N seconds",
816      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
817    /* The following entry must not be removed, as it is required for
818       the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST.  */
819    { "ldapserverlist-file",
820      GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
821      "dirmngr", "|FILE|read LDAP server list from FILE",
822      GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR },
823    /* This entry must come after at least one entry for
824       GC_BACKEND_DIRMNGR in this component, so that the entry for
825       "ldapserverlist-file will be initialized before this one.  */
826    { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
827      NULL, "LDAP server list",
828      GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
829    { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
830      "dirmngr", "|N|do not return more than N items in one query",
831      GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
832
833    { "OCSP",
834      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
835      "gnupg", N_("Configuration for OCSP") },
836    { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
837      "dirmngr", "allow sending OCSP requests",
838      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
839    { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
840      "dirmngr", "ignore certificate contained OCSP service URLs",
841       GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
842    { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
843      "dirmngr", "|URL|use OCSP responder at URL",
844      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
845    { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
846      "dirmngr", "|FPR|OCSP response signed by FPR",
847      GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
848
849
850    GC_OPTION_NULL
851  };
852
853 \f
854 /* Component system.  Each component is a set of options that can be
855    configured at the same time.  If you change this, don't forget to
856    update GC_COMPONENT below.  */
857 typedef enum
858   {
859     /* The classic GPG for OpenPGP.  */
860     GC_COMPONENT_GPG,
861
862     /* The GPG Agent.  */
863     GC_COMPONENT_GPG_AGENT,
864
865     /* The Smardcard Daemon.  */
866     GC_COMPONENT_SCDAEMON,
867
868     /* GPG for S/MIME.  */
869     GC_COMPONENT_GPGSM,
870
871     /* The LDAP Directory Manager for CRLs.  */
872     GC_COMPONENT_DIRMNGR,
873
874     /* The number of components.  */
875     GC_COMPONENT_NR
876   } gc_component_t;
877
878
879 /* The information associated with each component.  */
880 static struct
881 {
882   /* The name of this component.  Must not contain a colon (':')
883      character.  */
884   const char *name;
885
886   /* The gettext domain for the description DESC.  If this is NULL,
887      then the description is not translated.  */
888   const char *desc_domain;
889
890   /* The description for this domain.  */
891   const char *desc;
892
893   /* The list of options for this component, terminated by
894      GC_OPTION_NULL.  */
895   gc_option_t *options;
896 } gc_component[] =
897   {
898     { "gpg", NULL,   "GPG for OpenPGP", gc_options_gpg },
899     { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
900     { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
901     { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
902     { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }
903   };
904
905 \f
906 /* Engine specific support.  */
907 void
908 gpg_agent_runtime_change (void)
909 {
910 #ifndef HAVE_W32_SYSTEM
911   char *agent = getenv ("GPG_AGENT_INFO");
912   char *pid_str;
913   unsigned long pid_long;
914   char *tail;
915   pid_t pid;
916
917   if (!agent)
918     return;
919
920   pid_str = strchr (agent, ':');
921   if (!pid_str)
922     return;
923
924   pid_str++;
925   errno = 0;
926   pid_long = strtoul (pid_str, &tail, 0);
927   if (errno || (*tail != ':' && *tail != '\0'))
928     return;
929
930   pid = (pid_t) pid_long;
931
932   /* Check for overflow.  */
933   if (pid_long != (unsigned long) pid)
934     return;
935
936   /* Ignore any errors here.  */
937   kill (pid, SIGHUP);
938 #endif /*!HAVE_W32_SYSTEM*/
939 }
940
941 \f
942 /* More or less Robust version of dgettext.  It has the side effect of
943    switching the codeset to utf-8 because this is what we want to
944    output.  In theory it is posible to keep the orginal code set and
945    switch back for regular disgnostic output (redefine "_(" for that)
946    but given the natur of this tool, being something invoked from
947    other pograms, it does not make much sense.  */
948 static const char *
949 my_dgettext (const char *domain, const char *msgid)
950 {
951 #ifdef ENABLE_NLS
952   if (domain)
953     {
954       static int switched_codeset;
955       char *text;
956       
957       if (!switched_codeset)
958         {
959           switched_codeset = 1;
960           bind_textdomain_codeset (PACKAGE_GT, "utf-8");
961
962           bindtextdomain ("dirmngr", LOCALEDIR);
963           bind_textdomain_codeset ("dirmngr", "utf-8");
964    
965         }
966
967       /* Note: This is a hack to actually use the gnupg2 domain as
968          long we are in a transition phase where gnupg 1.x and 1.9 may
969          coexist. */
970       if (!strcmp (domain, "gnupg"))
971         domain = PACKAGE_GT;
972
973       text = dgettext (domain, msgid);
974       return text ? text : msgid;
975     }
976   else
977 #endif
978     return msgid;
979 }
980
981
982 /* Percent-Escape special characters.  The string is valid until the
983    next invocation of the function.  */
984 static char *
985 percent_escape (const char *src)
986 {
987   static char *esc_str;
988   static int esc_str_len;
989   int new_len = 3 * strlen (src) + 1;
990   char *dst;
991
992   if (esc_str_len < new_len)
993     {
994       char *new_esc_str = realloc (esc_str, new_len);
995       if (!new_esc_str)
996         gc_error (1, errno, "can not escape string");
997       esc_str = new_esc_str;
998       esc_str_len = new_len;
999     }
1000
1001   dst = esc_str;
1002   while (*src)
1003     {
1004       if (*src == '%')
1005         {
1006           *(dst++) = '%';
1007           *(dst++) = '2';
1008           *(dst++) = '5';
1009         }         
1010       else if (*src == ':')
1011         {
1012           /* The colon is used as field separator.  */
1013           *(dst++) = '%';
1014           *(dst++) = '3';
1015           *(dst++) = 'a';
1016         }
1017       else if (*src == ',')
1018         {
1019           /* The comma is used as list separator.  */
1020           *(dst++) = '%';
1021           *(dst++) = '2';
1022           *(dst++) = 'c';
1023         }
1024       else
1025         *(dst++) = *(src);
1026       src++;
1027     }
1028   *dst = '\0';
1029   return esc_str;
1030 }
1031
1032
1033
1034 /* Percent-Deescape special characters.  The string is valid until the
1035    next invocation of the function.  */
1036 static char *
1037 percent_deescape (const char *src)
1038 {
1039   static char *str;
1040   static int str_len;
1041   int new_len = 3 * strlen (src) + 1;
1042   char *dst;
1043
1044   if (str_len < new_len)
1045     {
1046       char *new_str = realloc (str, new_len);
1047       if (!new_str)
1048         gc_error (1, errno, "can not deescape string");
1049       str = new_str;
1050       str_len = new_len;
1051     }
1052
1053   dst = str;
1054   while (*src)
1055     {
1056       if (*src == '%')
1057         {
1058           int val = hextobyte (src + 1);
1059
1060           if (val < 0)
1061             gc_error (1, 0, "malformed end of string %s", src);
1062
1063           *(dst++) = (char) val;
1064           src += 3;
1065         }         
1066       else
1067         *(dst++) = *(src++);
1068     }
1069   *dst = '\0';
1070   return str;
1071 }
1072
1073 \f
1074 /* List all components that are available.  */
1075 void
1076 gc_component_list_components (FILE *out)
1077 {
1078   gc_component_t idx;
1079
1080   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1081     {
1082       const char *desc = gc_component[idx].desc;
1083       desc = my_dgettext (gc_component[idx].desc_domain, desc);
1084       fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc));
1085     }
1086 }
1087
1088 \f
1089 /* Find the component with the name NAME.  Returns -1 if not
1090    found.  */
1091 int
1092 gc_component_find (const char *name)
1093 {
1094   gc_component_t idx;
1095
1096   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1097     {
1098       if (!strcmp (name, gc_component[idx].name))
1099         return idx;
1100     }
1101   return -1;
1102 }
1103
1104 \f
1105 /* List the option OPTION.  */
1106 static void
1107 list_one_option (const gc_option_t *option, FILE *out)
1108 {
1109   const char *desc = NULL;
1110   char *arg_name = NULL;
1111
1112   if (option->desc)
1113     {
1114       desc = my_dgettext (option->desc_domain, option->desc);
1115
1116       if (*desc == '|')
1117         {
1118           const char *arg_tail = strchr (&desc[1], '|');
1119
1120           if (arg_tail)
1121             {
1122               int arg_len = arg_tail - &desc[1];
1123               arg_name = xmalloc (arg_len + 1);
1124               memcpy (arg_name, &desc[1], arg_len);
1125               arg_name[arg_len] = '\0';
1126               desc = arg_tail + 1;
1127             }
1128         }
1129     }
1130
1131
1132   /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1133      PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE ANY
1134      FIELDS.  */
1135
1136   /* The name field.  */
1137   fprintf (out, "%s", option->name);
1138
1139   /* The flags field.  */
1140   fprintf (out, ":%lu", option->flags);
1141   if (opt.verbose)
1142     {
1143       putc (' ', out);
1144           
1145       if (!option->flags)
1146         fprintf (out, "none");
1147       else
1148         {
1149           unsigned long flags = option->flags;
1150           unsigned long flag = 0;
1151           unsigned long first = 1;
1152
1153           while (flags)
1154             {
1155               if (flags & 1)
1156                 {
1157                   if (first)
1158                     first = 0;
1159                   else
1160                     putc (',', out);
1161                   fprintf (out, "%s", gc_flag[flag].name);
1162                 }
1163               flags >>= 1;
1164               flag++;
1165             }
1166         }
1167     }
1168
1169   /* The level field.  */
1170   fprintf (out, ":%u", option->level);
1171   if (opt.verbose)
1172     fprintf (out, " %s", gc_level[option->level].name);
1173
1174   /* The description field.  */
1175   fprintf (out, ":%s", desc ? percent_escape (desc) : "");
1176   
1177   /* The type field.  */
1178   fprintf (out, ":%u", option->arg_type);
1179   if (opt.verbose)
1180     fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1181
1182   /* The alternate type field.  */
1183   fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1184   if (opt.verbose)
1185     fprintf (out, " %s",
1186              gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1187
1188   /* The argument name field.  */
1189   fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
1190   if (arg_name)
1191     xfree (arg_name);
1192
1193   /* The default value field.  */
1194   fprintf (out, ":%s", option->default_value ? option->default_value : "");
1195
1196   /* The default argument field.  */
1197   fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1198
1199   /* The value field.  */
1200   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1201       && (option->flags & GC_OPT_FLAG_LIST)
1202       && option->value)
1203     /* The special format "1,1,1,1,...,1" is converted to a number
1204        here.  */
1205     fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1206   else
1207     fprintf (out, ":%s", option->value ? option->value : "");
1208
1209   /* ADD NEW FIELDS HERE.  */
1210
1211   putc ('\n', out);
1212 }
1213
1214
1215 /* List all options of the component COMPONENT.  */
1216 void
1217 gc_component_list_options (int component, FILE *out)
1218 {  
1219   const gc_option_t *option = gc_component[component].options;
1220   const gc_option_t *group_option = NULL;
1221
1222   while (option->name)
1223     {
1224       /* Do not output unknown or internal options.  */
1225       if (!(option->flags & GC_OPT_FLAG_GROUP)
1226           && (!option->active || option->level == GC_LEVEL_INTERNAL))
1227         {
1228           option++;
1229           continue;
1230         }
1231
1232       if (option->flags & GC_OPT_FLAG_GROUP)
1233         group_option = option;
1234       else
1235         {
1236           if (group_option)
1237             {
1238               list_one_option (group_option, out);
1239               group_option = NULL;
1240             }
1241
1242           list_one_option (option, out);
1243         }
1244
1245       option++;
1246     }
1247 }
1248
1249
1250 /* Find the option NAME in component COMPONENT, for the backend
1251    BACKEND.  If BACKEND is GC_BACKEND_ANY, any backend will match.  */
1252 static gc_option_t *
1253 find_option (gc_component_t component, const char *name,
1254              gc_backend_t backend)
1255 {
1256   gc_option_t *option = gc_component[component].options;
1257   while (option->name)
1258     {
1259       if (!(option->flags & GC_OPT_FLAG_GROUP)
1260           && !strcmp (option->name, name)
1261           && (backend == GC_BACKEND_ANY || option->backend == backend))
1262         break;
1263       option++;
1264     }
1265   return option->name ? option : NULL;
1266 }
1267
1268 \f
1269 /* Determine the configuration pathname for the component COMPONENT
1270    and backend BACKEND.  */
1271 static char *
1272 get_config_pathname (gc_component_t component, gc_backend_t backend)
1273 {
1274   char *pathname = NULL;
1275   gc_option_t *option = find_option
1276     (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
1277   assert (option);
1278   assert (option->arg_type == GC_ARG_TYPE_PATHNAME);
1279   assert (!(option->flags & GC_OPT_FLAG_LIST));
1280
1281   if (!option->active || !option->default_value)
1282     gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
1283               gc_backend[backend].option_config_filename,
1284               gc_backend[backend].name);
1285
1286   if (option->value && *option->value)
1287     pathname = percent_deescape (&option->value[1]);
1288   else if (option->default_value && *option->default_value)
1289     pathname = percent_deescape (&option->default_value[1]);
1290   else
1291     pathname = "";
1292
1293 #ifdef HAVE_DOSISH_SYSTEM
1294   if (!(pathname[0] 
1295         && pathname[1] == ':'
1296         && (pathname[2] == '/' || pathname[2] == '\\')))
1297 #else
1298   if (pathname[0] != '/')
1299 #endif
1300     gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
1301               gc_backend[backend].option_config_filename,
1302               gc_backend[backend].name);
1303
1304   return pathname;
1305 }
1306
1307 \f
1308 /* Retrieve the options for the component COMPONENT from backend
1309    BACKEND, which we already know is a program-type backend.  */
1310 static void
1311 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
1312 {
1313   char *cmd_line;
1314   char *line = NULL;
1315   size_t line_len = 0;
1316   ssize_t length;
1317   FILE *config;
1318   char *config_pathname;
1319
1320   cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program);
1321
1322   config = popen (cmd_line, "r");
1323   if (!config)
1324     gc_error (1, errno, "could not gather active options from %s", cmd_line);
1325
1326   while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1327     {
1328       gc_option_t *option;
1329       char *linep;
1330       unsigned long flags = 0;
1331       char *default_value = NULL;
1332       
1333       /* Strip newline and carriage return, if present.  */
1334       while (length > 0
1335              && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1336         line[--length] = '\0';
1337
1338       linep = strchr (line, ':');
1339       if (linep)
1340         *(linep++) = '\0';
1341       
1342       /* Extract additional flags.  Default to none.  */
1343       if (linep)
1344         {
1345           char *end;
1346           char *tail;
1347
1348           end = strchr (linep, ':');
1349           if (end)
1350             *(end++) = '\0';
1351
1352           errno = 0;
1353           flags = strtoul (linep, &tail, 0);
1354           if (errno)
1355             gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line);
1356           if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1357             gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line);
1358
1359           linep = end;
1360         }
1361
1362       /* Extract default value, if present.  Default to empty if
1363          not.  */
1364       if (linep)
1365         {
1366           char *end;
1367
1368           end = strchr (linep, ':');
1369           if (end)
1370             *(end++) = '\0';
1371
1372           if (flags & GC_OPT_FLAG_DEFAULT)
1373             default_value = linep;
1374
1375           linep = end;
1376         }
1377
1378       /* Look up the option in the component and install the
1379          configuration data.  */
1380       option = find_option (component, line, backend);
1381       if (option)
1382         {
1383           if (option->active)
1384             gc_error (1, errno, "option %s returned twice from %s",
1385                       line, cmd_line);
1386           option->active = 1;
1387
1388           option->flags |= flags;
1389           if (default_value && *default_value)
1390             option->default_value = xstrdup (default_value);
1391         }
1392     }
1393   if (length < 0 || ferror (config))
1394     gc_error (1, errno, "error reading from %s", cmd_line);
1395   if (fclose (config) && ferror (config))
1396     gc_error (1, errno, "error closing %s", cmd_line);
1397   xfree (cmd_line);
1398
1399   /* At this point, we can parse the configuration file.  */
1400   config_pathname = get_config_pathname (component, backend);
1401
1402   config = fopen (config_pathname, "r");
1403   if (!config)
1404     gc_error (0, errno, "warning: can not open config file %s",
1405               config_pathname);
1406   else
1407     {
1408       while ((length = read_line (config, &line, &line_len, NULL)) > 0)
1409         {
1410           char *name;
1411           char *value;
1412           gc_option_t *option;
1413           
1414           name = line;
1415           while (*name == ' ' || *name == '\t')
1416             name++;
1417           if (!*name || *name == '#' || *name == '\r' || *name == '\n')
1418             continue;
1419
1420           value = name;
1421           while (*value && *value != ' ' && *value != '\t'
1422                  && *value != '#' && *value != '\r' && *value != '\n')
1423             value++;
1424           if (*value == ' ' || *value == '\t')
1425             {
1426               char *end;
1427
1428               *(value++) = '\0';
1429               while (*value == ' ' || *value == '\t')
1430                 value++;
1431
1432               end = value;
1433               while (*end && *end != '#' && *end != '\r' && *end != '\n')
1434                 end++;
1435               while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
1436                 end--;
1437               *end = '\0';
1438             }
1439           else
1440             *value = '\0';
1441
1442           /* Look up the option in the component and install the
1443              configuration data.  */
1444           option = find_option (component, line, backend);
1445           if (option)
1446             {
1447               char *opt_value;
1448
1449               if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1450                 {
1451                   if (*value)
1452                     gc_error (0, 0,
1453                               "warning: ignoring argument %s for option %s",
1454                               value, name);
1455                   opt_value = xstrdup ("1");
1456                 }
1457               else if (gc_arg_type[option->arg_type].fallback
1458                        == GC_ARG_TYPE_STRING)
1459                 opt_value = xasprintf ("\"%s", percent_escape (value));
1460               else
1461                 {
1462                   /* FIXME: Verify that the number is sane.  */
1463                   opt_value = xstrdup (value);
1464                 }
1465
1466               /* Now enter the option into the table.  */
1467               if (!(option->flags & GC_OPT_FLAG_LIST))
1468                 {
1469                   if (option->value)
1470                     free (option->value);
1471                   option->value = opt_value;
1472                 }
1473               else
1474                 {
1475                   if (!option->value)
1476                     option->value = opt_value;
1477                   else
1478                     {
1479                       char *opt_val = opt_value;
1480
1481                       option->value = xasprintf ("%s,%s", option->value,
1482                                                  opt_val);
1483                       xfree (opt_value);
1484                     }
1485                 }
1486             }
1487         }
1488
1489       if (length < 0 || ferror (config))
1490         gc_error (1, errno, "error reading from %s", config_pathname);
1491       if (fclose (config) && ferror (config))
1492         gc_error (1, errno, "error closing %s", config_pathname);
1493     }
1494
1495   xfree (line);
1496 }
1497
1498
1499 /* Retrieve the options for the component COMPONENT from backend
1500    BACKEND, which we already know is of type file list.  */ 
1501 static void
1502 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
1503 {
1504   gc_option_t *list_option;
1505   char *list_pathname;
1506   FILE *list_file;
1507   char *line = NULL;
1508   size_t line_len = 0;
1509   ssize_t length;
1510   char *list = NULL;
1511
1512   list_option = find_option (component,
1513                              gc_backend[backend].option_name, GC_BACKEND_ANY);
1514   assert (list_option);
1515   assert (!list_option->active);
1516
1517   list_pathname = get_config_pathname (component, backend);
1518   list_file = fopen (list_pathname, "r");
1519   if (!list_file)
1520     gc_error (0, errno, "warning: can not open list file %s", list_pathname);
1521   else
1522     {
1523
1524       while ((length = read_line (list_file, &line, &line_len, NULL)) > 0)
1525         {
1526           char *start;
1527           char *end;
1528           char *new_list;
1529
1530           start = line;
1531           while (*start == ' ' || *start == '\t')
1532             start++;
1533           if (!*start || *start == '#' || *start == '\r' || *start == '\n')
1534             continue;
1535
1536           end = start;
1537           while (*end && *end != '#' && *end != '\r' && *end != '\n')
1538             end++;
1539           /* Walk back to skip trailing white spaces.  Looks evil, but
1540              works because of the conditions on START and END imposed
1541              at this point (END is at least START + 1, and START is
1542              not a whitespace character).  */
1543           while (*(end - 1) == ' ' || *(end - 1) == '\t')
1544             end--;
1545           *end = '\0';
1546           /* FIXME: Oh, no!  This is so lame!  Should use realloc and
1547              really append.  */
1548           if (list)
1549             {
1550               new_list = xasprintf ("%s,\"%s", list, percent_escape (start));
1551               xfree (list);
1552               list = new_list;
1553             }
1554           else
1555             list = xasprintf ("\"%s", percent_escape (start));
1556         }
1557       if (length < 0 || ferror (list_file))
1558         gc_error (1, errno, "can not read list file %s", list_pathname);
1559     }
1560
1561   list_option->active = 1;
1562   list_option->value = list;
1563
1564   xfree (line);
1565 }
1566
1567
1568 /* Retrieve the currently active options and their defaults from all
1569    involved backends for this component.  Using -1 for component will
1570    retrieve all options from all components. */
1571 void
1572 gc_component_retrieve_options (int component)
1573 {
1574   int process_all = 0;
1575   int backend_seen[GC_BACKEND_NR];
1576   gc_backend_t backend;
1577   gc_option_t *option;
1578
1579   for (backend = 0; backend < GC_BACKEND_NR; backend++)
1580     backend_seen[backend] = 0;
1581
1582   if (component == -1)
1583     {
1584       process_all = 1;
1585       component = 0;
1586       assert (component < GC_COMPONENT_NR);
1587     }
1588       
1589   do
1590     {
1591       option = gc_component[component].options;
1592
1593       while (option->name)
1594         {
1595           if (!(option->flags & GC_OPT_FLAG_GROUP))
1596             {
1597               backend = option->backend;
1598               
1599               if (backend_seen[backend])
1600                 {
1601                   option++;
1602                   continue;
1603                 }
1604               backend_seen[backend] = 1;
1605               
1606               assert (backend != GC_BACKEND_ANY);
1607               
1608               if (gc_backend[backend].program)
1609                 retrieve_options_from_program (component, backend);
1610               else
1611                 retrieve_options_from_file (component, backend);
1612             }
1613           option++;
1614         }
1615     }
1616   while (process_all && ++component < GC_COMPONENT_NR);
1617
1618 }
1619 \f
1620 /* Perform a simple validity check based on the type.  Return in
1621    NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
1622    type GC_ARG_TYPE_NONE.  */
1623 static void
1624 option_check_validity (gc_option_t *option, unsigned long flags,
1625                        char *new_value, unsigned long *new_value_nr)
1626 {
1627   char *arg;
1628
1629   if (!option->active)
1630     gc_error (1, 0, "option %s not supported by backend %s",
1631               option->name, gc_backend[option->backend].name);
1632       
1633   if (option->new_flags || option->new_value)
1634     gc_error (1, 0, "option %s already changed", option->name);
1635
1636   if (flags & GC_OPT_FLAG_DEFAULT)
1637     {
1638       if (*new_value)
1639         gc_error (1, 0, "argument %s provided for deleted option %s",
1640                   new_value, option->name);
1641
1642       return;
1643     }
1644
1645   /* GC_ARG_TYPE_NONE options have special list treatment.  */
1646   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
1647     {
1648       char *tail;
1649
1650       errno = 0;
1651       *new_value_nr = strtoul (new_value, &tail, 0);
1652
1653       if (errno)
1654         gc_error (1, errno, "invalid argument for option %s",
1655                   option->name);
1656       if (*tail)
1657         gc_error (1, 0, "garbage after argument for option %s",
1658                       option->name);
1659
1660       if (!(option->flags & GC_OPT_FLAG_LIST))
1661         {
1662           if (*new_value_nr != 1)
1663             gc_error (1, 0, "argument for non-list option %s of type 0 "
1664                       "(none) must be 1", option->name);
1665         }
1666       else
1667         {
1668           if (*new_value_nr == 0)
1669             gc_error (1, 0, "argument for option %s of type 0 (none) "
1670                       "must be positive", option->name);
1671         }
1672
1673       return;
1674     }
1675
1676   arg = new_value;
1677   do
1678     {
1679       if (*arg == '\0' || *arg == ',')
1680         {
1681           if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
1682             gc_error (1, 0, "argument required for option %s", option->name);
1683
1684           if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
1685             gc_error (1, 0, "list found for non-list option %s", option->name);
1686         }
1687       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
1688         {
1689           if (*arg != '"')
1690             gc_error (1, 0, "string argument for option %s must begin "
1691                       "with a quote (\") character", option->name);
1692         }
1693       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1694         {
1695           errno = 0;
1696           (void) strtol (arg, &arg, 0);
1697
1698           if (errno)
1699             gc_error (1, errno, "invalid argument for option %s",
1700                       option->name);
1701
1702           if (*arg != '\0' && *arg != ',')
1703             gc_error (1, 0, "garbage after argument for option %s",
1704                       option->name);
1705         }
1706       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
1707         {
1708           errno = 0;
1709           (void) strtoul (arg, &arg, 0);
1710
1711           if (errno)
1712             gc_error (1, errno, "invalid argument for option %s",
1713                       option->name);
1714
1715           if (*arg != '\0' && *arg != ',')
1716             gc_error (1, 0, "garbage after argument for option %s",
1717                       option->name);
1718         }
1719       arg = strchr (arg, ',');
1720       if (arg)
1721         arg++;
1722     }
1723   while (arg && *arg);
1724 }
1725
1726
1727 /* Create and verify the new configuration file for the specified
1728    backend and component.  Returns 0 on success and -1 on error.  */
1729 static int
1730 change_options_file (gc_component_t component, gc_backend_t backend,
1731                      char **src_filenamep, char **dest_filenamep,
1732                      char **orig_filenamep)
1733 {
1734   static const char marker[] = "###+++--- GPGConf ---+++###";
1735   /* True if we are within the marker in the config file.  */
1736   int in_marker = 0;
1737   gc_option_t *option;
1738   char *line = NULL;
1739   size_t line_len;
1740   ssize_t length;
1741   int res;
1742   int fd;
1743   FILE *src_file = NULL;
1744   FILE *dest_file = NULL;
1745   char *src_filename;
1746   char *dest_filename;
1747   char *orig_filename;
1748   char *arg;
1749   char *cur_arg = NULL;
1750
1751   option = find_option (component,
1752                         gc_backend[backend].option_name, GC_BACKEND_ANY);
1753   assert (option);
1754   assert (option->active);
1755   assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
1756
1757   /* FIXME.  Throughout the function, do better error reporting.  */
1758   /* Note that get_config_pathname() calls percent_deescape(), so we
1759      call this before processing the arguments.  */
1760   dest_filename = xstrdup (get_config_pathname (component, backend));
1761   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
1762   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
1763
1764   arg = option->new_value;
1765   if (arg && arg[0] == '\0')
1766     arg = NULL;
1767   else if (arg)
1768     {
1769       char *end;
1770
1771       arg++;
1772       end = strchr (arg, ',');
1773       if (end)
1774         *end = '\0';
1775
1776       cur_arg = percent_deescape (arg);
1777       if (end)
1778         {
1779           *end = ',';
1780           arg = end + 1;
1781         }
1782       else
1783         arg = NULL;
1784     }
1785
1786 #if HAVE_W32_SYSTEM
1787   res = 0; 
1788 #warning no backups for W32 yet - need to write a copy function
1789 #else
1790   res = link (dest_filename, orig_filename);
1791 #endif
1792   if (res < 0 && errno != ENOENT)
1793     return -1;
1794   if (res < 0)
1795     {
1796       xfree (orig_filename);
1797       orig_filename = NULL;
1798     }
1799
1800   /* We now initialize the return strings, so the caller can do the
1801      cleanup for us.  */
1802   *src_filenamep = src_filename;
1803   *dest_filenamep = dest_filename;
1804   *orig_filenamep = orig_filename;
1805
1806   /* Use open() so that we can use O_EXCL.  */
1807   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
1808   if (fd < 0)
1809     return -1;
1810   src_file = fdopen (fd, "w");
1811   res = errno;
1812   if (!src_file)
1813     {
1814       errno = res;
1815       return -1;
1816     }
1817
1818   /* Only if ORIG_FILENAME is not NULL did the configuration file
1819      exist already.  In this case, we will copy its content into the
1820      new configuration file, changing it to our liking in the
1821      process.  */
1822   if (orig_filename)
1823     {
1824       dest_file = fopen (dest_filename, "r");
1825       if (!dest_file)
1826         goto change_file_one_err;
1827
1828       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
1829         {
1830           int disable = 0;
1831           char *start;
1832
1833           if (!strncmp (marker, line, sizeof (marker) - 1))
1834             {
1835               if (!in_marker)
1836                 in_marker = 1;
1837               else
1838                 break;
1839             }
1840
1841           start = line;
1842           while (*start == ' ' || *start == '\t')
1843             start++;
1844           if (*start && *start != '\r' && *start != '\n' && *start != '#')
1845             {
1846               char *end;
1847               char *endp;
1848               char saved_end;
1849
1850               endp = start;
1851               end = endp;
1852
1853               /* Search for the end of the line.  */
1854               while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
1855                 {
1856                   endp++;
1857                   if (*endp && *endp != ' ' && *endp != '\t'
1858                       && *endp != '\r' && *endp != '\n' && *endp != '#')
1859                     end = endp + 1;
1860                 }
1861               saved_end = *end;
1862               *end = '\0';
1863
1864               if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
1865                   || !cur_arg || strcmp (start, cur_arg))
1866                 disable = 1;
1867               else
1868                 {
1869                   /* Find next argument.  */
1870                   if (arg)
1871                     {
1872                       char *arg_end;
1873
1874                       arg++;
1875                       arg_end = strchr (arg, ',');
1876                       if (arg_end)
1877                         *arg_end = '\0';
1878
1879                       cur_arg = percent_deescape (arg);
1880                       if (arg_end)
1881                         {
1882                           *arg_end = ',';
1883                           arg = arg_end + 1;
1884                         }
1885                       else
1886                         arg = NULL;
1887                     }
1888                   else
1889                     cur_arg = NULL;
1890                 }
1891
1892               *end = saved_end;
1893             }
1894
1895           if (disable)
1896             {
1897               if (!in_marker)
1898                 {
1899                   fprintf (src_file,
1900                            "# GPGConf disabled this option here at %s\n",
1901                            asctimestamp (gnupg_get_time ()));
1902                   if (ferror (src_file))
1903                     goto change_file_one_err;
1904                   fprintf (src_file, "# %s", line);
1905                   if (ferror (src_file))
1906                     goto change_file_one_err;
1907                 }
1908             }
1909           else
1910             {
1911               fprintf (src_file, "%s", line);
1912               if (ferror (src_file))
1913                 goto change_file_one_err;
1914             }
1915         }
1916       if (length < 0 || ferror (dest_file))
1917         goto change_file_one_err;
1918     }
1919
1920   if (!in_marker)
1921     {
1922       /* There was no marker.  This is the first time we edit the
1923          file.  We add our own marker at the end of the file and
1924          proceed.  Note that we first write a newline, this guards us
1925          against files which lack the newline at the end of the last
1926          line, while it doesn't hurt us in all other cases.  */
1927       fprintf (src_file, "\n%s\n", marker);
1928       if (ferror (src_file))
1929         goto change_file_one_err;
1930     }
1931
1932   /* At this point, we have copied everything up to the end marker
1933      into the new file, except for the arguments we are going to add.
1934      Now, dump the new arguments and write the end marker, possibly
1935      followed by the rest of the original file.  */
1936   while (cur_arg)
1937     {
1938       fprintf (src_file, "%s\n", cur_arg);
1939
1940       /* Find next argument.  */
1941       if (arg)
1942         {
1943           char *end;
1944
1945           arg++;
1946           end = strchr (arg, ',');
1947           if (end)
1948             *end = '\0';
1949
1950           cur_arg = percent_deescape (arg);
1951           if (end)
1952             {
1953               *end = ',';
1954               arg = end + 1;
1955             }
1956           else
1957             arg = NULL;
1958         }
1959       else
1960         cur_arg = NULL;
1961     }
1962
1963   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
1964   if (ferror (src_file))
1965     goto change_file_one_err;
1966
1967   if (!in_marker)
1968     {
1969       fprintf (src_file, "# GPGConf edited this configuration file.\n");
1970       if (ferror (src_file))
1971         goto change_file_one_err;
1972       fprintf (src_file, "# It will disable options before this marked "
1973                "block, but it will\n");
1974       if (ferror (src_file))
1975         goto change_file_one_err;
1976       fprintf (src_file, "# never change anything below these lines.\n");
1977       if (ferror (src_file))
1978         goto change_file_one_err;
1979     }
1980   if (dest_file)
1981     {
1982       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
1983         {
1984           fprintf (src_file, "%s", line);
1985           if (ferror (src_file))
1986             goto change_file_one_err;
1987         }
1988       if (length < 0 || ferror (dest_file))
1989         goto change_file_one_err;
1990     }
1991   xfree (line);
1992   line = NULL;
1993
1994   res = fclose (src_file);
1995   if (res)
1996     {
1997       res = errno;
1998       close (fd);
1999       if (dest_file)
2000         fclose (dest_file);
2001       errno = res;
2002       return -1;
2003     }
2004   close (fd);
2005   if (dest_file)
2006     {
2007       res = fclose (dest_file);
2008       if (res)
2009         return -1;
2010     }
2011   return 0;
2012
2013  change_file_one_err:
2014   xfree (line);
2015   res = errno;
2016   if (src_file)
2017     {
2018       fclose (src_file);
2019       close (fd);
2020     }
2021   if (dest_file)
2022     fclose (dest_file);
2023   errno = res;
2024   return -1;
2025 }
2026
2027
2028 /* Create and verify the new configuration file for the specified
2029    backend and component.  Returns 0 on success and -1 on error.  */
2030 static int
2031 change_options_program (gc_component_t component, gc_backend_t backend,
2032                         char **src_filenamep, char **dest_filenamep,
2033                         char **orig_filenamep)
2034 {
2035   static const char marker[] = "###+++--- GPGConf ---+++###";
2036   /* True if we are within the marker in the config file.  */
2037   int in_marker = 0;
2038   gc_option_t *option;
2039   char *line = NULL;
2040   size_t line_len;
2041   ssize_t length;
2042   int res;
2043   int fd;
2044   FILE *src_file = NULL;
2045   FILE *dest_file = NULL;
2046   char *src_filename;
2047   char *dest_filename;
2048   char *orig_filename;
2049
2050   /* FIXME.  Throughout the function, do better error reporting.  */
2051   dest_filename = xstrdup (get_config_pathname (component, backend));
2052   src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ());
2053   orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ());
2054
2055 #if HAVE_W32_SYSTEM
2056   res = 0; 
2057 #warning no backups for W32 yet - need to write a copy function
2058 #else
2059   res = link (dest_filename, orig_filename);
2060 #endif
2061   if (res < 0 && errno != ENOENT)
2062     return -1;
2063   if (res < 0)
2064     {
2065       xfree (orig_filename);
2066       orig_filename = NULL;
2067     }
2068
2069   /* We now initialize the return strings, so the caller can do the
2070      cleanup for us.  */
2071   *src_filenamep = src_filename;
2072   *dest_filenamep = dest_filename;
2073   *orig_filenamep = orig_filename;
2074
2075   /* Use open() so that we can use O_EXCL.  */
2076   fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2077   if (fd < 0)
2078     return -1;
2079   src_file = fdopen (fd, "w");
2080   res = errno;
2081   if (!src_file)
2082     {
2083       errno = res;
2084       return -1;
2085     }
2086
2087   /* Only if ORIG_FILENAME is not NULL did the configuration file
2088      exist already.  In this case, we will copy its content into the
2089      new configuration file, changing it to our liking in the
2090      process.  */
2091   if (orig_filename)
2092     {
2093       dest_file = fopen (dest_filename, "r");
2094       if (!dest_file)
2095         goto change_one_err;
2096
2097       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2098         {
2099           int disable = 0;
2100           char *start;
2101
2102           if (!strncmp (marker, line, sizeof (marker) - 1))
2103             {
2104               if (!in_marker)
2105                 in_marker = 1;
2106               else
2107                 break;
2108             }
2109
2110           start = line;
2111           while (*start == ' ' || *start == '\t')
2112             start++;
2113           if (*start && *start != '\r' && *start != '\n' && *start != '#')
2114             {
2115               char *end;
2116               char saved_end;
2117
2118               end = start;
2119               while (*end && *end != ' ' && *end != '\t'
2120                      && *end != '\r' && *end != '\n' && *end != '#')
2121                 end++;
2122               saved_end = *end;
2123               *end = '\0';
2124
2125               option = find_option (component, start, backend);
2126               *end = saved_end;
2127               if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2128                              || option->new_value))
2129                 disable = 1;
2130             }
2131           if (disable)
2132             {
2133               if (!in_marker)
2134                 {
2135                   fprintf (src_file,
2136                            "# GPGConf disabled this option here at %s\n",
2137                            asctimestamp (gnupg_get_time ()));
2138                   if (ferror (src_file))
2139                     goto change_one_err;
2140                   fprintf (src_file, "# %s", line);
2141                   if (ferror (src_file))
2142                     goto change_one_err;
2143                 }
2144             }
2145           else
2146             {
2147               fprintf (src_file, "%s", line);
2148               if (ferror (src_file))
2149                 goto change_one_err;
2150             }
2151         }
2152       if (length < 0 || ferror (dest_file))
2153         goto change_one_err;
2154     }
2155
2156   if (!in_marker)
2157     {
2158       /* There was no marker.  This is the first time we edit the
2159          file.  We add our own marker at the end of the file and
2160          proceed.  Note that we first write a newline, this guards us
2161          against files which lack the newline at the end of the last
2162          line, while it doesn't hurt us in all other cases.  */
2163       fprintf (src_file, "\n%s\n", marker);
2164       if (ferror (src_file))
2165         goto change_one_err;
2166     }
2167   /* At this point, we have copied everything up to the end marker
2168      into the new file, except for the options we are going to change.
2169      Now, dump the changed options (except for those we are going to
2170      revert to their default), and write the end marker, possibly
2171      followed by the rest of the original file.  */
2172
2173   /* We have to turn on UTF8 strings for GnuPG.  */
2174   if (backend == GC_BACKEND_GPG)
2175     fprintf (src_file, "utf8-strings\n");
2176
2177   option = gc_component[component].options;
2178   while (option->name)
2179     {
2180       if (!(option->flags & GC_OPT_FLAG_GROUP)
2181           && option->backend == backend
2182           && option->new_value)
2183         {
2184           char *arg = option->new_value;
2185
2186           do
2187             {
2188               if (*arg == '\0' || *arg == ',')
2189                 {
2190                   fprintf (src_file, "%s\n", option->name);
2191                   if (ferror (src_file))
2192                     goto change_one_err;
2193                 }
2194               else if (gc_arg_type[option->arg_type].fallback
2195                        == GC_ARG_TYPE_NONE)
2196                 {
2197                   assert (*arg == '1');
2198                   fprintf (src_file, "%s\n", option->name);
2199                   if (ferror (src_file))
2200                     goto change_one_err;
2201
2202                   arg++;
2203                 }
2204               else if (gc_arg_type[option->arg_type].fallback
2205                        == GC_ARG_TYPE_STRING)
2206                 {
2207                   char *end;
2208                   
2209                   assert (*arg == '"');
2210                   arg++;
2211                   
2212                   end = strchr (arg, ',');
2213                   if (end)
2214                     *end = '\0';
2215
2216                   fprintf (src_file, "%s %s\n", option->name,
2217                            percent_deescape (arg));
2218                   if (ferror (src_file))
2219                     goto change_one_err;
2220
2221                   if (end)
2222                     *end = ',';
2223                   arg = end;
2224                 }
2225               else
2226                 {
2227                   char *end;
2228
2229                   end = strchr (arg, ',');
2230                   if (end)
2231                     *end = '\0';
2232
2233                   fprintf (src_file, "%s %s\n", option->name, arg);
2234                   if (ferror (src_file))
2235                     goto change_one_err;
2236
2237                   if (end)
2238                     *end = ',';
2239                   arg = end;
2240                 }
2241
2242               assert (arg == NULL || *arg == '\0' || *arg == ',');
2243               if (arg && *arg == ',')
2244                 arg++;
2245             }
2246           while (arg && *arg);
2247         }
2248       option++;
2249     }
2250
2251   fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2252   if (ferror (src_file))
2253     goto change_one_err;
2254
2255   if (!in_marker)
2256     {
2257       fprintf (src_file, "# GPGConf edited this configuration file.\n");
2258       if (ferror (src_file))
2259         goto change_one_err;
2260       fprintf (src_file, "# It will disable options before this marked "
2261                "block, but it will\n");
2262       if (ferror (src_file))
2263         goto change_one_err;
2264       fprintf (src_file, "# never change anything below these lines.\n");
2265       if (ferror (src_file))
2266         goto change_one_err;
2267     }
2268   if (dest_file)
2269     {
2270       while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0)
2271         {
2272           fprintf (src_file, "%s", line);
2273           if (ferror (src_file))
2274             goto change_one_err;
2275         }
2276       if (length < 0 || ferror (dest_file))
2277         goto change_one_err;
2278     }
2279   xfree (line);
2280   line = NULL;
2281
2282   res = fclose (src_file);
2283   if (res)
2284     {
2285       res = errno;
2286       close (fd);
2287       if (dest_file)
2288         fclose (dest_file);
2289       errno = res;
2290       return -1;
2291     }
2292   close (fd);
2293   if (dest_file)
2294     {
2295       res = fclose (dest_file);
2296       if (res)
2297         return -1;
2298     }
2299   return 0;
2300
2301  change_one_err:
2302   xfree (line);
2303   res = errno;
2304   if (src_file)
2305     {
2306       fclose (src_file);
2307       close (fd);
2308     }
2309   if (dest_file)
2310     fclose (dest_file);
2311   errno = res;
2312   return -1;
2313 }
2314
2315
2316 /* Common code for gc_component_change_options and
2317    gc_process_gpgconf_conf.  */
2318 static void
2319 change_one_value (gc_option_t *option, int *runtime,
2320                   unsigned long flags, char *new_value)
2321 {
2322   unsigned long new_value_nr = 0;
2323
2324   option_check_validity (option, flags, new_value, &new_value_nr);
2325
2326   if (option->flags & GC_OPT_FLAG_RUNTIME)
2327     runtime[option->backend] = 1;
2328
2329   option->new_flags = flags;
2330   if (!(flags & GC_OPT_FLAG_DEFAULT))
2331     {
2332       if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2333           && (option->flags & GC_OPT_FLAG_LIST))
2334         {
2335           char *str;
2336
2337           /* We convert the number to a list of 1's for convenient
2338              list handling.  */
2339           assert (new_value_nr > 0);
2340           option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2341           str = option->new_value;
2342           *(str++) = '1';
2343           while (--new_value_nr > 0)
2344             {
2345               *(str++) = ',';
2346               *(str++) = '1';
2347             }
2348           *(str++) = '\0';
2349         }
2350       else
2351         option->new_value = xstrdup (new_value);
2352     }
2353 }
2354
2355
2356 /* Read the modifications from IN and apply them.  If IN is NULL the
2357    modifications are expected to already have been set to the global
2358    table. */
2359 void
2360 gc_component_change_options (int component, FILE *in)
2361 {
2362   int err = 0;
2363   int runtime[GC_BACKEND_NR];
2364   char *src_pathname[GC_BACKEND_NR];
2365   char *dest_pathname[GC_BACKEND_NR];
2366   char *orig_pathname[GC_BACKEND_NR];
2367   gc_backend_t backend;
2368   gc_option_t *option;
2369   char *line = NULL;
2370   size_t line_len = 0;
2371   ssize_t length;
2372
2373   for (backend = 0; backend < GC_BACKEND_NR; backend++)
2374     {
2375       runtime[backend] = 0;
2376       src_pathname[backend] = NULL;
2377       dest_pathname[backend] = NULL;
2378       orig_pathname[backend] = NULL;
2379     }
2380
2381   if (in)
2382     {
2383       /* Read options from the file IN.  */
2384       while ((length = read_line (in, &line, &line_len, NULL)) > 0)
2385         {
2386           char *linep;
2387           unsigned long flags = 0;
2388           char *new_value = "";
2389           
2390           /* Strip newline and carriage return, if present.  */
2391           while (length > 0
2392                  && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2393             line[--length] = '\0';
2394           
2395           linep = strchr (line, ':');
2396           if (linep)
2397             *(linep++) = '\0';
2398           
2399           /* Extract additional flags.  Default to none.  */
2400           if (linep)
2401             {
2402               char *end;
2403               char *tail;
2404
2405               end = strchr (linep, ':');
2406               if (end)
2407                 *(end++) = '\0';
2408               
2409               errno = 0;
2410               flags = strtoul (linep, &tail, 0);
2411               if (errno)
2412                 gc_error (1, errno, "malformed flags in option %s", line);
2413               if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
2414                 gc_error (1, 0, "garbage after flags in option %s", line);
2415               
2416               linep = end;
2417             }
2418
2419           /* Don't allow setting of the no change flag.  */
2420           flags &= ~GC_OPT_FLAG_NO_CHANGE;
2421           
2422           /* Extract default value, if present.  Default to empty if not.  */
2423           if (linep)
2424             {
2425               char *end;
2426               end = strchr (linep, ':');
2427               if (end)
2428                 *(end++) = '\0';
2429               new_value = linep;
2430               linep = end;
2431             }
2432           
2433           option = find_option (component, line, GC_BACKEND_ANY);
2434           if (!option)
2435             gc_error (1, 0, "unknown option %s", line);
2436           
2437           if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
2438             {
2439               gc_error (0, 0, "ignoring new value for option %s",
2440                         option->name);
2441               continue;
2442             }
2443           
2444           change_one_value (option, runtime, flags, new_value);
2445         }
2446     }
2447
2448   /* Now that we have collected and locally verified the changes,
2449      write them out to new configuration files, verify them
2450      externally, and then commit them.  */
2451   option = gc_component[component].options;
2452   while (option->name)
2453     {
2454       /* Go on if we have already seen this backend, or if there is
2455          nothing to do.  */
2456       if (src_pathname[option->backend]
2457           || !(option->new_flags || option->new_value))
2458         {
2459           option++;
2460           continue;
2461         }
2462
2463       if (gc_backend[option->backend].program)
2464         err = change_options_program (component, option->backend,
2465                                       &src_pathname[option->backend],
2466                                       &dest_pathname[option->backend],
2467                                       &orig_pathname[option->backend]);
2468       else
2469         err = change_options_file (component, option->backend,
2470                                    &src_pathname[option->backend],
2471                                    &dest_pathname[option->backend],
2472                                    &orig_pathname[option->backend]);
2473         
2474       if (err)
2475         break;
2476           
2477       option++;
2478     }
2479
2480   if (!err)
2481     {
2482       int i;
2483
2484       for (i = 0; i < GC_BACKEND_NR; i++)
2485         {
2486           if (src_pathname[i])
2487             {
2488               /* FIXME: Make a verification here.  */
2489
2490               assert (dest_pathname[i]);
2491
2492               if (orig_pathname[i])
2493                 err = rename (src_pathname[i], dest_pathname[i]);
2494               else
2495                 {
2496 #ifdef HAVE_W32_SYSTEM
2497                   /* FIXME: Won't work becuase W32 doesn't silently
2498                      overwrite. Fix it by creating a backup copy and
2499                      deliting the orginal file first. */
2500                   err = rename (src_pathname[i], dest_pathname[i]);
2501 #else /*!HAVE_W32_SYSTEM*/
2502                   /* This is a bit safer than rename() because we
2503                      expect DEST_PATHNAME not to be there.  If it
2504                      happens to be there, this will fail.  */
2505                   err = link (src_pathname[i], dest_pathname[i]);
2506                   if (!err)
2507                     unlink (src_pathname[i]);
2508 #endif /*!HAVE_W32_SYSTEM*/
2509                 }
2510               if (err)
2511                 break;
2512               src_pathname[i] = NULL;
2513             }
2514         }
2515     }
2516
2517   if (err)
2518     {
2519       int i;
2520       int saved_errno = errno;
2521
2522       /* An error occured.  */
2523       for (i = 0; i < GC_BACKEND_NR; i++)
2524         {
2525           if (src_pathname[i])
2526             {
2527               /* The change was not yet committed.  */
2528               unlink (src_pathname[i]);
2529               if (orig_pathname[i])
2530                 unlink (orig_pathname[i]);
2531             }
2532           else
2533             {
2534               /* The changes were already committed.  FIXME: This is a
2535                  tad dangerous, as we don't know if we don't overwrite
2536                  a version of the file that is even newer than the one
2537                  we just installed.  */
2538               if (orig_pathname[i])
2539                 rename (orig_pathname[i], dest_pathname[i]);
2540               else
2541                 unlink (dest_pathname[i]);
2542             }
2543         }
2544       gc_error (1, saved_errno, "could not commit changes");
2545     }
2546
2547   /* If it all worked, notify the daemons of the changes.  */
2548   if (opt.runtime)
2549     for (backend = 0; backend < GC_BACKEND_NR; backend++)  
2550       {
2551         if (runtime[backend] && gc_backend[backend].runtime_change)
2552           (*gc_backend[backend].runtime_change) ();
2553       }
2554
2555   /* Move the per-process backup file into its place.  */
2556   for (backend = 0; backend < GC_BACKEND_NR; backend++)  
2557     if (orig_pathname[backend])
2558       {
2559         char *backup_pathname;
2560
2561         assert (dest_pathname[backend]);
2562
2563         backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]);
2564         rename (orig_pathname[backend], backup_pathname);
2565       }
2566
2567   xfree (line);
2568 }
2569
2570
2571 /* Check whether USER matches the current user of one of its group.
2572    This function may change USER.  Returns true is there is a
2573    match.  */
2574 static int
2575 key_matches_user_or_group (char *user)
2576 {
2577   char *group;
2578   int n;
2579
2580   if (*user == '*' && user[1] == 0)
2581     return 1; /* A single asterisk matches all users.  */
2582
2583   group = strchr (user, ':');
2584   if (group)
2585     *group++ = 0;
2586
2587   /* First check whether the user matches.  */
2588   if (*user)
2589     {
2590       static char *my_name;
2591
2592       if (!my_name)
2593         {
2594           struct passwd *pw = getpwuid ( getuid () );
2595           if (!pw)
2596             gc_error (1, errno, "getpwuid failed for current user");
2597           my_name = xstrdup (pw->pw_name);
2598         }
2599       if (!strcmp (user, my_name))
2600         return 1; /* Found.  */
2601     }
2602
2603   /* If that failed, check whether a group matches.  */
2604   if (group && *group)
2605     {
2606       static char *my_group;
2607       static char **my_supgroups;
2608
2609       if (!my_group)
2610         {
2611           struct group *gr = getgrgid ( getgid () );
2612           if (!gr)
2613             gc_error (1, errno, "getgrgid failed for current user");
2614           my_group = xstrdup (gr->gr_name);
2615         }
2616       if (!strcmp (group, my_group))
2617         return 1; /* Found.  */
2618
2619       if (!my_supgroups)
2620         {
2621           int ngids;
2622           gid_t *gids;
2623
2624           ngids = getgroups (0, NULL);
2625           gids  = xcalloc (ngids+1, sizeof *gids);
2626           ngids = getgroups (ngids, gids);
2627           if (ngids < 0)
2628             gc_error (1, errno, "getgroups failed for current user");
2629           my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
2630           for (n=0; n < ngids; n++)
2631             {
2632               struct group *gr = getgrgid ( gids[n] );
2633               if (!gr)
2634                 gc_error (1, errno, "getgrgid failed for supplementary group");
2635               my_supgroups[n] = xstrdup (gr->gr_name);
2636             }
2637           xfree (gids);
2638         }
2639
2640       for (n=0; my_supgroups[n]; n++)
2641         if (!strcmp (group, my_supgroups[n]))
2642           return 1; /* Found.  */
2643     }
2644
2645   return 0; /* No match.  */
2646 }
2647
2648
2649
2650 /* Read and process the global configuration file for gpgconf.  This
2651    optional file is used to update our internal tables at runtime and
2652    may also be used to set new default values.  If FNAME is NULL the
2653    default name will be used.  With UPDATE set to true the internal
2654    tables are actually updated; if not set, only a syntax check is
2655    done.  If DEFAULTS is true the global options are written to the
2656    configuration files.
2657
2658    Returns 0 on success or if the config file is not present; -1 is
2659    returned on error. */
2660 int
2661 gc_process_gpgconf_conf (const char *fname, int update, int defaults)
2662 {
2663   int result = 0;
2664   char *line = NULL;
2665   size_t line_len = 0;
2666   ssize_t length;
2667   FILE *config;
2668   int lineno = 0;
2669   int in_rule = 0;
2670   int got_match = 0;
2671   int runtime[GC_BACKEND_NR];
2672   int used_components[GC_COMPONENT_NR];
2673   int backend_id, component_id;
2674
2675   if (!fname)
2676     fname = GNUPG_SYSCONFDIR "/gpgconf.conf";
2677
2678   for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
2679     runtime[backend_id] = 0;
2680   for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
2681     used_components[component_id] = 0;
2682
2683   config = fopen (fname, "r");
2684   if (!config)
2685     {
2686       /* Do not print an error if the file is not available, except
2687          when runnign in syntax check mode.  */
2688       if (errno != ENOENT || !update)
2689         {
2690           gc_error (0, errno, "can not open global config file `%s'", fname);
2691           result = -1;
2692         }
2693       return result;
2694     }
2695
2696   while ((length = read_line (config, &line, &line_len, NULL)) > 0)
2697     {
2698       char *key, *component, *option, *flags, *value;
2699       char *empty;
2700       gc_option_t *option_info = NULL;
2701       char *p;
2702       int is_continuation;
2703       
2704       lineno++;
2705       key = line;
2706       while (*key == ' ' || *key == '\t')
2707         key++;
2708       if (!*key || *key == '#' || *key == '\r' || *key == '\n')
2709         continue;
2710
2711       is_continuation = (key != line);
2712
2713       /* Parse the key field.  */
2714       if (!is_continuation && got_match)
2715         break;  /* Finish after the first match.  */
2716       else if (!is_continuation)
2717         {
2718           in_rule = 0;
2719           for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
2720             ;
2721           if (!*p)
2722             {
2723               gc_error (0, 0, "missing rule at `%s', line %d", fname, lineno);
2724               result = -1;
2725               continue;
2726             }
2727           *p++ = 0;
2728           component = p;
2729         }
2730       else if (!in_rule)
2731         {
2732           gc_error (0, 0, "continuation but no rule at `%s', line %d",
2733                     fname, lineno);
2734           result = -1;
2735           continue;
2736         }
2737       else
2738         {
2739           component = key;
2740           key = NULL;
2741         }
2742
2743       in_rule = 1;
2744
2745       /* Parse the component.  */
2746       while (*component == ' ' || *component == '\t')
2747         component++;
2748       for (p=component; *p && !strchr (" \t\r\n", *p); p++)
2749         ;
2750       if (p == component)
2751         {
2752           gc_error (0, 0, "missing component at `%s', line %d",
2753                     fname, lineno);
2754           result = -1;
2755           continue;
2756         }
2757       empty = p;
2758       *p++ = 0;
2759       option = p;
2760       component_id = gc_component_find (component);
2761       if (component_id < 0)
2762         {
2763           gc_error (0, 0, "unknown component at `%s', line %d",
2764                     fname, lineno);
2765           result = -1;
2766         }
2767
2768       /* Parse the option name.  */
2769       while (*option == ' ' || *option == '\t')
2770         option++;
2771       for (p=option; *p && !strchr (" \t\r\n", *p); p++)
2772         ;
2773       if (p == option)
2774         {
2775           gc_error (0, 0, "missing option at `%s', line %d",
2776                     fname, lineno);
2777           result = -1;
2778           continue;
2779         }
2780       *p++ = 0;
2781       flags = p;
2782       if ( component_id != -1)
2783         {
2784           option_info = find_option (component_id, option, GC_BACKEND_ANY);
2785           if (!option_info)
2786             {
2787               gc_error (0, 0, "unknown option at `%s', line %d",
2788                         fname, lineno);
2789               result = -1;
2790             }
2791         }
2792
2793
2794       /* Parse the optional flags.  */
2795       while (*flags == ' ' || *flags == '\t')
2796         flags++;
2797       if (*flags == '[')
2798         {
2799           flags++;
2800           p = strchr (flags, ']');
2801           if (!p)
2802             {
2803               gc_error (0, 0, "syntax error in rule at `%s', line %d",
2804                         fname, lineno);
2805               result = -1;
2806               continue;
2807             }
2808           *p++ = 0;
2809           value = p;
2810         }
2811       else  /* No flags given.  */
2812         {
2813           value = flags;
2814           flags = NULL;
2815         }
2816
2817       /* Parse the optional value.  */
2818       while (*value == ' ' || *value == '\t')
2819        value++;
2820       for (p=value; *p && !strchr ("\r\n", *p); p++)
2821         ;
2822       if (p == value)
2823         value = empty; /* No value given; let it point to an empty string.  */
2824       else
2825         {
2826           /* Strip trailing white space.  */
2827           *p = 0;
2828           for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
2829             *p = 0;
2830         }
2831
2832       /* Check flag combinations.  */
2833       if (!flags)
2834         ;
2835       else if (!strcmp (flags, "default"))
2836         {
2837           if (*value)
2838             {
2839               gc_error (0, 0, "flag \"default\" may not be combined "
2840                         "with a value at `%s', line %d",
2841                         fname, lineno);
2842               result = -1;
2843             }
2844         }
2845       else if (!strcmp (flags, "change"))
2846         ;
2847       else if (!strcmp (flags, "no-change"))
2848         ;
2849       else
2850         {
2851           gc_error (0, 0, "unknown flag at `%s', line %d",
2852                     fname, lineno);
2853           result = -1;
2854         }
2855       
2856           
2857       /* Check whether the key matches but do this only if we are not
2858          running in syntax check mode. */
2859       if ( update 
2860            && !result
2861            && (got_match || (key && key_matches_user_or_group (key))) )
2862         {
2863           int newflags = 0;
2864
2865           got_match = 1;
2866
2867           /* Apply the flags from gpgconf.conf.  */
2868           if (!flags)
2869             ;
2870           else if (!strcmp (flags, "default"))
2871             newflags |= GC_OPT_FLAG_DEFAULT;
2872           else if (!strcmp (flags, "no-change"))
2873             option_info->flags |= GC_OPT_FLAG_NO_CHANGE;
2874           else if (!strcmp (flags, "change"))
2875             option_info->flags &= ~GC_OPT_FLAG_NO_CHANGE;
2876
2877           if (defaults)
2878             {
2879               assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
2880               used_components[component_id] = 1;
2881
2882               /* Here we explicitly allow to update the value again.  */
2883               if (newflags)
2884                 {
2885                   option_info->new_flags = 0;
2886                 }
2887               if (*value)
2888                 {
2889                   xfree (option_info->new_value);
2890                   option_info->new_value = NULL;
2891                 }
2892               change_one_value (option_info, runtime, newflags, value);
2893             }
2894         }
2895     }
2896
2897   if (length < 0 || ferror (config))
2898     {
2899       gc_error (0, errno, "error reading from `%s'", fname);
2900       result = -1;
2901     }
2902   if (fclose (config) && ferror (config))
2903     gc_error (0, errno, "error closing `%s'", fname);
2904
2905   xfree (line);
2906
2907   /* If it all worked, process the options. */
2908   if (!result && update && defaults)
2909     {
2910       /* We need to switch off the runtime update, so that we can do
2911          it later all at once. */
2912       int save_opt_runtime = opt.runtime;
2913       opt.runtime = 0;
2914
2915       for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
2916         {
2917           gc_component_change_options (component_id, NULL);
2918         }
2919       opt.runtime = save_opt_runtime;
2920
2921       if (opt.runtime)
2922         {
2923           for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)  
2924             if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
2925               (*gc_backend[backend_id].runtime_change) ();
2926         }
2927     }
2928
2929   return result;
2930 }