~ubuntu-branches/ubuntu/dapper/gnupg2/dapper

« back to all changes in this revision

Viewing changes to tools/gpgconf-comp.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

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