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