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