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