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