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