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