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