* keyserver.c (keyserver_spawn): Don't mess about with the $PATH.
[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: set_cmd( &cmd, aPipeMode); break;
1923           case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
1924
1925 #ifdef ENABLE_CARD_SUPPORT
1926           case aCardStatus: set_cmd (&cmd, aCardStatus); break;
1927           case aCardEdit: set_cmd (&cmd, aCardEdit); break;
1928           case aChangePIN: set_cmd (&cmd, aChangePIN); break;
1929           case oReaderPort:
1930             card_set_reader_port (pargs.r.ret_str);
1931             break;
1932           case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
1933           case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
1934           case oDisableCCID: opt.disable_ccid = 1; break;
1935 #endif /* ENABLE_CARD_SUPPORT*/
1936
1937           case oArmor: opt.armor = 1; opt.no_armor=0; break;
1938           case oOutput: opt.outfile = pargs.r.ret_str; break;
1939           case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
1940           case oQuiet: opt.quiet = 1; break;
1941           case oNoTTY: tty_no_terminal(1); break;
1942           case oDryRun: opt.dry_run = 1; break;
1943           case oInteractive: opt.interactive = 1; break;
1944           case oVerbose:
1945             g10_opt_verbose++;
1946             opt.verbose++;
1947             opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
1948             opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
1949             break;
1950           case oKOption: set_cmd( &cmd, aKMode ); break;
1951
1952           case oBatch: opt.batch = 1; nogreeting = 1; break;
1953           case oUseAgent:
1954 #ifndef __riscos__
1955             opt.use_agent = 1;
1956 #else /* __riscos__ */
1957             opt.use_agent = 0;
1958             riscos_not_implemented("use-agent");
1959 #endif /* __riscos__ */
1960             break;
1961           case oNoUseAgent: opt.use_agent = 0; break;
1962           case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
1963           case oAnswerYes: opt.answer_yes = 1; break;
1964           case oAnswerNo: opt.answer_no = 1; break;
1965           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
1966           case oPrimaryKeyring:
1967             sl=append_to_strlist( &nrings, pargs.r.ret_str);
1968             sl->flags=2;
1969             break;
1970           case oShowKeyring:
1971             deprecated_warning(configname,configlineno,"--show-keyring",
1972                                "--list-options ","show-keyring");
1973             opt.list_options|=LIST_SHOW_KEYRING;
1974             break;
1975           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
1976           case oDebugAll: opt.debug = ~0; break;
1977           case oDebugCCIDDriver: 
1978 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
1979             ccid_set_debug_level (1);
1980 #endif
1981             break;
1982           case oStatusFD:
1983             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1984             break;
1985           case oStatusFile:
1986             set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
1987             break;
1988           case oAttributeFD:
1989             set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
1990             break;
1991           case oAttributeFile:
1992             set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
1993             break;
1994           case oLoggerFD:
1995             log_set_logfile( NULL,
1996                              iobuf_translate_file_handle (pargs.r.ret_int, 1));
1997             break;
1998           case oLoggerFile:
1999             log_set_logfile( NULL, open_info_file (pargs.r.ret_str, 1) );
2000             break;
2001
2002           case oWithFingerprint:
2003             opt.with_fingerprint = 1;
2004             with_fpr=1; /*fall thru*/
2005           case oFingerprint: opt.fingerprint++; break;
2006           case oSecretKeyring:
2007             append_to_strlist( &sec_nrings, pargs.r.ret_str);
2008             break;
2009           case oOptions:
2010             /* config files may not be nested (silently ignore them) */
2011             if( !configfp ) {
2012                 m_free(configname);
2013                 configname = m_strdup(pargs.r.ret_str);
2014                 goto next_pass;
2015             }
2016             break;
2017           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
2018           case oNoDefKeyring: default_keyring = 0; break;
2019           case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
2020           case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
2021           case oNoGreeting: nogreeting = 1; break;
2022           case oNoVerbose: g10_opt_verbose = 0;
2023                            opt.verbose = 0; opt.list_sigs=0; break;
2024           case oQuickRandom: quick_random_gen(1); break;
2025           case oSKComments: opt.sk_comments=1; break;
2026           case oNoSKComments: opt.sk_comments=0; break;
2027           case oEmitVersion: opt.no_version=0; break;
2028           case oNoEmitVersion: opt.no_version=1; break;
2029           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
2030           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
2031           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
2032           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
2033           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
2034           case oDefRecipient:
2035                     if( *pargs.r.ret_str )
2036                         opt.def_recipient = make_username(pargs.r.ret_str);
2037                     break;
2038           case oDefRecipientSelf:
2039                     m_free(opt.def_recipient); opt.def_recipient = NULL;
2040                     opt.def_recipient_self = 1;
2041                     break;
2042           case oNoDefRecipient:
2043                     m_free(opt.def_recipient); opt.def_recipient = NULL;
2044                     opt.def_recipient_self = 0;
2045                     break;
2046           case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
2047           case oHomedir: break;
2048           case oNoBatch: opt.batch = 0; break;
2049           case oWithKeyData: opt.with_key_data=1; /* fall thru */
2050           case oWithColons: opt.with_colons=':'; break;
2051
2052           case oSkipVerify: opt.skip_verify=1; break;
2053           case oCompressKeys: opt.compress_keys = 1; break;
2054           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
2055             /* There are many programs (like mutt) that call gpg with
2056                --always-trust so keep this option around for a long
2057                time. */
2058           case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
2059           case oTrustModel:
2060             parse_trust_model(pargs.r.ret_str);
2061             break;
2062           case oForceOwnertrust:
2063             log_info(_("NOTE: %s is not for normal use!\n"),
2064                      "--force-ownertrust");
2065             opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
2066             if(opt.force_ownertrust==-1)
2067               {
2068                 log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
2069                 opt.force_ownertrust=0;
2070               }
2071             break;
2072           case oLoadExtension:
2073 #ifndef __riscos__
2074 #if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
2075             if(check_permissions(pargs.r.ret_str,2))
2076               log_info(_("cipher extension `%s' not loaded due to"
2077                          " unsafe permissions\n"),pargs.r.ret_str);
2078             else
2079               register_cipher_extension(orig_argc? *orig_argv:NULL,
2080                                         pargs.r.ret_str);
2081 #endif
2082 #else /* __riscos__ */
2083             riscos_not_implemented("load-extension");
2084 #endif /* __riscos__ */
2085             break;
2086           case oRFC1991:
2087             opt.compliance = CO_RFC1991;
2088             opt.force_v4_certs = 0;
2089             opt.escape_from = 1;
2090             break;
2091           case oOpenPGP:
2092           case oRFC2440:
2093             /* TODO: When 2440bis becomes a RFC, set new values for
2094                oOpenPGP. */
2095             opt.rfc2440_text=1;
2096             opt.compliance = CO_RFC2440;
2097             opt.allow_non_selfsigned_uid = 1;
2098             opt.allow_freeform_uid = 1;
2099             opt.pgp2_workarounds = 0;
2100             opt.escape_from = 0;
2101             opt.force_v3_sigs = 0;
2102             opt.compress_keys = 0;          /* not mandated, but we do it */
2103             opt.compress_sigs = 0;          /* ditto. */
2104             opt.not_dash_escaped = 0;
2105             opt.def_cipher_algo = 0;
2106             opt.def_digest_algo = 0;
2107             opt.cert_digest_algo = 0;
2108             opt.compress_algo = -1;
2109             opt.s2k_mode = 3; /* iterated+salted */
2110             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
2111             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
2112             break;
2113           case oPGP2:  opt.compliance = CO_PGP2;  break;
2114           case oPGP6:  opt.compliance = CO_PGP6;  break;
2115           case oPGP7:  opt.compliance = CO_PGP7;  break;
2116           case oPGP8:  opt.compliance = CO_PGP8;  break;
2117           case oGnuPG: opt.compliance = CO_GNUPG; break;
2118           case oCompressSigs: opt.compress_sigs = 1; break;
2119           case oRFC2440Text: opt.rfc2440_text=1; break;
2120           case oNoRFC2440Text: opt.rfc2440_text=0; break;
2121           case oRunAsShmCP:
2122 #ifndef __riscos__
2123 # ifndef USE_SHM_COPROCESSING
2124             /* not possible in the option file,
2125              * but we print the warning here anyway */
2126             log_error("shared memory coprocessing is not available\n");
2127 # endif
2128 #else /* __riscos__ */
2129             riscos_not_implemented("run-as-shm-coprocess");
2130 #endif /* __riscos__ */
2131             break;
2132           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
2133           case oForYourEyesOnly: eyes_only = 1; break;
2134           case oNoForYourEyesOnly: eyes_only = 0; break;
2135           case oSetPolicyURL:
2136             add_policy_url(pargs.r.ret_str,0);
2137             add_policy_url(pargs.r.ret_str,1);
2138             break;
2139           case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
2140           case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
2141           case oShowPolicyURL:
2142             deprecated_warning(configname,configlineno,"--show-policy-url",
2143                                "--list-options ","show-policy-urls");
2144             deprecated_warning(configname,configlineno,"--show-policy-url",
2145                                "--verify-options ","show-policy-urls");
2146             opt.list_options|=LIST_SHOW_POLICY_URLS;
2147             opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
2148             break;
2149           case oNoShowPolicyURL:
2150             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2151                                "--list-options ","no-show-policy-urls");
2152             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2153                                "--verify-options ","no-show-policy-urls");
2154             opt.list_options&=~LIST_SHOW_POLICY_URLS;
2155             opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
2156             break;
2157           case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
2158           case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
2159           case oNoUseEmbeddedFilename: opt.use_embedded_filename = 0; break;
2160           case oComment:
2161             if(pargs.r.ret_str[0])
2162               append_to_strlist(&opt.comments,pargs.r.ret_str);
2163             break;
2164           case oDefaultComment:
2165             deprecated_warning(configname,configlineno,
2166                                "--default-comment","--no-comments","");
2167             /* fall through */
2168           case oNoComments:
2169             free_strlist(opt.comments);
2170             opt.comments=NULL;
2171             break;
2172           case oThrowKeyids: opt.throw_keyid = 1; break;
2173           case oNoThrowKeyids: opt.throw_keyid = 0; break;
2174           case oShowPhotos:
2175             deprecated_warning(configname,configlineno,"--show-photos",
2176                                "--list-options ","show-photos");
2177             deprecated_warning(configname,configlineno,"--show-photos",
2178                                "--verify-options ","show-photos");
2179             opt.list_options|=LIST_SHOW_PHOTOS;
2180             opt.verify_options|=VERIFY_SHOW_PHOTOS;
2181             break;
2182           case oNoShowPhotos:
2183             deprecated_warning(configname,configlineno,"--no-show-photos",
2184                                "--list-options ","no-show-photos");
2185             deprecated_warning(configname,configlineno,"--no-show-photos",
2186                                "--verify-options ","no-show-photos");
2187             opt.list_options&=~LIST_SHOW_PHOTOS;
2188             opt.verify_options&=~VERIFY_SHOW_PHOTOS;
2189             break;
2190           case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
2191           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
2192           case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
2193           case oForceV4Certs: opt.force_v4_certs = 1; break;
2194           case oNoForceV4Certs: opt.force_v4_certs = 0; break;
2195           case oForceMDC: opt.force_mdc = 1; break;
2196           case oNoForceMDC: opt.force_mdc = 0; break;
2197           case oDisableMDC: opt.disable_mdc = 1; break;
2198           case oNoDisableMDC: opt.disable_mdc = 0; break;
2199           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
2200           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
2201           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
2202           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
2203           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
2204           case oEncryptTo: /* store the recipient in the second list */
2205             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2206             sl->flags = 1;
2207             break;
2208           case oHiddenEncryptTo: /* store the recipient in the second list */
2209             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2210             sl->flags = 1|2;
2211             break;
2212           case oRecipient: /* store the recipient */
2213             add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2214             any_explicit_recipient = 1;
2215             break;
2216           case oHiddenRecipient: /* store the recipient with a flag */
2217             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2218             sl->flags = 2;
2219             any_explicit_recipient = 1;
2220             break;
2221           case oTextmodeShort: opt.textmode = 2; break;
2222           case oTextmode: opt.textmode=1;  break;
2223           case oNoTextmode: opt.textmode=0;  break;
2224           case oExpert: opt.expert = 1; break;
2225           case oNoExpert: opt.expert = 0; break;
2226           case oAskSigExpire: opt.ask_sig_expire = 1; break;
2227           case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
2228           case oAskCertExpire: opt.ask_cert_expire = 1; break;
2229           case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
2230           case oAskCertLevel: opt.ask_cert_level = 1; break;
2231           case oNoAskCertLevel: opt.ask_cert_level = 0; break;
2232           case oUser: /* store the local users */
2233             add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
2234             break;
2235           case oCompress:
2236             /* this is the -z command line option */
2237             opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
2238             break;
2239           case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
2240           case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
2241           case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
2242           case oPasswdFD:
2243             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2244             opt.use_agent = 0;
2245             break;
2246           case oPasswdFile:
2247             pwfd = open_info_file (pargs.r.ret_str, 0);
2248             break;
2249           case oCommandFD:
2250             opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2251             break;
2252           case oCommandFile:
2253             opt.command_fd = open_info_file (pargs.r.ret_str, 0);
2254             break;
2255           case oCipherAlgo: 
2256             def_cipher_string = m_strdup(pargs.r.ret_str);
2257             break;
2258           case oDigestAlgo:
2259             def_digest_string = m_strdup(pargs.r.ret_str);
2260             break;
2261           case oCompressAlgo:
2262             /* If it is all digits, stick a Z in front of it for
2263                later.  This is for backwards compatibility with
2264                versions that took the compress algorithm number. */
2265             {
2266               char *pt=pargs.r.ret_str;
2267               while(*pt)
2268                 {
2269                   if(!isdigit(*pt))
2270                     break;
2271
2272                   pt++;
2273                 }
2274
2275               if(*pt=='\0')
2276                 {
2277                   compress_algo_string=m_alloc(strlen(pargs.r.ret_str)+2);
2278                   strcpy(compress_algo_string,"Z");
2279                   strcat(compress_algo_string,pargs.r.ret_str);
2280                 }
2281               else
2282                 compress_algo_string = m_strdup(pargs.r.ret_str);
2283             }
2284             break;
2285           case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
2286           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
2287           case oRequireSecmem: require_secmem=1; break;
2288           case oNoRequireSecmem: require_secmem=0; break;
2289           case oNoPermissionWarn: opt.no_perm_warn=1; break;
2290           case oNoMDCWarn: opt.no_mdc_warn=1; break;
2291           case oDisplayCharset:
2292             if( set_native_charset( pargs.r.ret_str ) )
2293                 log_error(_("`%s' is not a valid character set\n"),
2294                           pargs.r.ret_str);
2295             break;
2296           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
2297           case oEscapeFrom: opt.escape_from = 1; break;
2298           case oNoEscapeFrom: opt.escape_from = 0; break;
2299           case oLockOnce: opt.lock_once = 1; break;
2300           case oLockNever: disable_dotlock(); break;
2301           case oLockMultiple:
2302 #ifndef __riscos__
2303             opt.lock_once = 0;
2304 #else /* __riscos__ */
2305             riscos_not_implemented("lock-multiple");
2306 #endif /* __riscos__ */
2307             break;
2308           case oKeyServer:
2309             opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
2310                                               configname,configlineno);
2311             if(!opt.keyserver)
2312               log_error(_("could not parse keyserver URL\n"));
2313             break;
2314           case oKeyServerOptions:
2315             if(!parse_keyserver_options(pargs.r.ret_str))
2316               {
2317                 if(configname)
2318                   log_error(_("%s:%d: invalid keyserver options\n"),
2319                             configname,configlineno);
2320                 else
2321                   log_error(_("invalid keyserver options\n"));
2322               }
2323             break;
2324           case oImportOptions:
2325             if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
2326               {
2327                 if(configname)
2328                   log_error(_("%s:%d: invalid import options\n"),
2329                             configname,configlineno);
2330                 else
2331                   log_error(_("invalid import options\n"));
2332               }
2333             break;
2334           case oExportOptions:
2335             if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
2336               {
2337                 if(configname)
2338                   log_error(_("%s:%d: invalid export options\n"),
2339                             configname,configlineno);
2340                 else
2341                   log_error(_("invalid export options\n"));
2342               }
2343             break;
2344           case oListOptions:
2345             if(!parse_list_options(pargs.r.ret_str))
2346               {
2347                 if(configname)
2348                   log_error(_("%s:%d: invalid list options\n"),
2349                             configname,configlineno);
2350                 else
2351                   log_error(_("invalid list options\n"));
2352               }
2353             break;
2354           case oVerifyOptions:
2355             {
2356               struct parse_options vopts[]=
2357                 {
2358                   {"show-photos",VERIFY_SHOW_PHOTOS,NULL},
2359                   {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL},
2360                   {"show-notations",VERIFY_SHOW_NOTATIONS,NULL},
2361                   {"show-std-notations",VERIFY_SHOW_STD_NOTATIONS,NULL},
2362                   {"show-standard-notations",VERIFY_SHOW_STD_NOTATIONS,NULL},
2363                   {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL},
2364                   {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL},
2365                   {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL},
2366                   {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL},
2367                   {NULL,0,NULL}
2368                 };
2369
2370               if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
2371                 {
2372                   if(configname)
2373                     log_error(_("%s:%d: invalid verify options\n"),
2374                               configname,configlineno);
2375                   else
2376                     log_error(_("invalid verify options\n"));
2377                 }
2378             }
2379             break;
2380           case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
2381           case oExecPath:
2382             if(set_exec_path(pargs.r.ret_str,0))
2383               log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
2384             else
2385               opt.exec_path_set=1;
2386             break;
2387           case oSetNotation:
2388             add_notation_data( pargs.r.ret_str, 0 );
2389             add_notation_data( pargs.r.ret_str, 1 );
2390             break;
2391           case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
2392           case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
2393           case oShowNotation:
2394             deprecated_warning(configname,configlineno,"--show-notation",
2395                                "--list-options ","show-notations");
2396             deprecated_warning(configname,configlineno,"--show-notation",
2397                                "--verify-options ","show-notations");
2398             opt.list_options|=LIST_SHOW_NOTATIONS;
2399             opt.verify_options|=VERIFY_SHOW_NOTATIONS;
2400             break;
2401           case oNoShowNotation:
2402             deprecated_warning(configname,configlineno,"--no-show-notation",
2403                                "--list-options ","no-show-notations");
2404             deprecated_warning(configname,configlineno,"--no-show-notation",
2405                                "--verify-options ","no-show-notations");
2406             opt.list_options&=~LIST_SHOW_NOTATIONS;
2407             opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
2408             break;
2409           case oUtf8Strings: utf8_strings = 1; break;
2410           case oNoUtf8Strings: utf8_strings = 0; break;
2411           case oDisableCipherAlgo:
2412                 disable_cipher_algo( string_to_cipher_algo(pargs.r.ret_str) );
2413                 break;
2414           case oDisablePubkeyAlgo:
2415                 disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
2416                 break;
2417           case oNoSigCache: opt.no_sig_cache = 1; break;
2418           case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
2419           case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
2420           case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
2421           case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
2422           case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
2423           case oNoLiteral: opt.no_literal = 1; break;
2424           case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
2425           case oHonorHttpProxy:
2426                 add_to_strlist(&opt.keyserver_options.other,"http-proxy");
2427                 deprecated_warning(configname,configlineno,
2428                                    "--honor-http-proxy",
2429                                    "--keyserver-options ","http-proxy");
2430                 break;
2431           case oFastListMode: opt.fast_list_mode = 1; break;
2432           case oFixedListMode: opt.fixed_list_mode = 1; break;
2433           case oListOnly: opt.list_only=1; break;
2434           case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
2435           case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
2436           case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
2437           case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
2438           case oNoRandomSeedFile: use_random_seed = 0; break;
2439           case oAutoKeyRetrieve:
2440           case oNoAutoKeyRetrieve:
2441                 if(pargs.r_opt==oAutoKeyRetrieve)
2442                   opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
2443                 else
2444                   opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
2445
2446                 deprecated_warning(configname,configlineno,
2447                            pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
2448                                "--no-auto-key-retrieve","--keyserver-options ",
2449                            pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
2450                                "no-auto-key-retrieve");
2451                 break;
2452           case oShowSessionKey: opt.show_session_key = 1; break;
2453           case oOverrideSessionKey:
2454                 opt.override_session_key = pargs.r.ret_str;
2455                 break;
2456           case oMergeOnly:
2457                 deprecated_warning(configname,configlineno,"--merge-only",
2458                                    "--import-options ","merge-only");
2459                 opt.import_options|=IMPORT_MERGE_ONLY;
2460             break;
2461           case oAllowSecretKeyImport: /* obsolete */ break;
2462           case oTryAllSecrets: opt.try_all_secrets = 1; break;
2463           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
2464           case oEnableSpecialFilenames:
2465             iobuf_enable_special_filenames (1);
2466             break;
2467           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
2468           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
2469           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
2470           case oPreservePermissions: opt.preserve_permissions=1; break;
2471           case oDefaultPreferenceList:
2472             opt.def_preference_list = pargs.r.ret_str;
2473             break;
2474           case oPersonalCipherPreferences:
2475             pers_cipher_list=pargs.r.ret_str;
2476             break;
2477           case oPersonalDigestPreferences:
2478             pers_digest_list=pargs.r.ret_str;
2479             break;
2480           case oPersonalCompressPreferences:
2481             pers_compress_list=pargs.r.ret_str;
2482             break;
2483           case oDisplay: opt.display = pargs.r.ret_str; break;
2484           case oTTYname: opt.ttyname = pargs.r.ret_str; break;
2485           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
2486           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
2487           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
2488           case oGroup: add_group(pargs.r.ret_str); break;
2489           case oUnGroup: rm_group(pargs.r.ret_str); break;
2490           case oNoGroups:
2491             while(opt.grouplist)
2492               {
2493                 struct groupitem *iter=opt.grouplist;
2494                 free_strlist(iter->values);
2495                 opt.grouplist=opt.grouplist->next;
2496                 m_free(iter);
2497               }
2498             break;
2499           case oStrict: opt.strict=1; log_set_strict(1); break;
2500           case oNoStrict: opt.strict=0; log_set_strict(0); break;
2501           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
2502           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
2503           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
2504           case oMultifile: multifile=1; break;
2505           case oKeyidFormat:
2506             if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
2507               opt.keyid_format=KF_SHORT;
2508             else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
2509               opt.keyid_format=KF_LONG;
2510             else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
2511               opt.keyid_format=KF_0xSHORT;
2512             else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
2513               opt.keyid_format=KF_0xLONG;
2514             else
2515               log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
2516             break;
2517
2518           default : pargs.err = configfp? 1:2; break;
2519           }
2520       }
2521
2522
2523     if( configfp ) {
2524         fclose( configfp );
2525         configfp = NULL;
2526         /* Remember the first config file name. */
2527         if (!save_configname)
2528           save_configname = configname;
2529         else
2530           m_free(configname);
2531         configname = NULL;
2532         goto next_pass;
2533     }
2534     m_free( configname ); configname = NULL;
2535     if( log_get_errorcount(0) )
2536         g10_exit(2);
2537
2538     /* The command --gpgconf-list is pretty simple and may be called
2539        directly after the option parsing. */
2540     if (cmd == aGPGConfList)
2541       {
2542         gpgconf_list (save_configname);
2543         g10_exit (0);
2544       }
2545     m_free (save_configname);
2546
2547     if( nogreeting )
2548         greeting = 0;
2549
2550     if( greeting ) {
2551         fprintf(stderr, "%s %s; %s\n",
2552                         strusage(11), strusage(13), strusage(14) );
2553         fprintf(stderr, "%s\n", strusage(15) );
2554     }
2555 #ifdef IS_DEVELOPMENT_VERSION
2556     if( !opt.batch )
2557       {
2558         const char *s;
2559
2560         if((s=strusage(20)))
2561           log_info("%s\n",s);
2562         if((s=strusage(21)))
2563           log_info("%s\n",s);
2564         if((s=strusage(22)))
2565           log_info("%s\n",s);
2566       }
2567 #endif
2568
2569     if (opt.verbose > 2)
2570         log_info ("using character set `%s'\n", get_native_charset ());
2571
2572     if( may_coredump && !opt.quiet )
2573         log_info(_("WARNING: program may create a core file!\n"));
2574
2575     if (eyes_only) {
2576       if (opt.set_filename)
2577           log_info(_("WARNING: %s overrides %s\n"),
2578                    "--for-your-eyes-only","--set-filename");
2579
2580       opt.set_filename="_CONSOLE";
2581     }
2582
2583     if (opt.no_literal) {
2584         log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
2585         if (opt.textmode)
2586             log_error(_("%s not allowed with %s!\n"),
2587                        "--textmode", "--no-literal" );
2588         if (opt.set_filename)
2589             log_error(_("%s makes no sense with %s!\n"),
2590                         eyes_only?"--for-your-eyes-only":"--set-filename",
2591                         "--no-literal" );
2592     }
2593
2594     if (opt.set_filesize)
2595         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2596     if( opt.batch )
2597         tty_batchmode( 1 );
2598
2599     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
2600
2601     if(require_secmem && !got_secmem)
2602       {
2603         log_info(_("will not run with insecure memory due to %s\n"),
2604                  "--require-secmem");
2605         g10_exit(2);
2606       }
2607
2608     set_debug();
2609
2610     /* Do these after the switch(), so they can override settings. */
2611     if(PGP2)
2612       {
2613         int unusable=0;
2614
2615         if(cmd==aSign && !detached_sig)
2616           {
2617             log_info(_("you can only make detached or clear signatures "
2618                        "while in --pgp2 mode\n"));
2619             unusable=1;
2620           }
2621         else if(cmd==aSignEncr || cmd==aSignSym)
2622           {
2623             log_info(_("you can't sign and encrypt at the "
2624                        "same time while in --pgp2 mode\n"));
2625             unusable=1;
2626           }
2627         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
2628           {
2629             log_info(_("you must use files (and not a pipe) when "
2630                        "working with --pgp2 enabled.\n"));
2631             unusable=1;
2632           }
2633         else if(cmd==aEncr || cmd==aSym)
2634           {
2635             /* Everything else should work without IDEA (except using
2636                a secret key encrypted with IDEA and setting an IDEA
2637                preference, but those have their own error
2638                messages). */
2639
2640             if(check_cipher_algo(CIPHER_ALGO_IDEA))
2641               {
2642                 log_info(_("encrypting a message in --pgp2 mode requires "
2643                            "the IDEA cipher\n"));
2644                 idea_cipher_warn(1);
2645                 unusable=1;
2646               }
2647             else if(cmd==aSym)
2648               {
2649                 /* This only sets IDEA for symmetric encryption
2650                    since it is set via select_algo_from_prefs for
2651                    pk encryption. */
2652                 m_free(def_cipher_string);
2653                 def_cipher_string = m_strdup("idea");
2654               }
2655
2656             /* PGP2 can't handle the output from the textmode
2657                filter, so we disable it for anything that could
2658                create a literal packet (only encryption and
2659                symmetric encryption, since we disable signing
2660                above). */
2661             if(!unusable)
2662               opt.textmode=0;
2663           }
2664
2665         if(unusable)
2666           compliance_failure();
2667         else
2668           {
2669             opt.force_v4_certs = 0;
2670             opt.sk_comments = 0;
2671             opt.escape_from = 1;
2672             opt.force_v3_sigs = 1;
2673             opt.pgp2_workarounds = 1;
2674             opt.ask_sig_expire = 0;
2675             opt.ask_cert_expire = 0;
2676             m_free(def_digest_string);
2677             def_digest_string = m_strdup("md5");
2678             m_free(s2k_digest_string);
2679             s2k_digest_string = m_strdup("md5");
2680             opt.compress_algo = COMPRESS_ALGO_ZIP;
2681           }
2682       }
2683     else if(PGP6)
2684       {
2685         opt.sk_comments=0;
2686         opt.escape_from=1;
2687         opt.force_v3_sigs=1;
2688         opt.ask_sig_expire=0;
2689       }
2690     else if(PGP7)
2691       {
2692         opt.sk_comments=0;
2693         opt.escape_from=1;
2694         opt.force_v3_sigs=1;
2695         opt.ask_sig_expire=0;
2696       }
2697     else if(PGP8)
2698       {
2699         opt.escape_from=1;
2700       }
2701
2702     /* must do this after dropping setuid, because string_to...
2703      * may try to load an module */
2704     if( def_cipher_string ) {
2705         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
2706         if(opt.def_cipher_algo==0 &&
2707            (ascii_strcasecmp(def_cipher_string,"idea")==0
2708             || ascii_strcasecmp(def_cipher_string,"s1")==0))
2709           idea_cipher_warn(1);
2710         m_free(def_cipher_string); def_cipher_string = NULL;
2711         if( check_cipher_algo(opt.def_cipher_algo) )
2712             log_error(_("selected cipher algorithm is invalid\n"));
2713     }
2714     if( def_digest_string ) {
2715         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
2716         m_free(def_digest_string); def_digest_string = NULL;
2717         if( check_digest_algo(opt.def_digest_algo) )
2718             log_error(_("selected digest algorithm is invalid\n"));
2719     }
2720     if( compress_algo_string ) {
2721         opt.compress_algo = string_to_compress_algo(compress_algo_string);
2722         m_free(compress_algo_string); compress_algo_string = NULL;
2723         if( check_compress_algo(opt.compress_algo) )
2724             log_error(_("selected compression algorithm is invalid\n"));
2725     }
2726     if( cert_digest_string ) {
2727         opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
2728         m_free(cert_digest_string); cert_digest_string = NULL;
2729         if( check_digest_algo(opt.cert_digest_algo) )
2730             log_error(_("selected certification digest algorithm is invalid\n"));
2731     }
2732     if( s2k_cipher_string ) {
2733         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
2734         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
2735         if( check_cipher_algo(opt.s2k_cipher_algo) )
2736             log_error(_("selected cipher algorithm is invalid\n"));
2737     }
2738     if( s2k_digest_string ) {
2739         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
2740         m_free(s2k_digest_string); s2k_digest_string = NULL;
2741         if( check_digest_algo(opt.s2k_digest_algo) )
2742             log_error(_("selected digest algorithm is invalid\n"));
2743     }
2744     if( opt.completes_needed < 1 )
2745       log_error(_("completes-needed must be greater than 0\n"));
2746     if( opt.marginals_needed < 2 )
2747       log_error(_("marginals-needed must be greater than 1\n"));
2748     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
2749       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
2750     if(opt.def_cert_level<0 || opt.def_cert_level>3)
2751       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
2752     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
2753       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
2754     switch( opt.s2k_mode ) {
2755       case 0:
2756         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
2757         break;
2758       case 1: case 3: break;
2759       default:
2760         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
2761     }
2762
2763     /* This isn't actually needed, but does serve to error out if the
2764        string is invalid. */
2765     if(opt.def_preference_list &&
2766         keygen_set_std_prefs(opt.def_preference_list,0))
2767       log_error(_("invalid default preferences\n"));
2768
2769     /* We provide defaults for the personal digest list.  This is
2770        SHA-1. */
2771     if(!pers_digest_list)
2772       pers_digest_list="h2";
2773
2774     if(pers_cipher_list &&
2775        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
2776       log_error(_("invalid personal cipher preferences\n"));
2777
2778     if(pers_digest_list &&
2779        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
2780       log_error(_("invalid personal digest preferences\n"));
2781
2782     if(pers_compress_list &&
2783        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
2784       log_error(_("invalid personal compress preferences\n"));
2785
2786     /* We don't support all possible commands with multifile yet */
2787     if(multifile)
2788       {
2789         char *cmdname;
2790
2791         switch(cmd)
2792           {
2793           case aSign:
2794             cmdname="--sign";
2795             break;
2796           case aClearsign:
2797             cmdname="--clearsign";
2798             break;
2799           case aDetachedSign:
2800             cmdname="--detach-sign";
2801             break;
2802           case aSym:
2803             cmdname="--symmetric";
2804             break;
2805           case aEncrSym:
2806             cmdname="--symmetric --encrypt";
2807             break;
2808           case aStore:
2809             cmdname="--store";
2810             break;
2811           default:
2812             cmdname=NULL;
2813             break;
2814           }
2815
2816         if(cmdname)
2817           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
2818       }
2819
2820     if( log_get_errorcount(0) )
2821         g10_exit(2);
2822
2823     if(opt.compress_level==0)
2824       opt.compress_algo=COMPRESS_ALGO_NONE;
2825
2826     /* Check our chosen algorithms against the list of legal
2827        algorithms. */
2828
2829     if(!GNUPG)
2830       {
2831         const char *badalg=NULL;
2832         preftype_t badtype=PREFTYPE_NONE;
2833
2834         if(opt.def_cipher_algo
2835            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
2836           {
2837             badalg=cipher_algo_to_string(opt.def_cipher_algo);
2838             badtype=PREFTYPE_SYM;
2839           }
2840         else if(opt.def_digest_algo
2841                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
2842           {
2843             badalg=digest_algo_to_string(opt.def_digest_algo);
2844             badtype=PREFTYPE_HASH;
2845           }
2846         else if(opt.cert_digest_algo
2847                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
2848           {
2849             badalg=digest_algo_to_string(opt.cert_digest_algo);
2850             badtype=PREFTYPE_HASH;
2851           }
2852         else if(opt.compress_algo!=-1
2853                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
2854           {
2855             badalg=compress_algo_to_string(opt.compress_algo);
2856             badtype=PREFTYPE_ZIP;
2857           }
2858
2859         if(badalg)
2860           {
2861             switch(badtype)
2862               {
2863               case PREFTYPE_SYM:
2864                 log_info(_("you may not use cipher algorithm `%s'"
2865                            " while in %s mode\n"),
2866                          badalg,compliance_option_string());
2867                 break;
2868               case PREFTYPE_HASH:
2869                 log_info(_("you may not use digest algorithm `%s'"
2870                            " while in %s mode\n"),
2871                          badalg,compliance_option_string());
2872                 break;
2873               case PREFTYPE_ZIP:
2874                 log_info(_("you may not use compression algorithm `%s'"
2875                            " while in %s mode\n"),
2876                          badalg,compliance_option_string());
2877                 break;
2878               default:
2879                 BUG();
2880               }
2881
2882             compliance_failure();
2883           }
2884       }
2885
2886     /* set the random seed file */
2887     if( use_random_seed ) {
2888         char *p = make_filename(opt.homedir, "random_seed", NULL );
2889         set_random_seed_file(p);
2890         if (!access (p, F_OK))
2891           register_secured_file (p);
2892         m_free(p);
2893     }
2894
2895     if( !cmd && opt.fingerprint && !with_fpr ) {
2896         set_cmd( &cmd, aListKeys);
2897     }
2898
2899     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
2900         if( cmd == aKModeC ) {
2901             opt.fingerprint = 1;
2902             cmd = aKMode;
2903         }
2904         opt.list_sigs = 0;
2905         if( opt.verbose > 2 )
2906             opt.check_sigs++;
2907         if( opt.verbose > 1 )
2908             opt.list_sigs++;
2909
2910         opt.verbose = opt.verbose > 1;
2911         g10_opt_verbose = opt.verbose;
2912     }
2913
2914     /* kludge to let -sat generate a clear text signature */
2915     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
2916         cmd = aClearsign;
2917
2918     if( opt.verbose > 1 )
2919         set_packet_list_mode(1);
2920
2921     /* Add the keyrings, but not for some special commands and not in
2922        case of "-kvv userid keyring".  Also avoid adding the secret
2923        keyring for a couple of commands to avoid unneeded access in
2924        case the secrings are stored on a floppy.
2925        
2926        We always need to add the keyrings if we are running under
2927        SELinux, thi is so that the rings are added to the list of
2928        secured files. */
2929     if( ALWAYS_ADD_KEYRINGS 
2930         || (cmd != aDeArmor && cmd != aEnArmor
2931             && !(cmd == aKMode && argc == 2 )) ) 
2932       {
2933         if (ALWAYS_ADD_KEYRINGS
2934             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
2935                 && cmd != aVerify && cmd != aSym))
2936           {
2937             if (!sec_nrings || default_keyring) /* add default secret rings */
2938               keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
2939             for (sl = sec_nrings; sl; sl = sl->next)
2940               keydb_add_resource ( sl->d, 0, 1 );
2941           }
2942         if( !nrings || default_keyring )  /* add default ring */
2943             keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
2944         for(sl = nrings; sl; sl = sl->next )
2945             keydb_add_resource ( sl->d, sl->flags, 0 );
2946       }
2947     FREE_STRLIST(nrings);
2948     FREE_STRLIST(sec_nrings);
2949
2950
2951     if( pwfd != -1 )  /* read the passphrase now. */
2952         read_passphrase_from_fd( pwfd );
2953
2954     fname = argc? *argv : NULL;
2955
2956     switch( cmd ) {
2957       case aPrimegen:
2958       case aPrintMD:
2959       case aPrintMDs:
2960       case aGenRandom:
2961       case aDeArmor:
2962       case aEnArmor:
2963       case aFixTrustDB:
2964         break;
2965       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
2966       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
2967       default: rc = setup_trustdb(1, trustdb_name ); break;
2968     }
2969     if( rc )
2970         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
2971
2972
2973     switch (cmd)
2974       {
2975       case aStore: 
2976       case aSym:  
2977       case aSign: 
2978       case aSignSym: 
2979       case aClearsign: 
2980         if (!opt.quiet && any_explicit_recipient)
2981           log_info (_("WARNING: recipients (-r) given "
2982                       "without using public key encryption\n"));
2983         break;
2984       default:
2985         break;
2986       }
2987
2988     switch( cmd )
2989       {
2990       case aStore: /* only store the file */
2991         if( argc > 1 )
2992             wrong_args(_("--store [filename]"));
2993         if( (rc = encode_store(fname)) )
2994             log_error ("storing `%s' failed: %s\n",
2995                        print_fname_stdin(fname),g10_errstr(rc) );
2996         break;
2997       case aSym: /* encrypt the given file only with the symmetric cipher */
2998         if( argc > 1 )
2999             wrong_args(_("--symmetric [filename]"));
3000         if( (rc = encode_symmetric(fname)) )
3001             log_error (_("symmetric encryption of `%s' failed: %s\n"),
3002                         print_fname_stdin(fname),g10_errstr(rc) );
3003         break;
3004
3005       case aEncr: /* encrypt the given file */
3006         if(multifile)
3007           encode_crypt_files(argc, argv, remusr);
3008         else
3009           {
3010             if( argc > 1 )
3011               wrong_args(_("--encrypt [filename]"));
3012             if( (rc = encode_crypt(fname,remusr,0)) )
3013               log_error("%s: encryption failed: %s\n",
3014                         print_fname_stdin(fname), g10_errstr(rc) );
3015           }
3016         break;
3017
3018       case aEncrSym:
3019         /* This works with PGP 8 in the sense that it acts just like a
3020            symmetric message.  It doesn't work at all with 2 or 6.  It
3021            might work with 7, but alas, I don't have a copy to test
3022            with right now. */
3023         if( argc > 1 )
3024           wrong_args(_("--symmetric --encrypt [filename]"));
3025         else if(opt.s2k_mode==0)
3026           log_error(_("you cannot use --symmetric --encrypt"
3027                       " with --s2k-mode 0\n"));
3028         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3029           log_error(_("you cannot use --symmetric --encrypt"
3030                       " while in %s mode\n"),compliance_option_string());
3031         else
3032           {
3033             if( (rc = encode_crypt(fname,remusr,1)) )
3034               log_error("%s: encryption failed: %s\n",
3035                         print_fname_stdin(fname), g10_errstr(rc) );
3036           }
3037         break;
3038
3039       case aSign: /* sign the given file */
3040         sl = NULL;
3041         if( detached_sig ) { /* sign all files */
3042             for( ; argc; argc--, argv++ )
3043                 add_to_strlist( &sl, *argv );
3044         }
3045         else {
3046             if( argc > 1 )
3047                 wrong_args(_("--sign [filename]"));
3048             if( argc ) {
3049                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3050                 strcpy(sl->d, fname);
3051             }
3052         }
3053         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
3054             log_error("signing failed: %s\n", g10_errstr(rc) );
3055         free_strlist(sl);
3056         break;
3057
3058       case aSignEncr: /* sign and encrypt the given file */
3059         if( argc > 1 )
3060             wrong_args(_("--sign --encrypt [filename]"));
3061         if( argc ) {
3062             sl = m_alloc_clear( sizeof *sl + strlen(fname));
3063             strcpy(sl->d, fname);
3064         }
3065         else
3066             sl = NULL;
3067         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
3068             log_error("%s: sign+encrypt failed: %s\n",
3069                       print_fname_stdin(fname), g10_errstr(rc) );
3070         free_strlist(sl);
3071         break;
3072
3073       case aSignEncrSym: /* sign and encrypt the given file */
3074         if( argc > 1 )
3075             wrong_args(_("--symmetric --sign --encrypt [filename]"));
3076         else if(opt.s2k_mode==0)
3077           log_error(_("you cannot use --symmetric --sign --encrypt"
3078                       " with --s2k-mode 0\n"));
3079         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3080           log_error(_("you cannot use --symmetric --sign --encrypt"
3081                       " while in %s mode\n"),compliance_option_string());
3082         else
3083           {
3084             if( argc )
3085               {
3086                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3087                 strcpy(sl->d, fname);
3088               }
3089             else
3090               sl = NULL;
3091             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
3092               log_error("%s: symmetric+sign+encrypt failed: %s\n",
3093                         print_fname_stdin(fname), g10_errstr(rc) );
3094             free_strlist(sl);
3095           }
3096         break;
3097
3098       case aSignSym: /* sign and conventionally encrypt the given file */
3099         if (argc > 1)
3100             wrong_args(_("--sign --symmetric [filename]"));
3101         rc = sign_symencrypt_file (fname, locusr);
3102         if (rc)
3103             log_error("%s: sign+symmetric failed: %s\n",
3104                       print_fname_stdin(fname), g10_errstr(rc) );
3105         break;
3106
3107       case aClearsign: /* make a clearsig */
3108         if( argc > 1 )
3109             wrong_args(_("--clearsign [filename]"));
3110         if( (rc = clearsign_file(fname, locusr, NULL)) )
3111             log_error("%s: clearsign failed: %s\n",
3112                       print_fname_stdin(fname), g10_errstr(rc) );
3113         break;
3114
3115       case aVerify:
3116         if(multifile)
3117           {
3118             if( (rc = verify_files( argc, argv ) ))
3119               log_error("verify files failed: %s\n", g10_errstr(rc) );
3120           }
3121         else
3122           {
3123             if( (rc = verify_signatures( argc, argv ) ))
3124               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
3125           }
3126         break;
3127
3128       case aDecrypt:
3129         if(multifile)
3130           decrypt_messages(argc, argv);
3131         else
3132           {
3133             if( argc > 1 )
3134               wrong_args(_("--decrypt [filename]"));
3135             if( (rc = decrypt_message( fname ) ))
3136               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
3137           }
3138         break;
3139             
3140       case aSignKey:
3141         if( argc != 1 )
3142           wrong_args(_("--sign-key user-id"));
3143         /* fall through */
3144       case aLSignKey:
3145         if( argc != 1 )
3146           wrong_args(_("--lsign-key user-id"));
3147         /* fall through */
3148
3149         sl=NULL;
3150
3151         if(cmd==aSignKey)
3152           append_to_strlist(&sl,"sign");
3153         else if(cmd==aLSignKey)
3154           append_to_strlist(&sl,"lsign");
3155         else
3156           BUG();
3157
3158         append_to_strlist( &sl, "save" );
3159         username = make_username( fname );
3160         keyedit_menu(fname, locusr, sl, 0, 0 );
3161         m_free(username);
3162         free_strlist(sl);
3163         break;
3164
3165       case aEditKey: /* Edit a key signature */
3166         if( !argc )
3167             wrong_args(_("--edit-key user-id [commands]"));
3168         username = make_username( fname );
3169         if( argc > 1 ) {
3170             sl = NULL;
3171             for( argc--, argv++ ; argc; argc--, argv++ )
3172                 append_to_strlist( &sl, *argv );
3173             keyedit_menu( username, locusr, sl, 0, 1 );
3174             free_strlist(sl);
3175         }
3176         else
3177             keyedit_menu(username, locusr, NULL, 0, 1 );
3178         m_free(username);
3179         break;
3180
3181       case aDeleteKeys:
3182       case aDeleteSecretKeys:
3183       case aDeleteSecretAndPublicKeys:
3184         sl = NULL;
3185         /* I'm adding these in reverse order as add_to_strlist2
3186            reverses them again, and it's easier to understand in the
3187            proper order :) */
3188         for( ; argc; argc-- )
3189           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
3190         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
3191         free_strlist(sl);
3192         break;
3193
3194       case aCheckKeys:
3195         opt.check_sigs = 1;
3196       case aListSigs:
3197         opt.list_sigs = 1;
3198       case aListKeys:
3199         sl = NULL;
3200         for( ; argc; argc--, argv++ )
3201             add_to_strlist2( &sl, *argv, utf8_strings );
3202         public_key_list( sl );
3203         free_strlist(sl);
3204         break;
3205       case aListSecretKeys:
3206         sl = NULL;
3207         for( ; argc; argc--, argv++ )
3208             add_to_strlist2( &sl, *argv, utf8_strings );
3209         secret_key_list( sl );
3210         free_strlist(sl);
3211         break;
3212
3213       case aKMode: /* list keyring -- NOTE: This will be removed soon */
3214         if( argc < 2 ) { /* -kv [userid] */
3215             sl = NULL;
3216             if (argc && **argv)
3217                 add_to_strlist2( &sl, *argv, utf8_strings );
3218             public_key_list( sl );
3219             free_strlist(sl);
3220         }
3221         else if( argc == 2 ) { /* -kv userid keyring */
3222             if( access( argv[1], R_OK ) ) {
3223                 log_error(_("can't open `%s': %s\n"),
3224                                print_fname_stdin(argv[1]), strerror(errno));
3225             }
3226             else {
3227                 /* add keyring (default keyrings are not registered in this
3228                  * special case */
3229                 keydb_add_resource( argv[1], 0, 0 );
3230                 sl = NULL;
3231                 if (**argv)
3232                     add_to_strlist2( &sl, *argv, utf8_strings );
3233                 public_key_list( sl );
3234                 free_strlist(sl);
3235             }
3236         }
3237         else
3238             wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
3239         break;
3240
3241       case aKeygen: /* generate a key */
3242         if( opt.batch ) {
3243             if( argc > 1 )
3244                 wrong_args("--gen-key [parameterfile]");
3245             generate_keypair( argc? *argv : NULL, NULL, NULL );
3246         }
3247         else {
3248             if( argc )
3249                 wrong_args("--gen-key");
3250             generate_keypair(NULL, NULL, NULL);
3251         }
3252         break;
3253
3254       case aFastImport:
3255         opt.import_options |= IMPORT_FAST;
3256       case aImport:
3257         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3258         break;
3259
3260       case aExport:
3261       case aSendKeys:
3262       case aRecvKeys:
3263         sl = NULL;
3264         for( ; argc; argc--, argv++ )
3265             add_to_strlist2( &sl, *argv, utf8_strings );
3266         if( cmd == aSendKeys )
3267             rc=keyserver_export( sl );
3268         else if( cmd == aRecvKeys )
3269             rc=keyserver_import( sl );
3270         else
3271             rc=export_pubkeys( sl, opt.export_options );
3272         if(rc)
3273           {
3274             if(cmd==aSendKeys)
3275               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3276             else if(cmd==aRecvKeys)
3277               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3278             else
3279               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3280           }
3281         free_strlist(sl);
3282         break;
3283
3284      case aSearchKeys:
3285         sl = NULL;
3286         for( ; argc; argc--, argv++ )
3287           append_to_strlist2( &sl, *argv, utf8_strings );
3288         rc=keyserver_search( sl );
3289         if(rc)
3290           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3291         free_strlist(sl);
3292         break;
3293
3294       case aRefreshKeys:
3295         sl = NULL;
3296         for( ; argc; argc--, argv++ )
3297             add_to_strlist2( &sl, *argv, utf8_strings );
3298         rc=keyserver_refresh(sl);
3299         if(rc)
3300           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3301         free_strlist(sl);
3302         break;
3303
3304       case aExportSecret:
3305         sl = NULL;
3306         for( ; argc; argc--, argv++ )
3307             add_to_strlist2( &sl, *argv, utf8_strings );
3308         export_seckeys( sl );
3309         free_strlist(sl);
3310         break;
3311
3312       case aExportSecretSub:
3313         sl = NULL;
3314         for( ; argc; argc--, argv++ )
3315             add_to_strlist2( &sl, *argv, utf8_strings );
3316         export_secsubkeys( sl );
3317         free_strlist(sl);
3318         break;
3319
3320       case aGenRevoke:
3321         if( argc != 1 )
3322             wrong_args("--gen-revoke user-id");
3323         username =  make_username(*argv);
3324         gen_revoke( username );
3325         m_free( username );
3326         break;
3327
3328       case aDesigRevoke:
3329         if( argc != 1 )
3330             wrong_args("--desig-revoke user-id");
3331         username =  make_username(*argv);
3332         gen_desig_revoke( username );
3333         m_free( username );
3334         break;
3335
3336       case aDeArmor:
3337         if( argc > 1 )
3338             wrong_args("--dearmor [file]");
3339         rc = dearmor_file( argc? *argv: NULL );
3340         if( rc )
3341             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3342         break;
3343
3344       case aEnArmor:
3345         if( argc > 1 )
3346             wrong_args("--enarmor [file]");
3347         rc = enarmor_file( argc? *argv: NULL );
3348         if( rc )
3349             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3350         break;
3351
3352
3353       case aPrimegen:
3354         {   int mode = argc < 2 ? 0 : atoi(*argv);
3355
3356             if( mode == 1 && argc == 2 ) {
3357                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3358             }
3359             else if( mode == 2 && argc == 3 ) {
3360                 mpi_print( stdout, generate_elg_prime(
3361                                              0, atoi(argv[1]),
3362                                              atoi(argv[2]), NULL,NULL ), 1);
3363             }
3364             else if( mode == 3 && argc == 3 ) {
3365                 MPI *factors;
3366                 mpi_print( stdout, generate_elg_prime(
3367                                              1, atoi(argv[1]),
3368                                              atoi(argv[2]), NULL,&factors ), 1);
3369                 putchar('\n');
3370                 mpi_print( stdout, factors[0], 1 ); /* print q */
3371             }
3372             else if( mode == 4 && argc == 3 ) {
3373                 MPI g = mpi_alloc(1);
3374                 mpi_print( stdout, generate_elg_prime(
3375                                                  0, atoi(argv[1]),
3376                                                  atoi(argv[2]), g, NULL ), 1);
3377                 putchar('\n');
3378                 mpi_print( stdout, g, 1 );
3379                 mpi_free(g);
3380             }
3381             else
3382                 wrong_args("--gen-prime mode bits [qbits] ");
3383             putchar('\n');
3384         }
3385         break;
3386
3387       case aGenRandom:
3388         {
3389             int level = argc ? atoi(*argv):0;
3390             int count = argc > 1 ? atoi(argv[1]): 0;
3391             int endless = !count;
3392
3393             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3394                 wrong_args("--gen-random 0|1|2 [count]");
3395
3396             while( endless || count ) {
3397                 byte *p;
3398                 /* Wee need a multiple of 3, so that in case of
3399                    armored output we get a correct string.  No
3400                    linefolding is done, as it is best to levae this to
3401                    other tools */
3402                 size_t n = !endless && count < 99? count : 99;
3403
3404                 p = get_random_bits( n*8, level, 0);
3405 #ifdef HAVE_DOSISH_SYSTEM
3406                 setmode ( fileno(stdout), O_BINARY );
3407 #endif
3408                 if (opt.armor) {
3409                     char *tmp = make_radix64_string (p, n);
3410                     fputs (tmp, stdout);
3411                     m_free (tmp);
3412                     if (n%3 == 1)
3413                       putchar ('=');
3414                     if (n%3)
3415                       putchar ('=');
3416                 } else {
3417                     fwrite( p, n, 1, stdout );
3418                 }
3419                 m_free(p);
3420                 if( !endless )
3421                     count -= n;
3422             }
3423             if (opt.armor)
3424                 putchar ('\n');
3425         }
3426         break;
3427
3428       case aPrintMD:
3429         if( argc < 1)
3430             wrong_args("--print-md algo [files]");
3431         {
3432             int all_algos = (**argv=='*' && !(*argv)[1]);
3433             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3434
3435             if( !algo && !all_algos )
3436                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3437             else {
3438                 argc--; argv++;
3439                 if( !argc )
3440                     print_mds(NULL, algo);
3441                 else {
3442                     for(; argc; argc--, argv++ )
3443                         print_mds(*argv, algo);
3444                 }
3445             }
3446         }
3447         break;
3448
3449       case aPrintMDs: /* old option */
3450         if( !argc )
3451             print_mds(NULL,0);
3452         else {
3453             for(; argc; argc--, argv++ )
3454                 print_mds(*argv,0);
3455         }
3456         break;
3457
3458       case aListTrustDB:
3459         if( !argc )
3460             list_trustdb(NULL);
3461         else {
3462             for( ; argc; argc--, argv++ )
3463                 list_trustdb( *argv );
3464         }
3465         break;
3466
3467       case aUpdateTrustDB:
3468         if( argc )
3469             wrong_args("--update-trustdb");
3470         update_trustdb();
3471         break;
3472
3473       case aCheckTrustDB:
3474         /* Old versions allowed for arguments - ignore them */
3475         check_trustdb();
3476         break;
3477
3478       case aFixTrustDB:
3479         log_error("this command is not yet implemented.\n");
3480         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3481         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3482         break;
3483
3484       case aListTrustPath:
3485         if( !argc )
3486             wrong_args("--list-trust-path <user-ids>");
3487         for( ; argc; argc--, argv++ ) {
3488             username = make_username( *argv );
3489             list_trust_path( username );
3490             m_free(username);
3491         }
3492         break;
3493
3494       case aExportOwnerTrust:
3495         if( argc )
3496             wrong_args("--export-ownertrust");
3497         export_ownertrust();
3498         break;
3499
3500       case aImportOwnerTrust:
3501         if( argc > 1 )
3502             wrong_args("--import-owne