* gpgsm.c (main): Use GNUPG_DEFAULT_HOMEDIR constant.
[gnupg.git] / sm / gpgsm.c
1 /* gpgsm.c - GnuPG for S/MIME 
2  *      Copyright (C) 2001, 2002 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include <gcrypt.h>
31 #include "gpgsm.h"
32 #include "../assuan/assuan.h" /* malloc hooks */
33 #include "../kbx/keybox.h" /* malloc hooks */
34 #include "i18n.h"
35 #include "keydb.h"
36 #include "sysutils.h"
37
38 enum cmd_and_opt_values {
39   aNull = 0,
40   oArmor        = 'a',
41   aDetachedSign = 'b',
42   aSym          = 'c',
43   aDecrypt      = 'd',
44   aEncr         = 'e',
45   oInteractive  = 'i',
46   oKOption      = 'k',
47   oDryRun       = 'n',
48   oOutput       = 'o',
49   oQuiet        = 'q',
50   oRecipient    = 'r',
51   aSign         = 's',
52   oTextmodeShort= 't',
53   oUser         = 'u',
54   oVerbose      = 'v',
55   oCompress     = 'z',
56   oNotation     = 'N',
57   oBatch        = 500,
58   aClearsign,
59   aStore,
60   aKeygen,
61   aSignEncr,
62   aSignKey,
63   aLSignKey,
64   aListPackets,
65   aEditKey,
66   aDeleteKey,
67   aImport,
68   aVerify,
69   aVerifyFiles,
70   aListKeys,
71   aListExternalKeys,
72   aListSigs,
73   aListSecretKeys,
74   aSendKeys,
75   aRecvKeys,
76   aExport,
77   aCheckKeys,
78   aServer,                        
79   aLearnCard,
80
81   oOptions,
82   oDebug,
83   oDebugAll,
84   oDebugWait,
85   oDebugNoPathValidation,
86   oLogFile,
87
88   oEnableSpecialFilenames,
89
90   oAgentProgram,
91   oDisplay,
92   oTTYname,
93   oTTYtype,
94   oLCctype,
95   oLCmessages,
96
97   oDirmngrProgram,
98   oFakedSystemTime,
99
100
101   oAssumeArmor,
102   oAssumeBase64,
103   oAssumeBinary,
104
105   oBase64,
106   oNoArmor,
107
108   oDisableCRLChecks,
109   oEnableCRLChecks,
110
111   oIncludeCerts,
112   oPolicyFile,
113   oDisablePolicyChecks,
114   oEnablePolicyChecks,
115
116   
117
118   oTextmode,
119   oFingerprint,
120   oWithFingerprint,
121   oAnswerYes,
122   oAnswerNo,
123   oKeyring,
124   oSecretKeyring,
125   oDefaultKey,
126   oDefRecipient,
127   oDefRecipientSelf,
128   oNoDefRecipient,
129   oStatusFD,
130   oNoComment,
131   oNoVersion,
132   oEmitVersion,
133   oCompletesNeeded,
134   oMarginalsNeeded,
135   oMaxCertDepth,
136   oLoadExtension,
137   oRFC1991,
138   oOpenPGP,
139   oCipherAlgo,
140   oDigestAlgo,
141   oCompressAlgo,
142   oPasswdFD,
143   oCommandFD,
144   oNoVerbose,
145   oTrustDBName,
146   oNoSecmemWarn,
147   oNoDefKeyring,
148   oNoGreeting,
149   oNoTTY,
150   oNoOptions,
151   oNoBatch,
152   oHomedir,
153   oWithColons,
154   oWithKeyData,
155   oSkipVerify,
156   oCompressKeys,
157   oCompressSigs,
158   oAlwaysTrust,
159   oRunAsShmCP,
160   oSetFilename,
161   oSetPolicyURL,
162   oUseEmbeddedFilename,
163   oComment,
164   oDefaultComment,
165   oThrowKeyid,
166   oForceV3Sigs,
167   oForceMDC,
168   oS2KMode,
169   oS2KDigest,
170   oS2KCipher,
171   oCharset,
172   oNotDashEscaped,
173   oEscapeFrom,
174   oLockOnce,
175   oLockMultiple,
176   oLockNever,
177   oKeyServer,
178   oEncryptTo,
179   oNoEncryptTo,
180   oLoggerFD,
181   oUtf8Strings,
182   oNoUtf8Strings,
183   oDisableCipherAlgo,
184   oDisablePubkeyAlgo,
185   oAllowNonSelfsignedUID,
186   oAllowFreeformUID,
187   oNoLiteral,
188   oSetFilesize,
189   oHonorHttpProxy,
190   oFastListMode,
191   oListOnly,
192   oIgnoreTimeConflict,
193   oNoRandomSeedFile,
194   oNoAutoKeyRetrieve,
195   oUseAgent,
196   oMergeOnly,
197   oTryAllSecrets,
198   oTrustedKey,
199   oEmuMDEncodeBug,
200   aDummy
201  };
202
203
204 static ARGPARSE_OPTS opts[] = {
205
206     { 300, NULL, 0, N_("@Commands:\n ") },
207
208     { aSign, "sign",      256, N_("|[file]|make a signature")},
209     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
210     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
211     { aEncr, "encrypt",   256, N_("encrypt data")},
212     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
213     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
214     { aVerify, "verify"   , 256, N_("verify a signature")},
215     { aVerifyFiles, "verify-files" , 256, "@" },
216     { aListKeys, "list-keys", 256, N_("list keys")},
217     { aListExternalKeys, "list-external-keys", 256, N_("list external keys")},
218     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
219     { aListSigs,   "list-sigs", 256, N_("list certificate chain")}, 
220     { aListSigs,   "check-sigs",256, "@"},
221     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
222     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
223     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
224     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
225     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
226     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
227     { aImport, "import",      256     , N_("import certificates")},
228     { aExport, "export",      256     , N_("export certificates")},
229     { aLearnCard, "learn-card", 256 ,N_("register a smartcard")},
230     { aServer, "server",      256, N_("run in server mode")},
231     { oLogFile, "log-file"   ,2, N_("use a log file for the server")},
232     
233
234     { 301, NULL, 0, N_("@\nOptions:\n ") },
235
236     { oArmor, "armor",     0, N_("create ascii armored output")},
237     { oArmor, "armour",    0, "@" },
238     { oBase64, "base64",    0, N_("create base-64 encoded output")},
239     
240     { oAssumeArmor,  "assume-armor", 0, N_("assume input is in PEM format")},
241     { oAssumeBase64, "assume-base64", 0,
242                                       N_("assume input is in base-64 format")},
243     { oAssumeBinary, "assume-binary", 0,
244                                       N_("assume input is in binary format")},
245
246     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
247
248
249     { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")},
250     { oEnableCRLChecks, "enable-crl-checks", 0, "@"},
251
252     { oIncludeCerts, "include-certs", 1,
253                                  N_("|N|number of certificates to include") },
254
255     { oPolicyFile, "policy-file", 2,
256                     N_("|FILE|take policy information from FILE") },
257
258     { oDisablePolicyChecks, "disable-policy-checks", 0,
259                            N_("do not check certificate policies")},
260     { oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
261
262 #if 0
263     { oDefRecipient, "default-recipient" ,2,
264                                   N_("|NAME|use NAME as default recipient")},
265     { oDefRecipientSelf, "default-recipient-self" ,0,
266                                 N_("use the default key as default recipient")},
267     { oNoDefRecipient, "no-default-recipient", 0, "@" },
268     { oEncryptTo, "encrypt-to", 2, "@" },
269     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
270
271 #endif
272     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
273
274 #if 0
275     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
276     { oTextmodeShort, NULL,   0, "@"},
277     { oTextmode, "textmode",  0, N_("use canonical text mode")},
278 #endif
279
280     { oOutput, "output",    2, N_("use as output file")},
281     { oVerbose, "verbose",   0, N_("verbose") },
282     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
283     { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
284 #if 0
285     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
286     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
287 #endif
288     { oDryRun, "dry-run",   0, N_("do not make any changes") },
289   /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
290     /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/
291     { oBatch, "batch",     0, N_("batch mode: never ask")},
292     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
293     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
294
295     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
296     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
297     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
298     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
299     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
300     { oOptions, "options"   , 2, N_("read options from file")},
301
302     { oDebug, "debug"     ,4|16, "@"},
303     { oDebugAll, "debug-all" ,0, "@"},
304     { oDebugWait, "debug-wait" ,1, "@"},
305     { oDebugNoPathValidation, "debug-no-path-validation" ,0, "@"},
306     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
307     { aDummy, "no-comment", 0,   "@"},
308     { aDummy, "completes-needed", 1, "@"},
309     { aDummy, "marginals-needed", 1, "@"},
310     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
311     { aDummy, "trusted-key", 2, "@"},
312     { oLoadExtension, "load-extension" ,2,
313       N_("|FILE|load extension module FILE")},
314     { aDummy, "rfc1991",   0, "@"},
315     { aDummy, "openpgp",   0, "@"},
316     { aDummy, "s2k-mode",  1, "@"},
317     { aDummy, "s2k-digest-algo",2, "@"},
318     { aDummy, "s2k-cipher-algo",2, "@"},
319     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
320     { oDigestAlgo, "digest-algo", 2 ,
321       N_("|NAME|use message digest algorithm NAME")},
322 #if 0
323     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
324 #endif
325     { aDummy, "throw-keyid", 0, "@"},
326     { aDummy, "notation-data", 2, "@"},
327
328     { 302, NULL, 0, N_(
329   "@\n(See the man page for a complete listing of all commands and options)\n"
330                       )},
331
332     { 303, NULL, 0, N_("@\nExamples:\n\n"
333     " -se -r Bob [file]          sign and encrypt for user Bob\n"
334     " --clearsign [file]         make a clear text signature\n"
335     " --detach-sign [file]       make a detached signature\n"
336     " --list-keys [names]        show keys\n"
337     " --fingerprint [names]      show fingerprints\n"  ) },
338
339   /* hidden options */
340     { oNoVerbose, "no-verbose", 0, "@"},
341
342     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
343
344
345     { oTrustDBName, "trustdb-name", 2, "@" },
346     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, 
347     { oNoArmor, "no-armor",   0, "@"},
348     { oNoArmor, "no-armour",   0, "@"},
349     { oNoDefKeyring, "no-default-keyring", 0, "@" },
350     { oNoGreeting, "no-greeting", 0, "@" },
351     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
352     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
353     { oAgentProgram, "agent-program", 2 , "@" },
354     { oDisplay,    "display",     2, "@" },
355     { oTTYname,    "ttyname",     2, "@" },
356     { oTTYtype,    "ttytype",     2, "@" },
357     { oLCctype,    "lc-ctype",    2, "@" },
358     { oLCmessages, "lc-messages", 2, "@" },
359     { oDirmngrProgram, "dirmngr-program", 2 , "@" },
360     { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */
361
362
363     { oNoBatch, "no-batch", 0, "@" },
364     { oWithColons, "with-colons", 0, "@"},
365     { oWithKeyData,"with-key-data", 0, "@"},
366     { aListKeys, "list-key", 0, "@" }, /* alias */
367     { aListSigs, "list-sig", 0, "@" }, /* alias */
368     { aListSigs, "check-sig",0, "@" }, /* alias */
369     { oSkipVerify, "skip-verify",0, "@" },
370     { oCompressKeys, "compress-keys",0, "@"},
371     { oCompressSigs, "compress-sigs",0, "@"},
372     { oAlwaysTrust, "always-trust", 0, "@"},
373     { oNoVersion, "no-version", 0, "@"},
374     { oLockOnce, "lock-once", 0, "@" },
375     { oLockMultiple, "lock-multiple", 0, "@" },
376     { oLockNever, "lock-never", 0, "@" },
377     { oLoggerFD, "logger-fd",1, "@" },
378     { oWithFingerprint, "with-fingerprint", 0, "@" },
379     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
380     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
381     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
382     { oListOnly, "list-only", 0, "@"},
383     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
384     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
385 {0} };
386
387
388
389 int gpgsm_errors_seen = 0;
390
391 /* It is possible that we are currentlu running under setuid permissions */
392 static int maybe_setuid = 1;
393
394 /* Option --enable-special-filenames */
395 static int allow_special_filenames;
396
397
398 static char *build_list (const char *text,
399                          const char *(*mapf)(int), int (*chkf)(int));
400 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
401                      enum cmd_and_opt_values new_cmd );
402
403 static int check_special_filename (const char *fname);
404 static int open_read (const char *filename);
405 static FILE *open_fwrite (const char *filename);
406
407
408 static int
409 our_pk_test_algo (int algo)
410 {
411   return 1;
412 }
413
414 static int
415 our_cipher_test_algo (int algo)
416 {
417   return 1;
418 }
419
420 static int
421 our_md_test_algo (int algo)
422 {
423   return 1;
424 }
425
426 static const char *
427 my_strusage( int level )
428 {
429   static char *digests, *pubkeys, *ciphers;
430   const char *p;
431
432   switch (level)
433     {
434     case 11: p = "gpgsm (GnuPG)";
435       break;
436     case 13: p = VERSION; break;
437     case 17: p = PRINTABLE_OS_NAME; break;
438     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
439       break;
440     case 1:
441     case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
442       break;
443     case 41:
444       p = _("Syntax: gpgsm [options] [files]\n"
445             "sign, check, encrypt or decrypt using the S/MIME protocol\n"
446             "default operation depends on the input data\n");
447       break;
448
449     case 31: p = "\nHome: "; break;
450     case 32: p = opt.homedir; break;
451     case 33: p = _("\nSupported algorithms:\n"); break;
452     case 34:
453       if (!ciphers)
454         ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
455                               our_cipher_test_algo );
456       p = ciphers;
457       break;
458     case 35:
459       if (!pubkeys)
460         pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
461                               our_pk_test_algo );
462       p = pubkeys;
463       break;
464     case 36:
465       if (!digests)
466         digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
467       p = digests;
468       break;
469       
470     default: p = NULL; break;
471     }
472   return p;
473 }
474
475
476 static char *
477 build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
478 {
479   int i;
480   size_t n=strlen(text)+2;
481   char *list, *p;
482   
483   if (maybe_setuid) {
484     gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
485   }
486
487   for (i=1; i < 110; i++ )
488     if (!chkf(i))
489       n += strlen(mapf(i)) + 2;
490   list = xmalloc (21 + n);
491   *list = 0;
492   for (p=NULL, i=1; i < 110; i++)
493     {
494       if (!chkf(i))
495         {
496           if( !p )
497             p = stpcpy (list, text );
498           else
499             p = stpcpy (p, ", ");
500           p = stpcpy (p, mapf(i) );
501         }
502     }
503   if (p)
504     p = stpcpy(p, "\n" );
505   return list;
506 }
507
508
509 static void
510 i18n_init(void)
511 {
512 #ifdef USE_SIMPLE_GETTEXT
513   set_gettext_file (PACKAGE);
514 #else
515 # ifdef ENABLE_NLS
516 #  ifdef HAVE_LC_MESSAGES
517   setlocale (LC_TIME, "");
518   setlocale (LC_MESSAGES, "");
519 #  else
520   setlocale (LC_ALL, "" );
521 #  endif
522   bindtextdomain (PACKAGE, GNUPG_LOCALEDIR);
523   textdomain (PACKAGE);
524 # endif
525 #endif
526 }
527
528
529 static void
530 wrong_args (const char *text)
531 {
532   fputs (_("usage: gpgsm [options] "), stderr);
533   fputs (text, stderr);
534   putc ('\n', stderr);
535   gpgsm_exit (2);
536 }
537
538
539 static void
540 set_debug(void)
541 {
542   if (opt.debug & DBG_MPI_VALUE)
543     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
544   if (opt.debug & DBG_CRYPTO_VALUE )
545     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
546 }
547
548
549 static void
550 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
551 {
552   enum cmd_and_opt_values cmd = *ret_cmd;
553
554   if (!cmd || cmd == new_cmd)
555     cmd = new_cmd;
556   else if ( cmd == aSign && new_cmd == aEncr )
557     cmd = aSignEncr;
558   else if ( cmd == aEncr && new_cmd == aSign )
559     cmd = aSignEncr;
560   else if ( (cmd == aSign && new_cmd == aClearsign)
561             || (cmd == aClearsign && new_cmd == aSign) )
562     cmd = aClearsign;
563   else 
564     {
565       log_error(_("conflicting commands\n"));
566       gpgsm_exit(2);
567     }
568
569   *ret_cmd = cmd;
570 }
571
572
573 int
574 main ( int argc, char **argv)
575 {
576   ARGPARSE_ARGS pargs;
577   int orig_argc;
578   char **orig_argv;
579   const char *fname;
580   /*  char *username;*/
581   int may_coredump;
582   STRLIST sl, remusr= NULL, locusr=NULL;
583   STRLIST nrings=NULL;
584   int detached_sig = 0;
585   FILE *configfp = NULL;
586   char *configname = NULL;
587   unsigned configlineno;
588   int parse_debug = 0;
589   int default_config =1;
590   int default_keyring = 1;
591   char *logfile = NULL;
592   int greeting = 0;
593   int nogreeting = 0;
594   int debug_wait = 0;
595   int use_random_seed = 1;
596   int with_fpr = 0;
597   char *def_digest_string = NULL;
598   enum cmd_and_opt_values cmd = 0;
599   struct server_control_s ctrl;
600   CERTLIST recplist = NULL;
601
602   /* trap_unaligned ();*/
603   set_strusage (my_strusage);
604   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
605   /* Please note that we may running SUID(ROOT), so be very CAREFUL
606      when adding any stuff between here and the call to secmem_init()
607      somewhere after the option parsing */
608   log_set_prefix ("gpgsm", 1);
609   /* check that the libraries are suitable.  Do it here because the
610      option parse may need services of the library */
611   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
612     {
613       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
614                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
615     }
616   if (!ksba_check_version (NEED_LIBKSBA_VERSION) )
617     {
618       log_fatal( _("libksba is too old (need %s, have %s)\n"),
619                  NEED_LIBKSBA_VERSION, ksba_check_version (NULL) );
620     }
621
622   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
623
624   may_coredump = disable_core_dumps ();
625   
626   /* Fixme: init_signals();*/
627   
628   create_dotlock (NULL); /* register locking cleanup */
629   i18n_init();
630
631   opt.def_cipher_algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
632 #ifdef __MINGW32__
633   opt.homedir = read_w32_registry_string ( NULL,
634                                            "Software\\GNU\\GnuPG", "HomeDir" );
635 #else
636   opt.homedir = getenv ("GNUPGHOME");
637 #endif
638   if (!opt.homedir || !*opt.homedir ) 
639     opt.homedir = GNUPG_DEFAULT_HOMEDIR;
640
641   /* first check whether we have a config file on the commandline */
642   orig_argc = argc;
643   orig_argv = argv;
644   pargs.argc = &argc;
645   pargs.argv = &argv;
646   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
647   while (arg_parse( &pargs, opts))
648     {
649       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
650         parse_debug++;
651       else if (pargs.r_opt == oOptions)
652         { /* yes there is one, so we do not try the default one but
653              read the config file when it is encountered at the
654              commandline */
655           default_config = 0;
656         }
657       else if (pargs.r_opt == oNoOptions)
658         default_config = 0; /* --no-options */
659       else if (pargs.r_opt == oHomedir)
660         opt.homedir = pargs.r.ret_str;
661     }
662   
663   
664   /* initialize the secure memory. */
665   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
666   maybe_setuid = 0;
667
668   /* 
669      Now we are now working under our real uid 
670   */
671
672   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
673   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
674   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
675
676   /* Setup a default control structure for command line mode */
677   memset (&ctrl, 0, sizeof ctrl);
678   gpgsm_init_default_ctrl (&ctrl);
679   ctrl.no_server = 1;
680   ctrl.status_fd = -1; /* not status output */
681   ctrl.autodetect_encoding = 1;
682
683   /* set the default option file */
684   if (default_config )
685     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
686   /* cet the default policy file */
687   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
688   
689   argc        = orig_argc;
690   argv        = orig_argv;
691   pargs.argc  = &argc;
692   pargs.argv  = &argv;
693   pargs.flags =  1;  /* do not remove the args */
694
695  next_pass:
696   if (configname) {
697     configlineno = 0;
698     configfp = fopen (configname, "r");
699     if (!configfp)
700       {
701         if (default_config)
702           {
703             if (parse_debug)
704               log_info (_("NOTE: no default option file `%s'\n"), configname);
705           }
706         else 
707           {
708             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
709             gpgsm_exit(2);
710           }
711         xfree(configname);
712         configname = NULL;
713       }
714     if (parse_debug && configname)
715       log_info (_("reading options from `%s'\n"), configname);
716     default_config = 0;
717   }
718
719   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
720     {
721       switch (pargs.r_opt)
722         {
723         case aServer: 
724           opt.batch = 1;
725           set_cmd (&cmd, aServer);
726           break;
727
728         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
729         case aImport: set_cmd (&cmd, aImport); break;
730         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
731         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
732         case aExport: set_cmd (&cmd, aExport); break;
733         case aListKeys: set_cmd (&cmd, aListKeys); break;
734         case aListExternalKeys: set_cmd (&cmd, aListExternalKeys); break;
735         case aListSecretKeys: set_cmd (&cmd, aListSecretKeys); break;
736         case aListSigs: set_cmd (&cmd, aListSigs); break;
737
738         case aLearnCard: set_cmd (&cmd, aLearnCard); break;
739
740         case aDeleteKey:
741           set_cmd (&cmd, aDeleteKey);
742           greeting=1;
743           break;
744
745         case aDetachedSign:
746           detached_sig = 1;
747           set_cmd (&cmd, aSign ); 
748           break;
749           
750         case aSym: set_cmd (&cmd, aSym); break;
751         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
752         case aEncr: set_cmd (&cmd, aEncr); break;
753         case aSign: set_cmd (&cmd, aSign );  break;
754         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
755         case aClearsign: set_cmd (&cmd, aClearsign); break;
756         case aVerify: set_cmd (&cmd, aVerify); break;
757
758
759           /* output encoding selection */
760         case oArmor:
761           ctrl.create_pem = 1;
762           break;
763         case oBase64: 
764           ctrl.create_pem = 0;
765           ctrl.create_base64 = 1;
766           break;
767         case oNoArmor: 
768           ctrl.create_pem = 0;
769           ctrl.create_base64 = 0;
770           break;
771           
772           /* Input encoding selection */
773         case oAssumeArmor:
774           ctrl.autodetect_encoding = 0;
775           ctrl.is_pem = 1;
776           ctrl.is_base64 = 0;
777           break;
778         case oAssumeBase64:
779           ctrl.autodetect_encoding = 0;
780           ctrl.is_pem = 0;
781           ctrl.is_base64 = 1;
782           break;
783         case oAssumeBinary:
784           ctrl.autodetect_encoding = 0;
785           ctrl.is_pem = 0;
786           ctrl.is_base64 = 0;
787           break;
788
789         case oDisableCRLChecks:
790           opt.no_crl_check = 1;
791           break;
792         case oEnableCRLChecks:
793           opt.no_crl_check = 0;
794           break;
795
796         case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
797
798         case oPolicyFile:
799           xfree (opt.policy_file);
800           if (*pargs.r.ret_str)
801             opt.policy_file = xstrdup (pargs.r.ret_str);
802           else
803             opt.policy_file = NULL;
804           break;
805
806         case oDisablePolicyChecks:
807           opt.no_policy_check = 1;
808           break;
809         case oEnablePolicyChecks:
810           opt.no_policy_check = 0;
811           break;
812
813
814         case oOutput: opt.outfile = pargs.r.ret_str; break;
815
816         
817         case oQuiet: opt.quiet = 1; break;
818         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
819         case oDryRun: opt.dry_run = 1; break;
820
821         case oVerbose:
822           opt.verbose++;
823           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
824           break;
825         case oNoVerbose:
826           opt.verbose = 0;
827           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
828           break;
829
830         case oLogFile: logfile = pargs.r.ret_str; break;
831           
832         case oBatch: 
833           opt.batch = 1;
834           greeting = 0;
835           break;
836         case oNoBatch: opt.batch = 0; break;
837           
838         case oAnswerYes: opt.answer_yes = 1; break;
839         case oAnswerNo: opt.answer_no = 1; break;
840
841         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
842
843         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
844         case oDebugAll: opt.debug = ~0; break;
845         case oDebugWait: debug_wait = pargs.r.ret_int; break;
846         case oDebugNoPathValidation: opt.no_path_validation = 1; break;
847
848
849         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
850         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
851         case oWithFingerprint:
852           with_fpr=1; /*fall thru*/
853         case oFingerprint:
854           opt.fingerprint++;
855           break;
856
857         case oOptions:
858           /* config files may not be nested (silently ignore them) */
859           if (!configfp)
860             {
861               xfree(configname);
862               configname = xstrdup (pargs.r.ret_str);
863               goto next_pass;
864             }
865           break;
866         case oNoOptions: break; /* no-options */
867         case oHomedir: opt.homedir = pargs.r.ret_str; break;
868         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
869         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
870         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
871         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
872         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
873         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
874         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
875           
876         case oFakedSystemTime:
877           gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
878           break;
879
880         case oNoDefKeyring: default_keyring = 0; break;
881         case oNoGreeting: nogreeting = 1; break;
882
883         case oDefaultKey:
884           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
885           break;
886         case oDefRecipient:
887           if (*pargs.r.ret_str)
888             opt.def_recipient = xstrdup (pargs.r.ret_str);
889           break;
890         case oDefRecipientSelf:
891           xfree (opt.def_recipient);
892           opt.def_recipient = NULL;
893           opt.def_recipient_self = 1;
894           break;
895         case oNoDefRecipient:
896           xfree (opt.def_recipient);
897           opt.def_recipient = NULL;
898           opt.def_recipient_self = 0;
899           break;
900
901         case oWithKeyData: opt.with_key_data=1; /* fall thru */
902         case oWithColons: ctrl.with_colons = 1; break;
903
904         case oSkipVerify: opt.skip_verify=1; break;
905
906         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
907         case oEncryptTo: /* store the recipient in the second list */
908           sl = add_to_strlist (&remusr, pargs.r.ret_str);
909           sl->flags = 1;
910           break;
911
912         case oRecipient: /* store the recipient */
913           add_to_strlist ( &remusr, pargs.r.ret_str);
914           break;
915
916         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
917         case oTextmode: /*fixme:opt.textmode=1;*/  break;
918
919         case oUser: /* store the local users */
920           opt.local_user = pargs.r.ret_str;
921           add_to_strlist ( &locusr, pargs.r.ret_str);
922           break;
923
924         case oNoSecmemWarn:
925           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
926           break;
927
928         case oCipherAlgo:
929           opt.def_cipher_algoid = pargs.r.ret_str;
930           break;
931
932         case oDisableCipherAlgo: 
933           {
934             int algo = gcry_cipher_map_name (pargs.r.ret_str);
935             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
936           }
937           break;
938         case oDisablePubkeyAlgo: 
939           {
940             int algo = gcry_pk_map_name (pargs.r.ret_str);
941             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
942           }
943           break;
944
945         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
946         case oNoRandomSeedFile: use_random_seed = 0; break;
947
948         case oEnableSpecialFilenames: allow_special_filenames =1; break;
949           
950
951         case aDummy:
952           break;
953         default: 
954           pargs.err = configfp? 1:2; 
955           break;
956         }
957     }
958
959   if (configfp)
960     {
961       fclose (configfp);
962       configfp = NULL;
963       xfree (configname);
964       configname = NULL;
965       goto next_pass;
966     }
967   
968   xfree (configname);
969   configname = NULL;
970
971   if (log_get_errorcount(0))
972     gpgsm_exit(2);
973   
974   if (nogreeting)
975     greeting = 0;
976   
977   if (greeting)
978     {
979       fprintf(stderr, "%s %s; %s\n",
980               strusage(11), strusage(13), strusage(14) );
981       fprintf(stderr, "%s\n", strusage(15) );
982     }
983 #  ifdef IS_DEVELOPMENT_VERSION
984   if (!opt.batch)
985     {
986       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
987       log_info ("It is only intended for test purposes and should NOT be\n");
988       log_info ("used in a production environment or with production keys!\n");
989     }
990 #  endif
991
992   if (may_coredump && !opt.quiet)
993     log_info (_("WARNING: program may create a core file!\n"));
994
995   if (logfile)
996     {
997       log_set_file (logfile);
998       log_set_prefix (NULL, 1|2|4);
999     }
1000
1001   if (gnupg_faked_time_p ())
1002     {
1003       log_info (_("WARNING: running with faked system time: "));
1004       gpgsm_dump_time (gnupg_get_time ());
1005       log_printf ("\n");
1006     }
1007   
1008 /*FIXME    if (opt.batch) */
1009 /*      tty_batchmode (1); */
1010
1011   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
1012
1013   set_debug ();
1014
1015   /* FIXME: should set filenames of libgcrypt explicitly
1016    * gpg_opt_homedir = opt.homedir; */
1017
1018   /* must do this after dropping setuid, because the mapping functions
1019      may try to load an module and we may have disabled an algorithm */
1020   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
1021        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
1022     log_error (_("selected cipher algorithm is invalid\n"));
1023
1024   if (def_digest_string)
1025     {
1026       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
1027       xfree (def_digest_string);
1028       def_digest_string = NULL;
1029       if (our_md_test_algo(opt.def_digest_algo) )
1030         log_error (_("selected digest algorithm is invalid\n"));
1031     }
1032
1033   if (log_get_errorcount(0))
1034     gpgsm_exit(2);
1035   
1036   /* set the random seed file */
1037   if (use_random_seed) {
1038     char *p = make_filename (opt.homedir, "random_seed", NULL);
1039 #if 0
1040 #warning set_random_seed_file not yet available in Libgcrypt
1041     set_random_seed_file(p);
1042 #endif
1043     xfree(p);
1044   }
1045
1046
1047   if (!cmd && opt.fingerprint && !with_fpr)
1048     set_cmd (&cmd, aListKeys);
1049   
1050   if (!nrings && default_keyring)  /* add default keybox */
1051     keydb_add_resource ("pubring.kbx", 0, 0);
1052   for (sl = nrings; sl; sl = sl->next)
1053     keydb_add_resource (sl->d, 0, 0);
1054   FREE_STRLIST(nrings);
1055
1056   for (sl = remusr; sl; sl = sl->next)
1057     {
1058       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, &recplist);
1059       if (rc)
1060         {
1061           log_error (_("can't encrypt to `%s': %s\n"),
1062                      sl->d, gnupg_strerror (rc));
1063           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1064                          rc == -1? "1":
1065                          rc == GNUPG_Ambiguous_Name? "2 ": "0 ",
1066                          sl->d, NULL);
1067         }
1068   }
1069   if (log_get_errorcount(0))
1070     gpgsm_exit(1); /* must stop for invalid recipients */
1071   
1072
1073   
1074   fname = argc? *argv : NULL;
1075   
1076   switch (cmd)
1077     {
1078     case aServer:
1079       if (debug_wait)
1080         {
1081           log_debug ("waiting for debugger - my pid is %u .....\n",
1082                      (unsigned int)getpid());
1083           sleep (debug_wait);
1084           log_debug ("... okay\n");
1085          }
1086       gpgsm_server ();
1087       break;
1088
1089     case aEncr: /* encrypt the given file */
1090       if (!argc)
1091         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1092       else if (argc == 1)
1093         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1094       else
1095         wrong_args (_("--encrypt [datafile]"));
1096       break;
1097
1098     case aSign: /* sign the given file */
1099       /* FIXME: W we don't handle --output yet. We should also allow
1100          to concatenate multiple files for signing because that is
1101          what gpg does.*/
1102       if (!argc)
1103         gpgsm_sign (&ctrl, 0, detached_sig, stdout); /* create from stdin */
1104       else if (argc == 1)
1105         gpgsm_sign (&ctrl, open_read (*argv),
1106                     detached_sig, stdout); /* from file */
1107       else
1108         wrong_args (_("--sign [datafile]"));
1109       break;
1110 #if 0
1111       sl = NULL;
1112       if (detached_sig)
1113         { /* sign all files */
1114           for (; argc; argc--, argv++ )
1115             add_to_strlist ( &sl, *argv );
1116         }
1117       else
1118         {
1119           if (argc > 1 )
1120             wrong_args (_("--sign [filename]"));
1121           if (argc)
1122             {
1123               sl = xcalloc (1, sizeof *sl + strlen(fname));
1124               strcpy(sl->d, fname);
1125             }
1126         }
1127       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
1128         log_error ("signing failed: %s\n", gpg_errstr(rc) );
1129       free_strlist(sl);
1130 #endif
1131       break;
1132         
1133     case aSignEncr: /* sign and encrypt the given file */
1134       log_error ("this command has not yet been implemented\n");
1135 #if 0
1136       if (argc > 1)
1137         wrong_args(_("--sign --encrypt [filename]"));
1138       if (argc)
1139         {
1140           sl = xcalloc( 1, sizeof *sl + strlen(fname));
1141           strcpy(sl->d, fname);
1142         }
1143       else
1144         sl = NULL;
1145
1146       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1147         log_error ("%s: sign+encrypt failed: %s\n",
1148                    print_fname_stdin(fname), gpg_errstr(rc) );
1149       free_strlist(sl);
1150 #endif
1151       break;
1152
1153     case aClearsign: /* make a clearsig */
1154       log_error ("this command has not yet been implemented\n");
1155 #if 0
1156       if (argc > 1)
1157         wrong_args (_("--clearsign [filename]"));
1158       if ( (rc = clearsign_file(fname, locusr, NULL)) )
1159         log_error ("%s: clearsign failed: %s\n",
1160                    print_fname_stdin(fname), gpg_errstr(rc) );
1161 #endif
1162       break;
1163
1164     case aVerify:
1165       {
1166         FILE *fp = NULL;
1167
1168         if (argc == 2 && opt.outfile)
1169           log_info ("option --output ignored for a detached signature\n");
1170         else if (opt.outfile)
1171           fp = open_fwrite (opt.outfile);
1172
1173         if (!argc)
1174           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1175         else if (argc == 1)
1176           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1177         else if (argc == 2) /* detached signature (sig, detached) */
1178           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1179         else
1180           wrong_args (_("--verify [signature [detached_data]]"));
1181
1182         if (fp && fp != stdout)
1183           fclose (fp);
1184       }
1185       break;
1186
1187     case aVerifyFiles:
1188       log_error ("this command has not yet been implemented\n");
1189 /*        if ((rc = verify_files( argc, argv ))) */
1190 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
1191       break;
1192
1193     case aDecrypt:
1194       if (!argc)
1195         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1196       else if (argc == 1)
1197         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1198       else
1199         wrong_args (_("--decrypt [filename]"));
1200       break;
1201
1202     case aDeleteKey:
1203       if (argc != 1)
1204         wrong_args(_("--delete-key user-id"));
1205       log_error ("this command has not yet been implemented\n");
1206 /*        username = make_username (fname); */
1207 /*        if( (rc = delete_key(username)) ) */
1208 /*          log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */
1209 /*        xfree(username); */
1210       break;
1211
1212     case aListSigs:
1213       ctrl.with_chain = 1;
1214     case aListKeys:
1215       for (sl=NULL; argc; argc--, argv++)
1216         add_to_strlist (&sl, *argv);
1217       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1218       free_strlist(sl);
1219       break;
1220
1221     case aListExternalKeys:
1222       for (sl=NULL; argc; argc--, argv++)
1223         add_to_strlist (&sl, *argv);
1224       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
1225       free_strlist(sl);
1226       break;
1227
1228     case aListSecretKeys:
1229       for (sl=NULL; argc; argc--, argv++)
1230         add_to_strlist (&sl, *argv);
1231       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1232       free_strlist(sl);
1233       break;
1234
1235     case aKeygen: /* generate a key */
1236       log_error ("this function is not yet available from the commandline\n");
1237 /*        if (opt.batch) */
1238 /*          { */
1239 /*            if (argc > 1) */
1240 /*              wrong_args("--gen-key [parameterfile]"); */
1241 /*            generate_keypair (argc? *argv : NULL); */
1242 /*      } */
1243 /*        else */
1244 /*          { */
1245 /*            if (argc) */
1246 /*              wrong_args ("--gen-key"); */
1247 /*            generate_keypair(NULL); */
1248 /*      } */
1249       break;
1250
1251     case aImport:
1252       if (!argc)
1253         gpgsm_import (&ctrl, 0);
1254       else
1255         {
1256           for (; argc; argc--, argv++)
1257             gpgsm_import (&ctrl, open_read (*argv));
1258         }
1259       break;
1260
1261     case aExport:
1262       for (sl=NULL; argc; argc--, argv++)
1263         add_to_strlist (&sl, *argv);
1264       gpgsm_export (&ctrl, sl, stdout);
1265       free_strlist(sl);
1266       break;
1267
1268       
1269     case aSendKeys:
1270     case aRecvKeys:
1271       log_error ("this command has not yet been implemented\n");
1272 /*        sl = NULL; */
1273 /*        for ( ; argc; argc--, argv++ ) */
1274 /*          add_to_strlist (&sl, *argv); */
1275 /*        if ( cmd == aSendKeys ) */
1276 /*          ldap_export (sl); */
1277 /*        else if (cmd == aRecvKeys ) */
1278 /*          ldap_import (sl); */
1279 /*        else */
1280 /*          export_pubkeys (sl, (cmd == aExport)); */
1281 /*        free_strlist (sl); */
1282       break;
1283
1284
1285     case aLearnCard:
1286       if (argc)
1287         wrong_args ("--learn-card");
1288       else
1289         {
1290           int rc = gpgsm_agent_learn ();
1291           if (rc)
1292             log_error ("error learning card: %s\n", gnupg_strerror (rc));
1293         }
1294       break;
1295
1296
1297     default:
1298         log_error ("invalid command\n");
1299 #if 0
1300         if (argc > 1)
1301           wrong_args(_("[filename]"));
1302         /* Issue some output for the unix newbie */
1303         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1304             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1305           log_info (_("Go ahead and type your message ...\n"));
1306         
1307         if ( !(a = iobuf_open(fname)) )
1308           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1309         else
1310           {
1311             if (!opt.no_armor) 
1312               iobuf_close(a);
1313         }
1314 #endif
1315         break;
1316     }
1317   
1318   /* cleanup */
1319   gpgsm_release_certlist (recplist);
1320   FREE_STRLIST(remusr);
1321   FREE_STRLIST(locusr);
1322   gpgsm_exit(0);
1323   return 8; /*NEVER REACHED*/
1324 }
1325
1326
1327 void
1328 gpgsm_exit (int rc)
1329 {
1330   #if 0
1331 #warning no update_random_seed_file
1332   update_random_seed_file();
1333   #endif
1334 #if 0
1335   /* at this time a bit annoying */
1336   if (opt.debug & DBG_MEMSTAT_VALUE)
1337     {
1338       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1339       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1340     }
1341   if (opt.debug)
1342     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1343 #endif
1344   gcry_control (GCRYCTL_TERM_SECMEM );
1345   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1346   exit (rc);
1347 }
1348
1349
1350 void
1351 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1352 {
1353   ctrl->include_certs = 1;  /* only include the signer's cert */
1354 }
1355
1356
1357
1358 /* Check whether the filename has the form "-&nnnn", where n is a
1359    non-zero number.  Returns this number or -1 if it is not the case.  */
1360 static int
1361 check_special_filename (const char *fname)
1362 {
1363   if (allow_special_filenames
1364       && fname && *fname == '-' && fname[1] == '&' ) {
1365     int i;
1366     
1367     fname += 2;
1368     for (i=0; isdigit (fname[i]); i++ )
1369       ;
1370     if ( !fname[i] ) 
1371       return atoi (fname);
1372   }
1373   return -1;
1374 }
1375
1376
1377
1378 /* Open the FILENAME for read and return the filedescriptor.  Stop
1379    with an error message in case of problems.  "-" denotes stdin and
1380    if special filenames are allowed the given fd is opened instead. */
1381 static int 
1382 open_read (const char *filename)
1383 {
1384   int fd;
1385
1386   if (filename[0] == '-' && !filename[1])
1387     return 0; /* stdin */
1388   fd = check_special_filename (filename);
1389   if (fd != -1)
1390     return fd;
1391   fd = open (filename, O_RDONLY);
1392   if (fd == -1)
1393     {
1394       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1395       gpgsm_exit (2);
1396     }
1397   return fd;
1398 }
1399
1400 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1401    message in case of problems.  "-" denotes stdout and if special
1402    filenames are allowed the given fd is opened instead. Caller must
1403    close the returned stream unless it is stdout. */
1404 static FILE *
1405 open_fwrite (const char *filename)
1406 {
1407   int fd;
1408   FILE *fp;
1409
1410   if (filename[0] == '-' && !filename[1])
1411     return stdout;
1412
1413   fd = check_special_filename (filename);
1414   if (fd != -1)
1415     {
1416       fp = fdopen (dup (fd), "wb");
1417       if (!fp)
1418         {
1419           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1420           gpgsm_exit (2);
1421         }
1422       return fp;
1423     }
1424   fp = fopen (filename, "wb");
1425   if (!fp)
1426     {
1427       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1428       gpgsm_exit (2);
1429     }
1430   return fp;
1431 }