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