gpg: Relax printing of STATUS_FAILURE.
[gnupg.git] / g10 / gpg.c
index ecddb20..aaeddee 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -62,6 +62,7 @@
 #include "../common/init.h"
 #include "../common/mbox-util.h"
 #include "../common/shareddefs.h"
+#include "../common/compliance.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
 #define MY_O_BINARY  O_BINARY
@@ -200,6 +201,7 @@ enum cmd_and_opt_values
     oWithWKDHash,
     oWithColons,
     oWithKeyData,
+    oWithKeyOrigin,
     oWithTofuInfo,
     oWithSigList,
     oWithSigCheck,
@@ -372,6 +374,7 @@ enum cmd_and_opt_values
     oPersonalCompressPreferences,
     oAgentProgram,
     oDirmngrProgram,
+    oDisableDirmngr,
     oDisplay,
     oTTYname,
     oTTYtype,
@@ -418,6 +421,9 @@ enum cmd_and_opt_values
     oOnlySignTextIDs,
     oDisableSignerUID,
     oSender,
+    oKeyOrigin,
+    oRequestOrigin,
+    oNoSymkeyCache,
 
     oNoop
   };
@@ -614,6 +620,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
+  ARGPARSE_s_s (oKeyOrigin, "key-origin", "@"),
   ARGPARSE_s_s (oImportOptions, "import-options", "@"),
   ARGPARSE_s_s (oImportFilter,  "import-filter", "@"),
   ARGPARSE_s_s (oExportOptions, "export-options", "@"),
@@ -703,6 +710,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
   ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
