Lock scdaemon to CCID if once found.
[gnupg.git] / tools / gpgconf.c
1 /* gpgconf.c - Configuration utility for GnuPG
2  * Copyright (C) 2003, 2007, 2009, 2011 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
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "gpgconf.h"
27 #include "i18n.h"
28 #include "sysutils.h"
29
30 /* Constants to identify the commands and options. */
31 enum cmd_and_opt_values
32   {
33     aNull = 0,
34     oDryRun     = 'n',
35     oOutput     = 'o',
36     oQuiet      = 'q',
37     oVerbose    = 'v',
38     oRuntime    = 'r',
39     oComponent  = 'c',
40     oNoVerbose  = 500,
41     oHomedir,
42
43     aListComponents,
44     aCheckPrograms,
45     aListOptions,
46     aChangeOptions,
47     aCheckOptions,
48     aApplyDefaults,
49     aListConfig,
50     aCheckConfig,
51     aListDirs,
52     aKill,
53     aReload
54   };
55
56
57 /* The list of commands and options. */
58 static ARGPARSE_OPTS opts[] =
59   {
60     { 300, NULL, 0, N_("@Commands:\n ") },
61
62     { aListComponents, "list-components", 256, N_("list all components") },
63     { aCheckPrograms, "check-programs", 256, N_("check all programs") },
64     { aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
65     { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") },
66     { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") },
67     { aApplyDefaults, "apply-defaults", 256,
68       N_("apply global default values") },
69     { aListDirs, "list-dirs", 256,
70       N_("get the configuration directories for gpgconf") },
71     { aListConfig,   "list-config", 256,
72       N_("list global configuration file") },
73     { aCheckConfig,   "check-config", 256,
74       N_("check global configuration file") },
75     { aReload,        "reload", 256, N_("reload all or a given component")},
76     { aKill,          "kill", 256,   N_("kill a given component")},
77
78     { 301, NULL, 0, N_("@\nOptions:\n ") },
79
80     { oOutput, "output",    2, N_("use as output file") },
81     { oVerbose, "verbose",  0, N_("verbose") },
82     { oQuiet, "quiet",      0, N_("quiet") },
83     { oDryRun, "dry-run",   0, N_("do not make any changes") },
84     { oRuntime, "runtime",  0, N_("activate changes at runtime, if possible") },
85     /* hidden options */
86     { oNoVerbose, "no-verbose",  0, "@"},
87     {0}
88   };
89
90
91 /* Print usage information and and provide strings for help. */
92 static const char *
93 my_strusage( int level )
94 {
95   const char *p;
96
97   switch (level)
98     {
99     case 11: p = "gpgconf (GnuPG)";
100       break;
101     case 13: p = VERSION; break;
102     case 17: p = PRINTABLE_OS_NAME; break;
103     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
104
105     case 1:
106     case 40: p = _("Usage: gpgconf [options] (-h for help)");
107       break;
108     case 41:
109       p = _("Syntax: gpgconf [options]\n"
110             "Manage configuration options for tools of the GnuPG system\n");
111       break;
112
113     default: p = NULL; break;
114     }
115   return p;
116 }
117
118
119 /* Return the fp for the output.  This is usually stdout unless
120    --output has been used.  In the latter case this function opens
121    that file.  */
122 static estream_t
123 get_outfp (estream_t *fp)
124 {
125   if (!*fp)
126     {
127       if (opt.outfile)
128         {
129           *fp = es_fopen (opt.outfile, "w");
130           if (!*fp)
131             gc_error (1, errno, "can not open `%s'", opt.outfile);
132         }
133       else
134         *fp = es_stdout;
135     }
136   return *fp;
137 }
138
139
140 /* gpgconf main. */
141 int
142 main (int argc, char **argv)
143 {
144   ARGPARSE_ARGS pargs;
145   const char *fname;
146   int no_more_options = 0;
147   enum cmd_and_opt_values cmd = 0;
148   estream_t outfp = NULL;
149
150   gnupg_reopen_std ("gpgconf");
151   set_strusage (my_strusage);
152   log_set_prefix ("gpgconf", 1);
153
154   /* Make sure that our subsystems are ready.  */
155   i18n_init();
156   init_common_subsystems (&argc, &argv);
157
158   /* Parse the command line. */
159   pargs.argc  = &argc;
160   pargs.argv  = &argv;
161   pargs.flags =  1;  /* Do not remove the args.  */
162   while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
163     {
164       switch (pargs.r_opt)
165         {
166         case oOutput:    opt.outfile = pargs.r.ret_str; break;
167         case oQuiet:     opt.quiet = 1; break;
168         case oDryRun:    opt.dry_run = 1; break;
169         case oRuntime:
170           opt.runtime = 1;
171           break;
172         case oVerbose:   opt.verbose++; break;
173         case oNoVerbose: opt.verbose = 0; break;
174
175         case aListDirs:
176         case aListComponents:
177         case aCheckPrograms:
178         case aListOptions:
179         case aChangeOptions:
180         case aCheckOptions:
181         case aApplyDefaults:
182         case aListConfig:
183         case aCheckConfig:
184         case aReload:
185         case aKill:
186           cmd = pargs.r_opt;
187           break;
188
189         default: pargs.err = 2; break;
190         }
191     }
192
193   if (log_get_errorcount (0))
194     exit (2);
195
196   fname = argc ? *argv : NULL;
197
198   switch (cmd)
199     {
200     case aListComponents:
201     default:
202       /* List all components. */
203       gc_component_list_components (get_outfp (&outfp));
204       break;
205
206     case aCheckPrograms:
207       /* Check all programs. */
208       gc_check_programs (get_outfp (&outfp));
209       break;
210
211     case aListOptions:
212     case aChangeOptions:
213     case aCheckOptions:
214       if (!fname)
215         {
216           es_fputs (_("usage: gpgconf [options] "), es_stderr);
217           es_putc ('\n', es_stderr);
218           es_fputs (_("Need one component argument"), es_stderr);
219           es_putc ('\n', es_stderr);
220           exit (2);
221         }
222       else
223         {
224           int idx = gc_component_find (fname);
225           if (idx < 0)
226             {
227               es_fputs (_("Component not found"), es_stderr);
228               es_putc ('\n', es_stderr);
229               exit (1);
230             }
231           if (cmd == aCheckOptions)
232             gc_component_check_options (idx, get_outfp (&outfp), NULL);
233           else
234             {
235               gc_component_retrieve_options (idx);
236               if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
237                 exit (1);
238               if (cmd == aListOptions)
239                 gc_component_list_options (idx, get_outfp (&outfp));
240               else if (cmd == aChangeOptions)
241                 gc_component_change_options (idx, es_stdin, get_outfp (&outfp));
242             }
243         }
244       break;
245
246     case aKill:
247       if (!fname)
248         {
249           es_fputs (_("usage: gpgconf [options] "), es_stderr);
250           es_putc ('\n', es_stderr);
251           es_fputs (_("Need one component argument"), es_stderr);
252           es_putc ('\n', es_stderr);
253           exit (2);
254         }
255       else
256         {
257           /* Kill a given component.  */
258           int idx;
259
260           idx = gc_component_find (fname);
261           if (idx < 0)
262             {
263               es_fputs (_("Component not found"), es_stderr);
264               es_putc ('\n', es_stderr);
265               exit (1);
266             }
267           else
268             {
269               gc_component_kill (idx);
270             }
271         }
272       break;
273
274     case aReload:
275       if (!fname)
276         {
277           /* Reload all.  */
278           gc_component_reload (-1);
279         }
280       else
281         {
282           /* Reload given component.  */
283           int idx;
284
285           idx = gc_component_find (fname);
286           if (idx < 0)
287             {
288               es_fputs (_("Component not found"), es_stderr);
289               es_putc ('\n', es_stderr);
290               exit (1);
291             }
292           else
293             {
294               gc_component_reload (idx);
295             }
296         }
297       break;
298
299     case aListConfig:
300       if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
301         exit (1);
302       break;
303
304     case aCheckConfig:
305       if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
306         exit (1);
307       break;
308
309     case aApplyDefaults:
310       if (fname)
311         {
312           es_fputs (_("usage: gpgconf [options] "), es_stderr);
313           es_putc ('\n', es_stderr);
314           es_fputs (_("No argument allowed"), es_stderr);
315           es_putc ('\n', es_stderr);
316           exit (2);
317         }
318       gc_component_retrieve_options (-1);
319       if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
320         exit (1);
321       break;
322
323     case aListDirs:
324       /* Show the system configuration directories for gpgconf.  */
325       get_outfp (&outfp);
326       es_fprintf (outfp, "sysconfdir:%s\n",
327                   gc_percent_escape (gnupg_sysconfdir ()));
328       es_fprintf (outfp, "bindir:%s\n",
329                   gc_percent_escape (gnupg_bindir ()));
330       es_fprintf (outfp, "libexecdir:%s\n",
331                   gc_percent_escape (gnupg_libexecdir ()));
332       es_fprintf (outfp, "libdir:%s\n",
333                   gc_percent_escape (gnupg_libdir ()));
334       es_fprintf (outfp, "datadir:%s\n",
335                   gc_percent_escape (gnupg_datadir ()));
336       es_fprintf (outfp, "localedir:%s\n",
337                   gc_percent_escape (gnupg_localedir ()));
338       es_fprintf (outfp, "dirmngr-socket:%s\n",
339                   gc_percent_escape (dirmngr_socket_name ()));
340       {
341         char *infostr = getenv ("GPG_AGENT_INFO");
342
343         if (!infostr || !*infostr)
344           infostr = make_filename (default_homedir (), "S.gpg-agent", NULL);
345         else
346           {
347             char *tmp;
348
349             infostr = xstrdup (infostr);
350             tmp = strchr (infostr, PATHSEP_C);
351             if (!tmp || tmp == infostr)
352               {
353                 xfree (infostr);
354                 infostr = NULL;
355               }
356             else
357               *tmp = 0;
358           }
359         es_fprintf (outfp, "agent-socket:%s\n",
360                     infostr? gc_percent_escape (infostr) : "");
361         xfree (infostr);
362       }
363       {
364         /* We need to use make_filename to expand a possible "~/".  */
365         char *tmp = make_filename (default_homedir (), NULL);
366         es_fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
367         xfree (tmp);
368       }
369       break;
370     }
371
372   if (outfp != es_stdout)
373     if (es_fclose (outfp))
374       gc_error (1, errno, "error closing `%s'", opt.outfile);
375
376   return 0;
377 }