g13: Add commands --suspend and --remove.
[gnupg.git] / g13 / g13.c
1 /* g13.c - Disk Key management with GnuPG
2  * Copyright (C) 2009 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 <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <ctype.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <npth.h>
29
30 #include "g13.h"
31
32 #include <gcrypt.h>
33 #include <assuan.h>
34
35 #include "i18n.h"
36 #include "sysutils.h"
37 #include "gc-opt-flags.h"
38 #include "asshelp.h"
39 #include "../common/init.h"
40 #include "keyblob.h"
41 #include "server.h"
42 #include "runner.h"
43 #include "create.h"
44 #include "mount.h"
45 #include "suspend.h"
46 #include "mountinfo.h"
47 #include "backend.h"
48 #include "call-syshelp.h"
49
50
51 enum cmd_and_opt_values {
52   aNull = 0,
53   oQuiet        = 'q',
54   oVerbose      = 'v',
55   oRecipient    = 'r',
56
57   aGPGConfList  = 500,
58   aGPGConfTest,
59   aCreate,
60   aMount,
61   aUmount,
62   aSuspend,
63   aResume,
64   aServer,
65
66   oOptions,
67   oDebug,
68   oDebugLevel,
69   oDebugAll,
70   oDebugNone,
71   oDebugWait,
72   oDebugAllowCoreDump,
73   oLogFile,
74   oNoLogFile,
75   oAuditLog,
76
77   oOutput,
78
79   oAgentProgram,
80   oGpgProgram,
81   oType,
82
83   oDisplay,
84   oTTYname,
85   oTTYtype,
86   oLCctype,
87   oLCmessages,
88   oXauthority,
89
90   oStatusFD,
91   oLoggerFD,
92
93   oNoVerbose,
94   oNoSecmemWarn,
95   oNoGreeting,
96   oNoTTY,
97   oNoOptions,
98   oHomedir,
99   oWithColons,
100   oDryRun,
101   oNoDetach,
102
103   oNoRandomSeedFile,
104   oFakedSystemTime
105  };
106
107
108 static ARGPARSE_OPTS opts[] = {
109
110   ARGPARSE_group (300, N_("@Commands:\n ")),
111
112   ARGPARSE_c (aCreate, "create", N_("Create a new file system container")),
113   ARGPARSE_c (aMount,  "mount",  N_("Mount a file system container") ),
114   ARGPARSE_c (aUmount, "umount", N_("Unmount a file system container") ),
115   ARGPARSE_c (aSuspend, "suspend", N_("Suspend a file system container") ),
116   ARGPARSE_c (aResume,  "resume",  N_("Resume a file system container") ),
117   ARGPARSE_c (aServer, "server", N_("Run in server mode")),
118
119   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
120   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
121
122   ARGPARSE_group (301, N_("@\nOptions:\n ")),
123
124   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
125   ARGPARSE_s_s (oType, "type", N_("|NAME|use container format NAME")),
126
127   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
128   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
129   ARGPARSE_s_n (oQuiet, "quiet",  N_("be somewhat more quiet")),
130   ARGPARSE_s_n (oNoTTY, "no-tty", N_("don't use the terminal at all")),
131   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
132   ARGPARSE_s_s (oLogFile, "log-file",  N_("|FILE|write log output to FILE")),
133   ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"),
134   ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
135
136   ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
137
138   ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
139
140   ARGPARSE_s_s (oDebug, "debug", "@"),
141   ARGPARSE_s_s (oDebugLevel, "debug-level",
142                 N_("|LEVEL|set the debugging level to LEVEL")),
143   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
144   ARGPARSE_s_n (oDebugNone, "debug-none", "@"),
145   ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
146   ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"),
147
148   ARGPARSE_s_i (oStatusFD, "status-fd",
149                 N_("|FD|write status info to this FD")),
150
151   ARGPARSE_group (302, N_(
152   "@\n(See the man page for a complete listing of all commands and options)\n"
153   )),
154
155   ARGPARSE_group (303, N_("@\nExamples:\n\n"
156     " blurb\n"
157                           " blurb\n")),
158
159   /* Hidden options. */
160   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
161   ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
162   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
163   ARGPARSE_s_n (oNoOptions, "no-options", "@"),
164   ARGPARSE_s_s (oHomedir, "homedir", "@"),
165   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
166   ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"),
167   ARGPARSE_s_s (oDisplay,    "display", "@"),
168   ARGPARSE_s_s (oTTYname,    "ttyname", "@"),
169   ARGPARSE_s_s (oTTYtype,    "ttytype", "@"),
170   ARGPARSE_s_s (oLCctype,    "lc-ctype", "@"),
171   ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
172   ARGPARSE_s_s (oXauthority, "xauthority", "@"),
173   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
174   ARGPARSE_s_n (oWithColons, "with-colons", "@"),
175   ARGPARSE_s_n (oNoRandomSeedFile,  "no-random-seed-file", "@"),
176
177   /* Command aliases.  */
178
179   ARGPARSE_end ()
180 };
181
182
183 /* The list of supported debug flags.  */
184 static struct debug_flags_s debug_flags [] =
185   {
186     { DBG_MOUNT_VALUE  , "mount"  },
187     { DBG_CRYPTO_VALUE , "crypto"  },
188     { DBG_MEMORY_VALUE , "memory"  },
189     { DBG_MEMSTAT_VALUE, "memstat" },
190     { DBG_IPC_VALUE    , "ipc"     },
191     { 0, NULL }
192   };
193
194
195 /* The timer tick interval used by the idle task.  */
196 #define TIMERTICK_INTERVAL_SEC     (1)
197
198 /* It is possible that we are currently running under setuid permissions.  */
199 static int maybe_setuid = 1;
200
201 /* Helper to implement --debug-level and --debug.  */
202 static const char *debug_level;
203 static unsigned int debug_value;
204
205 /* Flag to indicate that a shutdown was requested.  */
206 static int shutdown_pending;
207
208 /* The thread id of the idle task.  */
209 static npth_t idle_task_thread;
210
211
212 /* The container type as specified on the command line.  */
213 static int cmdline_conttype;
214
215
216 \f
217 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
218                      enum cmd_and_opt_values new_cmd );
219
220 static void start_idle_task (void);
221 static void join_idle_task (void);
222
223 \f
224 /* Begin NPth wrapper functions. */
225 ASSUAN_SYSTEM_NPTH_IMPL;
226
227 \f
228 static const char *
229 my_strusage( int level )
230 {
231   const char *p;
232
233   switch (level)
234     {
235     case 11: p = "@G13@ (@GNUPG@)";
236       break;
237     case 13: p = VERSION; break;
238     case 17: p = PRINTABLE_OS_NAME; break;
239     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
240       break;
241     case 1:
242     case 40: p = _("Usage: @G13@ [options] [files] (-h for help)");
243       break;
244     case 41:
245       p = _("Syntax: @G13@ [options] [files]\n"
246             "Create, mount or unmount an encrypted file system container\n");
247       break;
248
249     case 31: p = "\nHome: "; break;
250     case 32: p = opt.homedir; break;
251
252     default: p = NULL; break;
253     }
254   return p;
255 }
256
257
258 static void
259 wrong_args (const char *text)
260 {
261   fprintf (stderr, _("usage: %s [options] "), G13_NAME);
262   fputs (text, stderr);
263   putc ('\n', stderr);
264   g13_exit (2);
265 }
266
267
268 /* Setup the debugging.  With a DEBUG_LEVEL of NULL only the active
269    debug flags are propagated to the subsystems.  With DEBUG_LEVEL
270    set, a specific set of debug flags is set; and individual debugging
271    flags will be added on top.  */
272 static void
273 set_debug (void)
274 {
275   int numok = (debug_level && digitp (debug_level));
276   int numlvl = numok? atoi (debug_level) : 0;
277
278   if (!debug_level)
279     ;
280   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
281     opt.debug = 0;
282   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
283     opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE;
284   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
285     opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE;
286   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
287     opt.debug = (DBG_IPC_VALUE|DBG_MOUNT_VALUE|DBG_CRYPTO_VALUE);
288   else if (!strcmp (debug_level, "guru") || numok)
289     {
290       opt.debug = ~0;
291       /* if (numok) */
292       /*   opt.debug &= ~(DBG_HASHING_VALUE); */
293     }
294   else
295     {
296       log_error (_("invalid debug-level '%s' given\n"), debug_level);
297       g13_exit(2);
298     }
299
300   opt.debug |= debug_value;
301
302   if (opt.debug && !opt.verbose)
303     opt.verbose = 1;
304   if (opt.debug)
305     opt.quiet = 0;
306
307   if (opt.debug & DBG_CRYPTO_VALUE )
308     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
309   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
310
311   if (opt.debug)
312     parse_debug_flag (NULL, &opt.debug, debug_flags);
313 }
314
315
316
317 static void
318 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
319 {
320   enum cmd_and_opt_values cmd = *ret_cmd;
321
322   if (!cmd || cmd == new_cmd)
323     cmd = new_cmd;
324   else
325     {
326       log_error (_("conflicting commands\n"));
327       g13_exit (2);
328     }
329
330   *ret_cmd = cmd;
331 }
332
333
334 int
335 main ( int argc, char **argv)
336 {
337   ARGPARSE_ARGS pargs;
338   int orig_argc;
339   char **orig_argv;
340   gpg_error_t err = 0;
341   /* const char *fname; */
342   int may_coredump;
343   FILE *configfp = NULL;
344   char *configname = NULL;
345   unsigned configlineno;
346   int parse_debug = 0;
347   int no_more_options = 0;
348   int default_config =1;
349   char *logfile = NULL;
350   int greeting = 0;
351   int nogreeting = 0;
352   /* int debug_wait = 0; */
353   int use_random_seed = 1;
354   /* int nodetach = 0; */
355   /* int nokeysetup = 0; */
356   enum cmd_and_opt_values cmd = 0;
357   struct server_control_s ctrl;
358   strlist_t recipients = NULL;
359
360   /*mtrace();*/
361
362   early_system_init ();
363   gnupg_reopen_std (G13_NAME);
364   set_strusage (my_strusage);
365   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
366
367   log_set_prefix (G13_NAME, 1);
368
369   /* Make sure that our subsystems are ready.  */
370   i18n_init ();
371   init_common_subsystems (&argc, &argv);
372
373   npth_init ();
374
375   /* Check that the Libgcrypt is suitable.  */
376   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
377     log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
378                NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
379
380   /* Take extra care of the random pool.  */
381   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
382
383   may_coredump = disable_core_dumps ();
384
385   g13_init_signals ();
386
387   dotlock_create (NULL, 0); /* Register locking cleanup.  */
388
389   opt.session_env = session_env_new ();
390   if (!opt.session_env)
391     log_fatal ("error allocating session environment block: %s\n",
392                strerror (errno));
393
394   opt.homedir = default_homedir ();
395
396   /* First check whether we have a config file on the commandline.  */
397   orig_argc = argc;
398   orig_argv = argv;
399   pargs.argc = &argc;
400   pargs.argv = &argv;
401   pargs.flags= 1|(1<<6);  /* Do not remove the args, ignore version.  */
402   while (arg_parse( &pargs, opts))
403     {
404       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
405         parse_debug++;
406       else if (pargs.r_opt == oOptions)
407         { /* Yes, there is one, so we do not try the default one but
408              read the config file when it is encountered at the
409              commandline.  */
410           default_config = 0;
411         }
412       else if (pargs.r_opt == oNoOptions)
413         default_config = 0; /* --no-options */
414       else if (pargs.r_opt == oHomedir)
415         opt.homedir = pargs.r.ret_str;
416     }
417
418   /* Initialize the secure memory. */
419   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
420   maybe_setuid = 0;
421
422   /*
423      Now we are now working under our real uid
424   */
425
426   /* Setup malloc hooks. */
427   {
428     struct assuan_malloc_hooks malloc_hooks;
429
430     malloc_hooks.malloc = gcry_malloc;
431     malloc_hooks.realloc = gcry_realloc;
432     malloc_hooks.free = gcry_free;
433     assuan_set_malloc_hooks (&malloc_hooks);
434   }
435
436   /* Prepare libassuan.  */
437   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
438   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
439   setup_libassuan_logging (&opt.debug);
440
441   /* Setup a default control structure for command line mode.  */
442   memset (&ctrl, 0, sizeof ctrl);
443   g13_init_default_ctrl (&ctrl);
444   ctrl.no_server = 1;
445   ctrl.status_fd = -1; /* No status output. */
446
447   /* Set the default option file */
448   if (default_config )
449     configname = make_filename (opt.homedir, G13_NAME".conf", NULL);
450
451   argc        = orig_argc;
452   argv        = orig_argv;
453   pargs.argc  = &argc;
454   pargs.argv  = &argv;
455   pargs.flags =  1;  /* Do not remove the args.  */
456
457  next_pass:
458   if (configname)
459     {
460       configlineno = 0;
461       configfp = fopen (configname, "r");
462       if (!configfp)
463         {
464           if (default_config)
465             {
466               if (parse_debug)
467                 log_info (_("Note: no default option file '%s'\n"), configname);
468             }
469           else
470             {
471               log_error (_("option file '%s': %s\n"),
472                          configname, strerror(errno));
473               g13_exit(2);
474             }
475           xfree (configname);
476           configname = NULL;
477         }
478       if (parse_debug && configname)
479         log_info (_("reading options from '%s'\n"), configname);
480       default_config = 0;
481     }
482
483   while (!no_more_options
484          && optfile_parse (configfp, configname, &configlineno, &pargs, opts))
485     {
486       switch (pargs.r_opt)
487         {
488         case aGPGConfList:
489         case aGPGConfTest:
490           set_cmd (&cmd, pargs.r_opt);
491           nogreeting = 1;
492           /* nokeysetup = 1; */
493           break;
494
495         case aServer:
496         case aMount:
497         case aUmount:
498         case aSuspend:
499         case aResume:
500         case aCreate:
501           set_cmd (&cmd, pargs.r_opt);
502           break;
503
504         case oOutput: opt.outfile = pargs.r.ret_str; break;
505
506         case oQuiet: opt.quiet = 1; break;
507         case oNoGreeting: nogreeting = 1; break;
508         case oNoTTY:  break;
509
510         case oDryRun: opt.dry_run = 1; break;
511
512         case oVerbose:
513           opt.verbose++;
514           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
515           break;
516         case oNoVerbose:
517           opt.verbose = 0;
518           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
519           break;
520
521         case oLogFile: logfile = pargs.r.ret_str; break;
522         case oNoLogFile: logfile = NULL; break;
523
524         case oNoDetach: /*nodetach = 1; */break;
525
526         case oDebug:
527           if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
528             {
529               pargs.r_opt = ARGPARSE_INVALID_ARG;
530               pargs.err = ARGPARSE_PRINT_ERROR;
531             }
532             break;
533         case oDebugAll: debug_value = ~0; break;
534         case oDebugNone: debug_value = 0; break;
535         case oDebugLevel: debug_level = pargs.r.ret_str; break;
536         case oDebugWait: /*debug_wait = pargs.r.ret_int; */break;
537         case oDebugAllowCoreDump:
538           may_coredump = enable_core_dumps ();
539           break;
540
541         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
542         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
543
544         case oNoOptions: break; /* no-options */
545         case oOptions:
546           /* Config files may not be nested (silently ignore them).  */
547           if (!configfp)
548             {
549               xfree(configname);
550               configname = xstrdup (pargs.r.ret_str);
551               goto next_pass;
552             }
553           break;
554
555         case oHomedir: opt.homedir = pargs.r.ret_str; break;
556
557         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
558         case oGpgProgram: opt.gpg_program = pargs.r.ret_str;  break;
559         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
560         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
561         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
562         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
563         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
564         case oXauthority: opt.xauthority = xstrdup (pargs.r.ret_str); break;
565
566         case oFakedSystemTime:
567           {
568             time_t faked_time = isotime2epoch (pargs.r.ret_str);
569             if (faked_time == (time_t)(-1))
570               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
571             gnupg_set_time (faked_time, 0);
572           }
573           break;
574
575         case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break;
576
577         case oNoRandomSeedFile: use_random_seed = 0; break;
578
579         case oRecipient: /* Store the encryption key.  */
580           add_to_strlist (&recipients, pargs.r.ret_str);
581           break;
582
583         case oType:
584           if (!strcmp (pargs.r.ret_str, "help"))
585             {
586               be_parse_conttype_name (NULL);
587               g13_exit (0);
588             }
589           cmdline_conttype = be_parse_conttype_name (pargs.r.ret_str);
590           if (!cmdline_conttype)
591             {
592               pargs.r_opt = ARGPARSE_INVALID_ARG;
593               pargs.err = ARGPARSE_PRINT_ERROR;
594             }
595           break;
596
597         default:
598           pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
599           break;
600         }
601     }
602
603   /* XXX Construct GPG arguments.  */
604   {
605     strlist_t last;
606     last = append_to_strlist (&opt.gpg_arguments, "-z");
607     last = append_to_strlist (&last, "0");
608     last = append_to_strlist (&last, "--trust-model");
609     last = append_to_strlist (&last, "always");
610     (void) last;
611   }
612
613   if (configfp)
614     {
615       fclose (configfp);
616       configfp = NULL;
617       /* Keep a copy of the config filename. */
618       opt.config_filename = configname;
619       configname = NULL;
620       goto next_pass;
621     }
622   xfree (configname);
623   configname = NULL;
624
625   if (!opt.config_filename)
626     opt.config_filename = make_filename (opt.homedir, G13_NAME".conf", NULL);
627
628   if (log_get_errorcount(0))
629     g13_exit(2);
630
631   /* Now that we have the options parsed we need to update the default
632      control structure.  */
633   g13_init_default_ctrl (&ctrl);
634   ctrl.recipients = recipients;
635   recipients = NULL;
636
637   if (nogreeting)
638     greeting = 0;
639
640   if (greeting)
641     {
642       fprintf (stderr, "%s %s; %s\n",
643                strusage(11), strusage(13), strusage(14) );
644       fprintf (stderr, "%s\n", strusage(15) );
645     }
646
647   if (may_coredump && !opt.quiet)
648     log_info (_("WARNING: program may create a core file!\n"));
649
650   /* Print a warning if an argument looks like an option.  */
651   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
652     {
653       int i;
654
655       for (i=0; i < argc; i++)
656         if (argv[i][0] == '-' && argv[i][1] == '-')
657           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
658     }
659
660
661   if (logfile)
662     {
663       log_set_file (logfile);
664       log_set_prefix (NULL, 1|2|4);
665     }
666
667   if (gnupg_faked_time_p ())
668     {
669       gnupg_isotime_t tbuf;
670
671       log_info (_("WARNING: running with faked system time: "));
672       gnupg_get_isotime (tbuf);
673       dump_isotime (tbuf);
674       log_printf ("\n");
675     }
676
677   /* Print any pending secure memory warnings.  */
678   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
679
680   /* Setup the debug flags for all subsystems.  */
681   set_debug ();
682
683   /* Install emergency cleanup handler.  */
684   g13_install_emergency_cleanup ();
685
686   /* Terminate if we found any error until now.  */
687   if (log_get_errorcount(0))
688     g13_exit (2);
689
690   /* Set the standard GnuPG random seed file.  */
691   if (use_random_seed)
692     {
693       char *p = make_filename (opt.homedir, "random_seed", NULL);
694       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
695       xfree(p);
696     }
697
698   /* Store given filename into FNAME. */
699   /* fname = argc? *argv : NULL; */
700
701   /* Parse all given encryption keys.  This does a lookup of the keys
702      and stops if any of the given keys was not found. */
703 #if 0 /* Currently not implemented.  */
704   if (!nokeysetup)
705     {
706       strlist_t sl;
707       int failed = 0;
708
709       for (sl = ctrl->recipients; sl; sl = sl->next)
710         if (check_encryption_key ())
711           failed = 1;
712       if (failed)
713         g13_exit (1);
714     }
715 #endif /*0*/
716
717   /* Dispatch command.  */
718   err = 0;
719   switch (cmd)
720     {
721     case aGPGConfList:
722       { /* List options and default values in the GPG Conf format.  */
723         char *config_filename_esc = percent_escape (opt.config_filename, NULL);
724
725         printf ("gpgconf-g13.conf:%lu:\"%s\n",
726                 GC_OPT_FLAG_DEFAULT, config_filename_esc);
727         xfree (config_filename_esc);
728
729         printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
730         printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
731         printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
732         printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
733       }
734       break;
735     case aGPGConfTest:
736       /* This is merely a dummy command to test whether the
737          configuration file is valid.  */
738       break;
739
740     case aServer:
741       {
742         start_idle_task ();
743         ctrl.no_server = 0;
744         err = g13_server (&ctrl);
745         if (err)
746           log_error ("server exited with error: %s <%s>\n",
747                      gpg_strerror (err), gpg_strsource (err));
748         else
749           g13_request_shutdown ();
750       }
751       break;
752
753     case aCreate: /* Create a new container. */
754       {
755         if (argc != 1)
756           wrong_args ("--create filename");
757         start_idle_task ();
758         err = g13_create_container (&ctrl, argv[0]);
759         if (err)
760           log_error ("error creating a new container: %s <%s>\n",
761                      gpg_strerror (err), gpg_strsource (err));
762         else
763           g13_request_shutdown ();
764       }
765       break;
766
767     case aMount: /* Mount a container. */
768       {
769         if (argc != 1 && argc != 2 )
770           wrong_args ("--mount filename [mountpoint]");
771         start_idle_task ();
772         err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL);
773         if (err)
774           log_error ("error mounting container '%s': %s <%s>\n",
775                      *argv, gpg_strerror (err), gpg_strsource (err));
776       }
777       break;
778
779     case aUmount: /* Unmount a mounted container.  */
780       {
781         if (argc != 1)
782           wrong_args ("--umount filename");
783         err = GPG_ERR_NOT_IMPLEMENTED;
784         log_error ("error unmounting container '%s': %s <%s>\n",
785                    *argv, gpg_strerror (err), gpg_strsource (err));
786       }
787       break;
788
789     case aSuspend: /* Suspend a container. */
790       {
791         /* Fixme: Should we add a suspend all container option?  */
792         if (argc != 1)
793           wrong_args ("--suspend filename");
794         err = g13_suspend_container (&ctrl, argv[0]);
795         if (err)
796           log_error ("error suspending container '%s': %s <%s>\n",
797                      *argv, gpg_strerror (err), gpg_strsource (err));
798       }
799       break;
800
801     case aResume: /* Resume a suspended container. */
802       {
803         /* Fixme: Should we add a resume all container option?  */
804         if (argc != 1)
805           wrong_args ("--resume filename");
806         err = g13_resume_container (&ctrl, argv[0]);
807         if (err)
808           log_error ("error resuming container '%s': %s <%s>\n",
809                      *argv, gpg_strerror (err), gpg_strsource (err));
810       }
811       break;
812
813     default:
814       log_error (_("invalid command (there is no implicit command)\n"));
815       break;
816     }
817
818   g13_deinit_default_ctrl (&ctrl);
819
820   if (!err)
821     join_idle_task ();
822
823   /* Cleanup.  */
824   g13_exit (0);
825   return 8; /*NOTREACHED*/
826 }
827
828
829 /* Store defaults into the per-connection CTRL object.  */
830 void
831 g13_init_default_ctrl (ctrl_t ctrl)
832 {
833   ctrl->conttype = cmdline_conttype? cmdline_conttype : CONTTYPE_ENCFS;
834 }
835
836
837 /* Release remaining resources allocated in the CTRL object.  */
838 void
839 g13_deinit_default_ctrl (ctrl_t ctrl)
840 {
841   call_syshelp_release (ctrl);
842   FREE_STRLIST (ctrl->recipients);
843 }
844
845
846 /* Request a shutdown.  This can be used when the process should
847  * finish instead of running the idle task.  */
848 void
849 g13_request_shutdown (void)
850 {
851   shutdown_pending++;
852 }
853
854
855 /* This function is called for each signal we catch.  It is run in the
856    main context or the one of a NPth thread and thus it is not
857    restricted in what it may do.  */
858 static void
859 handle_signal (int signo)
860 {
861   switch (signo)
862     {
863 #ifndef HAVE_W32_SYSTEM
864     case SIGHUP:
865       log_info ("SIGHUP received - re-reading configuration\n");
866       /* Fixme:  Not yet implemented.  */
867       break;
868
869     case SIGUSR1:
870       log_info ("SIGUSR1 received - printing internal information:\n");
871       /* Fixme: We need to see how to integrate pth dumping into our
872          logging system.  */
873       /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
874       mountinfo_dump_all ();
875       break;
876
877     case SIGUSR2:
878       log_info ("SIGUSR2 received - no action defined\n");
879       break;
880
881     case SIGTERM:
882       if (!shutdown_pending)
883         log_info ("SIGTERM received - shutting down ...\n");
884       else
885         log_info ("SIGTERM received - still %u runners active\n",
886                   runner_get_threads ());
887       shutdown_pending++;
888       if (shutdown_pending > 2)
889         {
890           log_info ("shutdown forced\n");
891           log_info ("%s %s stopped\n", strusage(11), strusage(13) );
892           g13_exit (0);
893         }
894       break;
895
896     case SIGINT:
897       log_info ("SIGINT received - immediate shutdown\n");
898       log_info( "%s %s stopped\n", strusage(11), strusage(13));
899       g13_exit (0);
900       break;
901 #endif /*!HAVE_W32_SYSTEM*/
902
903     default:
904       log_info ("signal %d received - no action defined\n", signo);
905     }
906 }
907
908
909 /* This ticker function is called about every TIMERTICK_INTERVAL_SEC
910    seconds. */
911 static void
912 handle_tick (void)
913 {
914   /* log_debug ("TICK\n"); */
915 }
916
917
918 /* The idle task.  We use a separate thread to do idle stuff and to
919    catch signals.  */
920 static void *
921 idle_task (void *dummy_arg)
922 {
923   int signo;           /* The number of a raised signal is stored here.  */
924   int saved_errno;
925   struct timespec abstime;
926   struct timespec curtime;
927   struct timespec timeout;
928   int ret;
929
930   (void)dummy_arg;
931
932   /* Create the event to catch the signals. */
933 #ifndef HAVE_W32_SYSTEM
934   npth_sigev_init ();
935   npth_sigev_add (SIGHUP);
936   npth_sigev_add (SIGUSR1);
937   npth_sigev_add (SIGUSR2);
938   npth_sigev_add (SIGINT);
939   npth_sigev_add (SIGTERM);
940   npth_sigev_fini ();
941 #endif
942
943   npth_clock_gettime (&abstime);
944   abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
945
946   for (;;)
947     {
948       /* The shutdown flag allows us to terminate the idle task.  */
949       if (shutdown_pending)
950         {
951           runner_cancel_all ();
952
953           if (!runner_get_threads ())
954             break; /* ready */
955         }
956
957       npth_clock_gettime (&curtime);
958       if (!(npth_timercmp (&curtime, &abstime, <)))
959         {
960           /* Timeout.  */
961           handle_tick ();
962           npth_clock_gettime (&abstime);
963           abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
964         }
965       npth_timersub (&abstime, &curtime, &timeout);
966
967 #ifndef HAVE_W32_SYSTEM
968       ret = npth_pselect (0, NULL, NULL, NULL, &timeout, npth_sigev_sigmask());
969       saved_errno = errno;
970
971       while (npth_sigev_get_pending(&signo))
972         handle_signal (signo);
973 #else
974       ret = npth_eselect (0, NULL, NULL, NULL, &timeout, NULL, NULL);
975       saved_errno = errno;
976 #endif
977
978       if (ret == -1 && saved_errno != EINTR)
979         {
980           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
981                      strerror (saved_errno));
982           npth_sleep (1);
983           continue;
984         }
985
986       if (ret <= 0)
987         {
988           /* Interrupt or timeout.  Will be handled when calculating the
989              next timeout.  */
990           continue;
991         }
992
993       /* Here one would add processing of file descriptors.  */
994     }
995
996   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
997   return NULL;
998 }
999
1000
1001 /* Start the idle task.   */
1002 static void
1003 start_idle_task (void)
1004 {
1005   npth_attr_t tattr;
1006   npth_t thread;
1007   sigset_t sigs;       /* The set of signals we want to catch.  */
1008   int err;
1009
1010 #ifndef HAVE_W32_SYSTEM
1011   /* These signals should always go to the idle task, so they need to
1012      be blocked everywhere else.  We assume start_idle_task is called
1013      from the main thread before any other threads are created.  */
1014   sigemptyset (&sigs);
1015   sigaddset (&sigs, SIGHUP);
1016   sigaddset (&sigs, SIGUSR1);
1017   sigaddset (&sigs, SIGUSR2);
1018   sigaddset (&sigs, SIGINT);
1019   sigaddset (&sigs, SIGTERM);
1020   npth_sigmask (SIG_BLOCK, &sigs, NULL);
1021 #endif
1022
1023   npth_attr_init (&tattr);
1024   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1025
1026   err = npth_create (&thread, &tattr, idle_task, NULL);
1027   if (err)
1028     {
1029       log_fatal ("error starting idle task: %s\n", strerror (err));
1030       return; /*NOTREACHED*/
1031     }
1032   npth_setname_np (thread, "idle-task");
1033   idle_task_thread = thread;
1034   npth_attr_destroy (&tattr);
1035 }
1036
1037
1038 /* Wait for the idle task to finish.  */
1039 static void
1040 join_idle_task (void)
1041 {
1042   int err;
1043
1044   /* FIXME: This assumes that a valid pthread_t is non-null.  That is
1045      not guaranteed.  */
1046   if (idle_task_thread)
1047     {
1048       err = npth_join (idle_task_thread, NULL);
1049       if (err)
1050         log_error ("waiting for idle task thread failed: %s\n",
1051                    strerror (err));
1052     }
1053 }