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