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