+  ARGPARSE_s_s (oRequestOrigin,   "request-origin", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
@@ -782,6 +790,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
+  ARGPARSE_s_n (oWithKeyOrigin,   "with-key-origin", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -832,6 +841,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
   ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
+  ARGPARSE_s_n (oDisableDirmngr, "disable-dirmngr", "@"),
   ARGPARSE_s_s (oDisplay,    "display",    "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
@@ -879,6 +889,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oAutoKeyLocate, "auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutoKeyLocate, "no-auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
+  ARGPARSE_s_n (oNoSymkeyCache, "no-symkey-cache", "@"),
 
   /* Dummy options with warnings.  */
   ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
@@ -1157,6 +1168,7 @@ static void
 wrong_args( const char *text)
 {
   es_fprintf (es_stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  log_inc_errorcount ();
   g10_exit(2);
 }
 
@@ -1852,6 +1864,10 @@ gpgconf_list (const char *configfile)
   es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
   es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("max-cert-depth:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("completes-needed:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("marginals-needed:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* The next one is an info only item and should match the macros at
      the top of keygen.c  */
@@ -2073,11 +2089,8 @@ parse_tofu_policy (const char *policystr)
 }
 
 
-/* Parse the value of --compliance.  */
-static int
-parse_compliance_option (const char *string)
-{
-  struct { const char *keyword; enum cmd_and_opt_values option; } list[] = {
+static struct gnupg_compliance_option compliance_options[] =
+  {
     { "gnupg",      oGnuPG },
     { "openpgp",    oOpenPGP },
     { "rfc4880bis", oRFC4880bis },
@@ -2088,26 +2101,6 @@ parse_compliance_option (const char *string)
     { "pgp8",       oPGP8 },
     { "de-vs",      oDE_VS }
   };
-  int i;
-
-  if (!ascii_strcasecmp (string, "help"))
-    {
-      log_info (_("valid values for option '%s':\n"), "--compliance");
-      for (i=0; i < DIM (list); i++)
-        log_info ("  %s\n", list[i].keyword);
-      g10_exit (1);
-    }
-
-  for (i=0; i < DIM (list); i++)
-    if (!ascii_strcasecmp (string, list[i].keyword))
-      return list[i].option;
-
-  log_error (_("invalid value for option '%s'\n"), "--compliance");
-  if (!opt.quiet)
-    log_info (_("(use \"help\" to list choices)\n"));
-  g10_exit (1);
-}
-
 
 
 /* Helper to set compliance related options.  This is a separate
@@ -2166,6 +2159,7 @@ set_compliance_option (enum cmd_and_opt_values option)
     case oDE_VS:
       set_compliance_option (oOpenPGP);
       opt.compliance = CO_DE_VS;
+      opt.force_mdc = 1;
       /* Fixme: Change other options.  */
       break;
 
@@ -2309,6 +2303,7 @@ main (int argc, char **argv)
     int ovrseskeyfd = -1;
     int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
+    int default_akl = 1;
     int require_secmem = 0;
     int got_secmem = 0;
     struct assuan_malloc_hooks malloc_hooks;
@@ -2349,6 +2344,9 @@ main (int argc, char **argv)
 
     dotlock_create (NULL, 0); /* Register lock file cleanup. */
 
+    /* Tell the compliance module who we are.  */
+    gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG);
+
     opt.autostart = 1;
     opt.session_env = session_env_new ();
     if (!opt.session_env)
@@ -2371,9 +2369,10 @@ main (int argc, char **argv)
     opt.max_cert_depth = 5;
     opt.escape_from = 1;
     opt.flags.require_cross_cert = 1;
-    opt.import_options = 0;
+    opt.import_options = IMPORT_REPAIR_KEYS;
     opt.export_options = EXPORT_ATTRIBUTES;
-    opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
+    opt.keyserver_options.import_options = (IMPORT_REPAIR_KEYS
+                                           | IMPORT_REPAIR_PKS_SUBKEY_BUG);
     opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
     opt.keyserver_options.options = KEYSERVER_HONOR_PKA_RECORD;
     opt.verify_options = (LIST_SHOW_UID_VALIDITY
@@ -2398,7 +2397,6 @@ main (int argc, char **argv)
     opt.passphrase_repeat = 1;
     opt.emit_version = 0;
     opt.weak_digests = NULL;
-    additional_weak_digest("MD5");
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
@@ -2474,6 +2472,10 @@ main (int argc, char **argv)
     assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
     setup_libassuan_logging (&opt.debug, NULL);
 
+    /* Set default options which require that malloc stuff is ready.  */
+    additional_weak_digest ("MD5");
+    parse_auto_key_locate ("local,wkd");
+
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
     if (default_config)
@@ -2748,6 +2750,10 @@ main (int argc, char **argv)
             opt.with_wkd_hash = 1;
             break;
 
+         case oWithKeyOrigin:
+            opt.with_key_origin = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
@@ -2861,7 +2867,15 @@ main (int argc, char **argv)
            break;
 
           case oCompliance:
-            set_compliance_option (parse_compliance_option (pargs.r.ret_str));
+           {
+             int compliance = gnupg_parse_compliance_option
+                (pargs.r.ret_str,
+                 compliance_options, DIM (compliance_options),
+                 opt.quiet);
+             if (compliance < 0)
+               g10_exit (1);
+             set_compliance_option (compliance);
+           }
             break;
           case oOpenPGP:
           case oRFC2440:
@@ -3087,10 +3101,16 @@ main (int argc, char **argv)
               log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
            break;
 
+          case oRequestOrigin:
+           opt.request_origin = parse_request_origin (pargs.r.ret_str);
+           if (opt.request_origin == -1)
+              log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str);
+           break;
+
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
            if (! gnupg_fd_valid (opt.command_fd))
-             log_fatal ("command-fd is invalid: %s\n", strerror (errno));
+             log_error ("command-fd is invalid: %s\n", strerror (errno));
             break;
          case oCommandFile:
             opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
@@ -3327,13 +3347,14 @@ main (int argc, char **argv)
          case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
          case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
          case oNoRandomSeedFile: use_random_seed = 0; break;
+
          case oAutoKeyRetrieve:
+            opt.keyserver_options.options |= KEYSERVER_AUTO_KEY_RETRIEVE;
+            break;
          case oNoAutoKeyRetrieve:
-               if(pargs.r_opt==oAutoKeyRetrieve)
-                 opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
-               else
-                 opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
-               break;
+            opt.keyserver_options.options &= ~KEYSERVER_AUTO_KEY_RETRIEVE;
+            break;
+
          case oShowSessionKey: opt.show_session_key = 1; break;
          case oOverrideSessionKey:
                opt.override_session_key = pargs.r.ret_str;
@@ -3384,6 +3405,7 @@ main (int argc, char **argv)
            break;
           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
           case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
+         case oDisableDirmngr: opt.disable_dirmngr = 1;  break;
           case oWeakDigest:
            additional_weak_digest(pargs.r.ret_str);
            break;
@@ -3458,6 +3480,13 @@ main (int argc, char **argv)
          case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
 
          case oAutoKeyLocate:
+            if (default_akl)
+              {
+                /* This is the first time --aito-key-locate is seen.
+                 * We need to reset the default akl.  */
+                default_akl = 0;
+                release_akl();
+              }
            if(!parse_auto_key_locate(pargs.r.ret_str))
              {
                if(configname)
@@ -3471,6 +3500,12 @@ main (int argc, char **argv)
            release_akl();
            break;
 
+         case oKeyOrigin:
+           if(!parse_key_origin (pargs.r.ret_str))
+              log_error (_("invalid argument for option \"%.50s\"\n"),
+                         "--key-origin");
+           break;
+
          case oEnableLargeRSA:
 #if SECMEM_BUFFER_SIZE >= 65536
             opt.flags.large_rsa=1;
@@ -3523,6 +3558,7 @@ main (int argc, char **argv)
             break;
 
           case oNoAutostart: opt.autostart = 0; break;
+          case oNoSymkeyCache: opt.no_symkey_cache = 1; break;
 
          case oDefaultNewKeyAlgo:
             opt.def_new_key_algo = pargs.r.ret_str;
@@ -3531,7 +3567,16 @@ main (int argc, char **argv)
          case oNoop: break;
 
          default:
-            pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
+            if (configfp)
+              pargs.err = ARGPARSE_PRINT_WARNING;
+            else
+              {
+                pargs.err = ARGPARSE_PRINT_ERROR;
+                /* The argparse fucntion calls a plain exit and thus
+                 * we need to print a status here.  */
+                write_status_failure ("option-parser",
+                                      gpg_error(GPG_ERR_GENERAL));
+              }
             break;
          }
       }
@@ -3550,7 +3595,10 @@ main (int argc, char **argv)
       }
     xfree(configname); configname = NULL;
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
     /* The command --gpgconf-list is pretty simple and may be called
        directly after the option parsing. */
@@ -3571,7 +3619,10 @@ main (int argc, char **argv)
                  "--print-pks-records",
                  "--export-options export-pka");
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
 
     if( nogreeting )
@@ -3672,6 +3723,7 @@ main (int argc, char **argv)
       {
        log_info(_("will not run with insecure memory due to %s\n"),
                 "--require-secmem");
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
        g10_exit(2);
       }
 
@@ -3812,7 +3864,11 @@ main (int argc, char **argv)
       }
 
     if( log_get_errorcount(0) )
-       g10_exit(2);
+      {
+        write_status_failure ("option-postprocessing",
+                              gpg_error(GPG_ERR_GENERAL));
+       g10_exit (2);
+      }
 
     if(opt.compress_level==0)
       opt.compress_algo=COMPRESS_ALGO_NONE;
@@ -3855,19 +3911,22 @@ main (int argc, char **argv)
            switch(badtype)
              {
              case PREFTYPE_SYM:
-               log_info(_("you may not use cipher algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("cipher algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                        badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_HASH:
-               log_info(_("you may not use digest algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("digest algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_ZIP:
-               log_info(_("you may not use compression algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("compression algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              default:
                BUG();
@@ -3877,6 +3936,44 @@ main (int argc, char **argv)
          }
       }
 
+    /* Check our chosen algorithms against the list of allowed
+     * algorithms in the current compliance mode, and fail hard if it
+     * is not.  This is us being nice to the user informing her early
+     * that the chosen algorithms are not available.  We also check
+     * and enforce this right before the actual operation.  */
+    if (opt.def_cipher_algo
+       && ! gnupg_cipher_is_allowed (opt.compliance,
+                                     cmd == aEncr
+                                     || cmd == aSignEncr
+                                     || cmd == aEncrSym
+                                     || cmd == aSym
+                                     || cmd == aSignSym
+                                     || cmd == aSignEncrSym,
+                                     opt.def_cipher_algo,
+                                     GCRY_CIPHER_MODE_NONE))
+      log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+                openpgp_cipher_algo_name (opt.def_cipher_algo),
+                gnupg_compliance_option_string (opt.compliance));
+
+    if (opt.def_digest_algo
+       && ! gnupg_digest_is_allowed (opt.compliance,
+                                     cmd == aSign
+                                     || cmd == aSignEncr
+                                     || cmd == aSignEncrSym
+                                     || cmd == aSignSym
+                                     || cmd == aClearsign,
+                                     opt.def_digest_algo))
+      log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+                gcry_md_algo_name (opt.def_digest_algo),
+                gnupg_compliance_option_string (opt.compliance));
+
+    /* Fail hard.  */
+    if (log_get_errorcount (0))
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
+       g10_exit (2);
+      }
+
     /* Set the random seed file. */
     if( use_random_seed ) {
       char *p = make_filename (gnupg_homedir (), "random_seed", NULL );
@@ -4086,7 +4183,8 @@ main (int argc, char **argv)
                      " with --s2k-mode 0\n"));
        else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --encrypt"
-                     " while in %s mode\n"),compliance_option_string());
+                     " in %s mode\n"),
+                   gnupg_compliance_option_string (opt.compliance));
        else
          {
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
@@ -4146,7 +4244,8 @@ main (int argc, char **argv)
                      " with --s2k-mode 0\n"));
        else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --sign --encrypt"
