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