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