-                     " while in %s mode\n"),compliance_option_string());
+                     " in %s mode\n"),
+                   gnupg_compliance_option_string (opt.compliance));
        else
          {
            if( argc )
@@ -4303,9 +4402,9 @@ main (int argc, char **argv)
        break;
 
       case aCheckKeys:
-       opt.check_sigs = 1;
+       opt.check_sigs = 1; /* fall through */
       case aListSigs:
-       opt.list_sigs = 1;
+       opt.list_sigs = 1; /* fall through */
       case aListKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
@@ -4447,11 +4546,11 @@ main (int argc, char **argv)
         {
           const char *x_fpr, *x_expire;
 
-          if (argc != 2)
-            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+          if (argc < 2)
+            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE [SUBKEY-FPRS]");
           x_fpr = *argv++; argc--;
           x_expire = *argv++; argc--;
-          keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
         }
        break;
 
@@ -4468,9 +4567,10 @@ main (int argc, char **argv)
        break;
 
       case aFastImport:
-        opt.import_options |= IMPORT_FAST;
+        opt.import_options |= IMPORT_FAST; /* fall through */
       case aImport:
-       import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
+       import_keys (ctrl, argc? argv:NULL, argc, NULL,
+                     opt.import_options, opt.key_origin, opt.key_origin_url);
        break;
 
        /* TODO: There are a number of command that use this same
@@ -4558,7 +4658,7 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
-       rc = keyserver_fetch (ctrl, sl);
+       rc = keyserver_fetch (ctrl, sl, opt.key_origin);
        if(rc)
           {
             write_status_failure ("fetch-keys", rc);
@@ -4856,7 +4956,10 @@ main (int argc, char **argv)
 
          hd = keydb_new ();
          if (! hd)
-            g10_exit (1);
+            {
+              write_status_failure ("tofu-driver", gpg_error(GPG_ERR_GENERAL));
+              g10_exit (1);
+            }
 
           tofu_begin_batch_update (ctrl);
 
@@ -4870,6 +4973,7 @@ main (int argc, char **argv)
                {
                  log_error (_("error parsing key specification '%s': %s\n"),
                              argv[i], gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4883,6 +4987,8 @@ main (int argc, char **argv)
                  log_error (_("'%s' does not appear to be a valid"
                               " key ID, fingerprint or keygrip\n"),
                             argv[i]);
+                  write_status_failure ("tofu-driver",
+                                        gpg_error(GPG_ERR_GENERAL));
                  g10_exit (1);
                }
 
@@ -4893,6 +4999,7 @@ main (int argc, char **argv)
                      the string.  */
                   log_error ("keydb_search_reset failed: %s\n",
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4901,6 +5008,7 @@ main (int argc, char **argv)
                {
                  log_error (_("key \"%s\" not found: %s\n"), argv[i],
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4909,12 +5017,16 @@ main (int argc, char **argv)
                {
                  log_error (_("error reading keyblock: %s\n"),
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
              merge_keys_and_selfsig (ctrl, kb);
              if (tofu_set_policy (ctrl, kb, policy))
-               g10_exit (1);
+                {
+                  write_status_failure ("tofu-driver", rc);
+                  g10_exit (1);
+                }
 
               release_kbnode (kb);
            }
@@ -4930,7 +5042,7 @@ main (int argc, char **argv)
         if (!opt.quiet)
           log_info (_("WARNING: no command supplied."
                       "  Trying to guess what you mean ...\n"));
-        /*FALLTHU*/
+        /*FALLTHRU*/
       case aListPackets:
        if( argc > 1 )
            wrong_args("[filename]");
@@ -4996,6 +5108,12 @@ emergency_cleanup (void)
 void
 g10_exit( int rc )
 {
+  /* If we had an error but not printed an error message, do it now.
+   * Note that write_status_failure will never print a second failure
+   * status line. */
+  if (rc)
+    write_status_failure ("gpg-exit", gpg_error (GPG_ERR_GENERAL));
+
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
   if (DBG_CLOCK)
     log_clock ("stop");