* keylist.c (print_seckey_info, print_pubkey_info): --keyid-format
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <unistd.h>
29 #include <assert.h>
30 #ifdef HAVE_DOSISH_SYSTEM
31 #include <fcntl.h> /* for setmode() */
32 #endif
33 #ifdef HAVE_STAT
34 #include <sys/stat.h> /* for stat() */
35 #endif
36
37 #define INCLUDED_BY_MAIN_MODULE 1
38 #include "packet.h"
39 #include "iobuf.h"
40 #include "memory.h"
41 #include "util.h"
42 #include "main.h"
43 #include "options.h"
44 #include "keydb.h"
45 #include "trustdb.h"
46 #include "mpi.h"
47 #include "cipher.h"
48 #include "filter.h"
49 #include "ttyio.h"
50 #include "i18n.h"
51 #include "status.h"
52 #include "g10defs.h"
53 #include "keyserver-internal.h"
54 #include "exec.h"
55 #include "cardglue.h"
56
57 enum cmd_and_opt_values
58   {
59     aNull = 0,
60     oArmor        = 'a',
61     aDetachedSign = 'b',
62     aSym          = 'c',
63     aDecrypt      = 'd',
64     aEncr         = 'e',
65     oInteractive  = 'i',
66     oKOption      = 'k',
67     oDryRun       = 'n',
68     oOutput       = 'o',
69     oQuiet        = 'q',
70     oRecipient    = 'r',
71     oHiddenRecipient = 'R',
72     aSign         = 's',
73     oTextmodeShort= 't',
74     oUser         = 'u',
75     oVerbose      = 'v',
76     oCompress     = 'z',
77     oSetNotation  = 'N',
78     oBatch        = 500,
79     oMaxOutput,
80     oSigNotation,
81     oCertNotation,
82     oShowNotation,
83     oNoShowNotation,
84     aEncrFiles,
85     aEncrSym,
86     aDecryptFiles,
87     aClearsign,
88     aStore,
89     aKeygen,
90     aSignEncr,
91     aSignEncrSym,
92     aSignSym,
93     aSignKey,
94     aLSignKey,
95     aNRSignKey,
96     aNRLSignKey,
97     aListConfig,
98     aListPackets,
99     aEditKey,
100     aDeleteKeys,
101     aDeleteSecretKeys,
102     aDeleteSecretAndPublicKeys,
103     aKMode,
104     aKModeC,
105     aImport,
106     aFastImport,
107     aVerify,
108     aVerifyFiles,
109     aListKeys,
110     aListSigs,
111     aListSecretKeys,
112     aSendKeys,
113     aRecvKeys,
114     aSearchKeys,
115     aExport,
116     aExportSecret,
117     aExportSecretSub,
118     aCheckKeys,
119     aGenRevoke,
120     aDesigRevoke,
121     aPrimegen,
122     aPrintMD,
123     aPrintMDs,
124     aCheckTrustDB,
125     aUpdateTrustDB,
126     aFixTrustDB,
127     aListTrustDB,
128     aListTrustPath,
129     aExportOwnerTrust,
130     aListOwnerTrust,
131     aImportOwnerTrust,
132     aDeArmor,
133     aEnArmor,
134     aGenRandom,
135     aPipeMode,
136     aRebuildKeydbCaches,
137     aRefreshKeys,
138     aCardStatus,
139     aCardEdit,
140     aChangePIN,
141
142     oTextmode,
143     oNoTextmode,
144     oExpert,
145     oNoExpert,
146     oAskSigExpire,
147     oNoAskSigExpire,
148     oAskCertExpire,
149     oNoAskCertExpire,
150     oAskCertLevel,
151     oNoAskCertLevel,
152     oFingerprint,
153     oWithFingerprint,
154     oAnswerYes,
155     oAnswerNo,
156     oDefCertLevel,
157     oMinCertLevel,
158     oKeyring,
159     oPrimaryKeyring,
160     oSecretKeyring,
161     oShowKeyring,
162     oDefaultKey,
163     oDefRecipient,
164     oDefRecipientSelf,
165     oNoDefRecipient,
166     oOptions,
167     oDebug,
168     oDebugAll,
169     oStatusFD,
170 #ifdef __riscos__
171     oStatusFile,
172 #endif /* __riscos__ */
173     oAttributeFD,
174 #ifdef __riscos__
175     oAttributeFile,
176 #endif /* __riscos__ */
177     oSKComments,
178     oNoSKComments,
179     oEmitVersion,
180     oNoEmitVersion,
181     oCompletesNeeded,
182     oMarginalsNeeded,
183     oMaxCertDepth,
184     oLoadExtension,
185     oGnuPG,
186     oRFC1991,
187     oRFC2440,
188     oOpenPGP,
189     oPGP2,
190     oPGP6,
191     oPGP7,
192     oPGP8,
193     oCipherAlgo,
194     oDigestAlgo,
195     oCertDigestAlgo,
196     oCompressAlgo,
197     oCompressLevel,
198     oBZ2CompressLevel,
199     oBZ2CompressLowmem,
200     oPasswdFD,
201 #ifdef __riscos__
202     oPasswdFile,
203 #endif /* __riscos__ */
204     oCommandFD,
205 #ifdef __riscos__
206     oCommandFile,
207 #endif /* __riscos__ */
208     oQuickRandom,
209     oNoVerbose,
210     oTrustDBName,
211     oNoSecmemWarn,
212     oNoPermissionWarn,
213     oNoMDCWarn,
214     oNoArmor,
215     oNoDefKeyring,
216     oNoGreeting,
217     oNoTTY,
218     oNoOptions,
219     oNoBatch,
220     oHomedir,
221     oWithColons,
222     oWithKeyData,
223     oSkipVerify,
224     oCompressKeys,
225     oCompressSigs,
226     oAlwaysTrust,
227     oTrustModel,
228     oForceOwnertrust,
229     oRunAsShmCP,
230     oSetFilename,
231     oForYourEyesOnly,
232     oNoForYourEyesOnly,
233     oSetPolicyURL,
234     oSigPolicyURL,
235     oCertPolicyURL,
236     oShowPolicyURL,
237     oNoShowPolicyURL,
238     oSigKeyserverURL,
239     oUseEmbeddedFilename,
240     oComment,
241     oDefaultComment,
242     oNoComments,
243     oThrowKeyid,
244     oNoThrowKeyid,
245     oShowPhotos,
246     oNoShowPhotos,
247     oPhotoViewer,
248     oForceV3Sigs,
249     oNoForceV3Sigs,
250     oForceV4Certs,
251     oNoForceV4Certs,
252     oForceMDC,
253     oNoForceMDC,
254     oDisableMDC,
255     oNoDisableMDC,
256     oS2KMode,
257     oS2KDigest,
258     oS2KCipher,
259     oSimpleSKChecksum,                          
260     oCharset,
261     oNotDashEscaped,
262     oEscapeFrom,
263     oNoEscapeFrom,
264     oLockOnce,
265     oLockMultiple,
266     oLockNever,
267     oKeyServer,
268     oKeyServerOptions,
269     oImportOptions,
270     oExportOptions,
271     oListOptions,
272     oVerifyOptions,
273     oTempDir,
274     oExecPath,
275     oEncryptTo,
276     oHiddenEncryptTo,
277     oNoEncryptTo,
278     oLoggerFD,
279 #ifdef __riscos__
280     oLoggerFile,
281 #endif /* __riscos__ */
282     oUtf8Strings,
283     oNoUtf8Strings,
284     oDisableCipherAlgo,
285     oDisablePubkeyAlgo,
286     oAllowNonSelfsignedUID,
287     oNoAllowNonSelfsignedUID,
288     oAllowFreeformUID,
289     oNoAllowFreeformUID,
290     oAllowSecretKeyImport,                      
291     oEnableSpecialFilenames,
292     oNoLiteral,
293     oSetFilesize,
294     oHonorHttpProxy,
295     oFastListMode,
296     oListOnly,
297     oIgnoreTimeConflict,
298     oIgnoreValidFrom,
299     oIgnoreCrcError,
300     oIgnoreMDCError,
301     oShowSessionKey,
302     oOverrideSessionKey,
303     oNoRandomSeedFile,
304     oAutoKeyRetrieve,
305     oNoAutoKeyRetrieve,
306     oUseAgent,
307     oNoUseAgent,
308     oGpgAgentInfo,
309     oMergeOnly,
310     oTryAllSecrets,
311     oTrustedKey,
312     oNoExpensiveTrustChecks,
313     oFixedListMode,
314     oNoSigCache,
315     oNoSigCreateCheck,
316     oAutoCheckTrustDB,
317     oNoAutoCheckTrustDB,
318     oPreservePermissions,
319     oDefaultPreferenceList,
320     oPersonalCipherPreferences,
321     oPersonalDigestPreferences,
322     oPersonalCompressPreferences,
323     oDisplay,
324     oTTYname,
325     oTTYtype,
326     oLCctype,
327     oLCmessages,
328     oGroup,
329     oUnGroup,
330     oNoGroups,
331     oStrict,
332     oNoStrict,
333     oMangleDosFilenames,
334     oNoMangleDosFilenames,
335     oEnableProgressFilter,
336     oMultifile,
337     oKeyidFormat,
338
339     oReaderPort,
340     octapiDriver,
341     opcscDriver,
342     oDisableCCID,
343
344     aTest
345   };
346
347
348 static ARGPARSE_OPTS opts[] = {
349
350     { 300, NULL, 0, N_("@Commands:\n ") },
351
352     { aSign, "sign",      256, N_("|[file]|make a signature")},
353     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature")},
354     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
355     { aEncr, "encrypt",   256, N_("encrypt data")},
356     { aEncrFiles, "encrypt-files", 256, "@"},
357     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
358     { aStore, "store",     256, "@"},
359     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
360     { aDecryptFiles, "decrypt-files", 256, "@"},
361     { aVerify, "verify"   , 256, N_("verify a signature")},
362     { aVerifyFiles, "verify-files" , 256, "@" },
363     { aListKeys, "list-keys", 256, N_("list keys")},
364     { aListKeys, "list-public-keys", 256, "@" },
365     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
366     { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
367     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
368     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
369     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
370     { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")},
371     { aDeleteSecretKeys, "delete-secret-keys",256,
372                                     N_("remove keys from the secret keyring")},
373     { aSignKey,  "sign-key"   ,256, N_("sign a key")},
374     { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
375     { aNRSignKey, "nrsign-key"  ,256, "@"},
376     { aNRLSignKey, "nrlsign-key"  ,256, "@"},
377     { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
378     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
379     { aDesigRevoke, "desig-revoke",256, "@" },
380     { aExport, "export"           , 256, N_("export keys") },
381     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
382     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
383     { aSearchKeys, "search-keys" , 256,
384                                     N_("search for keys on a key server") },
385     { aRefreshKeys, "refresh-keys", 256,
386                                     N_("update all keys from a keyserver")},
387     { aExportSecret, "export-secret-keys" , 256, "@" },
388     { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
389     { aImport, "import",      256     , N_("import/merge keys")},
390     { aFastImport, "fast-import",  256 , "@"},
391 #ifdef ENABLE_CARD_SUPPORT
392     { aCardStatus,  "card-status", 256, N_("print the card status")},
393     { aCardEdit,   "card-edit",  256, N_("change data on a card")},
394     { aChangePIN,  "change-pin", 256, N_("change a card's PIN")},
395 #endif
396     { aListConfig, "list-config", 256, "@"},
397     { aListPackets, "list-packets",256, "@"},
398     { aExportOwnerTrust, "export-ownertrust", 256, "@"},
399     { aImportOwnerTrust, "import-ownertrust", 256, "@"},
400     { aUpdateTrustDB,
401               "update-trustdb",0 , N_("update the trust database")},
402     { aCheckTrustDB, "check-trustdb", 0, "@"},
403     { aFixTrustDB, "fix-trustdb", 0, "@"},
404     { aDeArmor, "dearmor", 256, "@"},
405     { aDeArmor, "dearmour", 256, "@"},
406     { aEnArmor, "enarmor", 256, "@"},
407     { aEnArmor, "enarmour", 256, "@"},
408     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
409     { aPrimegen, "gen-prime" , 256, "@" },
410     { aGenRandom, "gen-random" , 256, "@" },
411
412     { 301, NULL, 0, N_("@\nOptions:\n ") },
413
414     { oArmor, "armor",     0, N_("create ascii armored output")},
415     { oArmor, "armour",     0, "@" },
416     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
417     { oHiddenRecipient, "hidden-recipient", 2, "@" },
418     { oRecipient, "remote-user", 2, "@"},  /* old option name */
419     { oDefRecipient, "default-recipient", 2, "@"},
420     { oDefRecipientSelf, "default-recipient-self", 0, "@"},
421     { oNoDefRecipient, "no-default-recipient", 0, "@" },
422     { oTempDir, "temp-directory", 2, "@" },
423     { oExecPath, "exec-path", 2, "@" },
424     { oEncryptTo, "encrypt-to", 2, "@" },
425     { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
426     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
427     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
428     { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
429     { oCompressLevel, "compress-level", 1, "@" },
430     { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
431     { oBZ2CompressLowmem, "bzip2-compress-lowmem", 0, "@" },
432     { oTextmodeShort, NULL,   0, "@"},
433     { oTextmode, "textmode",  0, N_("use canonical text mode")},
434     { oNoTextmode, "no-textmode",  0, "@"},
435     { oExpert, "expert",   0, "@"},
436     { oNoExpert, "no-expert",   0, "@"},
437     { oAskSigExpire, "ask-sig-expire",   0, "@"},
438     { oNoAskSigExpire, "no-ask-sig-expire",   0, "@"},
439     { oAskCertExpire, "ask-cert-expire",   0, "@"},
440     { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
441     { oAskCertLevel, "ask-cert-level",   0, "@"},
442     { oNoAskCertLevel, "no-ask-cert-level",   0, "@"},
443     { oOutput, "output",    2, N_("use as output file")},
444     { oMaxOutput, "max-output", 16|4, "@" },
445     { oVerbose, "verbose",   0, N_("verbose") },
446     { oQuiet,   "quiet",   0, "@"},
447     { oNoTTY, "no-tty", 0, "@"},
448     { oForceV3Sigs, "force-v3-sigs", 0, "@"},
449     { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@"},
450     { oForceV4Certs, "force-v4-certs", 0, "@"},
451     { oNoForceV4Certs, "no-force-v4-certs", 0, "@"},
452     { oForceMDC, "force-mdc", 0, "@"},
453     { oNoForceMDC, "no-force-mdc", 0, "@" },
454     { oDisableMDC, "disable-mdc", 0, "@"},
455     { oNoDisableMDC, "no-disable-mdc", 0, "@" },
456     { oDryRun, "dry-run",   0, N_("do not make any changes") },
457     { oInteractive, "interactive", 0, N_("prompt before overwriting") },
458     { oUseAgent, "use-agent",0, "@"},
459     { oNoUseAgent, "no-use-agent",0, "@"},
460     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
461     { oBatch, "batch", 0, "@"},
462     { oAnswerYes, "yes", 0, "@"},
463     { oAnswerNo, "no", 0, "@"},
464     { oKeyring, "keyring", 2, "@"},
465     { oPrimaryKeyring, "primary-keyring",2, "@" },
466     { oSecretKeyring, "secret-keyring", 2, "@"},
467     { oShowKeyring, "show-keyring", 0, "@"},
468     { oDefaultKey, "default-key", 2, "@"},
469     { oKeyServer, "keyserver", 2, "@"},
470     { oKeyServerOptions, "keyserver-options",2,"@"},
471     { oImportOptions, "import-options",2,"@"},
472     { oExportOptions, "export-options",2,"@"},
473     { oListOptions, "list-options",2,"@"},
474     { oVerifyOptions, "verify-options",2,"@"},
475     { oCharset, "charset", 2, "@"},
476     { oOptions, "options", 2, "@"},
477     { oDebug, "debug"     ,4|16, "@"},
478     { oDebugAll, "debug-all" ,0, "@"},
479     { oStatusFD, "status-fd" ,1, "@"},
480 #ifdef __riscos__
481     { oStatusFile, "status-file" ,2, "@"},
482 #endif /* __riscos__ */
483     { oAttributeFD, "attribute-fd" ,1, "@" },
484 #ifdef __riscos__
485     { oAttributeFile, "attribute-file" ,2, "@" },
486 #endif /* __riscos__ */
487     { oNoSKComments, "no-sk-comments", 0,   "@"},
488     { oSKComments, "sk-comments", 0,   "@"},
489     { oCompletesNeeded, "completes-needed", 1, "@"},
490     { oMarginalsNeeded, "marginals-needed", 1, "@"},
491     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
492     { oTrustedKey, "trusted-key", 2, "@"},
493     { oLoadExtension, "load-extension", 2, "@"},
494     { oGnuPG, "gnupg",   0, "@"},
495     { oGnuPG, "no-pgp2", 0, "@"},
496     { oGnuPG, "no-pgp6", 0, "@"},
497     { oGnuPG, "no-pgp7", 0, "@"},
498     { oGnuPG, "no-pgp8", 0, "@"},
499     { oRFC1991, "rfc1991",   0, "@"},
500     { oRFC2440, "rfc2440", 0, "@" },
501     { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
502     { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
503     { oPGP6, "pgp6", 0, "@"},
504     { oPGP7, "pgp7", 0, "@"},
505     { oPGP8, "pgp8", 0, "@"},
506     { oS2KMode, "s2k-mode", 1, "@"},
507     { oS2KDigest, "s2k-digest-algo", 2, "@"},
508     { oS2KCipher, "s2k-cipher-algo", 2, "@"},
509     { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
510     { oCipherAlgo, "cipher-algo", 2, "@"},
511     { oDigestAlgo, "digest-algo", 2, "@"},
512     { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
513     { oCompressAlgo,"compress-algo", 2, "@"},
514     { oThrowKeyid, "throw-keyid", 0, "@"},
515     { oNoThrowKeyid, "no-throw-keyid", 0, "@" },
516     { oShowPhotos,   "show-photos", 0, "@" },
517     { oNoShowPhotos, "no-show-photos", 0, "@" },
518     { oPhotoViewer,  "photo-viewer", 2, "@" },
519     { oSetNotation,  "set-notation", 2, "@" },
520     { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
521     { oSigNotation,  "sig-notation", 2, "@" },
522     { oCertNotation, "cert-notation", 2, "@" },
523
524     { 302, NULL, 0, N_(
525   "@\n(See the man page for a complete listing of all commands and options)\n"
526                       )},
527
528     { 303, NULL, 0, N_("@\nExamples:\n\n"
529     " -se -r Bob [file]          sign and encrypt for user Bob\n"
530     " --clearsign [file]         make a clear text signature\n"
531     " --detach-sign [file]       make a detached signature\n"
532     " --list-keys [names]        show keys\n"
533     " --fingerprint [names]      show fingerprints\n"  ) },
534
535   /* hidden options */
536     { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
537     { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */
538     { aPrintMDs, "print-mds" , 256, "@"}, /* old */
539     { aListTrustDB, "list-trustdb",0 , "@"},
540     /* Not yet used */
541     /* { aListTrustPath, "list-trust-path",0, "@"}, */
542     { aPipeMode,  "pipemode", 0, "@" },
543     { oKOption, NULL,    0, "@"},
544     { oPasswdFD, "passphrase-fd",1, "@" },
545 #ifdef __riscos__
546     { oPasswdFile, "passphrase-file",2, "@" },
547 #endif /* __riscos__ */
548     { oCommandFD, "command-fd",1, "@" },
549 #ifdef __riscos__
550     { oCommandFile, "command-file",2, "@" },
551 #endif /* __riscos__ */
552     { oQuickRandom, "quick-random", 0, "@"},
553     { oNoVerbose, "no-verbose", 0, "@"},
554     { oTrustDBName, "trustdb-name", 2, "@" },
555     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
556     { oNoPermissionWarn, "no-permission-warning", 0, "@" },
557     { oNoMDCWarn, "no-mdc-warning", 0, "@" },
558     { oNoArmor, "no-armor",   0, "@"},
559     { oNoArmor, "no-armour",   0, "@"},
560     { oNoDefKeyring, "no-default-keyring", 0, "@" },
561     { oNoGreeting, "no-greeting", 0, "@" },
562     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
563     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
564     { oNoBatch, "no-batch", 0, "@" },
565     { oWithColons, "with-colons", 0, "@"},
566     { oWithKeyData,"with-key-data", 0, "@"},
567     { aListKeys, "list-key", 0, "@" }, /* alias */
568     { aListSigs, "list-sig", 0, "@" }, /* alias */
569     { aCheckKeys, "check-sig",0, "@" }, /* alias */
570     { oSkipVerify, "skip-verify",0, "@" },
571     { oCompressKeys, "compress-keys",0, "@"},
572     { oCompressSigs, "compress-sigs",0, "@"},
573     { oDefCertLevel, "default-cert-check-level", 1, "@"}, /* Old option */
574     { oDefCertLevel, "default-cert-level", 1, "@"},
575     { oMinCertLevel, "min-cert-level", 1, "@"},
576     { oAlwaysTrust, "always-trust", 0, "@"},
577     { oTrustModel, "trust-model", 2, "@"},
578     { oForceOwnertrust, "force-ownertrust", 2, "@"},
579     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
580     { oSetFilename, "set-filename", 2, "@" },
581     { oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
582     { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
583     { oSetPolicyURL, "set-policy-url", 2, "@" },
584     { oSigPolicyURL, "sig-policy-url", 2, "@" },
585     { oCertPolicyURL, "cert-policy-url", 2, "@" },
586     { oShowPolicyURL, "show-policy-url", 0, "@" },
587     { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
588     { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
589     { oShowNotation, "show-notation", 0, "@" },
590     { oNoShowNotation, "no-show-notation", 0, "@" },
591     { oComment, "comment", 2, "@" },
592     { oDefaultComment, "default-comment", 0, "@" },
593     { oNoComments, "no-comments", 0, "@" },
594     { oEmitVersion, "emit-version", 0, "@"},
595     { oNoEmitVersion, "no-emit-version", 0, "@"},
596     { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
597     { oNotDashEscaped, "not-dash-escaped", 0, "@" },
598     { oEscapeFrom, "escape-from-lines", 0, "@" },
599     { oNoEscapeFrom, "no-escape-from-lines", 0, "@" },
600     { oLockOnce, "lock-once", 0, "@" },
601     { oLockMultiple, "lock-multiple", 0, "@" },
602     { oLockNever, "lock-never", 0, "@" },
603     { oLoggerFD, "logger-fd",1, "@" },
604 #ifdef __riscos__
605     { oLoggerFile, "logger-file",2, "@" },
606 #endif /* __riscos__ */
607     { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
608     { oUtf8Strings, "utf8-strings", 0, "@" },
609     { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
610     { oWithFingerprint, "with-fingerprint", 0, "@" },
611     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
612     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
613     { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
614     { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" },
615     { oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
616     { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" },
617     { oNoLiteral, "no-literal", 0, "@" },
618     { oSetFilesize, "set-filesize", 20, "@" },
619     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
620     { oFastListMode,"fast-list-mode", 0, "@" },
621     { oFixedListMode,"fixed-list-mode", 0, "@" },
622     { oListOnly, "list-only", 0, "@"},
623     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
624     { oIgnoreValidFrom,    "ignore-valid-from",    0, "@" },
625     { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
626     { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
627     { oShowSessionKey, "show-session-key", 0, "@" },
628     { oOverrideSessionKey, "override-session-key", 2, "@" },
629     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
630     { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" },
631     { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
632     { oNoSigCache,         "no-sig-cache", 0, "@" },
633     { oNoSigCreateCheck,   "no-sig-create-check", 0, "@" },
634     { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"},
635     { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
636     { oMergeOnly,         "merge-only", 0, "@" },
637     { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
638     { oTryAllSecrets,  "try-all-secrets", 0, "@" },
639     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
640     { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" },
641     { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" },
642     { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
643     { oPreservePermissions, "preserve-permissions", 0, "@"},
644     { oDefaultPreferenceList,  "default-preference-list", 2, "@"},
645     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
646     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
647     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
648     /* Aliases.  I constantly mistype these, and assume other people
649        do as well. */
650     { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
651     { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
652     { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
653     { oDisplay,    "display",     2, "@" },
654     { oTTYname,    "ttyname",     2, "@" },
655     { oTTYtype,    "ttytype",     2, "@" },
656     { oLCctype,    "lc-ctype",    2, "@" },
657     { oLCmessages, "lc-messages", 2, "@" },
658     { oGroup,      "group",       2, "@" },
659     { oUnGroup,    "ungroup",     2, "@" },
660     { oNoGroups,   "no-groups",    0, "@" },
661     { oStrict,     "strict",      0, "@" },
662     { oNoStrict,   "no-strict",   0, "@" },
663     { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
664     { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
665     { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
666     { oMultifile, "multifile", 0, "@" },
667     { oKeyidFormat, "keyid-format", 2, "@" },
668
669     { oReaderPort, "reader-port",    2, "@"},
670     { octapiDriver, "ctapi-driver",  2, "@"},
671     { opcscDriver, "pcsc-driver",    2, "@"},
672     { oDisableCCID, "disable-ccid", 0, "@"},
673
674 {0} };
675
676
677 int g10_errors_seen = 0;
678
679 static int utf8_strings = 0;
680 static int maybe_setuid = 1;
681
682 static char *build_list( const char *text, char letter,
683                          const char *(*mapf)(int), int (*chkf)(int) );
684 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
685                         enum cmd_and_opt_values new_cmd );
686 static void print_mds( const char *fname, int algo );
687 static void add_notation_data( const char *string, int which );
688 static void add_policy_url( const char *string, int which );
689 static void add_keyserver_url( const char *string, int which );
690
691 const char *
692 strusage( int level )
693 {
694   static char *digests, *pubkeys, *ciphers, *zips;
695     const char *p;
696     switch( level ) {
697       case 11: p = "gpg (GnuPG)";
698         break;
699       case 13: p = VERSION; break;
700       case 17: p = PRINTABLE_OS_NAME; break;
701       case 19: p =
702             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
703         break;
704
705 #ifdef IS_DEVELOPMENT_VERSION
706       case 20:
707         p="NOTE: THIS IS A DEVELOPMENT VERSION!";
708         break;
709       case 21:
710         p="It is only intended for test purposes and should NOT be";
711         break;
712       case 22:
713         p="used in a production environment or with production keys!";
714         break;
715 #endif
716
717       case 1:
718       case 40:  p =
719             _("Usage: gpg [options] [files] (-h for help)");
720         break;
721       case 41:  p =
722             _("Syntax: gpg [options] [files]\n"
723               "sign, check, encrypt or decrypt\n"
724               "default operation depends on the input data\n");
725         break;
726
727       case 31: p = "\nHome: "; break;
728 #ifndef __riscos__
729       case 32: p = opt.homedir; break;
730 #else /* __riscos__ */
731       case 32: p = make_filename(opt.homedir, NULL); break;
732 #endif /* __riscos__ */
733       case 33: p = _("\nSupported algorithms:\n"); break;
734       case 34:
735         if( !pubkeys )
736             pubkeys = build_list(_("Pubkey: "), 0, pubkey_algo_to_string,
737                                                         check_pubkey_algo );
738         p = pubkeys;
739         break;
740       case 35:
741         if( !ciphers )
742             ciphers = build_list(_("Cipher: "), 'S', cipher_algo_to_string,
743                                                         check_cipher_algo );
744         p = ciphers;
745         break;
746       case 36:
747         if( !digests )
748             digests = build_list(_("Hash: "), 'H', digest_algo_to_string,
749                                                         check_digest_algo );
750         p = digests;
751         break;
752       case 37:
753         if( !zips )
754             zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
755                                                         check_compress_algo);
756         p = zips;
757         break;
758
759       default:  p = default_strusage(level);
760     }
761     return p;
762 }
763
764
765 static char *
766 build_list( const char *text, char letter,
767             const char * (*mapf)(int), int (*chkf)(int) )
768 {
769     int i;
770     const char *s;
771     size_t n=strlen(text)+2;
772     char *list, *p, *line=NULL;
773
774     if( maybe_setuid )
775         secmem_init( 0 );    /* drop setuid */
776
777     for(i=0; i <= 110; i++ )
778         if( !chkf(i) && (s=mapf(i)) )
779             n += strlen(s) + 7 + 2;
780     list = m_alloc( 21 + n ); *list = 0;
781     for(p=NULL, i=0; i <= 110; i++ ) {
782         if( !chkf(i) && (s=mapf(i)) ) {
783             if( !p ) {
784                 p = stpcpy( list, text );
785                 line=p;
786             }
787             else
788                 p = stpcpy( p, ", ");
789
790             if(strlen(line)>60) {
791               int spaces=strlen(text);
792
793               list=m_realloc(list,n+spaces+1);
794               /* realloc could move the block, so find the end again */
795               p=list;
796               while(*p)
797                 p++;
798
799               p=stpcpy(p, "\n");
800               line=p;
801               for(;spaces;spaces--)
802                 p=stpcpy(p, " ");
803             }
804
805             p = stpcpy(p, s );
806             if(opt.verbose && letter)
807               {
808                 char num[8];
809                 sprintf(num," (%c%d)",letter,i);
810                 p = stpcpy(p,num);
811               }
812         }
813     }
814     if( p )
815         p = stpcpy(p, "\n" );
816     return list;
817 }
818
819
820 static void
821 i18n_init(void)
822 {
823 #ifdef USE_SIMPLE_GETTEXT
824     set_gettext_file( PACKAGE );
825 #else
826 #ifdef ENABLE_NLS
827     setlocale( LC_ALL, "" );
828     bindtextdomain( PACKAGE, G10_LOCALEDIR );
829     textdomain( PACKAGE );
830 #endif
831 #endif
832 }
833
834 static void
835 wrong_args( const char *text)
836 {
837     fputs(_("usage: gpg [options] "),stderr);
838     fputs(text,stderr);
839     putc('\n',stderr);
840     g10_exit(2);
841 }
842
843
844 static char *
845 make_username( const char *string )
846 {
847     char *p;
848     if( utf8_strings )
849         p = m_strdup(string);
850     else
851         p = native_to_utf8( string );
852     return p;
853 }
854
855
856 static void
857 set_debug(void)
858 {
859     if( opt.debug & DBG_MEMORY_VALUE )
860         memory_debug_mode = 1;
861     if( opt.debug & DBG_MEMSTAT_VALUE )
862         memory_stat_debug_mode = 1;
863     if( opt.debug & DBG_MPI_VALUE )
864         mpi_debug_mode = 1;
865     if( opt.debug & DBG_CIPHER_VALUE )
866         g10c_debug_mode = 1;
867     if( opt.debug & DBG_IOBUF_VALUE )
868         iobuf_debug_mode = 1;
869
870 }
871
872
873 /* We need the home directory also in some other directories, so make
874    sure that both variables are always in sync. */
875 static void
876 set_homedir (char *dir)
877 {
878   if (!dir)
879     dir = "";
880   g10_opt_homedir = opt.homedir = dir;
881 }
882
883
884 /* We set the screen dimensions for UI purposes.  Do not allow screens
885    smaller than 80x24 for the sake of simplicity. */
886 static void
887 set_screen_dimensions(void)
888 {
889 #ifndef _WIN32
890   char *str;
891
892   str=getenv("COLUMNS");
893   if(str)
894     opt.screen_columns=atoi(str);
895
896   str=getenv("LINES");
897   if(str)
898     opt.screen_lines=atoi(str);
899 #endif
900
901   if(opt.screen_columns<80 || opt.screen_columns>255)
902     opt.screen_columns=80;
903
904   if(opt.screen_lines<24 || opt.screen_lines>255)
905     opt.screen_lines=24;
906 }
907
908
909 static void
910 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
911 {
912     enum cmd_and_opt_values cmd = *ret_cmd;
913
914     if( !cmd || cmd == new_cmd )
915         cmd = new_cmd;
916     else if( cmd == aSign && new_cmd == aEncr )
917         cmd = aSignEncr;
918     else if( cmd == aEncr && new_cmd == aSign )
919         cmd = aSignEncr;
920     else if( cmd == aSign && new_cmd == aSym )
921         cmd = aSignSym;
922     else if( cmd == aSym && new_cmd == aSign )
923         cmd = aSignSym;
924     else if( cmd == aSym && new_cmd == aEncr )
925         cmd = aEncrSym;
926     else if( cmd == aEncr && new_cmd == aSym )
927         cmd = aEncrSym;
928     else if( cmd == aKMode && new_cmd == aSym )
929         cmd = aKModeC;
930     else if (cmd == aSignEncr && new_cmd == aSym)
931         cmd = aSignEncrSym;
932     else if (cmd == aSignSym && new_cmd == aEncr)
933         cmd = aSignEncrSym;
934     else if (cmd == aEncrSym && new_cmd == aSign)
935         cmd = aSignEncrSym;
936     else if(    ( cmd == aSign     && new_cmd == aClearsign )
937              || ( cmd == aClearsign && new_cmd == aSign )  )
938         cmd = aClearsign;
939     else {
940         log_error(_("conflicting commands\n"));
941         g10_exit(2);
942     }
943
944     *ret_cmd = cmd;
945 }
946
947
948 static void
949 add_group(char *string)
950 {
951   char *name,*value;
952   struct groupitem *item;
953
954   /* Break off the group name */
955   name=strsep(&string,"=");
956   if(string==NULL)
957     {
958       log_error(_("no = sign found in group definition \"%s\"\n"),name);
959       return;
960     }
961
962   trim_trailing_ws(name,strlen(name));
963
964   /* Does this group already exist? */
965   for(item=opt.grouplist;item;item=item->next)
966     if(strcasecmp(item->name,name)==0)
967       break;
968
969   if(!item)
970     {
971       item=m_alloc(sizeof(struct groupitem));
972       item->name=name;
973       item->next=opt.grouplist;
974       item->values=NULL;
975       opt.grouplist=item;
976     }
977
978   /* Break apart the values */
979   while ((value= strsep(&string," \t")))
980     {
981       if (*value)
982         add_to_strlist2(&item->values,value,utf8_strings);
983     }
984 }
985
986
987 static void
988 rm_group(char *name)
989 {
990   struct groupitem *item,*last=NULL;
991
992   trim_trailing_ws(name,strlen(name));
993
994   for(item=opt.grouplist;item;last=item,item=item->next)
995     {
996       if(strcasecmp(item->name,name)==0)
997         {
998           if(last)
999             last->next=item->next;
1000           else
1001             opt.grouplist=item->next;
1002
1003           free_strlist(item->values);
1004           m_free(item);
1005           break;
1006         }
1007     }
1008 }
1009
1010
1011 /* We need to check three things.
1012
1013    0) The homedir.  It must be x00, a directory, and owned by the
1014    user.
1015
1016    1) The options/gpg.conf file.  Okay unless it or its containing
1017    directory is group or other writable or not owned by us.  Disable
1018    exec in this case.
1019
1020    2) Extensions.  Same as #1.
1021
1022    Returns true if the item is unsafe. */
1023 static int
1024 check_permissions(const char *path,int item)
1025 {
1026 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
1027   static int homedir_cache=-1;
1028   char *tmppath,*dir;
1029   struct stat statbuf,dirbuf;
1030   int homedir=0,ret=0,checkonly=0;
1031   int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
1032
1033   if(opt.no_perm_warn)
1034     return 0;
1035
1036   assert(item==0 || item==1 || item==2);
1037
1038   /* extensions may attach a path */
1039   if(item==2 && path[0]!=DIRSEP_C)
1040     {
1041       if(strchr(path,DIRSEP_C))
1042         tmppath=make_filename(path,NULL);
1043       else
1044         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
1045     }
1046   else
1047     tmppath=m_strdup(path);
1048
1049   /* If the item is located in the homedir, but isn't the homedir,
1050      don't continue if we already checked the homedir itself.  This is
1051      to avoid user confusion with an extra options file warning which
1052      could be rectified if the homedir itself had proper
1053      permissions. */
1054   if(item!=0 && homedir_cache>-1
1055      && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
1056     {
1057       ret=homedir_cache;
1058       goto end;
1059     }
1060
1061   /* It's okay if the file or directory doesn't exist */
1062   if(stat(tmppath,&statbuf)!=0)
1063     {
1064       ret=0;
1065       goto end;
1066     }
1067
1068   /* Now check the enclosing directory.  Theoretically, we could walk
1069      this test up to the root directory /, but for the sake of sanity,
1070      I'm stopping at one level down. */
1071   dir=make_dirname(tmppath);
1072
1073   if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode))
1074     {
1075       /* Weird error */
1076       ret=1;
1077       goto end;
1078     }
1079
1080   m_free(dir);
1081
1082   /* Assume failure */
1083   ret=1;
1084
1085   if(item==0)
1086     {
1087       /* The homedir must be x00, a directory, and owned by the user. */
1088
1089       if(S_ISDIR(statbuf.st_mode))
1090         {
1091           if(statbuf.st_uid==getuid())
1092             {
1093               if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1094                 ret=0;
1095               else
1096                 perm=1;
1097             }
1098           else
1099             own=1;
1100
1101           homedir_cache=ret;
1102         }
1103     }
1104   else if(item==1 || item==2)
1105     {
1106       /* The options or extension file.  Okay unless it or its
1107          containing directory is group or other writable or not owned
1108          by us or root. */
1109
1110       if(S_ISREG(statbuf.st_mode))
1111         {
1112           if(statbuf.st_uid==getuid() || statbuf.st_uid==0)
1113             {
1114               if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1115                 {
1116                   /* it's not writable, so make sure the enclosing
1117                      directory is also not writable */
1118                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1119                     {
1120                       if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1121                         ret=0;
1122                       else
1123                         enc_dir_perm=1;
1124                     }
1125                   else
1126                     enc_dir_own=1;
1127                 }
1128               else
1129                 {
1130                   /* it's writable, so the enclosing directory had
1131                      better not let people get to it. */
1132                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1133                     {
1134                       if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1135                         ret=0;
1136                       else
1137                         perm=enc_dir_perm=1; /* unclear which one to fix! */
1138                     }
1139                   else
1140                     enc_dir_own=1;
1141                 }
1142             }
1143           else
1144             own=1;
1145         }
1146     }
1147   else
1148     BUG();
1149
1150   if(!checkonly)
1151     {
1152       if(own)
1153         {
1154           if(item==0)
1155             log_info(_("WARNING: unsafe ownership on "
1156                        "homedir \"%s\"\n"),tmppath);
1157           else if(item==1)
1158             log_info(_("WARNING: unsafe ownership on "
1159                        "configuration file \"%s\"\n"),tmppath);
1160           else
1161             log_info(_("WARNING: unsafe ownership on "
1162                        "extension \"%s\"\n"),tmppath);
1163         }
1164       if(perm)
1165         {
1166           if(item==0)
1167             log_info(_("WARNING: unsafe permissions on "
1168                        "homedir \"%s\"\n"),tmppath);
1169           else if(item==1)
1170             log_info(_("WARNING: unsafe permissions on "
1171                        "configuration file \"%s\"\n"),tmppath);
1172           else
1173             log_info(_("WARNING: unsafe permissions on "
1174                        "extension \"%s\"\n"),tmppath);
1175         }
1176       if(enc_dir_own)
1177         {
1178           if(item==0)
1179             log_info(_("WARNING: unsafe enclosing directory ownership on "
1180                        "homedir \"%s\"\n"),tmppath);
1181           else if(item==1)
1182             log_info(_("WARNING: unsafe enclosing directory ownership on "
1183                        "configuration file \"%s\"\n"),tmppath);
1184           else
1185             log_info(_("WARNING: unsafe enclosing directory ownership on "
1186                        "extension \"%s\"\n"),tmppath);
1187         }
1188       if(enc_dir_perm)
1189         {
1190           if(item==0)
1191             log_info(_("WARNING: unsafe enclosing directory permissions on "
1192                        "homedir \"%s\"\n"),tmppath);
1193           else if(item==1)
1194             log_info(_("WARNING: unsafe enclosing directory permissions on "
1195                        "configuration file \"%s\"\n"),tmppath);
1196           else
1197             log_info(_("WARNING: unsafe enclosing directory permissions on "
1198                        "extension \"%s\"\n"),tmppath);
1199         }
1200     }
1201
1202  end:
1203   m_free(tmppath);
1204
1205   if(homedir)
1206     homedir_cache=ret;
1207
1208   return ret;
1209
1210 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
1211
1212   return 0;
1213 }
1214
1215
1216 static void
1217 print_algo_numbers(int (*checker)(int))
1218 {
1219   int i,first=1;
1220
1221   for(i=0;i<=110;i++)
1222     {
1223       if(!checker(i))
1224         {
1225           if(first)
1226             first=0;
1227           else
1228             printf(";");
1229           printf("%d",i);
1230         }
1231     }
1232 }
1233
1234
1235 /* In the future, we can do all sorts of interesting configuration
1236    output here.  For now, just give "group" as the Enigmail folks need
1237    it, and pubkey, cipher, hash, and compress as they may be useful
1238    for frontends. */
1239 static void
1240 list_config(char *items)
1241 {
1242   int show_all=(items==NULL);
1243   char *name=NULL;
1244
1245   if(!opt.with_colons)
1246     return;
1247
1248   while(show_all || (name=strsep(&items," ")))
1249     {
1250       int any=0;
1251
1252       if(show_all || ascii_strcasecmp(name,"group")==0)
1253         {
1254           struct groupitem *iter;
1255
1256           for(iter=opt.grouplist;iter;iter=iter->next)
1257             {
1258               STRLIST sl;
1259
1260               printf("cfg:group:");
1261               print_string(stdout,iter->name,strlen(iter->name),':');
1262               printf(":");
1263
1264               for(sl=iter->values;sl;sl=sl->next)
1265                 {
1266                   print_string2(stdout,sl->d,strlen(sl->d),':',';');
1267                   if(sl->next)
1268                     printf(";");
1269                 }
1270
1271               printf("\n");
1272             }
1273
1274           any=1;
1275         }
1276
1277       if(show_all || ascii_strcasecmp(name,"version")==0)
1278         {
1279           printf("cfg:version:");
1280           print_string(stdout,VERSION,strlen(VERSION),':');
1281           printf("\n");
1282           any=1;
1283         }
1284
1285       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
1286         {
1287           printf("cfg:pubkey:");
1288           print_algo_numbers(check_pubkey_algo);
1289           printf("\n");
1290           any=1;
1291         }
1292
1293       if(show_all || ascii_strcasecmp(name,"cipher")==0)
1294         {
1295           printf("cfg:cipher:");
1296           print_algo_numbers(check_cipher_algo);
1297           printf("\n");
1298           any=1;
1299         }
1300
1301       if(show_all
1302          || ascii_strcasecmp(name,"digest")==0
1303          || ascii_strcasecmp(name,"hash")==0)
1304         {
1305           printf("cfg:digest:");
1306           print_algo_numbers(check_digest_algo);
1307           printf("\n");
1308           any=1;
1309         }
1310
1311       if(show_all || ascii_strcasecmp(name,"compress")==0)
1312         {
1313           printf("cfg:compress:");
1314           print_algo_numbers(check_compress_algo);
1315           printf("\n");
1316           any=1;
1317         }
1318
1319       if(show_all)
1320         break;
1321
1322       if(!any)
1323         log_error(_("unknown configuration item \"%s\"\n"),name);
1324     }
1325 }
1326
1327
1328 /* Collapses argc/argv into a single string that must be freed */
1329 static char *
1330 collapse_args(int argc,char *argv[])
1331 {
1332   char *str=NULL;
1333   int i,first=1,len=0;
1334
1335   for(i=0;i<argc;i++)
1336     {
1337       len+=strlen(argv[i])+2;
1338       str=m_realloc(str,len);
1339       if(first)
1340         {
1341           str[0]='\0';
1342           first=0;
1343         }
1344       else
1345         strcat(str," ");
1346
1347       strcat(str,argv[i]);
1348     }
1349
1350   return str;
1351 }
1352
1353
1354 int
1355 main( int argc, char **argv )
1356 {
1357     ARGPARSE_ARGS pargs;
1358     IOBUF a;
1359     int rc=0;
1360     int orig_argc;
1361     char **orig_argv;
1362     const char *fname;
1363     char *username;
1364     int may_coredump;
1365     STRLIST sl, remusr= NULL, locusr=NULL;
1366     STRLIST nrings=NULL, sec_nrings=NULL;
1367     armor_filter_context_t afx;
1368     int detached_sig = 0;
1369     FILE *configfp = NULL;
1370     char *configname = NULL;
1371     unsigned configlineno;
1372     int parse_debug = 0;
1373     int default_config = 1;
1374     int default_keyring = 1;
1375     int greeting = 0;
1376     int nogreeting = 0;
1377     int use_random_seed = 1;
1378     enum cmd_and_opt_values cmd = 0;
1379     const char *trustdb_name = NULL;
1380     char *def_cipher_string = NULL;
1381     char *def_digest_string = NULL;
1382     char *compress_algo_string = NULL;
1383     char *cert_digest_string = NULL;
1384     char *s2k_cipher_string = NULL;
1385     char *s2k_digest_string = NULL;
1386     char *pers_cipher_list = NULL;
1387     char *pers_digest_list = NULL;
1388     char *pers_compress_list = NULL;
1389     int eyes_only=0;
1390     int multifile=0;
1391     int pwfd = -1;
1392     int with_fpr = 0; /* make an option out of --fingerprint */
1393     int any_explicit_recipient = 0;
1394 #ifdef USE_SHM_COPROCESSING
1395     ulong requested_shm_size=0;
1396 #endif
1397
1398 #ifdef __riscos__
1399     opt.lock_once = 1;
1400 #endif /* __riscos__ */
1401
1402     trap_unaligned();
1403     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
1404     /* Please note that we may running SUID(ROOT), so be very CAREFUL
1405      * when adding any stuff between here and the call to
1406      * secmem_init()  somewhere after the option parsing
1407      */
1408     log_set_name("gpg");
1409     secure_random_alloc(); /* put random number into secure memory */
1410     may_coredump = disable_core_dumps();
1411     init_signals();
1412     create_dotlock(NULL); /* register locking cleanup */
1413     i18n_init();
1414     opt.command_fd = -1; /* no command fd */
1415     opt.compress_level = -1; /* defaults to standard compress level */
1416     opt.bz2_compress_level = -1; /* defaults to standard compress level */
1417     /* note: if you change these lines, look at oOpenPGP */
1418     opt.def_cipher_algo = 0;
1419     opt.def_digest_algo = 0;
1420     opt.cert_digest_algo = 0;
1421     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
1422     opt.s2k_mode = 3; /* iterated+salted */
1423     opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
1424 #ifdef USE_CAST5
1425     opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
1426 #else
1427     opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
1428 #endif
1429     opt.completes_needed = 1;
1430     opt.marginals_needed = 3;
1431     opt.max_cert_depth = 5;
1432     opt.pgp2_workarounds = 1;
1433     opt.force_v3_sigs = 1;
1434     opt.escape_from = 1;
1435     opt.import_options=IMPORT_SK2PK;
1436     opt.export_options=EXPORT_INCLUDE_ATTRIBUTES;
1437     opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
1438     opt.keyserver_options.export_options=EXPORT_INCLUDE_ATTRIBUTES;
1439     opt.keyserver_options.include_subkeys=1;
1440     opt.keyserver_options.include_revoked=1;
1441     opt.keyserver_options.try_dns_srv=1;
1442     opt.verify_options=
1443       VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
1444     opt.trust_model=TM_AUTO;
1445     opt.mangle_dos_filenames=0;
1446     opt.min_cert_level=2;
1447     set_screen_dimensions();
1448     opt.keyid_format=KF_SHORT;
1449 #if defined (_WIN32)
1450     set_homedir ( read_w32_registry_string( NULL,
1451                                     "Software\\GNU\\GnuPG", "HomeDir" ));
1452 #else
1453     set_homedir ( getenv("GNUPGHOME") );
1454 #endif
1455     if( !*opt.homedir )
1456         set_homedir ( GNUPG_HOMEDIR );
1457
1458 #ifdef ENABLE_CARD_SUPPORT
1459 # ifdef _WIN32
1460     opt.pcsc_driver = "winscard.dll"; 
1461 #else
1462     opt.pcsc_driver = "libpcsclite.so"; 
1463 #endif
1464 #endif /*ENABLE_CARD_SUPPORT*/
1465
1466     /* check whether we have a config file on the commandline */
1467     orig_argc = argc;
1468     orig_argv = argv;
1469     pargs.argc = &argc;
1470     pargs.argv = &argv;
1471     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
1472     while( arg_parse( &pargs, opts) ) {
1473         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
1474             parse_debug++;
1475         else if( pargs.r_opt == oOptions ) {
1476             /* yes there is one, so we do not try the default one, but
1477              * read the option file when it is encountered at the commandline
1478              */
1479             default_config = 0;
1480         }
1481         else if( pargs.r_opt == oNoOptions )
1482             default_config = 0; /* --no-options */
1483         else if( pargs.r_opt == oHomedir )
1484             set_homedir ( pargs.r.ret_str );
1485         else if( pargs.r_opt == oNoPermissionWarn )
1486             opt.no_perm_warn=1;
1487         else if (pargs.r_opt == oStrict )
1488           {
1489             opt.strict=1;
1490             log_set_strict(1);
1491           }
1492         else if (pargs.r_opt == oNoStrict )
1493           {
1494             opt.strict=0;
1495             log_set_strict(0);
1496           }
1497 #ifdef USE_SHM_COPROCESSING
1498         else if( pargs.r_opt == oRunAsShmCP ) {
1499             /* does not make sense in a options file, we do it here,
1500              * so that we are the able to drop setuid as soon as possible */
1501             opt.shm_coprocess = 1;
1502             requested_shm_size = pargs.r.ret_ulong;
1503         }
1504         else if ( pargs.r_opt == oStatusFD ) {
1505             /* this is needed to ensure that the status-fd filedescriptor is
1506              * initialized when init_shm_coprocessing() is called */
1507             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1508         }
1509 #endif
1510     }
1511
1512 #ifdef HAVE_DOSISH_SYSTEM
1513     if ( strchr (opt.homedir,'\\') ) {
1514         char *d, *buf = m_alloc (strlen (opt.homedir)+1);
1515         const char *s = opt.homedir;
1516         for (d=buf,s=opt.homedir; *s; s++)
1517             *d++ = *s == '\\'? '/': *s;
1518         *d = 0;
1519         set_homedir (buf);
1520     }
1521 #endif
1522 #ifdef USE_SHM_COPROCESSING
1523     if( opt.shm_coprocess ) {
1524         init_shm_coprocessing(requested_shm_size, 1 );
1525     }
1526 #endif
1527     /* initialize the secure memory. */
1528     secmem_init( 32768 );
1529     maybe_setuid = 0;
1530     /* Okay, we are now working under our real uid */
1531
1532     set_native_charset (NULL); /* Try to auto set the character set */
1533
1534     /* Try for a version specific config file first */
1535     if( default_config )
1536       {
1537         char *name=m_strdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
1538         char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
1539
1540         do
1541           {
1542             if(configname)
1543               {
1544                 char *tok;
1545
1546                 m_free(configname);
1547                 configname=NULL;
1548
1549                 if((tok=strrchr(ver,SAFE_VERSION_DASH)))
1550                   *tok='\0';
1551                 else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
1552                   *tok='\0';
1553                 else
1554                   break;
1555               }
1556
1557             configname = make_filename(opt.homedir,name,NULL);
1558           }
1559         while(access(configname,R_OK));
1560
1561         m_free(name);
1562
1563         if(!configname)
1564           configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
1565         if (!access (configname, R_OK))
1566           { /* Print a warning when both config files are present. */
1567             char *p = make_filename(opt.homedir, "options", NULL );
1568             if (!access (p, R_OK))
1569               log_info (_("NOTE: old default options file `%s' ignored\n"), p);
1570             m_free (p);
1571           }
1572         else
1573           { /* Keep on using the old default one. */
1574             m_free (configname);
1575             configname = make_filename(opt.homedir, "options", NULL );
1576           }
1577       }
1578     argc = orig_argc;
1579     argv = orig_argv;
1580     pargs.argc = &argc;
1581     pargs.argv = &argv;
1582     pargs.flags=  1;  /* do not remove the args */
1583
1584     /* By this point we have a homedir, and cannot change it. */
1585     check_permissions(opt.homedir,0);
1586
1587   next_pass:
1588     if( configname ) {
1589       if(check_permissions(configname,1))
1590         {
1591           /* If any options file is unsafe, then disable any external
1592              programs for keyserver calls or photo IDs.  Since the
1593              external program to call is set in the options file, a
1594              unsafe options file can lead to an arbitrary program
1595              being run. */
1596
1597           opt.exec_disable=1;
1598         }
1599
1600         configlineno = 0;
1601         configfp = fopen( configname, "r" );
1602         if( !configfp ) {
1603             if( default_config ) {
1604                 if( parse_debug )
1605                     log_info(_("NOTE: no default option file `%s'\n"),
1606                                                             configname );
1607             }
1608             else {
1609                 log_error(_("option file `%s': %s\n"),
1610                                     configname, strerror(errno) );
1611                 g10_exit(2);
1612             }
1613             m_free(configname); configname = NULL;
1614         }
1615         if( parse_debug && configname )
1616             log_info(_("reading options from `%s'\n"), configname );
1617         default_config = 0;
1618     }
1619
1620     while( optfile_parse( configfp, configname, &configlineno,
1621                                                 &pargs, opts) )
1622       {
1623         switch( pargs.r_opt )
1624           {
1625           case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
1626           case aListConfig: set_cmd( &cmd, aListConfig); break;
1627           case aListPackets: set_cmd( &cmd, aListPackets); break;
1628           case aImport: set_cmd( &cmd, aImport); break;
1629           case aFastImport: set_cmd( &cmd, aFastImport); break;
1630           case aSendKeys: set_cmd( &cmd, aSendKeys); break;
1631           case aRecvKeys: set_cmd( &cmd, aRecvKeys); break;
1632           case aSearchKeys: set_cmd( &cmd, aSearchKeys); break;
1633           case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break;
1634           case aExport: set_cmd( &cmd, aExport); break;
1635           case aListKeys: set_cmd( &cmd, aListKeys); break;
1636           case aListSigs: set_cmd( &cmd, aListSigs); break;
1637           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
1638           case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
1639           case aDeleteSecretKeys:
1640             set_cmd( &cmd, aDeleteSecretKeys);
1641             greeting=1;
1642             break;
1643           case aDeleteSecretAndPublicKeys:
1644             set_cmd( &cmd, aDeleteSecretAndPublicKeys);
1645             greeting=1; 
1646             break;
1647           case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
1648
1649           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
1650           case aSym: set_cmd( &cmd, aSym); break;
1651
1652           case aDecryptFiles: multifile=1; /* fall through */
1653           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
1654
1655           case aEncrFiles: multifile=1; /* fall through */
1656           case aEncr: set_cmd( &cmd, aEncr); break;
1657
1658           case aVerifyFiles: multifile=1; /* fall through */
1659           case aVerify: set_cmd( &cmd, aVerify); break;
1660
1661           case aSign: set_cmd( &cmd, aSign );  break;
1662           case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
1663           case aSignKey: set_cmd( &cmd, aSignKey); break;
1664           case aLSignKey: set_cmd( &cmd, aLSignKey); break;
1665           case aNRSignKey: set_cmd( &cmd, aNRSignKey); break;
1666           case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break;
1667           case aStore: set_cmd( &cmd, aStore); break;
1668           case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
1669           case aClearsign: set_cmd( &cmd, aClearsign); break;
1670           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
1671           case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
1672           case aPrimegen: set_cmd( &cmd, aPrimegen); break;
1673           case aGenRandom: set_cmd( &cmd, aGenRandom); break;
1674           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
1675           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
1676           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
1677           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
1678           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
1679           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
1680           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
1681           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
1682           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
1683           case aListOwnerTrust:
1684             deprecated_warning(configname,configlineno,
1685                                "--list-ownertrust","--export-ownertrust","");
1686           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
1687           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
1688           case aPipeMode: set_cmd( &cmd, aPipeMode); break;
1689           case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
1690
1691 #ifdef ENABLE_CARD_SUPPORT
1692           case aCardStatus: set_cmd (&cmd, aCardStatus); break;
1693           case aCardEdit: set_cmd (&cmd, aCardEdit); break;
1694           case aChangePIN: set_cmd (&cmd, aChangePIN); break;
1695           case oReaderPort:
1696             card_set_reader_port (pargs.r.ret_str);
1697             break;
1698           case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
1699           case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
1700           case oDisableCCID: opt.disable_ccid = 1; break;
1701 #endif /* ENABLE_CARD_SUPPORT*/
1702
1703           case oArmor: opt.armor = 1; opt.no_armor=0; break;
1704           case oOutput: opt.outfile = pargs.r.ret_str; break;
1705           case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
1706           case oQuiet: opt.quiet = 1; break;
1707           case oNoTTY: tty_no_terminal(1); break;
1708           case oDryRun: opt.dry_run = 1; break;
1709           case oInteractive: opt.interactive = 1; break;
1710           case oVerbose:
1711             g10_opt_verbose++;
1712             opt.verbose++;
1713             opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
1714             opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
1715             break;
1716           case oKOption: set_cmd( &cmd, aKMode ); break;
1717
1718           case oBatch: opt.batch = 1; nogreeting = 1; break;
1719           case oUseAgent:
1720 #ifndef __riscos__
1721             opt.use_agent = 1;
1722 #else /* __riscos__ */
1723             opt.use_agent = 0;
1724             riscos_not_implemented("use-agent");
1725 #endif /* __riscos__ */
1726             break;
1727           case oNoUseAgent: opt.use_agent = 0; break;
1728           case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
1729           case oAnswerYes: opt.answer_yes = 1; break;
1730           case oAnswerNo: opt.answer_no = 1; break;
1731           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
1732           case oPrimaryKeyring:
1733             sl=append_to_strlist( &nrings, pargs.r.ret_str);
1734             sl->flags=2;
1735             break;
1736           case oShowKeyring:
1737             deprecated_warning(configname,configlineno,"--show-keyring",
1738                                "--list-options ","show-keyring");
1739             opt.list_options|=LIST_SHOW_KEYRING;
1740             break;
1741           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
1742           case oDebugAll: opt.debug = ~0; break;
1743           case oStatusFD:
1744             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1745             break;
1746 #ifdef __riscos__
1747           case oStatusFile:
1748             set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
1749             break;
1750 #endif /* __riscos__ */
1751           case oAttributeFD:
1752             set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
1753             break;
1754 #ifdef __riscos__
1755           case oAttributeFile:
1756             set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
1757             break;
1758 #endif /* __riscos__ */
1759           case oLoggerFD:
1760             log_set_logfile( NULL,
1761                              iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1762             break;
1763 #ifdef __riscos__
1764           case oLoggerFile:
1765             log_set_logfile( NULL,
1766                              iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
1767             break;
1768 #endif /* __riscos__ */
1769           case oWithFingerprint:
1770             opt.with_fingerprint = 1;
1771             with_fpr=1; /*fall thru*/
1772           case oFingerprint: opt.fingerprint++; break;
1773           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
1774           case oOptions:
1775             /* config files may not be nested (silently ignore them) */
1776             if( !configfp ) {
1777                 m_free(configname);
1778                 configname = m_strdup(pargs.r.ret_str);
1779                 goto next_pass;
1780             }
1781             break;
1782           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
1783           case oNoDefKeyring: default_keyring = 0; break;
1784           case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
1785           case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
1786           case oNoGreeting: nogreeting = 1; break;
1787           case oNoVerbose: g10_opt_verbose = 0;
1788                            opt.verbose = 0; opt.list_sigs=0; break;
1789           case oQuickRandom: quick_random_gen(1); break;
1790           case oSKComments: opt.sk_comments=1; break;
1791           case oNoSKComments: opt.sk_comments=0; break;
1792           case oEmitVersion: opt.no_version=0; break;
1793           case oNoEmitVersion: opt.no_version=1; break;
1794           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
1795           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
1796           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
1797           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
1798           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
1799           case oDefRecipient:
1800                     if( *pargs.r.ret_str )
1801                         opt.def_recipient = make_username(pargs.r.ret_str);
1802                     break;
1803           case oDefRecipientSelf:
1804                     m_free(opt.def_recipient); opt.def_recipient = NULL;
1805                     opt.def_recipient_self = 1;
1806                     break;
1807           case oNoDefRecipient:
1808                     m_free(opt.def_recipient); opt.def_recipient = NULL;
1809                     opt.def_recipient_self = 0;
1810                     break;
1811           case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
1812           case oHomedir: break;
1813           case oNoBatch: opt.batch = 0; break;
1814           case oWithKeyData: opt.with_key_data=1; /* fall thru */
1815           case oWithColons: opt.with_colons=':'; break;
1816
1817           case oSkipVerify: opt.skip_verify=1; break;
1818           case oCompressKeys: opt.compress_keys = 1; break;
1819           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
1820             /* There are many programs (like mutt) that call gpg with
1821                --always-trust so keep this option around for a long
1822                time. */
1823           case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
1824           case oTrustModel:
1825             if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0)
1826               opt.trust_model=TM_PGP;
1827             else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0)
1828               opt.trust_model=TM_CLASSIC;
1829             else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0)
1830               opt.trust_model=TM_ALWAYS;
1831             else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0)
1832               opt.trust_model=TM_AUTO;
1833             else
1834               log_error("unknown trust model \"%s\"\n",pargs.r.ret_str);
1835             break;
1836           case oForceOwnertrust:
1837             log_info(_("NOTE: %s is not for normal use!\n"),
1838                      "--force-ownertrust");
1839             opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
1840             if(opt.force_ownertrust==-1)
1841               {
1842                 log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str);
1843                 opt.force_ownertrust=0;
1844               }
1845             break;
1846           case oLoadExtension:
1847 #ifndef __riscos__
1848 #if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
1849             if(check_permissions(pargs.r.ret_str,2))
1850               log_info(_("cipher extension \"%s\" not loaded due to "
1851                          "unsafe permissions\n"),pargs.r.ret_str);
1852             else
1853               register_cipher_extension(orig_argc? *orig_argv:NULL,
1854                                         pargs.r.ret_str);
1855 #endif
1856 #else /* __riscos__ */
1857             riscos_not_implemented("load-extension");
1858 #endif /* __riscos__ */
1859             break;
1860           case oRFC1991:
1861             opt.compliance = CO_RFC1991;
1862             opt.force_v4_certs = 0;
1863             opt.escape_from = 1;
1864             break;
1865           case oRFC2440:
1866           case oOpenPGP:
1867             /* TODO: When 2440bis becomes a RFC, these may need
1868                changing. */
1869             opt.compliance = CO_RFC2440;
1870             opt.allow_non_selfsigned_uid = 1;
1871             opt.allow_freeform_uid = 1;
1872             opt.pgp2_workarounds = 0;
1873             opt.escape_from = 0;
1874             opt.force_v3_sigs = 0;
1875             opt.compress_keys = 0;          /* not mandated  but we do it */
1876             opt.compress_sigs = 0;          /* ditto. */
1877             opt.not_dash_escaped = 0;
1878             opt.def_cipher_algo = 0;
1879             opt.def_digest_algo = 0;
1880             opt.cert_digest_algo = 0;
1881             opt.compress_algo = -1;
1882             opt.s2k_mode = 3; /* iterated+salted */
1883             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
1884             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
1885             break;
1886           case oPGP2:  opt.compliance = CO_PGP2;  break;
1887           case oPGP6:  opt.compliance = CO_PGP6;  break;
1888           case oPGP7:  opt.compliance = CO_PGP7;  break;
1889           case oPGP8:  opt.compliance = CO_PGP8;  break;
1890           case oGnuPG: opt.compliance = CO_GNUPG; break;
1891           case oCompressSigs: opt.compress_sigs = 1; break;
1892           case oRunAsShmCP:
1893 #ifndef __riscos__
1894 # ifndef USE_SHM_COPROCESSING
1895             /* not possible in the option file,
1896              * but we print the warning here anyway */
1897             log_error("shared memory coprocessing is not available\n");
1898 # endif
1899 #else /* __riscos__ */
1900             riscos_not_implemented("run-as-shm-coprocess");
1901 #endif /* __riscos__ */
1902             break;
1903           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
1904           case oForYourEyesOnly: eyes_only = 1; break;
1905           case oNoForYourEyesOnly: eyes_only = 0; break;
1906           case oSetPolicyURL:
1907             add_policy_url(pargs.r.ret_str,0);
1908             add_policy_url(pargs.r.ret_str,1);
1909             break;
1910           case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
1911           case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
1912           case oShowPolicyURL:
1913             deprecated_warning(configname,configlineno,"--show-policy-url",
1914                                "--list-options ","show-policy-urls");
1915             deprecated_warning(configname,configlineno,"--show-policy-url",
1916                                "--verify-options ","show-policy-urls");
1917             opt.list_options|=LIST_SHOW_POLICY_URLS;
1918             opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
1919             break;
1920           case oNoShowPolicyURL:
1921             deprecated_warning(configname,configlineno,"--no-show-policy-url",
1922                                "--list-options ","no-show-policy-urls");
1923             deprecated_warning(configname,configlineno,"--no-show-policy-url",
1924                                "--verify-options ","no-show-policy-urls");
1925             opt.list_options&=~LIST_SHOW_POLICY_URLS;
1926             opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
1927             break;
1928           case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
1929           case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
1930           case oComment:
1931             if(pargs.r.ret_str[0])
1932               add_to_strlist(&opt.comments,pargs.r.ret_str);
1933             break;
1934           case oDefaultComment:
1935             deprecated_warning(configname,configlineno,
1936                                "--default-comment","--no-comments","");
1937             /* fall through */
1938           case oNoComments:
1939             free_strlist(opt.comments);
1940             opt.comments=NULL;
1941             break;
1942           case oThrowKeyid: opt.throw_keyid = 1; break;
1943           case oNoThrowKeyid: opt.throw_keyid = 0; break;
1944           case oShowPhotos:
1945             deprecated_warning(configname,configlineno,"--show-photos",
1946                                "--list-options ","show-photos");
1947             deprecated_warning(configname,configlineno,"--show-photos",
1948                                "--verify-options ","show-photos");
1949             opt.list_options|=LIST_SHOW_PHOTOS;
1950             opt.verify_options|=VERIFY_SHOW_PHOTOS;
1951             break;
1952           case oNoShowPhotos:
1953             deprecated_warning(configname,configlineno,"--no-show-photos",
1954                                "--list-options ","no-show-photos");
1955             deprecated_warning(configname,configlineno,"--no-show-photos",
1956                                "--verify-options ","no-show-photos");
1957             opt.list_options&=~LIST_SHOW_PHOTOS;
1958             opt.verify_options&=~VERIFY_SHOW_PHOTOS;
1959             break;
1960           case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
1961           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
1962           case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
1963           case oForceV4Certs: opt.force_v4_certs = 1; break;
1964           case oNoForceV4Certs: opt.force_v4_certs = 0; break;
1965           case oForceMDC: opt.force_mdc = 1; break;
1966           case oNoForceMDC: opt.force_mdc = 0; break;
1967           case oDisableMDC: opt.disable_mdc = 1; break;
1968           case oNoDisableMDC: opt.disable_mdc = 0; break;
1969           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
1970           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
1971           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
1972           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
1973           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
1974           case oEncryptTo: /* store the recipient in the second list */
1975             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
1976             sl->flags = 1;
1977             break;
1978           case oHiddenEncryptTo: /* store the recipient in the second list */
1979             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
1980             sl->flags = 1|2;
1981             break;
1982           case oRecipient: /* store the recipient */
1983             add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
1984             any_explicit_recipient = 1;
1985             break;
1986           case oHiddenRecipient: /* store the recipient with a flag */
1987             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
1988             sl->flags = 2;
1989             any_explicit_recipient = 1;
1990             break;
1991           case oTextmodeShort: opt.textmode = 2; break;
1992           case oTextmode: opt.textmode=1;  break;
1993           case oNoTextmode: opt.textmode=0;  break;
1994           case oExpert: opt.expert = 1; break;
1995           case oNoExpert: opt.expert = 0; break;
1996           case oAskSigExpire: opt.ask_sig_expire = 1; break;
1997           case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
1998           case oAskCertExpire: opt.ask_cert_expire = 1; break;
1999           case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
2000           case oAskCertLevel: opt.ask_cert_level = 1; break;
2001           case oNoAskCertLevel: opt.ask_cert_level = 0; break;
2002           case oUser: /* store the local users */
2003             add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
2004             break;
2005           case oCompress:
2006             /* this is the -z command line option */
2007             opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
2008             break;
2009           case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
2010           case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
2011           case oBZ2CompressLowmem: opt.bz2_compress_lowmem=1; break;
2012           case oPasswdFD:
2013             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2014             opt.use_agent = 0;
2015             break;
2016 #ifdef __riscos__
2017           case oPasswdFile:
2018             pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
2019             break;
2020 #endif /* __riscos__ */
2021           case oCommandFD:
2022             opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2023             break;
2024 #ifdef __riscos__
2025           case oCommandFile:
2026             opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
2027             break;
2028 #endif /* __riscos__ */
2029           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
2030           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
2031           case oCompressAlgo:
2032             /* If it is all digits, stick a Z in front of it for
2033                later.  This is for backwards compatibility with
2034                versions that took the compress algorithm number. */
2035             {
2036               char *pt=pargs.r.ret_str;
2037               while(*pt)
2038                 {
2039                   if(!isdigit(*pt))
2040                     break;
2041
2042                   pt++;
2043                 }
2044
2045               if(*pt=='\0')
2046                 {
2047                   compress_algo_string=m_alloc(strlen(pargs.r.ret_str)+2);
2048                   strcpy(compress_algo_string,"Z");
2049                   strcat(compress_algo_string,pargs.r.ret_str);
2050                 }
2051               else
2052                 compress_algo_string = m_strdup(pargs.r.ret_str);
2053             }
2054             break;
2055           case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
2056           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
2057           case oNoPermissionWarn: opt.no_perm_warn=1; break;
2058           case oNoMDCWarn: opt.no_mdc_warn=1; break;
2059           case oCharset:
2060             if( set_native_charset( pargs.r.ret_str ) )
2061                 log_error(_("%s is not a valid character set\n"),
2062                                                     pargs.r.ret_str);
2063             break;
2064           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
2065           case oEscapeFrom: opt.escape_from = 1; break;
2066           case oNoEscapeFrom: opt.escape_from = 0; break;
2067           case oLockOnce: opt.lock_once = 1; break;
2068           case oLockNever: disable_dotlock(); break;
2069           case oLockMultiple:
2070 #ifndef __riscos__
2071             opt.lock_once = 0;
2072 #else /* __riscos__ */
2073             riscos_not_implemented("lock-multiple");
2074 #endif /* __riscos__ */
2075             break;
2076           case oKeyServer:
2077             opt.keyserver_uri=m_strdup(pargs.r.ret_str);
2078             if(parse_keyserver_uri(pargs.r.ret_str,configname,configlineno))
2079               log_error(_("could not parse keyserver URI\n"));
2080             break;
2081           case oKeyServerOptions:
2082             parse_keyserver_options(pargs.r.ret_str);
2083             break;
2084           case oImportOptions:
2085             if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
2086               {
2087                 if(configname)
2088                   log_error(_("%s:%d: invalid import options\n"),
2089                             configname,configlineno);
2090                 else
2091                   log_error(_("invalid import options\n"));
2092               }
2093             break;
2094           case oExportOptions:
2095             if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
2096               {
2097                 if(configname)
2098                   log_error(_("%s:%d: invalid export options\n"),
2099                             configname,configlineno);
2100                 else
2101                   log_error(_("invalid export options\n"));
2102               }
2103             break;
2104           case oListOptions:
2105             {
2106               struct parse_options lopts[]=
2107                 {
2108                   {"show-photos",LIST_SHOW_PHOTOS,NULL},
2109                   {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL},
2110                   {"show-notations",LIST_SHOW_NOTATIONS,NULL},
2111                   {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL},
2112                   {"show-validity",LIST_SHOW_VALIDITY,NULL},
2113                   {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS,NULL},
2114                   {"show-unusable-subkeys",LIST_SHOW_UNUSABLE_SUBKEYS,NULL},
2115                   {"show-keyring",LIST_SHOW_KEYRING,NULL},
2116                   {"show-sig-expire",LIST_SHOW_SIG_EXPIRE,NULL},
2117                   {NULL,0,NULL}
2118                 };
2119
2120               if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts,1))
2121                 {
2122                   if(configname)
2123                     log_error(_("%s:%d: invalid list options\n"),
2124                               configname,configlineno);
2125                   else
2126                     log_error(_("invalid list options\n"));
2127                 }
2128             }
2129             break;
2130           case oVerifyOptions:
2131             {
2132               struct parse_options vopts[]=
2133                 {
2134                   {"show-photos",VERIFY_SHOW_PHOTOS,NULL},
2135                   {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL},
2136                   {"show-notations",VERIFY_SHOW_NOTATIONS,NULL},
2137                   {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL},
2138                   {"show-validity",VERIFY_SHOW_VALIDITY,NULL},
2139                   {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL},
2140                   {NULL,0,NULL}
2141                 };
2142
2143               if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
2144                 {
2145                   if(configname)
2146                     log_error(_("%s:%d: invalid verify options\n"),
2147                               configname,configlineno);
2148                   else
2149                     log_error(_("invalid verify options\n"));
2150                 }
2151             }
2152             break;
2153           case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
2154           case oExecPath:
2155             if(set_exec_path(pargs.r.ret_str,0))
2156               log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
2157             else
2158               opt.exec_path_set=1;
2159             break;
2160           case oSetNotation:
2161             add_notation_data( pargs.r.ret_str, 0 );
2162             add_notation_data( pargs.r.ret_str, 1 );
2163             break;
2164           case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
2165           case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
2166           case oShowNotation:
2167             deprecated_warning(configname,configlineno,"--show-notation",
2168                                "--list-options ","show-notations");
2169             deprecated_warning(configname,configlineno,"--show-notation",
2170                                "--verify-options ","show-notations");
2171             opt.list_options|=LIST_SHOW_NOTATIONS;
2172             opt.verify_options|=VERIFY_SHOW_NOTATIONS;
2173             break;
2174           case oNoShowNotation:
2175             deprecated_warning(configname,configlineno,"--no-show-notation",
2176                                "--list-options ","no-show-notations");
2177             deprecated_warning(configname,configlineno,"--no-show-notation",
2178                                "--verify-options ","no-show-notations");
2179             opt.list_options&=~LIST_SHOW_NOTATIONS;
2180             opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
2181             break;
2182           case oUtf8Strings: utf8_strings = 1; break;
2183           case oNoUtf8Strings: utf8_strings = 0; break;
2184           case oDisableCipherAlgo:
2185                 disable_cipher_algo( string_to_cipher_algo(pargs.r.ret_str) );
2186                 break;
2187           case oDisablePubkeyAlgo:
2188                 disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
2189                 break;
2190           case oNoSigCache: opt.no_sig_cache = 1; break;
2191           case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
2192           case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
2193           case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
2194           case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
2195           case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
2196           case oNoLiteral: opt.no_literal = 1; break;
2197           case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
2198           case oHonorHttpProxy:
2199                 add_to_strlist(&opt.keyserver_options.other,"http-proxy");
2200                 deprecated_warning(configname,configlineno,
2201                                    "--honor-http-proxy",
2202                                    "--keyserver-options ","http-proxy");
2203                 break;
2204           case oFastListMode: opt.fast_list_mode = 1; break;
2205           case oFixedListMode: opt.fixed_list_mode = 1; break;
2206           case oListOnly: opt.list_only=1; break;
2207           case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
2208           case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
2209           case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
2210           case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
2211           case oNoRandomSeedFile: use_random_seed = 0; break;
2212           case oAutoKeyRetrieve:
2213           case oNoAutoKeyRetrieve:
2214                 opt.keyserver_options.auto_key_retrieve=
2215                                              (pargs.r_opt==oAutoKeyRetrieve);
2216                 deprecated_warning(configname,configlineno,
2217                            pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
2218                                "--no-auto-key-retrieve","--keyserver-options ",
2219                            pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
2220                                "no-auto-key-retrieve");
2221                 break;
2222           case oShowSessionKey: opt.show_session_key = 1; break;
2223           case oOverrideSessionKey:
2224                 opt.override_session_key = pargs.r.ret_str;
2225                 break;
2226           case oMergeOnly:
2227                 deprecated_warning(configname,configlineno,"--merge-only",
2228                                    "--import-options ","merge-only");
2229                 opt.import_options|=IMPORT_MERGE_ONLY;
2230             break;
2231           case oAllowSecretKeyImport: /* obsolete */ break;
2232           case oTryAllSecrets: opt.try_all_secrets = 1; break;
2233           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
2234           case oEnableSpecialFilenames:
2235             iobuf_enable_special_filenames (1);
2236             break;
2237           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
2238           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
2239           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
2240           case oPreservePermissions: opt.preserve_permissions=1; break;
2241           case oDefaultPreferenceList:
2242             opt.def_preference_list = pargs.r.ret_str;
2243             break;
2244           case oPersonalCipherPreferences:
2245             pers_cipher_list=pargs.r.ret_str;
2246             break;
2247           case oPersonalDigestPreferences:
2248             pers_digest_list=pargs.r.ret_str;
2249             break;
2250           case oPersonalCompressPreferences:
2251             pers_compress_list=pargs.r.ret_str;
2252             break;
2253           case oDisplay: opt.display = pargs.r.ret_str; break;
2254           case oTTYname: opt.ttyname = pargs.r.ret_str; break;
2255           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
2256           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
2257           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
2258           case oGroup: add_group(pargs.r.ret_str); break;
2259           case oUnGroup: rm_group(pargs.r.ret_str); break;
2260           case oNoGroups:
2261             while(opt.grouplist)
2262               {
2263                 struct groupitem *iter=opt.grouplist;
2264                 free_strlist(iter->values);
2265                 opt.grouplist=opt.grouplist->next;
2266                 m_free(iter);
2267               }
2268             break;
2269           case oStrict: opt.strict=1; log_set_strict(1); break;
2270           case oNoStrict: opt.strict=0; log_set_strict(0); break;
2271           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
2272           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
2273           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
2274           case oMultifile: multifile=1; break;
2275           case oKeyidFormat:
2276             if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
2277               opt.keyid_format=KF_SHORT;
2278             else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
2279               opt.keyid_format=KF_LONG;
2280             else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
2281               opt.keyid_format=KF_0xSHORT;
2282             else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
2283               opt.keyid_format=KF_0xLONG;
2284             else
2285               log_error("unknown keyid-format \"%s\"\n",pargs.r.ret_str);
2286             break;
2287
2288           default : pargs.err = configfp? 1:2; break;
2289           }
2290       }
2291
2292     if( configfp ) {
2293         fclose( configfp );
2294         configfp = NULL;
2295         m_free(configname); configname = NULL;
2296         goto next_pass;
2297     }
2298     m_free( configname ); configname = NULL;
2299     if( log_get_errorcount(0) )
2300         g10_exit(2);
2301     if( nogreeting )
2302         greeting = 0;
2303
2304     if( greeting ) {
2305         fprintf(stderr, "%s %s; %s\n",
2306                         strusage(11), strusage(13), strusage(14) );
2307         fprintf(stderr, "%s\n", strusage(15) );
2308     }
2309 #ifdef IS_DEVELOPMENT_VERSION
2310     if( !opt.batch )
2311       {
2312         const char *s;
2313
2314         if((s=strusage(20)))
2315           log_info("%s\n",s);
2316         if((s=strusage(21)))
2317           log_info("%s\n",s);
2318         if((s=strusage(22)))
2319           log_info("%s\n",s);
2320       }
2321 #endif
2322
2323     if (opt.verbose > 2)
2324         log_info ("using character set `%s'\n", get_native_charset ());
2325
2326     if( may_coredump && !opt.quiet )
2327         log_info(_("WARNING: program may create a core file!\n"));
2328
2329     if (eyes_only) {
2330       if (opt.set_filename)
2331           log_info(_("WARNING: %s overrides %s\n"),
2332                    "--for-your-eyes-only","--set-filename");
2333
2334       opt.set_filename="_CONSOLE";
2335     }
2336
2337     if (opt.no_literal) {
2338         log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
2339         if (opt.textmode)
2340             log_error(_("%s not allowed with %s!\n"),
2341                        "--textmode", "--no-literal" );
2342         if (opt.set_filename)
2343             log_error(_("%s makes no sense with %s!\n"),
2344                         eyes_only?"--for-your-eyes-only":"--set-filename",
2345                         "--no-literal" );
2346     }
2347
2348     if (opt.set_filesize)
2349         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2350     if( opt.batch )
2351         tty_batchmode( 1 );
2352
2353     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
2354
2355     set_debug();
2356
2357     /* Do these after the switch(), so they can override settings. */
2358     if(PGP2)
2359       {
2360         int unusable=0;
2361
2362         if(cmd==aSign && !detached_sig)
2363           {
2364             log_info(_("you can only make detached or clear signatures "
2365                        "while in --pgp2 mode\n"));
2366             unusable=1;
2367           }
2368         else if(cmd==aSignEncr || cmd==aSignSym)
2369           {
2370             log_info(_("you can't sign and encrypt at the "
2371                        "same time while in --pgp2 mode\n"));
2372             unusable=1;
2373           }
2374         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
2375           {
2376             log_info(_("you must use files (and not a pipe) when "
2377                        "working with --pgp2 enabled.\n"));
2378             unusable=1;
2379           }
2380         else if(cmd==aEncr || cmd==aSym)
2381           {
2382             /* Everything else should work without IDEA (except using
2383                a secret key encrypted with IDEA and setting an IDEA
2384                preference, but those have their own error
2385                messages). */
2386
2387             if(check_cipher_algo(CIPHER_ALGO_IDEA))
2388               {
2389                 log_info(_("encrypting a message in --pgp2 mode requires "
2390                            "the IDEA cipher\n"));
2391                 idea_cipher_warn(1);
2392                 unusable=1;
2393               }
2394             else if(cmd==aSym)
2395               {
2396                 /* This only sets IDEA for symmetric encryption
2397                    since it is set via select_algo_from_prefs for
2398                    pk encryption. */
2399                 m_free(def_cipher_string);
2400                 def_cipher_string = m_strdup("idea");
2401               }
2402
2403             /* PGP2 can't handle the output from the textmode
2404                filter, so we disable it for anything that could
2405                create a literal packet (only encryption and
2406                symmetric encryption, since we disable signing
2407                above). */
2408             if(!unusable)
2409               opt.textmode=0;
2410           }
2411
2412         if(unusable)
2413           compliance_failure();
2414         else
2415           {
2416             opt.force_v4_certs = 0;
2417             opt.sk_comments = 0;
2418             opt.escape_from = 1;
2419             opt.force_v3_sigs = 1;
2420             opt.pgp2_workarounds = 1;
2421             opt.ask_sig_expire = 0;
2422             opt.ask_cert_expire = 0;
2423             m_free(def_digest_string);
2424             def_digest_string = m_strdup("md5");
2425             opt.compress_algo = COMPRESS_ALGO_ZIP;
2426           }
2427       }
2428     else if(PGP6)
2429       {
2430         opt.sk_comments=0;
2431         opt.escape_from=1;
2432         opt.force_v3_sigs=1;
2433         opt.ask_sig_expire=0;
2434       }
2435     else if(PGP7)
2436       {
2437         opt.sk_comments=0;
2438         opt.escape_from=1;
2439         opt.force_v3_sigs=1;
2440         opt.ask_sig_expire=0;
2441       }
2442     else if(PGP8)
2443       {
2444         opt.escape_from=1;
2445       }
2446
2447     /* must do this after dropping setuid, because string_to...
2448      * may try to load an module */
2449     if( def_cipher_string ) {
2450         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
2451         if(opt.def_cipher_algo==0 &&
2452            (ascii_strcasecmp(def_cipher_string,"idea")==0
2453             || ascii_strcasecmp(def_cipher_string,"s1")==0))
2454           idea_cipher_warn(1);
2455         m_free(def_cipher_string); def_cipher_string = NULL;
2456         if( check_cipher_algo(opt.def_cipher_algo) )
2457             log_error(_("selected cipher algorithm is invalid\n"));
2458     }
2459     if( def_digest_string ) {
2460         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
2461         m_free(def_digest_string); def_digest_string = NULL;
2462         if( check_digest_algo(opt.def_digest_algo) )
2463             log_error(_("selected digest algorithm is invalid\n"));
2464     }
2465     if( compress_algo_string ) {
2466         opt.compress_algo = string_to_compress_algo(compress_algo_string);
2467         m_free(compress_algo_string); compress_algo_string = NULL;
2468         if( check_compress_algo(opt.compress_algo) )
2469             log_error(_("selected compression algorithm is invalid\n"));
2470     }
2471     if( cert_digest_string ) {
2472         opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
2473         m_free(cert_digest_string); cert_digest_string = NULL;
2474         if( check_digest_algo(opt.cert_digest_algo) )
2475             log_error(_("selected certification digest algorithm is invalid\n"));
2476     }
2477     if( s2k_cipher_string ) {
2478         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
2479         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
2480         if( check_cipher_algo(opt.s2k_cipher_algo) )
2481             log_error(_("selected cipher algorithm is invalid\n"));
2482     }
2483     if( s2k_digest_string ) {
2484         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
2485         m_free(s2k_digest_string); s2k_digest_string = NULL;
2486         if( check_digest_algo(opt.s2k_digest_algo) )
2487             log_error(_("selected digest algorithm is invalid\n"));
2488     }
2489     if( opt.completes_needed < 1 )
2490       log_error(_("completes-needed must be greater than 0\n"));
2491     if( opt.marginals_needed < 2 )
2492       log_error(_("marginals-needed must be greater than 1\n"));
2493     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
2494       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
2495     if(opt.def_cert_level<0 || opt.def_cert_level>3)
2496       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
2497     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
2498       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
2499     switch( opt.s2k_mode ) {
2500       case 0:
2501         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
2502         break;
2503       case 1: case 3: break;
2504       default:
2505         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
2506     }
2507
2508     /* This isn't actually needed, but does serve to error out if the
2509        string is invalid. */
2510     if(opt.def_preference_list &&
2511         keygen_set_std_prefs(opt.def_preference_list,0))
2512       log_error(_("invalid default preferences\n"));
2513
2514     /* We provide defaults for the personal digest list.  This is
2515        SHA-1. */
2516     if(!pers_digest_list)
2517       pers_digest_list="h2";
2518
2519     if(pers_cipher_list &&
2520        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
2521       log_error(_("invalid personal cipher preferences\n"));
2522
2523     if(pers_digest_list &&
2524        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
2525       log_error(_("invalid personal digest preferences\n"));
2526
2527     if(pers_compress_list &&
2528        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
2529       log_error(_("invalid personal compress preferences\n"));
2530
2531     /* We don't support all possible commands with multifile yet */
2532     if(multifile)
2533       {
2534         char *cmdname;
2535
2536         switch(cmd)
2537           {
2538           case aSign:
2539             cmdname="--sign";
2540             break;
2541           case aClearsign:
2542             cmdname="--clearsign";
2543             break;
2544           case aDetachedSign:
2545             cmdname="--detach-sign";
2546             break;
2547           case aSym:
2548             cmdname="--symmetric";
2549             break;
2550           case aEncrSym:
2551             cmdname="--symmetric --encrypt";
2552             break;
2553           case aStore:
2554             cmdname="--store";
2555             break;
2556           default:
2557             cmdname=NULL;
2558             break;
2559           }
2560
2561         if(cmdname)
2562           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
2563       }
2564
2565     if( log_get_errorcount(0) )
2566         g10_exit(2);
2567
2568     if(opt.compress_level==0)
2569       opt.compress_algo=COMPRESS_ALGO_NONE;
2570
2571     /* Check our chosen algorithms against the list of legal
2572        algorithms. */
2573
2574     if(!GNUPG)
2575       {
2576         const char *badalg=NULL;
2577         preftype_t badtype=PREFTYPE_NONE;
2578
2579         if(opt.def_cipher_algo
2580            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
2581           {
2582             badalg=cipher_algo_to_string(opt.def_cipher_algo);
2583             badtype=PREFTYPE_SYM;
2584           }
2585         else if(opt.def_digest_algo
2586                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
2587           {
2588             badalg=digest_algo_to_string(opt.def_digest_algo);
2589             badtype=PREFTYPE_HASH;
2590           }
2591         else if(opt.cert_digest_algo
2592                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
2593           {
2594             badalg=digest_algo_to_string(opt.cert_digest_algo);
2595             badtype=PREFTYPE_HASH;
2596           }
2597         else if(opt.compress_algo!=-1
2598                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
2599           {
2600             badalg=compress_algo_to_string(opt.compress_algo);
2601             badtype=PREFTYPE_ZIP;
2602           }
2603
2604         if(badalg)
2605           {
2606             switch(badtype)
2607               {
2608               case PREFTYPE_SYM:
2609                 log_info(_("you may not use cipher algorithm \"%s\" "
2610                            "while in %s mode\n"),
2611                          badalg,compliance_option_string());
2612                 break;
2613               case PREFTYPE_HASH:
2614                 log_info(_("you may not use digest algorithm \"%s\" "
2615                            "while in %s mode\n"),
2616                          badalg,compliance_option_string());
2617                 break;
2618               case PREFTYPE_ZIP:
2619                 log_info(_("you may not use compression algorithm \"%s\" "
2620                            "while in %s mode\n"),
2621                          badalg,compliance_option_string());
2622                 break;
2623               default:
2624                 BUG();
2625               }
2626
2627             compliance_failure();
2628           }
2629       }
2630
2631     /* set the random seed file */
2632     if( use_random_seed ) {
2633         char *p = make_filename(opt.homedir, "random_seed", NULL );
2634         set_random_seed_file(p);
2635         m_free(p);
2636     }
2637
2638     if( !cmd && opt.fingerprint && !with_fpr ) {
2639         set_cmd( &cmd, aListKeys);
2640     }
2641
2642     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
2643         if( cmd == aKModeC ) {
2644             opt.fingerprint = 1;
2645             cmd = aKMode;
2646         }
2647         opt.list_sigs = 0;
2648         if( opt.verbose > 2 )
2649             opt.check_sigs++;
2650         if( opt.verbose > 1 )
2651             opt.list_sigs++;
2652
2653         opt.verbose = opt.verbose > 1;
2654         g10_opt_verbose = opt.verbose;
2655     }
2656
2657     /* kludge to let -sat generate a clear text signature */
2658     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
2659         cmd = aClearsign;
2660
2661     if( opt.verbose > 1 )
2662         set_packet_list_mode(1);
2663
2664     /* Add the keyrings, but not for some special commands and not in
2665        case of "-kvv userid keyring".  Also avoid adding the secret
2666        keyring for a couple of commands to avoid unneeded access in
2667        case the secrings are stored on a floppy */
2668     if( cmd != aDeArmor && cmd != aEnArmor
2669         && !(cmd == aKMode && argc == 2 ) ) 
2670       {
2671         if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
2672             && cmd != aVerify && cmd != aSym)
2673           {
2674             if (!sec_nrings || default_keyring) /* add default secret rings */
2675               keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
2676             for (sl = sec_nrings; sl; sl = sl->next)
2677               keydb_add_resource ( sl->d, 0, 1 );
2678           }
2679         if( !nrings || default_keyring )  /* add default ring */
2680             keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
2681         for(sl = nrings; sl; sl = sl->next )
2682             keydb_add_resource ( sl->d, sl->flags, 0 );
2683       }
2684     FREE_STRLIST(nrings);
2685     FREE_STRLIST(sec_nrings);
2686
2687
2688     if( pwfd != -1 )  /* read the passphrase now. */
2689         read_passphrase_from_fd( pwfd );
2690
2691     fname = argc? *argv : NULL;
2692
2693     switch( cmd ) {
2694       case aPrimegen:
2695       case aPrintMD:
2696       case aPrintMDs:
2697       case aGenRandom:
2698       case aDeArmor:
2699       case aEnArmor:
2700       case aFixTrustDB:
2701         break;
2702       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
2703       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
2704       default: rc = setup_trustdb(1, trustdb_name ); break;
2705     }
2706     if( rc )
2707         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
2708
2709
2710     switch (cmd)
2711       {
2712       case aStore: 
2713       case aSym:  
2714       case aSign: 
2715       case aSignSym: 
2716       case aClearsign: 
2717         if (!opt.quiet && any_explicit_recipient)
2718           log_info (_("WARNING: recipients (-r) given "
2719                       "without using public key encryption\n"));
2720         break;
2721       default:
2722         break;
2723       }
2724
2725     switch( cmd )
2726       {
2727       case aStore: /* only store the file */
2728         if( argc > 1 )
2729             wrong_args(_("--store [filename]"));
2730         if( (rc = encode_store(fname)) )
2731             log_error_f( print_fname_stdin(fname),
2732                         "store failed: %s\n", g10_errstr(rc) );
2733         break;
2734       case aSym: /* encrypt the given file only with the symmetric cipher */
2735         if( argc > 1 )
2736             wrong_args(_("--symmetric [filename]"));
2737         if( (rc = encode_symmetric(fname)) )
2738             log_error_f(print_fname_stdin(fname),
2739                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
2740         break;
2741
2742       case aEncr: /* encrypt the given file */
2743         if(multifile)
2744           encode_crypt_files(argc, argv, remusr);
2745         else
2746           {
2747             if( argc > 1 )
2748               wrong_args(_("--encrypt [filename]"));
2749             if( (rc = encode_crypt(fname,remusr,0)) )
2750               log_error("%s: encryption failed: %s\n",
2751                         print_fname_stdin(fname), g10_errstr(rc) );
2752           }
2753         break;
2754
2755       case aEncrSym:
2756         /* This works with PGP 8 in the sense that it acts just like a
2757            symmetric message.  It doesn't work at all with 2 or 6.  It
2758            might work with 7, but alas, I don't have a copy to test
2759            with right now. */
2760         if( argc > 1 )
2761           wrong_args(_("--symmetric --encrypt [filename]"));
2762         else if(opt.s2k_mode==0)
2763           log_error(_("you cannot use --symmetric --encrypt"
2764                       " with --s2k-mode 0\n"));
2765         else if(PGP2 || PGP6 || PGP7 || RFC1991)
2766           log_error(_("you cannot use --symmetric --encrypt"
2767                       " while in %s mode\n"),compliance_option_string());
2768         else
2769           {
2770             if( (rc = encode_crypt(fname,remusr,1)) )
2771               log_error("%s: encryption failed: %s\n",
2772                         print_fname_stdin(fname), g10_errstr(rc) );
2773           }
2774         break;
2775
2776       case aSign: /* sign the given file */
2777         sl = NULL;
2778         if( detached_sig ) { /* sign all files */
2779             for( ; argc; argc--, argv++ )
2780                 add_to_strlist( &sl, *argv );
2781         }
2782         else {
2783             if( argc > 1 )
2784                 wrong_args(_("--sign [filename]"));
2785             if( argc ) {
2786                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
2787                 strcpy(sl->d, fname);
2788             }
2789         }
2790         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
2791             log_error("signing failed: %s\n", g10_errstr(rc) );
2792         free_strlist(sl);
2793         break;
2794
2795       case aSignEncr: /* sign and encrypt the given file */
2796         if( argc > 1 )
2797             wrong_args(_("--sign --encrypt [filename]"));
2798         if( argc ) {
2799             sl = m_alloc_clear( sizeof *sl + strlen(fname));
2800             strcpy(sl->d, fname);
2801         }
2802         else
2803             sl = NULL;
2804         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
2805             log_error("%s: sign+encrypt failed: %s\n",
2806                       print_fname_stdin(fname), g10_errstr(rc) );
2807         free_strlist(sl);
2808         break;
2809
2810       case aSignEncrSym: /* sign and encrypt the given file */
2811         if( argc > 1 )
2812             wrong_args(_("--symmetric --sign --encrypt [filename]"));
2813         else if(opt.s2k_mode==0)
2814           log_error(_("you cannot use --symmetric --sign --encrypt"
2815                       " with --s2k-mode 0\n"));
2816         else if(PGP2 || PGP6 || PGP7 || RFC1991)
2817           log_error(_("you cannot use --symmetric --sign --encrypt"
2818                       " while in %s mode\n"),compliance_option_string());
2819         else
2820           {
2821             if( argc )
2822               {
2823                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
2824                 strcpy(sl->d, fname);
2825               }
2826             else
2827               sl = NULL;
2828             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
2829               log_error("%s: symmetric+sign+encrypt failed: %s\n",
2830                         print_fname_stdin(fname), g10_errstr(rc) );
2831             free_strlist(sl);
2832           }
2833         break;
2834
2835       case aSignSym: /* sign and conventionally encrypt the given file */
2836         if (argc > 1)
2837             wrong_args(_("--sign --symmetric [filename]"));
2838         rc = sign_symencrypt_file (fname, locusr);
2839         if (rc)
2840             log_error("%s: sign+symmetric failed: %s\n",
2841                       print_fname_stdin(fname), g10_errstr(rc) );
2842         break;
2843
2844       case aClearsign: /* make a clearsig */
2845         if( argc > 1 )
2846             wrong_args(_("--clearsign [filename]"));
2847         if( (rc = clearsign_file(fname, locusr, NULL)) )
2848             log_error("%s: clearsign failed: %s\n",
2849                       print_fname_stdin(fname), g10_errstr(rc) );
2850         break;
2851
2852       case aVerify:
2853         if(multifile)
2854           {
2855             if( (rc = verify_files( argc, argv ) ))
2856               log_error("verify files failed: %s\n", g10_errstr(rc) );
2857           }
2858         else
2859           {
2860             if( (rc = verify_signatures( argc, argv ) ))
2861               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
2862           }
2863         break;
2864
2865       case aDecrypt:
2866         if(multifile)
2867           decrypt_messages(argc, argv);
2868         else
2869           {
2870             if( argc > 1 )
2871               wrong_args(_("--decrypt [filename]"));
2872             if( (rc = decrypt_message( fname ) ))
2873               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
2874           }
2875         break;
2876             
2877       case aSignKey:
2878         if( argc != 1 )
2879           wrong_args(_("--sign-key user-id"));
2880         /* fall through */
2881       case aLSignKey:
2882         if( argc != 1 )
2883           wrong_args(_("--lsign-key user-id"));
2884         /* fall through */
2885       case aNRSignKey:
2886         if( argc != 1 )
2887           wrong_args(_("--nrsign-key user-id"));
2888         /* fall through */
2889       case aNRLSignKey:
2890         if( argc != 1 )
2891           wrong_args(_("--nrlsign-key user-id"));
2892
2893         sl=NULL;
2894
2895         if(cmd==aSignKey)
2896           append_to_strlist(&sl,"sign");
2897         else if(cmd==aLSignKey)
2898           append_to_strlist(&sl,"lsign");
2899         else if(cmd==aNRSignKey)
2900           append_to_strlist(&sl,"nrsign");
2901         else if(cmd==aNRLSignKey)
2902           append_to_strlist(&sl,"nrlsign");
2903         else
2904           BUG();
2905
2906         append_to_strlist( &sl, "save" );
2907         username = make_username( fname );
2908         keyedit_menu(fname, locusr, sl, 0, 0 );
2909         m_free(username);
2910         free_strlist(sl);
2911         break;
2912
2913       case aEditKey: /* Edit a key signature */
2914         if( !argc )
2915             wrong_args(_("--edit-key user-id [commands]"));
2916         username = make_username( fname );
2917         if( argc > 1 ) {
2918             sl = NULL;
2919             for( argc--, argv++ ; argc; argc--, argv++ )
2920                 append_to_strlist( &sl, *argv );
2921             keyedit_menu( username, locusr, sl, 0, 1 );
2922             free_strlist(sl);
2923         }
2924         else
2925             keyedit_menu(username, locusr, NULL, 0, 1 );
2926         m_free(username);
2927         break;
2928
2929       case aDeleteKeys:
2930       case aDeleteSecretKeys:
2931       case aDeleteSecretAndPublicKeys:
2932         sl = NULL;
2933         /* I'm adding these in reverse order as add_to_strlist2
2934            reverses them again, and it's easier to understand in the
2935            proper order :) */
2936         for( ; argc; argc-- )
2937           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
2938         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
2939         free_strlist(sl);
2940         break;
2941
2942       case aCheckKeys:
2943         opt.check_sigs = 1;
2944       case aListSigs:
2945         opt.list_sigs = 1;
2946       case aListKeys:
2947         sl = NULL;
2948         for( ; argc; argc--, argv++ )
2949             add_to_strlist2( &sl, *argv, utf8_strings );
2950         public_key_list( sl );
2951         free_strlist(sl);
2952         break;
2953       case aListSecretKeys:
2954         sl = NULL;
2955         for( ; argc; argc--, argv++ )
2956             add_to_strlist2( &sl, *argv, utf8_strings );
2957         secret_key_list( sl );
2958         free_strlist(sl);
2959         break;
2960
2961       case aKMode: /* list keyring -- NOTE: This will be removed soon */
2962         if( argc < 2 ) { /* -kv [userid] */
2963             sl = NULL;
2964             if (argc && **argv)
2965                 add_to_strlist2( &sl, *argv, utf8_strings );
2966             public_key_list( sl );
2967             free_strlist(sl);
2968         }
2969         else if( argc == 2 ) { /* -kv userid keyring */
2970             if( access( argv[1], R_OK ) ) {
2971                 log_error(_("can't open %s: %s\n"),
2972                                print_fname_stdin(argv[1]), strerror(errno));
2973             }
2974             else {
2975                 /* add keyring (default keyrings are not registered in this
2976                  * special case */
2977                 keydb_add_resource( argv[1], 0, 0 );
2978                 sl = NULL;
2979                 if (**argv)
2980                     add_to_strlist2( &sl, *argv, utf8_strings );
2981                 public_key_list( sl );
2982                 free_strlist(sl);
2983             }
2984         }
2985         else
2986             wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
2987         break;
2988
2989       case aKeygen: /* generate a key */
2990         if( opt.batch ) {
2991             if( argc > 1 )
2992                 wrong_args("--gen-key [parameterfile]");
2993             generate_keypair( argc? *argv : NULL, NULL );
2994         }
2995         else {
2996             if( argc )
2997                 wrong_args("--gen-key");
2998             generate_keypair(NULL, NULL);
2999         }
3000         break;
3001
3002       case aFastImport:
3003         opt.import_options |= IMPORT_FAST_IMPORT;
3004       case aImport:
3005         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3006         break;
3007
3008       case aExport:
3009       case aSendKeys:
3010       case aRecvKeys:
3011         sl = NULL;
3012         for( ; argc; argc--, argv++ )
3013             add_to_strlist2( &sl, *argv, utf8_strings );
3014         if( cmd == aSendKeys )
3015             rc=keyserver_export( sl );
3016         else if( cmd == aRecvKeys )
3017             rc=keyserver_import( sl );
3018         else
3019             rc=export_pubkeys( sl, opt.export_options );
3020         if(rc)
3021           {
3022             if(cmd==aSendKeys)
3023               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3024             else if(cmd==aRecvKeys)
3025               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3026             else
3027               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3028           }
3029         free_strlist(sl);
3030         break;
3031
3032      case aSearchKeys:
3033         sl = NULL;
3034         for( ; argc; argc--, argv++ )
3035           append_to_strlist2( &sl, *argv, utf8_strings );
3036         rc=keyserver_search( sl );
3037         if(rc)
3038           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3039         free_strlist(sl);
3040         break;
3041
3042       case aRefreshKeys:
3043         sl = NULL;
3044         for( ; argc; argc--, argv++ )
3045             add_to_strlist2( &sl, *argv, utf8_strings );
3046         rc=keyserver_refresh(sl);
3047         if(rc)
3048           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3049         free_strlist(sl);
3050         break;
3051
3052       case aExportSecret:
3053         sl = NULL;
3054         for( ; argc; argc--, argv++ )
3055             add_to_strlist2( &sl, *argv, utf8_strings );
3056         export_seckeys( sl );
3057         free_strlist(sl);
3058         break;
3059
3060       case aExportSecretSub:
3061         sl = NULL;
3062         for( ; argc; argc--, argv++ )
3063             add_to_strlist2( &sl, *argv, utf8_strings );
3064         export_secsubkeys( sl );
3065         free_strlist(sl);
3066         break;
3067
3068       case aGenRevoke:
3069         if( argc != 1 )
3070             wrong_args("--gen-revoke user-id");
3071         username =  make_username(*argv);
3072         gen_revoke( username );
3073         m_free( username );
3074         break;
3075
3076       case aDesigRevoke:
3077         if( argc != 1 )
3078             wrong_args("--desig-revoke user-id");
3079         username =  make_username(*argv);
3080         gen_desig_revoke( username );
3081         m_free( username );
3082         break;
3083
3084       case aDeArmor:
3085         if( argc > 1 )
3086             wrong_args("--dearmor [file]");
3087         rc = dearmor_file( argc? *argv: NULL );
3088         if( rc )
3089             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3090         break;
3091
3092       case aEnArmor:
3093         if( argc > 1 )
3094             wrong_args("--enarmor [file]");
3095         rc = enarmor_file( argc? *argv: NULL );
3096         if( rc )
3097             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3098         break;
3099
3100
3101       case aPrimegen:
3102         {   int mode = argc < 2 ? 0 : atoi(*argv);
3103
3104             if( mode == 1 && argc == 2 ) {
3105                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3106             }
3107             else if( mode == 2 && argc == 3 ) {
3108                 mpi_print( stdout, generate_elg_prime(
3109                                              0, atoi(argv[1]),
3110                                              atoi(argv[2]), NULL,NULL ), 1);
3111             }
3112             else if( mode == 3 && argc == 3 ) {
3113                 MPI *factors;
3114                 mpi_print( stdout, generate_elg_prime(
3115                                              1, atoi(argv[1]),
3116                                              atoi(argv[2]), NULL,&factors ), 1);
3117                 putchar('\n');
3118                 mpi_print( stdout, factors[0], 1 ); /* print q */
3119             }
3120             else if( mode == 4 && argc == 3 ) {
3121                 MPI g = mpi_alloc(1);
3122                 mpi_print( stdout, generate_elg_prime(
3123                                                  0, atoi(argv[1]),
3124                                                  atoi(argv[2]), g, NULL ), 1);
3125                 putchar('\n');
3126                 mpi_print( stdout, g, 1 );
3127                 mpi_free(g);
3128             }
3129             else
3130                 wrong_args("--gen-prime mode bits [qbits] ");
3131             putchar('\n');
3132         }
3133         break;
3134
3135       case aGenRandom:
3136         {
3137             int level = argc ? atoi(*argv):0;
3138             int count = argc > 1 ? atoi(argv[1]): 0;
3139             int endless = !count;
3140
3141             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3142                 wrong_args("--gen-random 0|1|2 [count]");
3143
3144             while( endless || count ) {
3145                 byte *p;
3146                 /* Wee need a multiple of 3, so that in case of
3147                    armored output we get a correct string.  No
3148                    linefolding is done, as it is best to levae this to
3149                    other tools */
3150                 size_t n = !endless && count < 99? count : 99;
3151
3152                 p = get_random_bits( n*8, level, 0);
3153 #ifdef HAVE_DOSISH_SYSTEM
3154                 setmode ( fileno(stdout), O_BINARY );
3155 #endif
3156                 if (opt.armor) {
3157                     char *tmp = make_radix64_string (p, n);
3158                     fputs (tmp, stdout);
3159                     m_free (tmp);
3160                     if (n%3 == 1)
3161                       putchar ('=');
3162                     if (n%3)
3163                       putchar ('=');
3164                 } else {
3165                     fwrite( p, n, 1, stdout );
3166                 }
3167                 m_free(p);
3168                 if( !endless )
3169                     count -= n;
3170             }
3171             if (opt.armor)
3172                 putchar ('\n');
3173         }
3174         break;
3175
3176       case aPrintMD:
3177         if( argc < 1)
3178             wrong_args("--print-md algo [files]");
3179         {
3180             int all_algos = (**argv=='*' && !(*argv)[1]);
3181             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3182
3183             if( !algo && !all_algos )
3184                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3185             else {
3186                 argc--; argv++;
3187                 if( !argc )
3188                     print_mds(NULL, algo);
3189                 else {
3190                     for(; argc; argc--, argv++ )
3191                         print_mds(*argv, algo);
3192                 }
3193             }
3194         }
3195         break;
3196
3197       case aPrintMDs: /* old option */
3198         if( !argc )
3199             print_mds(NULL,0);
3200         else {
3201             for(; argc; argc--, argv++ )
3202                 print_mds(*argv,0);
3203         }
3204         break;
3205
3206       case aListTrustDB:
3207         if( !argc )
3208             list_trustdb(NULL);
3209         else {
3210             for( ; argc; argc--, argv++ )
3211                 list_trustdb( *argv );
3212         }
3213         break;
3214
3215       case aUpdateTrustDB:
3216         if( argc )
3217             wrong_args("--update-trustdb");
3218         update_trustdb();
3219         break;
3220
3221       case aCheckTrustDB:
3222         /* Old versions allowed for arguments - ignore them */
3223         check_trustdb();
3224         break;
3225
3226       case aFixTrustDB:
3227         log_error("this command is not yet implemented.\n");
3228         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3229         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3230         break;
3231
3232       case aListTrustPath:
3233         if( !argc )
3234             wrong_args("--list-trust-path <user-ids>");
3235         for( ; argc; argc--, argv++ ) {
3236             username = make_username( *argv );
3237             list_trust_path( username );
3238             m_free(username);
3239         }
3240         break;
3241
3242       case aExportOwnerTrust:
3243         if( argc )
3244             wrong_args("--export-ownertrust");
3245         export_ownertrust();
3246         break;
3247
3248       case aImportOwnerTrust:
3249         if( argc > 1 )
3250             wrong_args("--import-ownertrust [file]");
3251         import_ownertrust( argc? *argv:NULL );
3252         break;
3253       
3254       case aPipeMode:
3255         if ( argc )
3256             wrong_args ("--pipemode");
3257         run_in_pipemode ();
3258         break;
3259
3260       case aRebuildKeydbCaches:
3261         if (argc)
3262             wrong_args ("--rebuild-keydb-caches");
3263         keydb_rebuild_caches (1);
3264         break;
3265
3266 #ifdef ENABLE_CARD_SUPPORT
3267       case aCardStatus:
3268         if (argc)
3269             wrong_args ("--card-status");
3270         card_status (stdout, NULL, 0);
3271         break;
3272
3273       case aCardEdit:
3274         if (argc) {
3275             sl = NULL;
3276             for (argc--, argv++ ; argc; argc--, argv++)
3277                 append_to_strlist (&sl, *argv);
3278             card_edit (sl);
3279             free_strlist (sl);
3280         }
3281         else
3282             card_edit (NULL);
3283         break;
3284
3285       case aChangePIN:
3286         if (!argc)
3287             change_pin (0);
3288         else if (argc == 1)
3289             change_pin ( atoi (*argv));
3290         else
3291         wrong_args ("--change-pin [no]");
3292         break;
3293 #endif /* ENABLE_CARD_SUPPORT*/
3294
3295       case aListConfig:
3296         {
3297           char *str=collapse_args(argc,argv);
3298           list_config(str);
3299           m_free(str);
3300         }
3301         break;
3302
3303       case aListPackets:
3304         opt.list_packets=2;
3305       default:
3306         if( argc > 1 )
3307             wrong_args(_("[filename]"));
3308         /* Issue some output for the unix newbie */
3309         if( !fname && !opt.outfile && isatty( fileno(stdin) )
3310                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
3311             log_info(_("Go ahead and type your message ...\n"));
3312
3313         if( !(a = iobuf_open(fname)) )
3314             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
3315         else {
3316
3317             if( !opt.no_armor ) {
3318                 if( use_armor_filter( a ) ) {
3319                     memset( &afx, 0, sizeof afx);
3320                     iobuf_push_filter( a, armor_filter, &afx );
3321                 }
3322             }
3323             if( cmd == aListPackets ) {
3324                 set_packet_list_mode(1);
3325                 opt.list_packets=1;
3326             }
3327             rc = proc_packets(NULL, a );
3328             if( rc )
3329                 log_error("processing message failed: %s\n", g10_errstr(rc) );
3330             iobuf_close(a);
3331         }
3332         break;
3333       }
3334
3335     /* cleanup */
3336     FREE_STRLIST(remusr);
3337     FREE_STRLIST(locusr);
3338     g10_exit(0);
3339     return 8; /*NEVER REACHED*/
3340 }
3341
3342
3343 void
3344 g10_exit( int rc )
3345 {
3346 #ifdef ENABLE_CARD_SUPPORT
3347     card_close ();
3348 #endif
3349     update_random_seed_file();
3350     if( opt.debug & DBG_MEMSTAT_VALUE ) {
3351         m_print_stats("on exit");
3352         random_dump_stats();
3353     }
3354     if( opt.debug )
3355         secmem_dump_stats();
3356     secmem_term();
3357     rc = rc? rc : log_get_errorcount(0)? 2 :
3358                         g10_errors_seen? 1 : 0;
3359     exit(rc );
3360 }
3361
3362
3363 /* Pretty-print hex hashes.  This assumes at least an 80-character
3364    display, but there are a few other similar assumptions in the
3365    display code. */
3366 static void
3367 print_hex( MD_HANDLE md, int algo, const char *fname )
3368 {
3369   int i,n,count,indent=0;
3370   const byte *p;
3371
3372   if(fname)
3373     indent=printf("%s: ",fname);
3374
3375   if(indent>40)
3376     {
3377       printf("\n");
3378       indent=0;
3379     }
3380
3381   if(algo==DIGEST_ALGO_RMD160)
3382     indent+=printf("RMD160 = ");
3383   else if(algo>0)
3384     indent+=printf("%6s = ",digest_algo_to_string(algo));
3385   else
3386     algo=abs(algo);
3387
3388   count=indent;
3389
3390   p = md_read( md, algo );
3391   n = md_digest_length(algo);
3392
3393   count+=printf("%02X",*p++);
3394
3395   for(i=1;i<n;i++,p++)
3396     {
3397       if(n==16)
3398         {
3399           if(count+2>79)
3400             {
3401               printf("\n%*s",indent," ");
3402               count=indent;
3403             }
3404           else
3405             count+=printf(" ");
3406
3407           if(!(i%8))
3408             count+=printf(" ");
3409         }
3410       else if (n==20)
3411         {
3412           if(!(i%2))
3413             {
3414               if(count+4>79)
3415                 {
3416                   printf("\n%*s",indent," ");
3417                   count=indent;
3418                 }
3419               else
3420                 count+=printf(" ");
3421             }
3422
3423           if(!(i%10))
3424             count+=printf(" ");
3425         }
3426       else
3427         {
3428           if(!(i%4))
3429             {
3430               if(count+8>79)
3431                 {
3432                   printf("\n%*s",indent," ");
3433                   count=indent;
3434                 }
3435               else
3436                 count+=printf(" ");
3437             }
3438         }
3439
3440       count+=printf("%02X",*p);
3441     }
3442
3443   printf("\n");
3444 }
3445
3446 static void
3447 print_hashline( MD_HANDLE md, int algo, const char *fname )
3448 {
3449     int i, n;
3450     const byte *p;
3451     
3452     if ( fname ) {
3453         for (p = fname; *p; p++ ) {
3454             if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
3455                 printf("%%%02X", *p );
3456             else 
3457                 putchar( *p );
3458         }
3459     }
3460     putchar(':');
3461     printf("%d:", algo );
3462     p = md_read( md, algo );
3463     n = md_digest_length(algo);
3464     for(i=0; i < n ; i++, p++ ) 
3465         printf("%02X", *p );
3466     putchar(':');
3467     putchar('\n');
3468 }
3469
3470 static void
3471 print_mds( const char *fname, int algo )
3472 {
3473     FILE *fp;
3474     char buf[1024];
3475     size_t n;
3476     MD_HANDLE md;
3477
3478     if( !fname ) {
3479         fp = stdin;
3480 #ifdef HAVE_DOSISH_SYSTEM
3481         setmode ( fileno(fp) , O_BINARY );
3482 #endif
3483     }
3484     else {
3485         fp = fopen( fname, "rb" );
3486     }
3487     if( !fp ) {
3488         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3489         return;
3490     }
3491
3492     md = md_open( 0, 0 );
3493     if( algo )
3494         md_enable( md, algo );
3495     else {
3496         md_enable( md, DIGEST_ALGO_MD5 );
3497         md_enable( md, DIGEST_ALGO_SHA1 );
3498