0754d3a57e4a0c06ad3049496048ba9f2005879e
[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" ,1, "@"},
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     {
640       opt.homedir = "~/.gnupg-test" /*fixme: GNUPG_HOMEDIR*/;
641     }
642
643   /* first check whether we have a config file on the commandline */
644   orig_argc = argc;
645   orig_argv = argv;
646   pargs.argc = &argc;
647   pargs.argv = &argv;
648   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
649   while (arg_parse( &pargs, opts))
650     {
651       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
652         parse_debug++;
653       else if (pargs.r_opt == oOptions)
654         { /* yes there is one, so we do not try the default one but
655              read the config file when it is encountered at the
656              commandline */
657           default_config = 0;
658         }
659       else if (pargs.r_opt == oNoOptions)
660         default_config = 0; /* --no-options */
661       else if (pargs.r_opt == oHomedir)
662         opt.homedir = pargs.r.ret_str;
663     }
664   
665   
666   /* initialize the secure memory. */
667   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
668   maybe_setuid = 0;
669
670   /* 
671      Now we are now working under our real uid 
672   */
673
674   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
675   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
676   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
677
678   /* Setup a default control structure for command line mode */
679   memset (&ctrl, 0, sizeof ctrl);
680   gpgsm_init_default_ctrl (&ctrl);
681   ctrl.no_server = 1;
682   ctrl.status_fd = -1; /* not status output */
683   ctrl.autodetect_encoding = 1;
684
685   /* set the default option file */
686   if (default_config )
687     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
688   /* cet the default policy file */
689   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
690   
691   argc        = orig_argc;
692   argv        = orig_argv;
693   pargs.argc  = &argc;
694   pargs.argv  = &argv;
695   pargs.flags =  1;  /* do not remove the args */
696
697  next_pass:
698   if (configname) {
699     configlineno = 0;
700     configfp = fopen (configname, "r");
701     if (!configfp)
702       {
703         if (default_config)
704           {
705             if (parse_debug)
706               log_info (_("NOTE: no default option file `%s'\n"), configname);
707           }
708         else 
709           {
710             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
711             gpgsm_exit(2);
712           }
713         xfree(configname);
714         configname = NULL;
715       }
716     if (parse_debug && configname)
717       log_info (_("reading options from `%s'\n"), configname);
718     default_config = 0;
719   }
720
721   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
722     {
723       switch (pargs.r_opt)
724         {
725         case aServer: 
726           opt.batch = 1;
727           set_cmd (&cmd, aServer);
728           break;
729
730         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
731         case aImport: set_cmd (&cmd, aImport); break;
732         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
733         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
734         case aExport: set_cmd (&cmd, aExport); break;
735         case aListKeys: set_cmd (&cmd, aListKeys); break;
736         case aListExternalKeys: set_cmd (&cmd, aListExternalKeys); break;
737         case aListSecretKeys: set_cmd (&cmd, aListSecretKeys); break;
738         case aListSigs: set_cmd (&cmd, aListSigs); break;
739
740         case aLearnCard: set_cmd (&cmd, aLearnCard); break;
741
742         case aDeleteKey:
743           set_cmd (&cmd, aDeleteKey);
744           greeting=1;
745           break;
746
747         case aDetachedSign:
748           detached_sig = 1;
749           set_cmd (&cmd, aSign ); 
750           break;
751           
752         case aSym: set_cmd (&cmd, aSym); break;
753         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
754         case aEncr: set_cmd (&cmd, aEncr); break;
755         case aSign: set_cmd (&cmd, aSign );  break;
756         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
757         case aClearsign: set_cmd (&cmd, aClearsign); break;
758         case aVerify: set_cmd (&cmd, aVerify); break;
759
760
761           /* output encoding selection */
762         case oArmor:
763           ctrl.create_pem = 1;
764           break;
765         case oBase64: 
766           ctrl.create_pem = 0;
767           ctrl.create_base64 = 1;
768           break;
769         case oNoArmor: 
770           ctrl.create_pem = 0;
771           ctrl.create_base64 = 0;
772           break;
773           
774           /* Input encoding selection */
775         case oAssumeArmor:
776           ctrl.autodetect_encoding = 0;
777           ctrl.is_pem = 1;
778           ctrl.is_base64 = 0;
779           break;
780         case oAssumeBase64:
781           ctrl.autodetect_encoding = 0;
782           ctrl.is_pem = 0;
783           ctrl.is_base64 = 1;
784           break;
785         case oAssumeBinary:
786           ctrl.autodetect_encoding = 0;
787           ctrl.is_pem = 0;
788           ctrl.is_base64 = 0;
789           break;
790
791         case oDisableCRLChecks:
792           opt.no_crl_check = 1;
793           break;
794         case oEnableCRLChecks:
795           opt.no_crl_check = 0;
796           break;
797
798         case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
799
800         case oPolicyFile:
801           xfree (opt.policy_file);
802           if (*pargs.r.ret_str)
803             opt.policy_file = xstrdup (pargs.r.ret_str);
804           else
805             opt.policy_file = NULL;
806           break;
807
808         case oDisablePolicyChecks:
809           opt.no_policy_check = 1;
810           break;
811         case oEnablePolicyChecks:
812           opt.no_policy_check = 0;
813           break;
814
815
816         case oOutput: opt.outfile = pargs.r.ret_str; break;
817
818         
819         case oQuiet: opt.quiet = 1; break;
820         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
821         case oDryRun: opt.dry_run = 1; break;
822
823         case oVerbose:
824           opt.verbose++;
825           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
826           break;
827         case oNoVerbose:
828           opt.verbose = 0;
829           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
830           break;
831
832         case oLogFile: logfile = pargs.r.ret_str; break;
833           
834         case oBatch: 
835           opt.batch = 1;
836           greeting = 0;
837           break;
838         case oNoBatch: opt.batch = 0; break;
839           
840         case oAnswerYes: opt.answer_yes = 1; break;
841         case oAnswerNo: opt.answer_no = 1; break;
842
843         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
844
845         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
846         case oDebugAll: opt.debug = ~0; break;
847         case oDebugWait: debug_wait = pargs.r.ret_int; break;
848         case oDebugNoPathValidation: opt.no_path_validation = 1; break;
849
850
851         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
852         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
853         case oWithFingerprint:
854           with_fpr=1; /*fall thru*/
855         case oFingerprint:
856           opt.fingerprint++;
857           break;
858
859         case oOptions:
860           /* config files may not be nested (silently ignore them) */
861           if (!configfp)
862             {
863               xfree(configname);
864               configname = xstrdup (pargs.r.ret_str);
865               goto next_pass;
866             }
867           break;
868         case oNoOptions: break; /* no-options */
869         case oHomedir: opt.homedir = pargs.r.ret_str; break;
870         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
871         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
872         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
873         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
874         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
875         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
876         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
877           
878         case oFakedSystemTime:
879           gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
880           break;
881
882         case oNoDefKeyring: default_keyring = 0; break;
883         case oNoGreeting: nogreeting = 1; break;
884
885         case oDefaultKey:
886           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
887           break;
888         case oDefRecipient:
889           if (*pargs.r.ret_str)
890             opt.def_recipient = xstrdup (pargs.r.ret_str);
891           break;
892         case oDefRecipientSelf:
893           xfree (opt.def_recipient);
894           opt.def_recipient = NULL;
895           opt.def_recipient_self = 1;
896           break;
897         case oNoDefRecipient:
898           xfree (opt.def_recipient);
899           opt.def_recipient = NULL;
900           opt.def_recipient_self = 0;
901           break;
902
903         case oWithKeyData: opt.with_key_data=1; /* fall thru */
904         case oWithColons: ctrl.with_colons = 1; break;
905
906         case oSkipVerify: opt.skip_verify=1; break;
907
908         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
909         case oEncryptTo: /* store the recipient in the second list */
910           sl = add_to_strlist (&remusr, pargs.r.ret_str);
911           sl->flags = 1;
912           break;
913
914         case oRecipient: /* store the recipient */
915           add_to_strlist ( &remusr, pargs.r.ret_str);
916           break;
917
918         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
919         case oTextmode: /*fixme:opt.textmode=1;*/  break;
920
921         case oUser: /* store the local users */
922           opt.local_user = pargs.r.ret_str;
923           add_to_strlist ( &locusr, pargs.r.ret_str);
924           break;
925
926         case oNoSecmemWarn:
927           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
928           break;
929
930         case oCipherAlgo:
931           opt.def_cipher_algoid = pargs.r.ret_str;
932           break;
933
934         case oDisableCipherAlgo: 
935           {
936             int algo = gcry_cipher_map_name (pargs.r.ret_str);
937             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
938           }
939           break;
940         case oDisablePubkeyAlgo: 
941           {
942             int algo = gcry_pk_map_name (pargs.r.ret_str);
943             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
944           }
945           break;
946
947         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
948         case oNoRandomSeedFile: use_random_seed = 0; break;
949
950         case oEnableSpecialFilenames: allow_special_filenames =1; break;
951           
952
953         case aDummy:
954           break;
955         default: 
956           pargs.err = configfp? 1:2; 
957           break;
958         }
959     }
960
961   if (configfp)
962     {
963       fclose (configfp);
964       configfp = NULL;
965       xfree (configname);
966       configname = NULL;
967       goto next_pass;
968     }
969   
970   xfree (configname);
971   configname = NULL;
972
973   if (log_get_errorcount(0))
974     gpgsm_exit(2);
975   
976   if (nogreeting)
977     greeting = 0;
978   
979   if (greeting)
980     {
981       fprintf(stderr, "%s %s; %s\n",
982               strusage(11), strusage(13), strusage(14) );
983       fprintf(stderr, "%s\n", strusage(15) );
984     }
985 #  ifdef IS_DEVELOPMENT_VERSION
986   if (!opt.batch)
987     {
988       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
989       log_info ("It is only intended for test purposes and should NOT be\n");
990       log_info ("used in a production environment or with production keys!\n");
991     }
992 #  endif
993
994   if (may_coredump && !opt.quiet)
995     log_info (_("WARNING: program may create a core file!\n"));
996
997   if (logfile)
998     {
999       log_set_file (logfile);
1000       log_set_prefix (NULL, 1|2|4);
1001     }
1002
1003   if (gnupg_faked_time_p ())
1004     {
1005       log_info (_("WARNING: running with faked system time: "));
1006       gpgsm_dump_time (gnupg_get_time ());
1007       log_printf ("\n");
1008     }
1009   
1010 /*FIXME    if (opt.batch) */
1011 /*      tty_batchmode (1); */
1012
1013   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
1014
1015   set_debug ();
1016
1017   /* FIXME: should set filenames of libgcrypt explicitly
1018    * gpg_opt_homedir = opt.homedir; */
1019
1020   /* must do this after dropping setuid, because the mapping functions
1021      may try to load an module and we may have disabled an algorithm */
1022   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
1023        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
1024     log_error (_("selected cipher algorithm is invalid\n"));
1025
1026   if (def_digest_string)
1027     {
1028       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
1029       xfree (def_digest_string);
1030       def_digest_string = NULL;
1031       if (our_md_test_algo(opt.def_digest_algo) )
1032         log_error (_("selected digest algorithm is invalid\n"));
1033     }
1034
1035   if (log_get_errorcount(0))
1036     gpgsm_exit(2);
1037   
1038   /* set the random seed file */
1039   if (use_random_seed) {
1040     char *p = make_filename (opt.homedir, "random_seed", NULL);
1041 #if 0
1042 #warning set_random_seed_file not yet available in Libgcrypt
1043     set_random_seed_file(p);
1044 #endif
1045     xfree(p);
1046   }
1047
1048
1049   if (!cmd && opt.fingerprint && !with_fpr)
1050     set_cmd (&cmd, aListKeys);
1051   
1052   if (!nrings && default_keyring)  /* add default keybox */
1053     keydb_add_resource ("pubring.kbx", 0, 0);
1054   for (sl = nrings; sl; sl = sl->next)
1055     keydb_add_resource (sl->d, 0, 0);
1056   FREE_STRLIST(nrings);
1057
1058   for (sl = remusr; sl; sl = sl->next)
1059     {
1060       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, &recplist);
1061       if (rc)
1062         {
1063           log_error (_("can't encrypt to `%s': %s\n"),
1064                      sl->d, gnupg_strerror (rc));
1065           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1066                          rc == -1? "1":
1067                          rc == GNUPG_Ambiguous_Name? "2 ": "0 ",
1068                          sl->d, NULL);
1069         }
1070   }
1071   if (log_get_errorcount(0))
1072     gpgsm_exit(1); /* must stop for invalid recipients */
1073   
1074
1075   
1076   fname = argc? *argv : NULL;
1077   
1078   switch (cmd)
1079     {
1080     case aServer:
1081       if (debug_wait)
1082         {
1083           log_debug ("waiting for debugger - my pid is %u .....\n",
1084                      (unsigned int)getpid());
1085           sleep (debug_wait);
1086           log_debug ("... okay\n");
1087          }
1088       gpgsm_server ();
1089       break;
1090
1091     case aEncr: /* encrypt the given file */
1092       if (!argc)
1093         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1094       else if (argc == 1)
1095         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1096       else
1097         wrong_args (_("--encrypt [datafile]"));
1098       break;
1099
1100     case aSign: /* sign the given file */
1101       /* FIXME: W we don't handle --output yet. We should also allow
1102          to concatenate multiple files for signing because that is
1103          what gpg does.*/
1104       if (!argc)
1105         gpgsm_sign (&ctrl, 0, detached_sig, stdout); /* create from stdin */
1106       else if (argc == 1)
1107         gpgsm_sign (&ctrl, open_read (*argv),
1108                     detached_sig, stdout); /* from file */
1109       else
1110         wrong_args (_("--sign [datafile]"));
1111       break;
1112 #if 0
1113       sl = NULL;
1114       if (detached_sig)
1115         { /* sign all files */
1116           for (; argc; argc--, argv++ )
1117             add_to_strlist ( &sl, *argv );
1118         }
1119       else
1120         {
1121           if (argc > 1 )
1122             wrong_args (_("--sign [filename]"));
1123           if (argc)
1124             {
1125               sl = xcalloc (1, sizeof *sl + strlen(fname));
1126               strcpy(sl->d, fname);
1127             }
1128         }
1129       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
1130         log_error ("signing failed: %s\n", gpg_errstr(rc) );
1131       free_strlist(sl);
1132 #endif
1133       break;
1134         
1135     case aSignEncr: /* sign and encrypt the given file */
1136       log_error ("this command has not yet been implemented\n");
1137 #if 0
1138       if (argc > 1)
1139         wrong_args(_("--sign --encrypt [filename]"));
1140       if (argc)
1141         {
1142           sl = xcalloc( 1, sizeof *sl + strlen(fname));
1143           strcpy(sl->d, fname);
1144         }
1145       else
1146         sl = NULL;
1147
1148       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1149         log_error ("%s: sign+encrypt failed: %s\n",
1150                    print_fname_stdin(fname), gpg_errstr(rc) );
1151       free_strlist(sl);
1152 #endif
1153       break;
1154
1155     case aClearsign: /* make a clearsig */
1156       log_error ("this command has not yet been implemented\n");
1157 #if 0
1158       if (argc > 1)
1159         wrong_args (_("--clearsign [filename]"));
1160       if ( (rc = clearsign_file(fname, locusr, NULL)) )
1161         log_error ("%s: clearsign failed: %s\n",
1162                    print_fname_stdin(fname), gpg_errstr(rc) );
1163 #endif
1164       break;
1165
1166     case aVerify:
1167       {
1168         FILE *fp = NULL;
1169
1170         if (argc == 2 && opt.outfile)
1171           log_info ("option --output ignored for a detached signature\n");
1172         else if (opt.outfile)
1173           fp = open_fwrite (opt.outfile);
1174
1175         if (!argc)
1176           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1177         else if (argc == 1)
1178           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1179         else if (argc == 2) /* detached signature (sig, detached) */
1180           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1181         else
1182           wrong_args (_("--verify [signature [detached_data]]"));
1183
1184         if (fp && fp != stdout)
1185           fclose (fp);
1186       }
1187       break;
1188
1189     case aVerifyFiles:
1190       log_error ("this command has not yet been implemented\n");
1191 /*        if ((rc = verify_files( argc, argv ))) */
1192 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
1193       break;
1194
1195     case aDecrypt:
1196       if (!argc)
1197         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1198       else if (argc == 1)
1199         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1200       else
1201         wrong_args (_("--decrypt [filename]"));
1202       break;
1203
1204     case aDeleteKey:
1205       if (argc != 1)
1206         wrong_args(_("--delete-key user-id"));
1207       log_error ("this command has not yet been implemented\n");
1208 /*        username = make_username (fname); */
1209 /*        if( (rc = delete_key(username)) ) */
1210 /*          log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */
1211 /*        xfree(username); */
1212       break;
1213
1214     case aListSigs:
1215       ctrl.with_chain = 1;
1216     case aListKeys:
1217       for (sl=NULL; argc; argc--, argv++)
1218         add_to_strlist (&sl, *argv);
1219       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1220       free_strlist(sl);
1221       break;
1222
1223     case aListExternalKeys:
1224       for (sl=NULL; argc; argc--, argv++)
1225         add_to_strlist (&sl, *argv);
1226       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
1227       free_strlist(sl);
1228       break;
1229
1230     case aListSecretKeys:
1231       for (sl=NULL; argc; argc--, argv++)
1232         add_to_strlist (&sl, *argv);
1233       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1234       free_strlist(sl);
1235       break;
1236
1237     case aKeygen: /* generate a key */
1238       log_error ("this function is not yet available from the commandline\n");
1239 /*        if (opt.batch) */
1240 /*          { */
1241 /*            if (argc > 1) */
1242 /*              wrong_args("--gen-key [parameterfile]"); */
1243 /*            generate_keypair (argc? *argv : NULL); */
1244 /*      } */
1245 /*        else */
1246 /*          { */
1247 /*            if (argc) */
1248 /*              wrong_args ("--gen-key"); */
1249 /*            generate_keypair(NULL); */
1250 /*      } */
1251       break;
1252
1253     case aImport:
1254       if (!argc)
1255         gpgsm_import (&ctrl, 0);
1256       else
1257         {
1258           for (; argc; argc--, argv++)
1259             gpgsm_import (&ctrl, open_read (*argv));
1260         }
1261       break;
1262
1263     case aExport:
1264       for (sl=NULL; argc; argc--, argv++)
1265         add_to_strlist (&sl, *argv);
1266       gpgsm_export (&ctrl, sl, stdout);
1267       free_strlist(sl);
1268       break;
1269
1270       
1271     case aSendKeys:
1272     case aRecvKeys:
1273       log_error ("this command has not yet been implemented\n");
1274 /*        sl = NULL; */
1275 /*        for ( ; argc; argc--, argv++ ) */
1276 /*          add_to_strlist (&sl, *argv); */
1277 /*        if ( cmd == aSendKeys ) */
1278 /*          ldap_export (sl); */
1279 /*        else if (cmd == aRecvKeys ) */
1280 /*          ldap_import (sl); */
1281 /*        else */
1282 /*          export_pubkeys (sl, (cmd == aExport)); */
1283 /*        free_strlist (sl); */
1284       break;
1285
1286
1287     case aLearnCard:
1288       if (argc)
1289         wrong_args ("--learn-card");
1290       else
1291         {
1292           int rc = gpgsm_agent_learn ();
1293           if (rc)
1294             log_error ("error learning card: %s\n", gnupg_strerror (rc));
1295         }
1296       break;
1297
1298
1299     default:
1300         log_error ("invalid command\n");
1301 #if 0
1302         if (argc > 1)
1303           wrong_args(_("[filename]"));
1304         /* Issue some output for the unix newbie */
1305         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1306             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1307           log_info (_("Go ahead and type your message ...\n"));
1308         
1309         if ( !(a = iobuf_open(fname)) )
1310           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1311         else
1312           {
1313             if (!opt.no_armor) 
1314               iobuf_close(a);
1315         }
1316 #endif
1317         break;
1318     }
1319   
1320   /* cleanup */
1321   gpgsm_release_certlist (recplist);
1322   FREE_STRLIST(remusr);
1323   FREE_STRLIST(locusr);
1324   gpgsm_exit(0);
1325   return 8; /*NEVER REACHED*/
1326 }
1327
1328
1329 void
1330 gpgsm_exit (int rc)
1331 {
1332   #if 0
1333 #warning no update_random_seed_file
1334   update_random_seed_file();
1335   #endif
1336 #if 0
1337   /* at this time a bit annoying */
1338   if (opt.debug & DBG_MEMSTAT_VALUE)
1339     {
1340       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1341       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1342     }
1343   if (opt.debug)
1344     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1345 #endif
1346   gcry_control (GCRYCTL_TERM_SECMEM );
1347   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1348   exit (rc);
1349 }
1350
1351
1352 void
1353 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1354 {
1355   ctrl->include_certs = 1;  /* only include the signer's cert */
1356 }
1357
1358
1359
1360 /* Check whether the filename has the form "-&nnnn", where n is a
1361    non-zero number.  Returns this number or -1 if it is not the case.  */
1362 static int
1363 check_special_filename (const char *fname)
1364 {
1365   if (allow_special_filenames
1366       && fname && *fname == '-' && fname[1] == '&' ) {
1367     int i;
1368     
1369     fname += 2;
1370     for (i=0; isdigit (fname[i]); i++ )
1371       ;
1372     if ( !fname[i] ) 
1373       return atoi (fname);
1374   }
1375   return -1;
1376 }
1377
1378
1379
1380 /* Open the FILENAME for read and return the filedescriptor.  Stop
1381    with an error message in case of problems.  "-" denotes stdin and
1382    if special filenames are allowed the given fd is opened instead. */
1383 static int 
1384 open_read (const char *filename)
1385 {
1386   int fd;
1387
1388   if (filename[0] == '-' && !filename[1])
1389     return 0; /* stdin */
1390   fd = check_special_filename (filename);
1391   if (fd != -1)
1392     return fd;
1393   fd = open (filename, O_RDONLY);
1394   if (fd == -1)
1395     {
1396       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1397       gpgsm_exit (2);
1398     }
1399   return fd;
1400 }
1401
1402 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1403    message in case of problems.  "-" denotes stdout and if special
1404    filenames are allowed the given fd is opened instead. Caller must
1405    close the returned stream unless it is stdout. */
1406 static FILE *
1407 open_fwrite (const char *filename)
1408 {
1409   int fd;
1410   FILE *fp;
1411
1412   if (filename[0] == '-' && !filename[1])
1413     return stdout;
1414
1415   fd = check_special_filename (filename);
1416   if (fd != -1)
1417     {
1418       fp = fdopen (dup (fd), "wb");
1419       if (!fp)
1420         {
1421           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1422           gpgsm_exit (2);
1423         }
1424       return fp;
1425     }
1426   fp = fopen (filename, "wb");
1427   if (!fp)
1428     {
1429       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1430       gpgsm_exit (2);
1431     }
1432   return fp;
1433 }