Call log_set_prefix() with human-readable labels.
[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 = gnupg_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, GPGRT_LOG_WITH_PREFIX);
368
369   /* Make sure that our subsystems are ready.  */
370   i18n_init ();
371   init_common_subsystems (&argc, &argv);
372
373   npth_init ();
374
375   /* Take extra care of the random pool.  */
376   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
377
378   may_coredump = disable_core_dumps ();
379
380   g13_init_signals ();
381
382   dotlock_create (NULL, 0); /* Register locking cleanup.  */
383
384   opt.session_env = session_env_new ();
385   if (!opt.session_env)
386     log_fatal ("error allocating session environment block: %s\n",
387                strerror (errno));
388
389   /* First check whether we have a config file on the commandline.  */
390   orig_argc = argc;
391   orig_argv = argv;
392   pargs.argc = &argc;
393   pargs.argv = &argv;
394   pargs.flags= 1|(1<<6);  /* Do not remove the args, ignore version.  */
395   while (arg_parse( &pargs, opts))
396     {
397       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
398         parse_debug++;
399       else if (pargs.r_opt == oOptions)
400         { /* Yes, there is one, so we do not try the default one but
401              read the config file when it is encountered at the
402              commandline.  */
403           default_config = 0;
404         }
405       else if (pargs.r_opt == oNoOptions)
406         default_config = 0; /* --no-options */
407       else if (pargs.r_opt == oHomedir)
408         gnupg_set_homedir (pargs.r.ret_str);
409     }
410
411   /* Initialize the secure memory. */
412   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
413   maybe_setuid = 0;
414
415   /*
416      Now we are now working under our real uid
417   */
418
419   /* Setup malloc hooks. */
420   {
421     struct assuan_malloc_hooks malloc_hooks;
422
423     malloc_hooks.malloc = gcry_malloc;
424     malloc_hooks.realloc = gcry_realloc;
425     malloc_hooks.free = gcry_free;
426     assuan_set_malloc_hooks (&malloc_hooks);
427   }
428
429   /* Prepare libassuan.  */
430   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
431   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
432   setup_libassuan_logging (&opt.debug);
433
434   /* Setup a default control structure for command line mode.  */
435   memset (&ctrl, 0, sizeof ctrl);
436   g13_init_default_ctrl (&ctrl);
437   ctrl.no_server = 1;
438   ctrl.status_fd = -1; /* No status output. */
439
440   /* Set the default option file */
441   if (default_config )
442     configname = make_filename (gnupg_homedir (), G13_NAME".conf", NULL);
443
444   argc        = orig_argc;
445   argv        = orig_argv;
446   pargs.argc  = &argc;
447   pargs.argv  = &argv;
448   pargs.flags =  1;  /* Do not remove the args.  */
449
450  next_pass:
451   if (configname)
452     {
453       configlineno = 0;
454       configfp = fopen (configname, "r");
455       if (!configfp)
456         {
457           if (default_config)
458             {
459               if (parse_debug)
460                 log_info (_("Note: no default option file '%s'\n"), configname);
461             }
462           else
463             {
464               log_error (_("option file '%s': %s\n"),
465                          configname, strerror(errno));
466               g13_exit(2);
467             }
468           xfree (configname);
469           configname = NULL;
470         }
471       if (parse_debug && configname)
472         log_info (_("reading options from '%s'\n"), configname);
473       default_config = 0;
474     }
475
476   while (!no_more_options
477          && optfile_parse (configfp, configname, &configlineno, &pargs, opts))
478     {
479       switch (pargs.r_opt)
480         {
481         case aGPGConfList:
482         case aGPGConfTest:
483           set_cmd (&cmd, pargs.r_opt);
484           nogreeting = 1;
485           /* nokeysetup = 1; */
486           break;
487
488         case aServer:
489         case aMount:
490         case aUmount:
491         case aSuspend:
492         case aResume:
493         case aCreate:
494           set_cmd (&cmd, pargs.r_opt);
495           break;
496
497         case oOutput: opt.outfile = pargs.r.ret_str; break;
498
499         case oQuiet: opt.quiet = 1; break;
500         case oNoGreeting: nogreeting = 1; break;
501         case oNoTTY:  break;
502
503         case oDryRun: opt.dry_run = 1; break;
504
505         case oVerbose:
506           opt.verbose++;
507           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
508           break;
509         case oNoVerbose:
510           opt.verbose = 0;
511           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
512           break;
513
514         case oLogFile: logfile = pargs.r.ret_str; break;
515         case oNoLogFile: logfile = NULL; break;
516
517         case oNoDetach: /*nodetach = 1; */break;
518
519         case oDebug:
520           if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
521             {
522               pargs.r_opt = ARGPARSE_INVALID_ARG;
523               pargs.err = ARGPARSE_PRINT_ERROR;
524             }
525             break;
526         case oDebugAll: debug_value = ~0; break;
527         case oDebugNone: debug_value = 0; break;
528         case oDebugLevel: debug_level = pargs.r.ret_str; break;
529         case oDebugWait: /*debug_wait = pargs.r.ret_int; */break;
530         case oDebugAllowCoreDump:
531           may_coredump = enable_core_dumps ();
532           break;
533
534         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
535         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
536
537         case oNoOptions: break; /* no-options */
538         case oOptions:
539           /* Config files may not be nested (silently ignore them).  */
540           if (!configfp)
541             {
542               xfree(configname);
543               configname = xstrdup (pargs.r.ret_str);
544               goto next_pass;
545             }
546           break;
547
548         case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
549
550         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
551         case oGpgProgram: opt.gpg_program = pargs.r.ret_str;  break;
552         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
553         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
554         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
555         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
556         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
557         case oXauthority: opt.xauthority = xstrdup (pargs.r.ret_str); break;
558
559         case oFakedSystemTime:
560           {
561             time_t faked_time = isotime2epoch (pargs.r.ret_str);
562             if (faked_time == (time_t)(-1))
563               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
564             gnupg_set_time (faked_time, 0);
565           }
566           break;
567
568         case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break;
569
570         case oNoRandomSeedFile: use_random_seed = 0; break;
571
572         case oRecipient: /* Store the encryption key.  */
573           add_to_strlist (&recipients, pargs.r.ret_str);
574           break;
575
576         case oType:
577           if (!strcmp (pargs.r.ret_str, "help"))
578             {
579               be_parse_conttype_name (NULL);
580               g13_exit (0);
581             }
582           cmdline_conttype = be_parse_conttype_name (pargs.r.ret_str);
583           if (!cmdline_conttype)
584             {
585               pargs.r_opt = ARGPARSE_INVALID_ARG;
586               pargs.err = ARGPARSE_PRINT_ERROR;
587             }
588           break;
589
590         default:
591           pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
592           break;
593         }
594     }
595
596   /* XXX Construct GPG arguments.  */
597   {
598     strlist_t last;
599     last = append_to_strlist (&opt.gpg_arguments, "-z");
600     last = append_to_strlist (&last, "0");
601     last = append_to_strlist (&last, "--trust-model");
602     last = append_to_strlist (&last, "always");
603     (void) last;
604   }
605
606   if (configfp)
607     {
608       fclose (configfp);
609       configfp = NULL;
610       /* Keep a copy of the config filename. */
611       opt.config_filename = configname;
612       configname = NULL;
613       goto next_pass;
614     }
615   xfree (configname);
616   configname = NULL;
617
618   if (!opt.config_filename)
619     opt.config_filename = make_filename (gnupg_homedir (),
620                                          G13_NAME".conf", NULL);
621
622   if (log_get_errorcount(0))
623     g13_exit(2);
624
625   /* Now that we have the options parsed we need to update the default
626      control structure.  */
627   g13_init_default_ctrl (&ctrl);
628   ctrl.recipients = recipients;
629   recipients = NULL;
630
631   if (nogreeting)
632     greeting = 0;
633
634   if (greeting)
635     {
636       fprintf (stderr, "%s %s; %s\n",
637                strusage(11), strusage(13), strusage(14) );
638       fprintf (stderr, "%s\n", strusage(15) );
639     }
640
641   if (may_coredump && !opt.quiet)
642     log_info (_("WARNING: program may create a core file!\n"));
643
644   /* Print a warning if an argument looks like an option.  */
645   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
646     {
647       int i;
648
649       for (i=0; i < argc; i++)
650         if (argv[i][0] == '-' && argv[i][1] == '-')
651           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
652     }
653
654
655   if (logfile)
656     {
657       log_set_file (logfile);
658       log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
659     }
660
661   if (gnupg_faked_time_p ())
662     {
663       gnupg_isotime_t tbuf;
664
665       log_info (_("WARNING: running with faked system time: "));
666       gnupg_get_isotime (tbuf);
667       dump_isotime (tbuf);
668       log_printf ("\n");
669     }
670
671   /* Print any pending secure memory warnings.  */
672   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
673
674   /* Setup the debug flags for all subsystems.  */
675   set_debug ();
676
677   /* Install emergency cleanup handler.  */
678   g13_install_emergency_cleanup ();
679
680   /* Terminate if we found any error until now.  */
681   if (log_get_errorcount(0))
682     g13_exit (2);
683
684   /* Set the standard GnuPG random seed file.  */
685   if (use_random_seed)
686     {
687       char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
688       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
689       xfree(p);
690     }
691
692   /* Store given filename into FNAME. */
693   /* fname = argc? *argv : NULL; */
694
695   /* Parse all given encryption keys.  This does a lookup of the keys
696      and stops if any of the given keys was not found. */
697 #if 0 /* Currently not implemented.  */
698   if (!nokeysetup)
699     {
700       strlist_t sl;
701       int failed = 0;
702
703       for (sl = ctrl->recipients; sl; sl = sl->next)
704         if (check_encryption_key ())
705           failed = 1;
706       if (failed)
707         g13_exit (1);
708     }
709 #endif /*0*/
710
711   /* Dispatch command.  */
712   err = 0;
713   switch (cmd)
714     {
715     case aGPGConfList:
716       { /* List options and default values in the GPG Conf format.  */
717         char *config_filename_esc = percent_escape (opt.config_filename, NULL);
718
719         printf ("gpgconf-g13.conf:%lu:\"%s\n",
720                 GC_OPT_FLAG_DEFAULT, config_filename_esc);
721         xfree (config_filename_esc);
722
723         printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
724         printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
725         printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
726         printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
727       }
728       break;
729     case aGPGConfTest:
730       /* This is merely a dummy command to test whether the
731          configuration file is valid.  */
732       break;
733
734     case aServer:
735       {
736         start_idle_task ();
737         ctrl.no_server = 0;
738         err = g13_server (&ctrl);
739         if (err)
740           log_error ("server exited with error: %s <%s>\n",
741                      gpg_strerror (err), gpg_strsource (err));
742         else
743           g13_request_shutdown ();
744       }
745       break;
746
747     case aCreate: /* Create a new container. */
748       {
749         if (argc != 1)
750           wrong_args ("--create filename");
751         start_idle_task ();
752         err = g13_create_container (&ctrl, argv[0]);
753         if (err)
754           log_error ("error creating a new container: %s <%s>\n",
755                      gpg_strerror (err), gpg_strsource (err));
756         else
757           g13_request_shutdown ();
758       }
759       break;
760
761     case aMount: /* Mount a container. */
762       {
763         if (argc != 1 && argc != 2 )
764           wrong_args ("--mount filename [mountpoint]");
765         start_idle_task ();
766         err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL);
767         if (err)
768           log_error ("error mounting container '%s': %s <%s>\n",
769                      *argv, gpg_strerror (err), gpg_strsource (err));
770       }
771       break;
772
773     case aUmount: /* Unmount a mounted container.  */
774       {
775         if (argc != 1)
776           wrong_args ("--umount filename");
777         err = GPG_ERR_NOT_IMPLEMENTED;
778         log_error ("error unmounting container '%s': %s <%s>\n",
779                    *argv, gpg_strerror (err), gpg_strsource (err));
780       }
781       break;
782
783     case aSuspend: /* Suspend a container. */
784       {
785         /* Fixme: Should we add a suspend all container option?  */
786         if (argc != 1)
787           wrong_args ("--suspend filename");
788         err = g13_suspend_container (&ctrl, argv[0]);
789         if (err)
790           log_error ("error suspending container '%s': %s <%s>\n",
791                      *argv, gpg_strerror (err), gpg_strsource (err));
792       }
793       break;
794
795     case aResume: /* Resume a suspended container. */
796       {
797         /* Fixme: Should we add a resume all container option?  */
798         if (argc != 1)
799           wrong_args ("--resume filename");
800         err = g13_resume_container (&ctrl, argv[0]);
801         if (err)
802           log_error ("error resuming container '%s': %s <%s>\n",
803                      *argv, gpg_strerror (err), gpg_strsource (err));
804       }
805       break;
806
807     default:
808       log_error (_("invalid command (there is no implicit command)\n"));
809       break;
810     }
811
812   g13_deinit_default_ctrl (&ctrl);
813
814   if (!err)
815     join_idle_task ();
816
817   /* Cleanup.  */
818   g13_exit (0);
819   return 8; /*NOTREACHED*/
820 }
821
822
823 /* Store defaults into the per-connection CTRL object.  */
824 void
825 g13_init_default_ctrl (ctrl_t ctrl)
826 {
827   ctrl->conttype = cmdline_conttype? cmdline_conttype : CONTTYPE_ENCFS;
828 }
829
830
831 /* Release remaining resources allocated in the CTRL object.  */
832 void
833 g13_deinit_default_ctrl (ctrl_t ctrl)
834 {
835   call_syshelp_release (ctrl);
836   FREE_STRLIST (ctrl->recipients);
837 }
838
839
840 /* Request a shutdown.  This can be used when the process should
841  * finish instead of running the idle task.  */
842 void
843 g13_request_shutdown (void)
844 {
845   shutdown_pending++;
846 }
847
848
849 /* This function is called for each signal we catch.  It is run in the
850    main context or the one of a NPth thread and thus it is not
851    restricted in what it may do.  */
852 static void
853 handle_signal (int signo)
854 {
855   switch (signo)
856     {
857 #ifndef HAVE_W32_SYSTEM
858     case SIGHUP:
859       log_info ("SIGHUP received - re-reading configuration\n");
860       /* Fixme:  Not yet implemented.  */
861       break;
862
863     case SIGUSR1:
864       log_info ("SIGUSR1 received - printing internal information:\n");
865       /* Fixme: We need to see how to integrate pth dumping into our
866          logging system.  */
867       /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
868       mountinfo_dump_all ();
869       break;
870
871     case SIGUSR2:
872       log_info ("SIGUSR2 received - no action defined\n");
873       break;
874
875     case SIGTERM:
876       if (!shutdown_pending)
877         log_info ("SIGTERM received - shutting down ...\n");
878       else
879         log_info ("SIGTERM received - still %u runners active\n",
880                   runner_get_threads ());
881       shutdown_pending++;
882       if (shutdown_pending > 2)
883         {
884           log_info ("shutdown forced\n");
885           log_info ("%s %s stopped\n", strusage(11), strusage(13) );
886           g13_exit (0);
887         }
888       break;
889
890     case SIGINT:
891       log_info ("SIGINT received - immediate shutdown\n");
892       log_info( "%s %s stopped\n", strusage(11), strusage(13));
893       g13_exit (0);
894       break;
895 #endif /*!HAVE_W32_SYSTEM*/
896
897     default:
898       log_info ("signal %d received - no action defined\n", signo);
899     }
900 }
901
902
903 /* This ticker function is called about every TIMERTICK_INTERVAL_SEC
904    seconds. */
905 static void
906 handle_tick (void)
907 {
908   /* log_debug ("TICK\n"); */
909 }
910
911
912 /* The idle task.  We use a separate thread to do idle stuff and to
913    catch signals.  */
914 static void *
915 idle_task (void *dummy_arg)
916 {
917   int signo;           /* The number of a raised signal is stored here.  */
918   int saved_errno;
919   struct timespec abstime;
920   struct timespec curtime;
921   struct timespec timeout;
922   int ret;
923
924   (void)dummy_arg;
925
926   /* Create the event to catch the signals. */
927 #ifndef HAVE_W32_SYSTEM
928   npth_sigev_init ();
929   npth_sigev_add (SIGHUP);
930   npth_sigev_add (SIGUSR1);
931   npth_sigev_add (SIGUSR2);
932   npth_sigev_add (SIGINT);
933   npth_sigev_add (SIGTERM);
934   npth_sigev_fini ();
935 #endif
936
937   npth_clock_gettime (&abstime);
938   abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
939
940   for (;;)
941     {
942       /* The shutdown flag allows us to terminate the idle task.  */
943       if (shutdown_pending)
944         {
945           runner_cancel_all ();
946
947           if (!runner_get_threads ())
948             break; /* ready */
949         }
950
951       npth_clock_gettime (&curtime);
952       if (!(npth_timercmp (&curtime, &abstime, <)))
953         {
954           /* Timeout.  */
955           handle_tick ();
956           npth_clock_gettime (&abstime);
957           abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
958         }
959       npth_timersub (&abstime, &curtime, &timeout);
960
961 #ifndef HAVE_W32_SYSTEM
962       ret = npth_pselect (0, NULL, NULL, NULL, &timeout, npth_sigev_sigmask());
963       saved_errno = errno;
964
965       while (npth_sigev_get_pending(&signo))
966         handle_signal (signo);
967 #else
968       ret = npth_eselect (0, NULL, NULL, NULL, &timeout, NULL, NULL);
969       saved_errno = errno;
970 #endif
971
972       if (ret == -1 && saved_errno != EINTR)
973         {
974           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
975                      strerror (saved_errno));
976           npth_sleep (1);
977           continue;
978         }
979
980       if (ret <= 0)
981         {
982           /* Interrupt or timeout.  Will be handled when calculating the
983              next timeout.  */
984           continue;
985         }
986
987       /* Here one would add processing of file descriptors.  */
988     }
989
990   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
991   return NULL;
992 }
993
994
995 /* Start the idle task.   */
996 static void
997 start_idle_task (void)
998 {
999   npth_attr_t tattr;
1000   npth_t thread;
1001   sigset_t sigs;       /* The set of signals we want to catch.  */
1002   int err;
1003
1004 #ifndef HAVE_W32_SYSTEM
1005   /* These signals should always go to the idle task, so they need to
1006      be blocked everywhere else.  We assume start_idle_task is called
1007      from the main thread before any other threads are created.  */
1008   sigemptyset (&sigs);
1009   sigaddset (&sigs, SIGHUP);
1010   sigaddset (&sigs, SIGUSR1);
1011   sigaddset (&sigs, SIGUSR2);
1012   sigaddset (&sigs, SIGINT);
1013   sigaddset (&sigs, SIGTERM);
1014   npth_sigmask (SIG_BLOCK, &sigs, NULL);
1015 #endif
1016
1017   npth_attr_init (&tattr);
1018   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1019
1020   err = npth_create (&thread, &tattr, idle_task, NULL);
1021   if (err)
1022     {
1023       log_fatal ("error starting idle task: %s\n", strerror (err));
1024       return; /*NOTREACHED*/
1025     }
1026   npth_setname_np (thread, "idle-task");
1027   idle_task_thread = thread;
1028   npth_attr_destroy (&tattr);
1029 }
1030
1031
1032 /* Wait for the idle task to finish.  */
1033 static void
1034 join_idle_task (void)
1035 {
1036   int err;
1037
1038   /* FIXME: This assumes that a valid pthread_t is non-null.  That is
1039      not guaranteed.  */
1040   if (idle_task_thread)
1041     {
1042       err = npth_join (idle_task_thread, NULL);
1043       if (err)
1044         log_error ("waiting for idle task thread failed: %s\n",
1045                    strerror (err));
1046     }
1047 }