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