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