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