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