Changes to make use of code taken from libassuan. This replaces the
[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))
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 #ifndef ENABLE_AGENT_SUPPORT   
2595     if (opt.use_agent) {
2596       log_info(_("NOTE: %s is not available in this version\n"),
2597                "--use-agent");
2598       opt.use_agent = 0;
2599     }
2600 #endif /*!ENABLE_AGENT_SUPPORT*/
2601
2602     if (opt.set_filesize)
2603         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2604     if( opt.batch )
2605         tty_batchmode( 1 );
2606
2607     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
2608
2609     if(require_secmem && !got_secmem)
2610       {
2611         log_info(_("will not run with insecure memory due to %s\n"),
2612                  "--require-secmem");
2613         g10_exit(2);
2614       }
2615
2616     set_debug();
2617
2618     /* Do these after the switch(), so they can override settings. */
2619     if(PGP2)
2620       {
2621         int unusable=0;
2622
2623         if(cmd==aSign && !detached_sig)
2624           {
2625             log_info(_("you can only make detached or clear signatures "
2626                        "while in --pgp2 mode\n"));
2627             unusable=1;
2628           }
2629         else if(cmd==aSignEncr || cmd==aSignSym)
2630           {
2631             log_info(_("you can't sign and encrypt at the "
2632                        "same time while in --pgp2 mode\n"));
2633             unusable=1;
2634           }
2635         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
2636           {
2637             log_info(_("you must use files (and not a pipe) when "
2638                        "working with --pgp2 enabled.\n"));
2639             unusable=1;
2640           }
2641         else if(cmd==aEncr || cmd==aSym)
2642           {
2643             /* Everything else should work without IDEA (except using
2644                a secret key encrypted with IDEA and setting an IDEA
2645                preference, but those have their own error
2646                messages). */
2647
2648             if(check_cipher_algo(CIPHER_ALGO_IDEA))
2649               {
2650                 log_info(_("encrypting a message in --pgp2 mode requires "
2651                            "the IDEA cipher\n"));
2652                 idea_cipher_warn(1);
2653                 unusable=1;
2654               }
2655             else if(cmd==aSym)
2656               {
2657                 /* This only sets IDEA for symmetric encryption
2658                    since it is set via select_algo_from_prefs for
2659                    pk encryption. */
2660                 m_free(def_cipher_string);
2661                 def_cipher_string = m_strdup("idea");
2662               }
2663
2664             /* PGP2 can't handle the output from the textmode
2665                filter, so we disable it for anything that could
2666                create a literal packet (only encryption and
2667                symmetric encryption, since we disable signing
2668                above). */
2669             if(!unusable)
2670               opt.textmode=0;
2671           }
2672
2673         if(unusable)
2674           compliance_failure();
2675         else
2676           {
2677             opt.force_v4_certs = 0;
2678             opt.sk_comments = 0;
2679             opt.escape_from = 1;
2680             opt.force_v3_sigs = 1;
2681             opt.pgp2_workarounds = 1;
2682             opt.ask_sig_expire = 0;
2683             opt.ask_cert_expire = 0;
2684             m_free(def_digest_string);
2685             def_digest_string = m_strdup("md5");
2686             m_free(s2k_digest_string);
2687             s2k_digest_string = m_strdup("md5");
2688             opt.compress_algo = COMPRESS_ALGO_ZIP;
2689           }
2690       }
2691     else if(PGP6)
2692       {
2693         opt.sk_comments=0;
2694         opt.escape_from=1;
2695         opt.force_v3_sigs=1;
2696         opt.ask_sig_expire=0;
2697       }
2698     else if(PGP7)
2699       {
2700         opt.sk_comments=0;
2701         opt.escape_from=1;
2702         opt.force_v3_sigs=1;
2703         opt.ask_sig_expire=0;
2704       }
2705     else if(PGP8)
2706       {
2707         opt.escape_from=1;
2708       }
2709
2710     /* must do this after dropping setuid, because string_to...
2711      * may try to load an module */
2712     if( def_cipher_string ) {
2713         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
2714         if(opt.def_cipher_algo==0 &&
2715            (ascii_strcasecmp(def_cipher_string,"idea")==0
2716             || ascii_strcasecmp(def_cipher_string,"s1")==0))
2717           idea_cipher_warn(1);
2718         m_free(def_cipher_string); def_cipher_string = NULL;
2719         if( check_cipher_algo(opt.def_cipher_algo) )
2720             log_error(_("selected cipher algorithm is invalid\n"));
2721     }
2722     if( def_digest_string ) {
2723         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
2724         m_free(def_digest_string); def_digest_string = NULL;
2725         if( check_digest_algo(opt.def_digest_algo) )
2726             log_error(_("selected digest algorithm is invalid\n"));
2727     }
2728     if( compress_algo_string ) {
2729         opt.compress_algo = string_to_compress_algo(compress_algo_string);
2730         m_free(compress_algo_string); compress_algo_string = NULL;
2731         if( check_compress_algo(opt.compress_algo) )
2732             log_error(_("selected compression algorithm is invalid\n"));
2733     }
2734     if( cert_digest_string ) {
2735         opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
2736         m_free(cert_digest_string); cert_digest_string = NULL;
2737         if( check_digest_algo(opt.cert_digest_algo) )
2738             log_error(_("selected certification digest algorithm is invalid\n"));
2739     }
2740     if( s2k_cipher_string ) {
2741         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
2742         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
2743         if( check_cipher_algo(opt.s2k_cipher_algo) )
2744             log_error(_("selected cipher algorithm is invalid\n"));
2745     }
2746     if( s2k_digest_string ) {
2747         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
2748         m_free(s2k_digest_string); s2k_digest_string = NULL;
2749         if( check_digest_algo(opt.s2k_digest_algo) )
2750             log_error(_("selected digest algorithm is invalid\n"));
2751     }
2752     if( opt.completes_needed < 1 )
2753       log_error(_("completes-needed must be greater than 0\n"));
2754     if( opt.marginals_needed < 2 )
2755       log_error(_("marginals-needed must be greater than 1\n"));
2756     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
2757       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
2758     if(opt.def_cert_level<0 || opt.def_cert_level>3)
2759       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
2760     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
2761       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
2762     switch( opt.s2k_mode ) {
2763       case 0:
2764         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
2765         break;
2766       case 1: case 3: break;
2767       default:
2768         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
2769     }
2770
2771     /* This isn't actually needed, but does serve to error out if the
2772        string is invalid. */
2773     if(opt.def_preference_list &&
2774         keygen_set_std_prefs(opt.def_preference_list,0))
2775       log_error(_("invalid default preferences\n"));
2776
2777     /* We provide defaults for the personal digest list.  This is
2778        SHA-1. */
2779     if(!pers_digest_list)
2780       pers_digest_list="h2";
2781
2782     if(pers_cipher_list &&
2783        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
2784       log_error(_("invalid personal cipher preferences\n"));
2785
2786     if(pers_digest_list &&
2787        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
2788       log_error(_("invalid personal digest preferences\n"));
2789
2790     if(pers_compress_list &&
2791        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
2792       log_error(_("invalid personal compress preferences\n"));
2793
2794     /* We don't support all possible commands with multifile yet */
2795     if(multifile)
2796       {
2797         char *cmdname;
2798
2799         switch(cmd)
2800           {
2801           case aSign:
2802             cmdname="--sign";
2803             break;
2804           case aClearsign:
2805             cmdname="--clearsign";
2806             break;
2807           case aDetachedSign:
2808             cmdname="--detach-sign";
2809             break;
2810           case aSym:
2811             cmdname="--symmetric";
2812             break;
2813           case aEncrSym:
2814             cmdname="--symmetric --encrypt";
2815             break;
2816           case aStore:
2817             cmdname="--store";
2818             break;
2819           default:
2820             cmdname=NULL;
2821             break;
2822           }
2823
2824         if(cmdname)
2825           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
2826       }
2827
2828     if( log_get_errorcount(0) )
2829         g10_exit(2);
2830
2831     if(opt.compress_level==0)
2832       opt.compress_algo=COMPRESS_ALGO_NONE;
2833
2834     /* Check our chosen algorithms against the list of legal
2835        algorithms. */
2836
2837     if(!GNUPG)
2838       {
2839         const char *badalg=NULL;
2840         preftype_t badtype=PREFTYPE_NONE;
2841
2842         if(opt.def_cipher_algo
2843            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
2844           {
2845             badalg=cipher_algo_to_string(opt.def_cipher_algo);
2846             badtype=PREFTYPE_SYM;
2847           }
2848         else if(opt.def_digest_algo
2849                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
2850           {
2851             badalg=digest_algo_to_string(opt.def_digest_algo);
2852             badtype=PREFTYPE_HASH;
2853           }
2854         else if(opt.cert_digest_algo
2855                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
2856           {
2857             badalg=digest_algo_to_string(opt.cert_digest_algo);
2858             badtype=PREFTYPE_HASH;
2859           }
2860         else if(opt.compress_algo!=-1
2861                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
2862           {
2863             badalg=compress_algo_to_string(opt.compress_algo);
2864             badtype=PREFTYPE_ZIP;
2865           }
2866
2867         if(badalg)
2868           {
2869             switch(badtype)
2870               {
2871               case PREFTYPE_SYM:
2872                 log_info(_("you may not use cipher algorithm `%s'"
2873                            " while in %s mode\n"),
2874                          badalg,compliance_option_string());
2875                 break;
2876               case PREFTYPE_HASH:
2877                 log_info(_("you may not use digest algorithm `%s'"
2878                            " while in %s mode\n"),
2879                          badalg,compliance_option_string());
2880                 break;
2881               case PREFTYPE_ZIP:
2882                 log_info(_("you may not use compression algorithm `%s'"
2883                            " while in %s mode\n"),
2884                          badalg,compliance_option_string());
2885                 break;
2886               default:
2887                 BUG();
2888               }
2889
2890             compliance_failure();
2891           }
2892       }
2893
2894     /* set the random seed file */
2895     if( use_random_seed ) {
2896         char *p = make_filename(opt.homedir, "random_seed", NULL );
2897         set_random_seed_file(p);
2898         if (!access (p, F_OK))
2899           register_secured_file (p);
2900         m_free(p);
2901     }
2902
2903     if( !cmd && opt.fingerprint && !with_fpr ) {
2904         set_cmd( &cmd, aListKeys);
2905     }
2906
2907     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
2908         if( cmd == aKModeC ) {
2909             opt.fingerprint = 1;
2910             cmd = aKMode;
2911         }
2912         opt.list_sigs = 0;
2913         if( opt.verbose > 2 )
2914             opt.check_sigs++;
2915         if( opt.verbose > 1 )
2916             opt.list_sigs++;
2917
2918         opt.verbose = opt.verbose > 1;
2919         g10_opt_verbose = opt.verbose;
2920     }
2921
2922     /* kludge to let -sat generate a clear text signature */
2923     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
2924         cmd = aClearsign;
2925
2926     if( opt.verbose > 1 )
2927         set_packet_list_mode(1);
2928
2929     /* Add the keyrings, but not for some special commands and not in
2930        case of "-kvv userid keyring".  Also avoid adding the secret
2931        keyring for a couple of commands to avoid unneeded access in
2932        case the secrings are stored on a floppy.
2933        
2934        We always need to add the keyrings if we are running under
2935        SELinux, this is so that the rings are added to the list of
2936        secured files. */
2937     if( ALWAYS_ADD_KEYRINGS 
2938         || (cmd != aDeArmor && cmd != aEnArmor
2939             && !(cmd == aKMode && argc == 2 )) ) 
2940       {
2941         if (ALWAYS_ADD_KEYRINGS
2942             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
2943                 && cmd != aVerify && cmd != aSym))
2944           {
2945             if (!sec_nrings || default_keyring) /* add default secret rings */
2946               keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
2947             for (sl = sec_nrings; sl; sl = sl->next)
2948               keydb_add_resource ( sl->d, 0, 1 );
2949           }
2950         if( !nrings || default_keyring )  /* add default ring */
2951             keydb_add_resource ("pubring" EXTSEP_S "gpg", 4, 0);
2952         for(sl = nrings; sl; sl = sl->next )
2953             keydb_add_resource ( sl->d, sl->flags, 0 );
2954       }
2955     FREE_STRLIST(nrings);
2956     FREE_STRLIST(sec_nrings);
2957
2958
2959     if( pwfd != -1 )  /* read the passphrase now. */
2960         read_passphrase_from_fd( pwfd );
2961
2962     fname = argc? *argv : NULL;
2963
2964     switch( cmd ) {
2965       case aPrimegen:
2966       case aPrintMD:
2967       case aPrintMDs:
2968       case aGenRandom:
2969       case aDeArmor:
2970       case aEnArmor:
2971       case aFixTrustDB:
2972         break;
2973       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
2974       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
2975       default: rc = setup_trustdb(1, trustdb_name ); break;
2976     }
2977     if( rc )
2978         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
2979
2980
2981     switch (cmd)
2982       {
2983       case aStore: 
2984       case aSym:  
2985       case aSign: 
2986       case aSignSym: 
2987       case aClearsign: 
2988         if (!opt.quiet && any_explicit_recipient)
2989           log_info (_("WARNING: recipients (-r) given "
2990                       "without using public key encryption\n"));
2991         break;
2992       default:
2993         break;
2994       }
2995
2996     switch( cmd )
2997       {
2998       case aStore: /* only store the file */
2999         if( argc > 1 )
3000             wrong_args(_("--store [filename]"));
3001         if( (rc = encode_store(fname)) )
3002             log_error ("storing `%s' failed: %s\n",
3003                        print_fname_stdin(fname),g10_errstr(rc) );
3004         break;
3005       case aSym: /* encrypt the given file only with the symmetric cipher */
3006         if( argc > 1 )
3007             wrong_args(_("--symmetric [filename]"));
3008         if( (rc = encode_symmetric(fname)) )
3009             log_error (_("symmetric encryption of `%s' failed: %s\n"),
3010                         print_fname_stdin(fname),g10_errstr(rc) );
3011         break;
3012
3013       case aEncr: /* encrypt the given file */
3014         if(multifile)
3015           encode_crypt_files(argc, argv, remusr);
3016         else
3017           {
3018             if( argc > 1 )
3019               wrong_args(_("--encrypt [filename]"));
3020             if( (rc = encode_crypt(fname,remusr,0)) )
3021               log_error("%s: encryption failed: %s\n",
3022                         print_fname_stdin(fname), g10_errstr(rc) );
3023           }
3024         break;
3025
3026       case aEncrSym:
3027         /* This works with PGP 8 in the sense that it acts just like a
3028            symmetric message.  It doesn't work at all with 2 or 6.  It
3029            might work with 7, but alas, I don't have a copy to test
3030            with right now. */
3031         if( argc > 1 )
3032           wrong_args(_("--symmetric --encrypt [filename]"));
3033         else if(opt.s2k_mode==0)
3034           log_error(_("you cannot use --symmetric --encrypt"
3035                       " with --s2k-mode 0\n"));
3036         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3037           log_error(_("you cannot use --symmetric --encrypt"
3038                       " while in %s mode\n"),compliance_option_string());
3039         else
3040           {
3041             if( (rc = encode_crypt(fname,remusr,1)) )
3042               log_error("%s: encryption failed: %s\n",
3043                         print_fname_stdin(fname), g10_errstr(rc) );
3044           }
3045         break;
3046
3047       case aSign: /* sign the given file */
3048         sl = NULL;
3049         if( detached_sig ) { /* sign all files */
3050             for( ; argc; argc--, argv++ )
3051                 add_to_strlist( &sl, *argv );
3052         }
3053         else {
3054             if( argc > 1 )
3055                 wrong_args(_("--sign [filename]"));
3056             if( argc ) {
3057                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3058                 strcpy(sl->d, fname);
3059             }
3060         }
3061         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
3062             log_error("signing failed: %s\n", g10_errstr(rc) );
3063         free_strlist(sl);
3064         break;
3065
3066       case aSignEncr: /* sign and encrypt the given file */
3067         if( argc > 1 )
3068             wrong_args(_("--sign --encrypt [filename]"));
3069         if( argc ) {
3070             sl = m_alloc_clear( sizeof *sl + strlen(fname));
3071             strcpy(sl->d, fname);
3072         }
3073         else
3074             sl = NULL;
3075         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
3076             log_error("%s: sign+encrypt failed: %s\n",
3077                       print_fname_stdin(fname), g10_errstr(rc) );
3078         free_strlist(sl);
3079         break;
3080
3081       case aSignEncrSym: /* sign and encrypt the given file */
3082         if( argc > 1 )
3083             wrong_args(_("--symmetric --sign --encrypt [filename]"));
3084         else if(opt.s2k_mode==0)
3085           log_error(_("you cannot use --symmetric --sign --encrypt"
3086                       " with --s2k-mode 0\n"));
3087         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3088           log_error(_("you cannot use --symmetric --sign --encrypt"
3089                       " while in %s mode\n"),compliance_option_string());
3090         else
3091           {
3092             if( argc )
3093               {
3094                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3095                 strcpy(sl->d, fname);
3096               }
3097             else
3098               sl = NULL;
3099             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
3100               log_error("%s: symmetric+sign+encrypt failed: %s\n",
3101                         print_fname_stdin(fname), g10_errstr(rc) );
3102             free_strlist(sl);
3103           }
3104         break;
3105
3106       case aSignSym: /* sign and conventionally encrypt the given file */
3107         if (argc > 1)
3108             wrong_args(_("--sign --symmetric [filename]"));
3109         rc = sign_symencrypt_file (fname, locusr);
3110         if (rc)
3111             log_error("%s: sign+symmetric failed: %s\n",
3112                       print_fname_stdin(fname), g10_errstr(rc) );
3113         break;
3114
3115       case aClearsign: /* make a clearsig */
3116         if( argc > 1 )
3117             wrong_args(_("--clearsign [filename]"));
3118         if( (rc = clearsign_file(fname, locusr, NULL)) )
3119             log_error("%s: clearsign failed: %s\n",
3120                       print_fname_stdin(fname), g10_errstr(rc) );
3121         break;
3122
3123       case aVerify:
3124         if(multifile)
3125           {
3126             if( (rc = verify_files( argc, argv ) ))
3127               log_error("verify files failed: %s\n", g10_errstr(rc) );
3128           }
3129         else
3130           {
3131             if( (rc = verify_signatures( argc, argv ) ))
3132               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
3133           }
3134         break;
3135
3136       case aDecrypt:
3137         if(multifile)
3138           decrypt_messages(argc, argv);
3139         else
3140           {
3141             if( argc > 1 )
3142               wrong_args(_("--decrypt [filename]"));
3143             if( (rc = decrypt_message( fname ) ))
3144               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
3145           }
3146         break;
3147             
3148       case aSignKey:
3149         if( argc != 1 )
3150           wrong_args(_("--sign-key user-id"));
3151         /* fall through */
3152       case aLSignKey:
3153         if( argc != 1 )
3154           wrong_args(_("--lsign-key user-id"));
3155         /* fall through */
3156
3157         sl=NULL;
3158
3159         if(cmd==aSignKey)
3160           append_to_strlist(&sl,"sign");
3161         else if(cmd==aLSignKey)
3162           append_to_strlist(&sl,"lsign");
3163         else
3164           BUG();
3165
3166         append_to_strlist( &sl, "save" );
3167         username = make_username( fname );
3168         keyedit_menu(fname, locusr, sl, 0, 0 );
3169         m_free(username);
3170         free_strlist(sl);
3171         break;
3172
3173       case aEditKey: /* Edit a key signature */
3174         if( !argc )
3175             wrong_args(_("--edit-key user-id [commands]"));
3176         username = make_username( fname );
3177         if( argc > 1 ) {
3178             sl = NULL;
3179             for( argc--, argv++ ; argc; argc--, argv++ )
3180                 append_to_strlist( &sl, *argv );
3181             keyedit_menu( username, locusr, sl, 0, 1 );
3182             free_strlist(sl);
3183         }
3184         else
3185             keyedit_menu(username, locusr, NULL, 0, 1 );
3186         m_free(username);
3187         break;
3188
3189       case aDeleteKeys:
3190       case aDeleteSecretKeys:
3191       case aDeleteSecretAndPublicKeys:
3192         sl = NULL;
3193         /* I'm adding these in reverse order as add_to_strlist2
3194            reverses them again, and it's easier to understand in the
3195            proper order :) */
3196         for( ; argc; argc-- )
3197           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
3198         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
3199         free_strlist(sl);
3200         break;
3201
3202       case aCheckKeys:
3203         opt.check_sigs = 1;
3204       case aListSigs:
3205         opt.list_sigs = 1;
3206       case aListKeys:
3207         sl = NULL;
3208         for( ; argc; argc--, argv++ )
3209             add_to_strlist2( &sl, *argv, utf8_strings );
3210         public_key_list( sl );
3211         free_strlist(sl);
3212         break;
3213       case aListSecretKeys:
3214         sl = NULL;
3215         for( ; argc; argc--, argv++ )
3216             add_to_strlist2( &sl, *argv, utf8_strings );
3217         secret_key_list( sl );
3218         free_strlist(sl);
3219         break;
3220
3221       case aKMode: /* list keyring -- NOTE: This will be removed soon */
3222         if( argc < 2 ) { /* -kv [userid] */
3223             sl = NULL;
3224             if (argc && **argv)
3225                 add_to_strlist2( &sl, *argv, utf8_strings );
3226             public_key_list( sl );
3227             free_strlist(sl);
3228         }
3229         else if( argc == 2 ) { /* -kv userid keyring */
3230             if( access( argv[1], R_OK ) ) {
3231                 log_error(_("can't open `%s': %s\n"),
3232                                print_fname_stdin(argv[1]), strerror(errno));
3233             }
3234             else {
3235                 /* add keyring (default keyrings are not registered in this
3236                  * special case */
3237                 keydb_add_resource( argv[1], 0, 0 );
3238                 sl = NULL;
3239                 if (**argv)
3240                     add_to_strlist2( &sl, *argv, utf8_strings );
3241                 public_key_list( sl );
3242                 free_strlist(sl);
3243             }
3244         }
3245         else
3246             wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
3247         break;
3248
3249       case aKeygen: /* generate a key */
3250         if( opt.batch ) {
3251             if( argc > 1 )
3252                 wrong_args("--gen-key [parameterfile]");
3253             generate_keypair( argc? *argv : NULL, NULL, NULL );
3254         }
3255         else {
3256             if( argc )
3257                 wrong_args("--gen-key");
3258             generate_keypair(NULL, NULL, NULL);
3259         }
3260         break;
3261
3262       case aFastImport:
3263         opt.import_options |= IMPORT_FAST;
3264       case aImport:
3265         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3266         break;
3267
3268       case aExport:
3269       case aSendKeys:
3270       case aRecvKeys:
3271         sl = NULL;
3272         for( ; argc; argc--, argv++ )
3273             add_to_strlist2( &sl, *argv, utf8_strings );
3274         if( cmd == aSendKeys )
3275             rc=keyserver_export( sl );
3276         else if( cmd == aRecvKeys )
3277             rc=keyserver_import( sl );
3278         else
3279             rc=export_pubkeys( sl, opt.export_options );
3280         if(rc)
3281           {
3282             if(cmd==aSendKeys)
3283               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3284             else if(cmd==aRecvKeys)
3285               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3286             else
3287               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3288           }
3289         free_strlist(sl);
3290         break;
3291
3292      case aSearchKeys:
3293         sl = NULL;
3294         for( ; argc; argc--, argv++ )
3295           append_to_strlist2( &sl, *argv, utf8_strings );
3296         rc=keyserver_search( sl );
3297         if(rc)
3298           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3299         free_strlist(sl);
3300         break;
3301
3302       case aRefreshKeys:
3303         sl = NULL;
3304         for( ; argc; argc--, argv++ )
3305             add_to_strlist2( &sl, *argv, utf8_strings );
3306         rc=keyserver_refresh(sl);
3307         if(rc)
3308           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3309         free_strlist(sl);
3310         break;
3311
3312       case aExportSecret:
3313         sl = NULL;
3314         for( ; argc; argc--, argv++ )
3315             add_to_strlist2( &sl, *argv, utf8_strings );
3316         export_seckeys( sl );
3317         free_strlist(sl);
3318         break;
3319
3320       case aExportSecretSub:
3321         sl = NULL;
3322         for( ; argc; argc--, argv++ )
3323             add_to_strlist2( &sl, *argv, utf8_strings );
3324         export_secsubkeys( sl );
3325         free_strlist(sl);
3326         break;
3327
3328       case aGenRevoke:
3329         if( argc != 1 )
3330             wrong_args("--gen-revoke user-id");
3331         username =  make_username(*argv);
3332         gen_revoke( username );
3333         m_free( username );
3334         break;
3335
3336       case aDesigRevoke:
3337         if( argc != 1 )
3338             wrong_args("--desig-revoke user-id");
3339         username =  make_username(*argv);
3340         gen_desig_revoke( username );
3341         m_free( username );
3342         break;
3343
3344       case aDeArmor:
3345         if( argc > 1 )
3346             wrong_args("--dearmor [file]");
3347         rc = dearmor_file( argc? *argv: NULL );
3348         if( rc )
3349             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3350         break;
3351
3352       case aEnArmor:
3353         if( argc > 1 )
3354             wrong_args("--enarmor [file]");
3355         rc = enarmor_file( argc? *argv: NULL );
3356         if( rc )
3357             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3358         break;
3359
3360
3361       case aPrimegen:
3362         {   int mode = argc < 2 ? 0 : atoi(*argv);
3363
3364             if( mode == 1 && argc == 2 ) {
3365                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3366             }
3367             else if( mode == 2 && argc == 3 ) {
3368                 mpi_print( stdout, generate_elg_prime(
3369                                              0, atoi(argv[1]),
3370                                              atoi(argv[2]), NULL,NULL ), 1);
3371             }
3372             else if( mode == 3 && argc == 3 ) {
3373                 MPI *factors;
3374                 mpi_print( stdout, generate_elg_prime(
3375                                              1, atoi(argv[1]),
3376                                              atoi(argv[2]), NULL,&factors ), 1);
3377                 putchar('\n');
3378                 mpi_print( stdout, factors[0], 1 ); /* print q */
3379             }
3380             else if( mode == 4 && argc == 3 ) {
3381                 MPI g = mpi_alloc(1);
3382                 mpi_print( stdout, generate_elg_prime(
3383                                                  0, atoi(argv[1]),
3384                                                  atoi(argv[2]), g, NULL ), 1);
3385                 putchar('\n');
3386                 mpi_print( stdout, g, 1 );
3387                 mpi_free(g);
3388             }
3389             else
3390                 wrong_args("--gen-prime mode bits [qbits] ");
3391             putchar('\n');
3392         }
3393         break;
3394
3395       case aGenRandom:
3396         {
3397             int level = argc ? atoi(*argv):0;
3398             int count = argc > 1 ? atoi(argv[1]): 0;
3399             int endless = !count;
3400
3401             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3402                 wrong_args("--gen-random 0|1|2 [count]");
3403
3404             while( endless || count ) {
3405                 byte *p;
3406                 /* Wee need a multiple of 3, so that in case of
3407                    armored output we get a correct string.  No
3408                    linefolding is done, as it is best to levae this to
3409                    other tools */
3410                 size_t n = !endless && count < 99? count : 99;
3411
3412                 p = get_random_bits( n*8, level, 0);
3413 #ifdef HAVE_DOSISH_SYSTEM
3414                 setmode ( fileno(stdout), O_BINARY );
3415 #endif
3416                 if (opt.armor) {
3417                     char *tmp = make_radix64_string (p, n);
3418                     fputs (tmp, stdout);
3419                     m_free (tmp);
3420                     if (n%3 == 1)
3421                       putchar ('=');
3422                     if (n%3)
3423                       putchar ('=');
3424                 } else {
3425                     fwrite( p, n, 1, stdout );
3426                 }
3427                 m_free(p);
3428                 if( !endless )
3429                     count -= n;
3430             }
3431             if (opt.armor)
3432                 putchar ('\n');
3433         }
3434         break;
3435
3436       case aPrintMD:
3437         if( argc < 1)
3438             wrong_args("--print-md algo [files]");
3439         {
3440             int all_algos = (**argv=='*' && !(*argv)[1]);
3441             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3442
3443             if( !algo && !all_algos )
3444                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3445             else {
3446                 argc--; argv++;
3447                 if( !argc )
3448                     print_mds(NULL, algo);
3449                 else {
3450                     for(; argc; argc--, argv++ )
3451                         print_mds(*argv, algo);
3452                 }
3453             }
3454         }
3455         break;
3456
3457       case aPrintMDs: /* old option */
3458         if( !argc )
3459             print_mds(NULL,0);
3460         else {
3461             for(; argc; argc--, argv++ )
3462                 print_mds(*argv,0);
3463         }
3464         break;
3465
3466       case aListTrustDB:
3467         if( !argc )
3468             list_trustdb(NULL);
3469         else {
3470             for( ; argc; argc--, argv++ )
3471                 list_trustdb( *argv );
3472         }
3473         break;
3474
3475       case aUpdateTrustDB:
3476         if( argc )
3477             wrong_args("--update-trustdb");
3478         update_trustdb();
3479         break;
3480
3481       case aCheckTrustDB:
3482         /* Old versions allowed for arguments - ignore them */
3483         check_trustdb();
3484         break;
3485
3486       case aFixTrustDB:
3487         log_error("this command is not yet implemented.\n");
3488         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3489         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3490         break;
3491
3492       case aListTrustPath:
3493         if( !argc )
3494             wrong_args("--list-trust-path <user-ids>");
3495         for( ; argc; argc--, argv++ ) {
3496             username = make_username( *argv );
3497             list_trust_path( username );
3498             m_free(username);
3499         }
3500         break;
3501
3502       case aExportOwnerTrust: