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