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