* gpg.c (print_mds), armor.c (armor_filter, parse_hash_header): Add
[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 #elif defined(__GLIBC__)
1730     opt.pcsc_driver = "libpcsclite.so.1"; 
1731 #else
1732     opt.pcsc_driver = "libpcsclite.so"; 
1733 #endif
1734 #endif /*ENABLE_CARD_SUPPORT*/
1735
1736     /* check whether we have a config file on the commandline */
1737     orig_argc = argc;
1738     orig_argv = argv;
1739     pargs.argc = &argc;
1740     pargs.argv = &argv;
1741     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
1742     while( arg_parse( &pargs, opts) ) {
1743         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
1744             parse_debug++;
1745         else if( pargs.r_opt == oOptions ) {
1746             /* yes there is one, so we do not try the default one, but
1747              * read the option file when it is encountered at the commandline
1748              */
1749             default_config = 0;
1750         }
1751         else if( pargs.r_opt == oNoOptions )
1752             default_config = 0; /* --no-options */
1753         else if( pargs.r_opt == oHomedir )
1754             set_homedir ( pargs.r.ret_str );
1755         else if( pargs.r_opt == oNoPermissionWarn )
1756             opt.no_perm_warn=1;
1757         else if (pargs.r_opt == oStrict )
1758           {
1759             opt.strict=1;
1760             log_set_strict(1);
1761           }
1762         else if (pargs.r_opt == oNoStrict )
1763           {
1764             opt.strict=0;
1765             log_set_strict(0);
1766           }
1767 #ifdef USE_SHM_COPROCESSING
1768         else if( pargs.r_opt == oRunAsShmCP ) {
1769             /* does not make sense in a options file, we do it here,
1770              * so that we are the able to drop setuid as soon as possible */
1771             opt.shm_coprocess = 1;
1772             requested_shm_size = pargs.r.ret_ulong;
1773         }
1774         else if ( pargs.r_opt == oStatusFD ) {
1775             /* this is needed to ensure that the status-fd filedescriptor is
1776              * initialized when init_shm_coprocessing() is called */
1777             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1778         }
1779 #endif
1780     }
1781
1782 #ifdef HAVE_DOSISH_SYSTEM
1783     if ( strchr (opt.homedir,'\\') ) {
1784         char *d, *buf = xmalloc (strlen (opt.homedir)+1);
1785         const char *s = opt.homedir;
1786         for (d=buf,s=opt.homedir; *s; s++)
1787           {
1788             *d++ = *s == '\\'? '/': *s;
1789 #ifdef HAVE_W32_SYSTEM
1790             if (s[1] && IsDBCSLeadByte (*s))
1791               *d++ = *++s;
1792 #endif
1793           }
1794         *d = 0;
1795         set_homedir (buf);
1796     }
1797 #endif
1798 #ifdef USE_SHM_COPROCESSING
1799     if( opt.shm_coprocess ) {
1800         init_shm_coprocessing(requested_shm_size, 1 );
1801     }
1802 #endif
1803     /* initialize the secure memory. */
1804     got_secmem=secmem_init( 32768 );
1805     maybe_setuid = 0;
1806     /* Okay, we are now working under our real uid */
1807
1808 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
1809     /* There should be no way to get to this spot while still carrying
1810        setuid privs.  Just in case, bomb out if we are. */
1811     if(getuid()!=geteuid())
1812       BUG();
1813 #endif
1814
1815     set_native_charset (NULL); /* Try to auto set the character set */
1816
1817     /* Try for a version specific config file first */
1818     if( default_config )
1819       {
1820         char *name=xstrdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
1821         char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
1822
1823         do
1824           {
1825             if(configname)
1826               {
1827                 char *tok;
1828
1829                 xfree(configname);
1830                 configname=NULL;
1831
1832                 if((tok=strrchr(ver,SAFE_VERSION_DASH)))
1833                   *tok='\0';
1834                 else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
1835                   *tok='\0';
1836                 else
1837                   break;
1838               }
1839
1840             configname = make_filename(opt.homedir,name,NULL);
1841           }
1842         while(access(configname,R_OK));
1843
1844         xfree(name);
1845
1846         if(!configname)
1847           configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
1848         if (!access (configname, R_OK))
1849           { /* Print a warning when both config files are present. */
1850             char *p = make_filename(opt.homedir, "options", NULL );
1851             if (!access (p, R_OK))
1852               log_info (_("NOTE: old default options file `%s' ignored\n"), p);
1853             xfree (p);
1854           }
1855         else
1856           { /* Keep on using the old default one. */
1857             xfree (configname);
1858             configname = make_filename(opt.homedir, "options", NULL );
1859           }
1860       }
1861     argc = orig_argc;
1862     argv = orig_argv;
1863     pargs.argc = &argc;
1864     pargs.argv = &argv;
1865     pargs.flags=  1;  /* do not remove the args */
1866
1867     /* By this point we have a homedir, and cannot change it. */
1868     check_permissions(opt.homedir,0);
1869
1870   next_pass:
1871     if( configname ) {
1872       if(check_permissions(configname,1))
1873         {
1874           /* If any options file is unsafe, then disable any external
1875              programs for keyserver calls or photo IDs.  Since the
1876              external program to call is set in the options file, a
1877              unsafe options file can lead to an arbitrary program
1878              being run. */
1879
1880           opt.exec_disable=1;
1881         }
1882
1883         configlineno = 0;
1884         configfp = fopen( configname, "r" );
1885         if (configfp && is_secured_file (fileno (configfp)))
1886           {
1887             fclose (configfp);
1888             configfp = NULL;
1889             errno = EPERM;
1890           }
1891         if( !configfp ) {
1892             if( default_config ) {
1893                 if( parse_debug )
1894                     log_info(_("NOTE: no default option file `%s'\n"),
1895                                                             configname );
1896             }
1897             else {
1898                 log_error(_("option file `%s': %s\n"),
1899                                     configname, strerror(errno) );
1900                 g10_exit(2);
1901             }
1902             xfree(configname); configname = NULL;
1903         }
1904         if( parse_debug && configname )
1905             log_info(_("reading options from `%s'\n"), configname );
1906         default_config = 0;
1907     }
1908
1909     while( optfile_parse( configfp, configname, &configlineno,
1910                                                 &pargs, opts) )
1911       {
1912         switch( pargs.r_opt )
1913           {
1914           case aCheckKeys: 
1915           case aListConfig:
1916           case aGPGConfList:
1917           case aListPackets:
1918           case aImport: 
1919           case aFastImport: 
1920           case aSendKeys: 
1921           case aRecvKeys: 
1922           case aSearchKeys:
1923           case aRefreshKeys:
1924           case aFetchKeys:
1925           case aExport: 
1926             set_cmd (&cmd, pargs.r_opt);
1927             break;
1928           case aListKeys: set_cmd( &cmd, aListKeys); break;
1929           case aListSigs: set_cmd( &cmd, aListSigs); break;
1930           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
1931           case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
1932           case aDeleteSecretKeys:
1933             set_cmd( &cmd, aDeleteSecretKeys);
1934             greeting=1;
1935             break;
1936           case aDeleteSecretAndPublicKeys:
1937             set_cmd( &cmd, aDeleteSecretAndPublicKeys);
1938             greeting=1; 
1939             break;
1940           case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
1941
1942           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
1943           case aSym: set_cmd( &cmd, aSym); break;
1944
1945           case aDecryptFiles: multifile=1; /* fall through */
1946           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
1947
1948           case aEncrFiles: multifile=1; /* fall through */
1949           case aEncr: set_cmd( &cmd, aEncr); break;
1950
1951           case aVerifyFiles: multifile=1; /* fall through */
1952           case aVerify: set_cmd( &cmd, aVerify); break;
1953
1954           case aSign: set_cmd( &cmd, aSign );  break;
1955           case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
1956           case aSignKey: set_cmd( &cmd, aSignKey); break;
1957           case aLSignKey: set_cmd( &cmd, aLSignKey); break;
1958           case aStore: set_cmd( &cmd, aStore); break;
1959           case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
1960           case aClearsign: set_cmd( &cmd, aClearsign); break;
1961           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
1962           case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
1963           case aPrimegen: set_cmd( &cmd, aPrimegen); break;
1964           case aGenRandom: set_cmd( &cmd, aGenRandom); break;
1965           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
1966           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
1967           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
1968           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
1969           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
1970           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
1971           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
1972           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
1973           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
1974           case aListOwnerTrust:
1975             deprecated_warning(configname,configlineno,
1976                                "--list-ownertrust","--export-ownertrust","");
1977           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
1978           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
1979           case aPipeMode:
1980             deprecated_command ("--pipemode");
1981             set_cmd( &cmd, aPipeMode);
1982             break;
1983
1984           case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
1985
1986 #ifdef ENABLE_CARD_SUPPORT
1987           case aCardStatus: set_cmd (&cmd, aCardStatus); break;
1988           case aCardEdit: set_cmd (&cmd, aCardEdit); break;
1989           case aChangePIN: set_cmd (&cmd, aChangePIN); break;
1990           case oReaderPort:
1991             card_set_reader_port (pargs.r.ret_str);
1992             break;
1993           case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
1994           case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
1995           case oDisableCCID: opt.disable_ccid = 1; break;
1996 #endif /* ENABLE_CARD_SUPPORT*/
1997
1998           case oArmor: opt.armor = 1; opt.no_armor=0; break;
1999           case oOutput: opt.outfile = pargs.r.ret_str; break;
2000           case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
2001           case oQuiet: opt.quiet = 1; break;
2002           case oNoTTY: tty_no_terminal(1); break;
2003           case oDryRun: opt.dry_run = 1; break;
2004           case oInteractive: opt.interactive = 1; break;
2005           case oVerbose:
2006             g10_opt_verbose++;
2007             opt.verbose++;
2008             opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
2009             opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
2010             break;
2011           case oKOption: set_cmd( &cmd, aKMode ); break;
2012
2013           case oBatch: opt.batch = 1; nogreeting = 1; break;
2014           case oUseAgent:
2015 #ifndef __riscos__
2016             opt.use_agent = 1;
2017 #else /* __riscos__ */
2018             opt.use_agent = 0;
2019             riscos_not_implemented("use-agent");
2020 #endif /* __riscos__ */
2021             break;
2022           case oNoUseAgent: opt.use_agent = 0; break;
2023           case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
2024           case oAnswerYes: opt.answer_yes = 1; break;
2025           case oAnswerNo: opt.answer_no = 1; break;
2026           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
2027           case oPrimaryKeyring:
2028             sl=append_to_strlist( &nrings, pargs.r.ret_str);
2029             sl->flags=2;
2030             break;
2031           case oShowKeyring:
2032             deprecated_warning(configname,configlineno,"--show-keyring",
2033                                "--list-options ","show-keyring");
2034             opt.list_options|=LIST_SHOW_KEYRING;
2035             break;
2036           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
2037           case oDebugAll: opt.debug = ~0; break;
2038           case oDebugCCIDDriver: 
2039 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
2040             ccid_set_debug_level (ccid_set_debug_level (1)+1);
2041 #endif
2042             break;
2043           case oStatusFD:
2044             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
2045             break;
2046           case oStatusFile:
2047             set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
2048             break;
2049           case oAttributeFD:
2050             set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
2051             break;
2052           case oAttributeFile:
2053             set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
2054             break;
2055           case oLoggerFD:
2056             log_set_logfile( NULL,
2057                              iobuf_translate_file_handle (pargs.r.ret_int, 1));
2058             break;
2059           case oLoggerFile:
2060             log_set_logfile( NULL, open_info_file (pargs.r.ret_str, 1) );
2061             break;
2062
2063           case oWithFingerprint:
2064             opt.with_fingerprint = 1;
2065             with_fpr=1; /*fall thru*/
2066           case oFingerprint: opt.fingerprint++; break;
2067           case oSecretKeyring:
2068             append_to_strlist( &sec_nrings, pargs.r.ret_str);
2069             break;
2070           case oOptions:
2071             /* config files may not be nested (silently ignore them) */
2072             if( !configfp ) {
2073                 xfree(configname);
2074                 configname = xstrdup(pargs.r.ret_str);
2075                 goto next_pass;
2076             }
2077             break;
2078           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
2079           case oNoDefKeyring: default_keyring = 0; break;
2080           case oNoGreeting: nogreeting = 1; break;
2081           case oNoVerbose: g10_opt_verbose = 0;
2082                            opt.verbose = 0; opt.list_sigs=0; break;
2083           case oQuickRandom: quick_random_gen(1); break;
2084           case oEmitVersion: opt.no_version=0; break;
2085           case oNoEmitVersion: opt.no_version=1; break;
2086           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
2087           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
2088           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
2089           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
2090           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
2091           case oDefRecipient:
2092                     if( *pargs.r.ret_str )
2093                         opt.def_recipient = make_username(pargs.r.ret_str);
2094                     break;
2095           case oDefRecipientSelf:
2096                     xfree(opt.def_recipient); opt.def_recipient = NULL;
2097                     opt.def_recipient_self = 1;
2098                     break;
2099           case oNoDefRecipient:
2100                     xfree(opt.def_recipient); opt.def_recipient = NULL;
2101                     opt.def_recipient_self = 0;
2102                     break;
2103           case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
2104           case oHomedir: break;
2105           case oNoBatch: opt.batch = 0; break;
2106           case oWithKeyData: opt.with_key_data=1; /* fall thru */
2107           case oWithColons: opt.with_colons=':'; break;
2108
2109           case oSkipVerify: opt.skip_verify=1; break;
2110           case oCompressKeys: opt.compress_keys = 1; break;
2111           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
2112             /* There are many programs (like mutt) that call gpg with
2113                --always-trust so keep this option around for a long
2114                time. */
2115           case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
2116           case oTrustModel:
2117             parse_trust_model(pargs.r.ret_str);
2118             break;
2119           case oForceOwnertrust:
2120             log_info(_("NOTE: %s is not for normal use!\n"),
2121                      "--force-ownertrust");
2122             opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
2123             if(opt.force_ownertrust==-1)
2124               {
2125                 log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
2126                 opt.force_ownertrust=0;
2127               }
2128             break;
2129           case oLoadExtension:
2130 #ifndef __riscos__
2131 #if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
2132             if(check_permissions(pargs.r.ret_str,2))
2133               log_info(_("cipher extension `%s' not loaded due to"
2134                          " unsafe permissions\n"),pargs.r.ret_str);
2135             else
2136               register_cipher_extension(orig_argc? *orig_argv:NULL,
2137                                         pargs.r.ret_str);
2138 #endif
2139 #else /* __riscos__ */
2140             riscos_not_implemented("load-extension");
2141 #endif /* __riscos__ */
2142             break;
2143           case oRFC1991:
2144             opt.compliance = CO_RFC1991;
2145             opt.force_v4_certs = 0;
2146             opt.escape_from = 1;
2147             break;
2148           case oOpenPGP:
2149           case oRFC2440:
2150             /* TODO: When 2440bis becomes a RFC, set new values for
2151                oOpenPGP. */
2152             opt.rfc2440_text=1;
2153             opt.compliance = CO_RFC2440;
2154             opt.allow_non_selfsigned_uid = 1;
2155             opt.allow_freeform_uid = 1;
2156             opt.pgp2_workarounds = 0;
2157             opt.escape_from = 0;
2158             opt.force_v3_sigs = 0;
2159             opt.compress_keys = 0;          /* not mandated, but we do it */
2160             opt.compress_sigs = 0;          /* ditto. */
2161             opt.not_dash_escaped = 0;
2162             opt.def_cipher_algo = 0;
2163             opt.def_digest_algo = 0;
2164             opt.cert_digest_algo = 0;
2165             opt.compress_algo = -1;
2166             opt.s2k_mode = 3; /* iterated+salted */
2167             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
2168             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
2169             break;
2170           case oPGP2:  opt.compliance = CO_PGP2;  break;
2171           case oPGP6:  opt.compliance = CO_PGP6;  break;
2172           case oPGP7:  opt.compliance = CO_PGP7;  break;
2173           case oPGP8:  opt.compliance = CO_PGP8;  break;
2174           case oGnuPG: opt.compliance = CO_GNUPG; break;
2175           case oCompressSigs: opt.compress_sigs = 1; break;
2176           case oRFC2440Text: opt.rfc2440_text=1; break;
2177           case oNoRFC2440Text: opt.rfc2440_text=0; break;
2178           case oRunAsShmCP:
2179 #ifndef __riscos__
2180 # ifndef USE_SHM_COPROCESSING
2181             /* not possible in the option file,
2182              * but we print the warning here anyway */
2183             log_error("shared memory coprocessing is not available\n");
2184 # endif
2185 #else /* __riscos__ */
2186             riscos_not_implemented("run-as-shm-coprocess");
2187 #endif /* __riscos__ */
2188             break;
2189           case oSetFilename:
2190             if(utf8_strings)
2191               opt.set_filename = pargs.r.ret_str;
2192             else
2193               opt.set_filename = native_to_utf8(pargs.r.ret_str);
2194             break;
2195           case oForYourEyesOnly: eyes_only = 1; break;
2196           case oNoForYourEyesOnly: eyes_only = 0; break;
2197           case oSetPolicyURL:
2198             add_policy_url(pargs.r.ret_str,0);
2199             add_policy_url(pargs.r.ret_str,1);
2200             break;
2201           case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
2202           case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
2203           case oShowPolicyURL:
2204             deprecated_warning(configname,configlineno,"--show-policy-url",
2205                                "--list-options ","show-policy-urls");
2206             deprecated_warning(configname,configlineno,"--show-policy-url",
2207                                "--verify-options ","show-policy-urls");
2208             opt.list_options|=LIST_SHOW_POLICY_URLS;
2209             opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
2210             break;
2211           case oNoShowPolicyURL:
2212             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2213                                "--list-options ","no-show-policy-urls");
2214             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2215                                "--verify-options ","no-show-policy-urls");
2216             opt.list_options&=~LIST_SHOW_POLICY_URLS;
2217             opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
2218             break;
2219           case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
2220           case oUseEmbeddedFilename:
2221             opt.flags.use_embedded_filename=1;
2222             break;
2223           case oNoUseEmbeddedFilename:
2224             opt.flags.use_embedded_filename=0;
2225             break;
2226           case oComment:
2227             if(pargs.r.ret_str[0])
2228               append_to_strlist(&opt.comments,pargs.r.ret_str);
2229             break;
2230           case oDefaultComment:
2231             deprecated_warning(configname,configlineno,
2232                                "--default-comment","--no-comments","");
2233             /* fall through */
2234           case oNoComments:
2235             free_strlist(opt.comments);
2236             opt.comments=NULL;
2237             break;
2238           case oThrowKeyids: opt.throw_keyid = 1; break;
2239           case oNoThrowKeyids: opt.throw_keyid = 0; break;
2240           case oShowPhotos:
2241             deprecated_warning(configname,configlineno,"--show-photos",
2242                                "--list-options ","show-photos");
2243             deprecated_warning(configname,configlineno,"--show-photos",
2244                                "--verify-options ","show-photos");
2245             opt.list_options|=LIST_SHOW_PHOTOS;
2246             opt.verify_options|=VERIFY_SHOW_PHOTOS;
2247             break;
2248           case oNoShowPhotos:
2249             deprecated_warning(configname,configlineno,"--no-show-photos",
2250                                "--list-options ","no-show-photos");
2251             deprecated_warning(configname,configlineno,"--no-show-photos",
2252                                "--verify-options ","no-show-photos");
2253             opt.list_options&=~LIST_SHOW_PHOTOS;
2254             opt.verify_options&=~VERIFY_SHOW_PHOTOS;
2255             break;
2256           case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
2257           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
2258           case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
2259           case oForceV4Certs: opt.force_v4_certs = 1; break;
2260           case oNoForceV4Certs: opt.force_v4_certs = 0; break;
2261           case oForceMDC: opt.force_mdc = 1; break;
2262           case oNoForceMDC: opt.force_mdc = 0; break;
2263           case oDisableMDC: opt.disable_mdc = 1; break;
2264           case oNoDisableMDC: opt.disable_mdc = 0; break;
2265           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
2266           case oS2KDigest: s2k_digest_string = xstrdup(pargs.r.ret_str); break;
2267           case oS2KCipher: s2k_cipher_string = xstrdup(pargs.r.ret_str); break;
2268           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
2269           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
2270           case oEncryptTo: /* store the recipient in the second list */
2271             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2272             sl->flags = 1;
2273             break;
2274           case oHiddenEncryptTo: /* store the recipient in the second list */
2275             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2276             sl->flags = 1|2;
2277             break;
2278           case oRecipient: /* store the recipient */
2279             add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2280             any_explicit_recipient = 1;
2281             break;
2282           case oHiddenRecipient: /* store the recipient with a flag */
2283             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2284             sl->flags = 2;
2285             any_explicit_recipient = 1;
2286             break;
2287           case oTextmodeShort: opt.textmode = 2; break;
2288           case oTextmode: opt.textmode=1;  break;
2289           case oNoTextmode: opt.textmode=0;  break;
2290           case oExpert: opt.expert = 1; break;
2291           case oNoExpert: opt.expert = 0; break;
2292           case oDefSigExpire:
2293             if(*pargs.r.ret_str!='\0')
2294               {
2295                 if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
2296                   log_error(_("`%s' is not a valid signature expiration\n"),
2297                             pargs.r.ret_str);
2298                 else
2299                   opt.def_sig_expire=pargs.r.ret_str;
2300               }
2301             break;
2302           case oAskSigExpire: opt.ask_sig_expire = 1; break;
2303           case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
2304           case oDefCertExpire:
2305             if(*pargs.r.ret_str!='\0')
2306               {
2307                 if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
2308                   log_error(_("`%s' is not a valid signature expiration\n"),
2309                             pargs.r.ret_str);
2310                 else
2311                   opt.def_cert_expire=pargs.r.ret_str;
2312               }
2313             break;
2314           case oAskCertExpire: opt.ask_cert_expire = 1; break;
2315           case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
2316           case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
2317           case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
2318           case oAskCertLevel: opt.ask_cert_level = 1; break;
2319           case oNoAskCertLevel: opt.ask_cert_level = 0; break;
2320           case oLocalUser: /* store the local users */
2321             add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
2322             break;
2323           case oCompress:
2324             /* this is the -z command line option */
2325             opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
2326             break;
2327           case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
2328           case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
2329           case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
2330           case oPasswd:
2331             set_passphrase_from_string(pargs.r.ret_str);
2332             break;
2333           case oPasswdFD:
2334             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2335             opt.use_agent = 0;
2336             break;
2337           case oPasswdFile:
2338             pwfd = open_info_file (pargs.r.ret_str, 0);
2339             break;
2340           case oCommandFD:
2341             opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2342             break;
2343           case oCommandFile:
2344             opt.command_fd = open_info_file (pargs.r.ret_str, 0);
2345             break;
2346           case oCipherAlgo: 
2347             def_cipher_string = xstrdup(pargs.r.ret_str);
2348             break;
2349           case oDigestAlgo:
2350             def_digest_string = xstrdup(pargs.r.ret_str);
2351             break;
2352           case oCompressAlgo:
2353             /* If it is all digits, stick a Z in front of it for
2354                later.  This is for backwards compatibility with
2355                versions that took the compress algorithm number. */
2356             {
2357               char *pt=pargs.r.ret_str;
2358               while(*pt)
2359                 {
2360                   if (!isascii (*pt) || !isdigit (*pt))
2361                     break;
2362
2363                   pt++;
2364                 }
2365
2366               if(*pt=='\0')
2367                 {
2368                   compress_algo_string=xmalloc(strlen(pargs.r.ret_str)+2);
2369                   strcpy(compress_algo_string,"Z");
2370                   strcat(compress_algo_string,pargs.r.ret_str);
2371                 }
2372               else
2373                 compress_algo_string = xstrdup(pargs.r.ret_str);
2374             }
2375             break;
2376           case oCertDigestAlgo: cert_digest_string = xstrdup(pargs.r.ret_str); break;
2377           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
2378           case oRequireSecmem: require_secmem=1; break;
2379           case oNoRequireSecmem: require_secmem=0; break;
2380           case oNoPermissionWarn: opt.no_perm_warn=1; break;
2381           case oNoMDCWarn: opt.no_mdc_warn=1; break;
2382           case oDisplayCharset:
2383             if( set_native_charset( pargs.r.ret_str ) )
2384                 log_error(_("`%s' is not a valid character set\n"),
2385                           pargs.r.ret_str);
2386             break;
2387           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
2388           case oEscapeFrom: opt.escape_from = 1; break;
2389           case oNoEscapeFrom: opt.escape_from = 0; break;
2390           case oLockOnce: opt.lock_once = 1; break;
2391           case oLockNever:
2392             disable_dotlock ();
2393             random_disable_locking ();
2394             break;
2395           case oLockMultiple:
2396 #ifndef __riscos__
2397             opt.lock_once = 0;
2398 #else /* __riscos__ */
2399             riscos_not_implemented("lock-multiple");
2400 #endif /* __riscos__ */
2401             break;
2402           case oKeyServer:
2403             {
2404               struct keyserver_spec *keyserver;
2405               keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
2406                                             configname,configlineno);
2407               if(!keyserver)
2408                 log_error(_("could not parse keyserver URL\n"));
2409               else
2410                 {
2411                   keyserver->next=opt.keyserver;
2412                   opt.keyserver=keyserver;
2413                 }
2414             }
2415             break;
2416           case oKeyServerOptions:
2417             if(!parse_keyserver_options(pargs.r.ret_str))
2418               {
2419                 if(configname)
2420                   log_error(_("%s:%d: invalid keyserver options\n"),
2421                             configname,configlineno);
2422                 else
2423                   log_error(_("invalid keyserver options\n"));
2424               }
2425             break;
2426           case oImportOptions:
2427             if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
2428               {
2429                 if(configname)
2430                   log_error(_("%s:%d: invalid import options\n"),
2431                             configname,configlineno);
2432                 else
2433                   log_error(_("invalid import options\n"));
2434               }
2435             break;
2436           case oExportOptions:
2437             if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
2438               {
2439                 if(configname)
2440                   log_error(_("%s:%d: invalid export options\n"),
2441                             configname,configlineno);
2442                 else
2443                   log_error(_("invalid export options\n"));
2444               }
2445             break;
2446           case oListOptions:
2447             if(!parse_list_options(pargs.r.ret_str))
2448               {
2449                 if(configname)
2450                   log_error(_("%s:%d: invalid list options\n"),
2451                             configname,configlineno);
2452                 else
2453                   log_error(_("invalid list options\n"));
2454               }
2455             break;
2456           case oVerifyOptions:
2457             {
2458               struct parse_options vopts[]=
2459                 {
2460                   {"show-photos",VERIFY_SHOW_PHOTOS,NULL,
2461                    N_("display photo IDs during signature verification")},
2462                   {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL,
2463                    N_("show policy URLs during signature verification")},
2464                   {"show-notations",VERIFY_SHOW_NOTATIONS,NULL,
2465                    N_("show all notations during signature verification")},
2466                   {"show-std-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
2467                    N_("show IETF standard notations during signature verification")},
2468                   {"show-standard-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
2469                    NULL},
2470                   {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL,
2471                    N_("show user-supplied notations during signature verification")},
2472                   {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL,
2473                    N_("show preferred keyserver URLs during signature verification")},
2474                   {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL,
2475                    N_("show user ID validity during signature verification")},
2476                   {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL,
2477                    N_("show revoked and expired user IDs in signature verification")},
2478                   {"pka-lookups",VERIFY_PKA_LOOKUPS,NULL,
2479                    N_("validate signatures with PKA data")},
2480                   {"pka-trust-increase",VERIFY_PKA_TRUST_INCREASE,NULL,
2481                    N_("elevate the trust of signatures with valid PKA data")},
2482                   {NULL,0,NULL,NULL}
2483                 };
2484
2485               if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
2486                 {
2487                   if(configname)
2488                     log_error(_("%s:%d: invalid verify options\n"),
2489                               configname,configlineno);
2490                   else
2491                     log_error(_("invalid verify options\n"));
2492                 }
2493             }
2494             break;
2495           case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
2496           case oExecPath:
2497             if(set_exec_path(pargs.r.ret_str))
2498               log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
2499             else
2500               opt.exec_path_set=1;
2501             break;
2502           case oSetNotation:
2503             add_notation_data( pargs.r.ret_str, 0 );
2504             add_notation_data( pargs.r.ret_str, 1 );
2505             break;
2506           case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
2507           case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
2508           case oShowNotation:
2509             deprecated_warning(configname,configlineno,"--show-notation",
2510                                "--list-options ","show-notations");
2511             deprecated_warning(configname,configlineno,"--show-notation",
2512                                "--verify-options ","show-notations");
2513             opt.list_options|=LIST_SHOW_NOTATIONS;
2514             opt.verify_options|=VERIFY_SHOW_NOTATIONS;
2515             break;
2516           case oNoShowNotation:
2517             deprecated_warning(configname,configlineno,"--no-show-notation",
2518                                "--list-options ","no-show-notations");
2519             deprecated_warning(configname,configlineno,"--no-show-notation",
2520                                "--verify-options ","no-show-notations");
2521             opt.list_options&=~LIST_SHOW_NOTATIONS;
2522             opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
2523             break;
2524           case oUtf8Strings: utf8_strings = 1; break;
2525           case oNoUtf8Strings: utf8_strings = 0; break;
2526           case oDisableCipherAlgo:
2527                 disable_cipher_algo( string_to_cipher_algo(pargs.r.ret_str) );
2528                 break;
2529           case oDisablePubkeyAlgo:
2530                 disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
2531                 break;
2532           case oNoSigCache: opt.no_sig_cache = 1; break;
2533           case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
2534           case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
2535           case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
2536           case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
2537           case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
2538           case oNoLiteral: opt.no_literal = 1; break;
2539           case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
2540           case oHonorHttpProxy:
2541                 add_to_strlist(&opt.keyserver_options.other,"http-proxy");
2542                 deprecated_warning(configname,configlineno,
2543                                    "--honor-http-proxy",
2544                                    "--keyserver-options ","http-proxy");
2545                 break;
2546           case oFastListMode: opt.fast_list_mode = 1; break;
2547           case oFixedListMode: opt.fixed_list_mode = 1; break;
2548           case oListOnly: opt.list_only=1; break;
2549           case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
2550           case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
2551           case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
2552           case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
2553           case oNoRandomSeedFile: use_random_seed = 0; break;
2554           case oAutoKeyRetrieve:
2555           case oNoAutoKeyRetrieve:
2556                 if(pargs.r_opt==oAutoKeyRetrieve)
2557                   opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
2558                 else
2559                   opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
2560
2561                 deprecated_warning(configname,configlineno,
2562                            pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
2563                                "--no-auto-key-retrieve","--keyserver-options ",
2564                            pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
2565                                "no-auto-key-retrieve");
2566                 break;
2567           case oShowSessionKey: opt.show_session_key = 1; break;
2568           case oOverrideSessionKey:
2569                 opt.override_session_key = pargs.r.ret_str;
2570                 break;
2571           case oMergeOnly:
2572                 deprecated_warning(configname,configlineno,"--merge-only",
2573                                    "--import-options ","merge-only");
2574                 opt.import_options|=IMPORT_MERGE_ONLY;
2575             break;
2576           case oAllowSecretKeyImport: /* obsolete */ break;
2577           case oTryAllSecrets: opt.try_all_secrets = 1; break;
2578           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
2579           case oEnableSpecialFilenames:
2580             iobuf_enable_special_filenames (1);
2581             break;
2582           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
2583           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
2584           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
2585           case oPreservePermissions: opt.preserve_permissions=1; break;
2586           case oDefaultPreferenceList:
2587             opt.def_preference_list = pargs.r.ret_str;
2588             break;
2589           case oPersonalCipherPreferences:
2590             pers_cipher_list=pargs.r.ret_str;
2591             break;
2592           case oPersonalDigestPreferences:
2593             pers_digest_list=pargs.r.ret_str;
2594             break;
2595           case oPersonalCompressPreferences:
2596             pers_compress_list=pargs.r.ret_str;
2597             break;
2598           case oDisplay: opt.display = pargs.r.ret_str; break;
2599           case oTTYname: opt.ttyname = pargs.r.ret_str; break;
2600           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
2601           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
2602           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
2603           case oGroup: add_group(pargs.r.ret_str); break;
2604           case oUnGroup: rm_group(pargs.r.ret_str); break;
2605           case oNoGroups:
2606             while(opt.grouplist)
2607               {
2608                 struct groupitem *iter=opt.grouplist;
2609                 free_strlist(iter->values);
2610                 opt.grouplist=opt.grouplist->next;
2611                 xfree(iter);
2612               }
2613             break;
2614           case oStrict: opt.strict=1; log_set_strict(1); break;
2615           case oNoStrict: opt.strict=0; log_set_strict(0); break;
2616           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
2617           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
2618           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
2619           case oMultifile: multifile=1; break;
2620           case oKeyidFormat:
2621             if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
2622               opt.keyid_format=KF_SHORT;
2623             else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
2624               opt.keyid_format=KF_LONG;
2625             else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
2626               opt.keyid_format=KF_0xSHORT;
2627             else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
2628               opt.keyid_format=KF_0xLONG;
2629             else
2630               log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
2631             break;
2632
2633           case oExitOnStatusWriteError:
2634             opt.exit_on_status_write_error = 1;
2635             break;
2636
2637           case oLimitCardInsertTries: 
2638             opt.limit_card_insert_tries = pargs.r.ret_int; 
2639             break;
2640
2641           case oRequireCrossCert: opt.flags.require_cross_cert=1; break;
2642           case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
2643
2644           case oAutoKeyLocate:
2645             if(!parse_auto_key_locate(pargs.r.ret_str))
2646               {
2647                 if(configname)
2648                   log_error(_("%s:%d: invalid auto-key-locate list\n"),
2649                             configname,configlineno);
2650                 else
2651                   log_error(_("invalid auto-key-locate list\n"));
2652               }
2653             break;
2654           case oNoAutoKeyLocate:
2655             release_akl();
2656             break;
2657
2658           case oAllowMultisigVerification:
2659             opt.allow_multisig_verification = 1;
2660             break;
2661
2662           case oNoop: break;
2663
2664           default : pargs.err = configfp? 1:2; break;
2665           }
2666       }
2667
2668
2669     if( configfp ) {
2670         fclose( configfp );
2671         configfp = NULL;
2672         /* Remember the first config file name. */
2673         if (!save_configname)
2674           save_configname = configname;
2675         else
2676           xfree(configname);
2677         configname = NULL;
2678         goto next_pass;
2679     }
2680     xfree( configname ); configname = NULL;
2681     if( log_get_errorcount(0) )
2682         g10_exit(2);
2683
2684     /* The command --gpgconf-list is pretty simple and may be called
2685        directly after the option parsing. */
2686     if (cmd == aGPGConfList)
2687       {
2688         gpgconf_list (save_configname);
2689         g10_exit (0);
2690       }
2691     xfree (save_configname);
2692
2693     if( nogreeting )
2694         greeting = 0;
2695
2696     if( greeting ) {
2697         fprintf(stderr, "%s %s; %s\n",
2698                         strusage(11), strusage(13), strusage(14) );
2699         fprintf(stderr, "%s\n", strusage(15) );
2700     }
2701 #ifdef IS_DEVELOPMENT_VERSION
2702     if( !opt.batch )
2703       {
2704         const char *s;
2705
2706         if((s=strusage(20)))
2707           log_info("%s\n",s);
2708         if((s=strusage(21)))
2709           log_info("%s\n",s);
2710         if((s=strusage(22)))
2711           log_info("%s\n",s);
2712       }
2713 #endif
2714
2715     if (opt.verbose > 2)
2716         log_info ("using character set `%s'\n", get_native_charset ());
2717
2718     if( may_coredump && !opt.quiet )
2719         log_info(_("WARNING: program may create a core file!\n"));
2720
2721     if (eyes_only) {
2722       if (opt.set_filename)
2723           log_info(_("WARNING: %s overrides %s\n"),
2724                    "--for-your-eyes-only","--set-filename");
2725
2726       opt.set_filename="_CONSOLE";
2727     }
2728
2729     if (opt.no_literal) {
2730         log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
2731         if (opt.textmode)
2732             log_error(_("%s not allowed with %s!\n"),
2733                        "--textmode", "--no-literal" );
2734         if (opt.set_filename)
2735             log_error(_("%s makes no sense with %s!\n"),
2736                         eyes_only?"--for-your-eyes-only":"--set-filename",
2737                         "--no-literal" );
2738     }
2739
2740 #ifndef ENABLE_AGENT_SUPPORT   
2741     if (opt.use_agent) {
2742       log_info(_("NOTE: %s is not available in this version\n"),
2743                "--use-agent");
2744       opt.use_agent = 0;
2745     }
2746 #endif /*!ENABLE_AGENT_SUPPORT*/
2747
2748     if (opt.set_filesize)
2749         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2750     if( opt.batch )
2751         tty_batchmode( 1 );
2752
2753     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
2754
2755     if(require_secmem && !got_secmem)
2756       {
2757         log_info(_("will not run with insecure memory due to %s\n"),
2758                  "--require-secmem");
2759         g10_exit(2);
2760       }
2761
2762     set_debug();
2763
2764     /* Do these after the switch(), so they can override settings. */
2765     if(PGP2)
2766       {
2767         int unusable=0;
2768
2769         if(cmd==aSign && !detached_sig)
2770           {
2771             log_info(_("you can only make detached or clear signatures "
2772                        "while in --pgp2 mode\n"));
2773             unusable=1;
2774           }
2775         else if(cmd==aSignEncr || cmd==aSignSym)
2776           {
2777             log_info(_("you can't sign and encrypt at the "
2778                        "same time while in --pgp2 mode\n"));
2779             unusable=1;
2780           }
2781         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
2782           {
2783             log_info(_("you must use files (and not a pipe) when "
2784                        "working with --pgp2 enabled.\n"));
2785             unusable=1;
2786           }
2787         else if(cmd==aEncr || cmd==aSym)
2788           {
2789             /* Everything else should work without IDEA (except using
2790                a secret key encrypted with IDEA and setting an IDEA
2791                preference, but those have their own error
2792                messages). */
2793
2794             if(check_cipher_algo(CIPHER_ALGO_IDEA))
2795               {
2796                 log_info(_("encrypting a message in --pgp2 mode requires "
2797                            "the IDEA cipher\n"));
2798                 idea_cipher_warn(1);
2799                 unusable=1;
2800               }
2801             else if(cmd==aSym)
2802               {
2803                 /* This only sets IDEA for symmetric encryption
2804                    since it is set via select_algo_from_prefs for
2805                    pk encryption. */
2806                 xfree(def_cipher_string);
2807                 def_cipher_string = xstrdup("idea");
2808               }
2809
2810             /* PGP2 can't handle the output from the textmode
2811                filter, so we disable it for anything that could
2812                create a literal packet (only encryption and
2813                symmetric encryption, since we disable signing
2814                above). */
2815             if(!unusable)
2816               opt.textmode=0;
2817           }
2818
2819         if(unusable)
2820           compliance_failure();
2821         else
2822           {
2823             opt.force_v4_certs = 0;
2824             opt.escape_from = 1;
2825             opt.force_v3_sigs = 1;
2826             opt.pgp2_workarounds = 1;
2827             opt.ask_sig_expire = 0;
2828             opt.ask_cert_expire = 0;
2829             xfree(def_digest_string);
2830             def_digest_string = xstrdup("md5");
2831             xfree(s2k_digest_string);
2832             s2k_digest_string = xstrdup("md5");
2833             opt.compress_algo = COMPRESS_ALGO_ZIP;
2834           }
2835       }
2836     else if(PGP6)
2837       {
2838         opt.escape_from=1;
2839         opt.force_v3_sigs=1;
2840         opt.ask_sig_expire=0;
2841       }
2842     else if(PGP7)
2843       {
2844         opt.escape_from=1;
2845         opt.force_v3_sigs=1;
2846         opt.ask_sig_expire=0;
2847       }
2848     else if(PGP8)
2849       {
2850         opt.escape_from=1;
2851       }
2852
2853     /* must do this after dropping setuid, because string_to...
2854      * may try to load an module */
2855     if( def_cipher_string ) {
2856         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
2857         if(opt.def_cipher_algo==0 &&
2858            (ascii_strcasecmp(def_cipher_string,"idea")==0
2859             || ascii_strcasecmp(def_cipher_string,"s1")==0))
2860           idea_cipher_warn(1);
2861         xfree(def_cipher_string); def_cipher_string = NULL;
2862         if( check_cipher_algo(opt.def_cipher_algo) )
2863             log_error(_("selected cipher algorithm is invalid\n"));
2864     }
2865     if( def_digest_string ) {
2866         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
2867         xfree(def_digest_string); def_digest_string = NULL;
2868         if( check_digest_algo(opt.def_digest_algo) )
2869             log_error(_("selected digest algorithm is invalid\n"));
2870     }
2871     if( compress_algo_string ) {
2872         opt.compress_algo = string_to_compress_algo(compress_algo_string);
2873         xfree(compress_algo_string); compress_algo_string = NULL;
2874         if( check_compress_algo(opt.compress_algo) )
2875             log_error(_("selected compression algorithm is invalid\n"));
2876     }
2877     if( cert_digest_string ) {
2878         opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
2879         xfree(cert_digest_string); cert_digest_string = NULL;
2880         if( check_digest_algo(opt.cert_digest_algo) )
2881             log_error(_("selected certification digest algorithm is invalid\n"));
2882     }
2883     if( s2k_cipher_string ) {
2884         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
2885         xfree(s2k_cipher_string); s2k_cipher_string = NULL;
2886         if( check_cipher_algo(opt.s2k_cipher_algo) )
2887             log_error(_("selected cipher algorithm is invalid\n"));
2888     }
2889     if( s2k_digest_string ) {
2890         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
2891         xfree(s2k_digest_string); s2k_digest_string = NULL;
2892         if( check_digest_algo(opt.s2k_digest_algo) )
2893             log_error(_("selected digest algorithm is invalid\n"));
2894     }
2895     if( opt.completes_needed < 1 )
2896       log_error(_("completes-needed must be greater than 0\n"));
2897     if( opt.marginals_needed < 2 )
2898       log_error(_("marginals-needed must be greater than 1\n"));
2899     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
2900       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
2901     if(opt.def_cert_level<0 || opt.def_cert_level>3)
2902       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
2903     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
2904       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
2905     switch( opt.s2k_mode ) {
2906       case 0:
2907         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
2908         break;
2909       case 1: case 3: break;
2910       default:
2911         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
2912     }
2913
2914     /* This isn't actually needed, but does serve to error out if the
2915        string is invalid. */
2916     if(opt.def_preference_list &&
2917         keygen_set_std_prefs(opt.def_preference_list,0))
2918       log_error(_("invalid default preferences\n"));
2919
2920     /* We provide defaults for the personal digest list.  This is
2921        SHA-1. */
2922     if(!pers_digest_list)
2923       pers_digest_list="h2";
2924
2925     if(pers_cipher_list &&
2926        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
2927       log_error(_("invalid personal cipher preferences\n"));
2928
2929     if(pers_digest_list &&
2930        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
2931       log_error(_("invalid personal digest preferences\n"));
2932
2933     if(pers_compress_list &&
2934        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
2935       log_error(_("invalid personal compress preferences\n"));
2936
2937     /* We don't support all possible commands with multifile yet */
2938     if(multifile)
2939       {
2940         char *cmdname;
2941
2942         switch(cmd)
2943           {
2944           case aSign:
2945             cmdname="--sign";
2946             break;
2947           case aClearsign:
2948             cmdname="--clearsign";
2949             break;
2950           case aDetachedSign:
2951             cmdname="--detach-sign";
2952             break;
2953           case aSym:
2954             cmdname="--symmetric";
2955             break;
2956           case aEncrSym:
2957             cmdname="--symmetric --encrypt";
2958             break;
2959           case aStore:
2960             cmdname="--store";
2961             break;
2962           default:
2963             cmdname=NULL;
2964             break;
2965           }
2966
2967         if(cmdname)
2968           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
2969       }
2970
2971     if( log_get_errorcount(0) )
2972         g10_exit(2);
2973
2974     if(opt.compress_level==0)
2975       opt.compress_algo=COMPRESS_ALGO_NONE;
2976
2977     /* Check our chosen algorithms against the list of legal
2978        algorithms. */
2979
2980     if(!GNUPG)
2981       {
2982         const char *badalg=NULL;
2983         preftype_t badtype=PREFTYPE_NONE;
2984
2985         if(opt.def_cipher_algo
2986            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
2987           {
2988             badalg=cipher_algo_to_string(opt.def_cipher_algo);
2989             badtype=PREFTYPE_SYM;
2990           }
2991         else if(opt.def_digest_algo
2992                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
2993           {
2994             badalg=digest_algo_to_string(opt.def_digest_algo);
2995             badtype=PREFTYPE_HASH;
2996           }
2997         else if(opt.cert_digest_algo
2998                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
2999           {
3000             badalg=digest_algo_to_string(opt.cert_digest_algo);
3001             badtype=PREFTYPE_HASH;
3002           }
3003         else if(opt.compress_algo!=-1
3004                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
3005           {
3006             badalg=compress_algo_to_string(opt.compress_algo);
3007             badtype=PREFTYPE_ZIP;
3008           }
3009
3010         if(badalg)
3011           {
3012             switch(badtype)
3013               {
3014               case PREFTYPE_SYM:
3015                 log_info(_("you may not use cipher algorithm `%s'"
3016                            " while in %s mode\n"),
3017                          badalg,compliance_option_string());
3018                 break;
3019               case PREFTYPE_HASH:
3020                 log_info(_("you may not use digest algorithm `%s'"
3021                            " while in %s mode\n"),
3022                          badalg,compliance_option_string());
3023                 break;
3024               case PREFTYPE_ZIP:
3025                 log_info(_("you may not use compression algorithm `%s'"
3026                            " while in %s mode\n"),
3027                          badalg,compliance_option_string());
3028                 break;
3029               default:
3030                 BUG();
3031               }
3032
3033             compliance_failure();
3034           }
3035       }
3036
3037     /* set the random seed file */
3038     if( use_random_seed ) {
3039         char *p = make_filename(opt.homedir, "random_seed", NULL );
3040         set_random_seed_file(p);
3041         if (!access (p, F_OK))
3042           register_secured_file (p);
3043         xfree(p);
3044     }
3045
3046     if( !cmd && opt.fingerprint && !with_fpr ) {
3047         set_cmd( &cmd, aListKeys);
3048     }
3049
3050     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
3051         if( cmd == aKModeC ) {
3052             opt.fingerprint = 1;
3053             cmd = aKMode;
3054         }
3055         opt.list_sigs = 0;
3056         if( opt.verbose > 2 )
3057             opt.check_sigs++;
3058         if( opt.verbose > 1 )
3059             opt.list_sigs++;
3060
3061         opt.verbose = opt.verbose > 1;
3062         g10_opt_verbose = opt.verbose;
3063     }
3064
3065     /* kludge to let -sat generate a clear text signature */
3066     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
3067         cmd = aClearsign;
3068
3069     if( opt.verbose > 1 )
3070         set_packet_list_mode(1);
3071
3072     /* Add the keyrings, but not for some special commands and not in
3073        case of "-kvv userid keyring".  Also avoid adding the secret
3074        keyring for a couple of commands to avoid unneeded access in
3075        case the secrings are stored on a floppy.
3076        
3077        We always need to add the keyrings if we are running under
3078        SELinux, this is so that the rings are added to the list of
3079        secured files. */
3080     if( ALWAYS_ADD_KEYRINGS 
3081         || (cmd != aDeArmor && cmd != aEnArmor
3082             && !(cmd == aKMode && argc == 2 )) ) 
3083       {
3084         if (ALWAYS_ADD_KEYRINGS
3085             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
3086                 && cmd != aVerify && cmd != aSym))
3087           {
3088             if (!sec_nrings || default_keyring) /* add default secret rings */
3089               keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
3090             for (sl = sec_nrings; sl; sl = sl->next)
3091               keydb_add_resource ( sl->d, 0, 1 );
3092           }
3093         if( !nrings || default_keyring )  /* add default ring */
3094             keydb_add_resource ("pubring" EXTSEP_S "gpg", 4, 0);
3095         for(sl = nrings; sl; sl = sl->next )
3096             keydb_add_resource ( sl->d, sl->flags, 0 );
3097       }
3098     FREE_STRLIST(nrings);
3099     FREE_STRLIST(sec_nrings);
3100
3101
3102     if( pwfd != -1 )  /* read the passphrase now. */
3103         read_passphrase_from_fd( pwfd );
3104
3105     fname = argc? *argv : NULL;
3106
3107     if(fname && utf8_strings)
3108       opt.flags.utf8_filename=1;
3109
3110     switch( cmd ) {
3111       case aPrimegen:
3112       case aPrintMD:
3113       case aPrintMDs:
3114       case aGenRandom:
3115       case aDeArmor:
3116       case aEnArmor:
3117       case aFixTrustDB:
3118         break;
3119       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
3120       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
3121       default: rc = setup_trustdb(1, trustdb_name ); break;
3122     }
3123     if( rc )
3124         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
3125
3126
3127     switch (cmd)
3128       {
3129       case aStore: 
3130       case aSym:  
3131       case aSign: 
3132       case aSignSym: 
3133       case aClearsign: 
3134         if (!opt.quiet && any_explicit_recipient)
3135           log_info (_("WARNING: recipients (-r) given "
3136                       "without using public key encryption\n"));
3137         break;
3138       default:
3139         break;
3140       }
3141
3142     switch( cmd )
3143       {
3144       case aStore: /* only store the file */
3145         if( argc > 1 )
3146             wrong_args(_("--store [filename]"));
3147         if( (rc = encode_store(fname)) )
3148             log_error ("storing `%s' failed: %s\n",
3149                        print_fname_stdin(fname),g10_errstr(rc) );
3150         break;
3151       case aSym: /* encrypt the given file only with the symmetric cipher */
3152         if( argc > 1 )
3153             wrong_args(_("--symmetric [filename]"));
3154         if( (rc = encode_symmetric(fname)) )
3155             log_error (_("symmetric encryption of `%s' failed: %s\n"),
3156                         print_fname_stdin(fname),g10_errstr(rc) );
3157         break;
3158
3159       case aEncr: /* encrypt the given file */
3160         if(multifile)
3161           encode_crypt_files(argc, argv, remusr);
3162         else
3163           {
3164             if( argc > 1 )
3165               wrong_args(_("--encrypt [filename]"));
3166             if( (rc = encode_crypt(fname,remusr,0)) )
3167               log_error("%s: encryption failed: %s\n",
3168                         print_fname_stdin(fname), g10_errstr(rc) );
3169           }
3170         break;
3171
3172       case aEncrSym:
3173         /* This works with PGP 8 in the sense that it acts just like a
3174            symmetric message.  It doesn't work at all with 2 or 6.  It
3175            might work with 7, but alas, I don't have a copy to test
3176            with right now. */
3177         if( argc > 1 )
3178           wrong_args(_("--symmetric --encrypt [filename]"));
3179         else if(opt.s2k_mode==0)
3180           log_error(_("you cannot use --symmetric --encrypt"
3181                       " with --s2k-mode 0\n"));
3182         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3183           log_error(_("you cannot use --symmetric --encrypt"
3184                       " while in %s mode\n"),compliance_option_string());
3185         else
3186           {
3187             if( (rc = encode_crypt(fname,remusr,1)) )
3188               log_error("%s: encryption failed: %s\n",
3189                         print_fname_stdin(fname), g10_errstr(rc) );
3190           }
3191         break;
3192
3193       case aSign: /* sign the given file */
3194         sl = NULL;
3195         if( detached_sig ) { /* sign all files */
3196             for( ; argc; argc--, argv++ )
3197                 add_to_strlist( &sl, *argv );
3198         }
3199         else {
3200             if( argc > 1 )
3201                 wrong_args(_("--sign [filename]"));
3202             if( argc ) {
3203                 sl = xmalloc_clear( sizeof *sl + strlen(fname));
3204                 strcpy(sl->d, fname);
3205             }
3206         }
3207         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
3208             log_error("signing failed: %s\n", g10_errstr(rc) );
3209         free_strlist(sl);
3210         break;
3211
3212       case aSignEncr: /* sign and encrypt the given file */
3213         if( argc > 1 )
3214             wrong_args(_("--sign --encrypt [filename]"));
3215         if( argc ) {
3216             sl = xmalloc_clear( sizeof *sl + strlen(fname));
3217             strcpy(sl->d, fname);
3218         }
3219         else
3220             sl = NULL;
3221         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
3222             log_error("%s: sign+encrypt failed: %s\n",
3223                       print_fname_stdin(fname), g10_errstr(rc) );
3224         free_strlist(sl);
3225         break;
3226
3227       case aSignEncrSym: /* sign and encrypt the given file */
3228         if( argc > 1 )
3229             wrong_args(_("--symmetric --sign --encrypt [filename]"));
3230         else if(opt.s2k_mode==0)
3231           log_error(_("you cannot use --symmetric --sign --encrypt"
3232                       " with --s2k-mode 0\n"));
3233         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3234           log_error(_("you cannot use --symmetric --sign --encrypt"
3235                       " while in %s mode\n"),compliance_option_string());
3236         else
3237           {
3238             if( argc )
3239               {
3240                 sl = xmalloc_clear( sizeof *sl + strlen(fname));
3241                 strcpy(sl->d, fname);
3242               }
3243             else
3244               sl = NULL;
3245             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
3246               log_error("%s: symmetric+sign+encrypt failed: %s\n",
3247                         print_fname_stdin(fname), g10_errstr(rc) );
3248             free_strlist(sl);
3249           }
3250         break;
3251
3252       case aSignSym: /* sign and conventionally encrypt the given file */
3253         if (argc > 1)
3254             wrong_args(_("--sign --symmetric [filename]"));
3255         rc = sign_symencrypt_file (fname, locusr);
3256         if (rc)
3257             log_error("%s: sign+symmetric failed: %s\n",
3258                       print_fname_stdin(fname), g10_errstr(rc) );
3259         break;
3260
3261       case aClearsign: /* make a clearsig */
3262         if( argc > 1 )
3263             wrong_args(_("--clearsign [filename]"));
3264         if( (rc = clearsign_file(fname, locusr, NULL)) )
3265             log_error("%s: clearsign failed: %s\n",
3266                       print_fname_stdin(fname), g10_errstr(rc) );
3267         break;
3268
3269       case aVerify:
3270         if(multifile)
3271           {
3272             if( (rc = verify_files( argc, argv ) ))
3273               log_error("verify files failed: %s\n", g10_errstr(rc) );
3274           }
3275         else
3276           {
3277             if( (rc = verify_signatures( argc, argv ) ))
3278               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
3279           }
3280         break;
3281
3282       case aDecrypt:
3283         if(multifile)
3284           decrypt_messages(argc, argv);
3285         else
3286           {
3287             if( argc > 1 )
3288               wrong_args(_("--decrypt [filename]"));
3289             if( (rc = decrypt_message( fname ) ))
3290               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
3291           }
3292         break;
3293             
3294       case aSignKey:
3295         if( argc != 1 )
3296           wrong_args(_("--sign-key user-id"));
3297         /* fall through */
3298       case aLSignKey:
3299         if( argc != 1 )
3300           wrong_args(_("--lsign-key user-id"));
3301         /* fall through */
3302
3303         sl=NULL;
3304
3305         if(cmd==aSignKey)
3306           append_to_strlist(&sl,"sign");
3307         else if(cmd==aLSignKey)
3308           append_to_strlist(&sl,"lsign");
3309         else
3310           BUG();
3311
3312         append_to_strlist( &sl, "save" );
3313         username = make_username( fname );
3314         keyedit_menu(fname, locusr, sl, 0, 0 );
3315         xfree(username);
3316         free_strlist(sl);
3317         break;
3318
3319       case aEditKey: /* Edit a key signature */
3320         if( !argc )
3321             wrong_args(_("--edit-key user-id [commands]"));
3322         username = make_username( fname );
3323         if( argc > 1 ) {
3324             sl = NULL;
3325             for( argc--, argv++ ; argc; argc--, argv++ )
3326                 append_to_strlist( &sl, *argv );
3327             keyedit_menu( username, locusr, sl, 0, 1 );
3328             free_strlist(sl);
3329         }
3330         else
3331             keyedit_menu(username, locusr, NULL, 0, 1 );
3332         xfree(username);
3333         break;
3334
3335       case aDeleteKeys:
3336       case aDeleteSecretKeys:
3337       case aDeleteSecretAndPublicKeys:
3338         sl = NULL;
3339         /* I'm adding these in reverse order as add_to_strlist2
3340            reverses them again, and it's easier to understand in the
3341            proper order :) */
3342         for( ; argc; argc-- )
3343           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
3344         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
3345         free_strlist(sl);
3346         break;
3347
3348       case aCheckKeys:
3349         opt.check_sigs = 1;
3350       case aListSigs:
3351         opt.list_sigs = 1;
3352       case aListKeys:
3353         sl = NULL;
3354         for( ; argc; argc--, argv++ )
3355             add_to_strlist2( &sl, *argv, utf8_strings );
3356         public_key_list( sl );
3357         free_strlist(sl);
3358         break;
3359       case aListSecretKeys:
3360         sl = NULL;
3361         for( ; argc; argc--, argv++ )
3362             add_to_strlist2( &sl, *argv, utf8_strings );
3363         secret_key_list( sl );
3364         free_strlist(sl);
3365         break;
3366
3367       case aKMode: /* list keyring -- NOTE: This will be removed soon */
3368         if( argc < 2 ) { /* -kv [userid] */
3369             sl = NULL;
3370             if (argc && **argv)
3371                 add_to_strlist2( &sl, *argv, utf8_strings );
3372             public_key_list( sl );
3373             free_strlist(sl);
3374         }
3375         else if( argc == 2 ) { /* -kv userid keyring */
3376             if( access( argv[1], R_OK ) ) {
3377                 log_error(_("can't open `%s': %s\n"),
3378                                print_fname_stdin(argv[1]), strerror(errno));
3379             }
3380             else {
3381                 /* add keyring (default keyrings are not registered in this
3382                  * special case */
3383                 keydb_add_resource( argv[1], 0, 0 );
3384                 sl = NULL;
3385                 if (**argv)
3386                     add_to_strlist2( &sl, *argv, utf8_strings );
3387                 public_key_list( sl );
3388                 free_strlist(sl);
3389             }
3390         }
3391         else
3392             wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
3393         break;
3394
3395       case aKeygen: /* generate a key */
3396         if( opt.batch ) {
3397             if( argc > 1 )
3398                 wrong_args("--gen-key [parameterfile]");
3399             generate_keypair( argc? *argv : NULL, NULL, NULL );
3400         }
3401         else {
3402             if( argc )
3403                 wrong_args("--gen-key");
3404             generate_keypair(NULL, NULL, NULL);
3405         }
3406         break;
3407
3408       case aFastImport:
3409         opt.import_options |= IMPORT_FAST;
3410       case aImport:
3411         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3412         break;
3413
3414         /* TODO: There are a number of command that use this same
3415            "make strlist, call function, report error, free strlist"
3416            pattern.  Join them together here and avoid all that
3417            duplicated code. */
3418
3419       case aExport:
3420       case aSendKeys:
3421       case aRecvKeys:
3422         sl = NULL;
3423         for( ; argc; argc--, argv++ )
3424             append_to_strlist2( &sl, *argv, utf8_strings );
3425         if( cmd == aSendKeys )
3426             rc=keyserver_export( sl );
3427         else if( cmd == aRecvKeys )
3428             rc=keyserver_import( sl );
3429         else
3430             rc=export_pubkeys( sl, opt.export_options );
3431         if(rc)
3432           {
3433             if(cmd==aSendKeys)
3434               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3435             else if(cmd==aRecvKeys)
3436               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3437             else
3438               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3439           }
3440         free_strlist(sl);
3441         break;
3442
3443      case aSearchKeys:
3444         sl = NULL;
3445         for( ; argc; argc--, argv++ )
3446           append_to_strlist2( &sl, *argv, utf8_strings );
3447         rc=keyserver_search( sl );
3448         if(rc)
3449           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3450         free_strlist(sl);
3451         break;
3452
3453       case aRefreshKeys:
3454         sl = NULL;
3455         for( ; argc; argc--, argv++ )
3456             append_to_strlist2( &sl, *argv, utf8_strings );
3457         rc=keyserver_refresh(sl);
3458         if(rc)
3459           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3460         free_strlist(sl);
3461         break;
3462
3463       case aFetchKeys:
3464         sl = NULL;
3465         for( ; argc; argc--, argv++ )
3466             append_to_strlist2( &sl, *argv, utf8_strings );
3467         rc=keyserver_fetch(sl);
3468         if(rc)
3469           log_error("key fetch failed: %s\n",g10_errstr(rc));
3470         free_strlist(sl);
3471         break;
3472
3473       case aExportSecret:
3474         sl = NULL;
3475         for( ; argc; argc--, argv++ )
3476             add_to_strlist2( &sl, *argv, utf8_strings );
3477         export_seckeys( sl );
3478         free_strlist(sl);
3479         break;
3480
3481       case aExportSecretSub:
3482         sl = NULL;
3483         for( ; argc; argc--, argv++ )
3484             add_to_strlist2( &sl, *argv, utf8_strings );
3485         export_secsubkeys( sl );
3486         free_strlist(sl);
3487         break;
3488
3489       case aGenRevoke:
3490         if( argc != 1 )
3491             wrong_args("--gen-revoke user-id");
3492         username =  make_username(*argv);
3493         gen_revoke( username );
3494         xfree( username );
3495         break;
3496
3497       case aDesigRevoke:
3498         if( argc != 1 )
3499             wrong_args("--desig-revoke user-id");
3500         username =  make_username(*argv);
3501         gen_desig_revoke( username, locusr );
3502         xfree( username );
3503         break;
3504
3505       case aDeArmor:
3506         if( argc > 1 )
3507             wrong_args("--dearmor [file]");
3508         rc = dearmor_file( argc? *argv: NULL );
3509         if( rc )
3510             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3511         break;
3512
3513       case aEnArmor:
3514         if( argc > 1 )
3515             wrong_args("--enarmor [file]");
3516         rc = enarmor_file( argc? *argv: NULL );
3517         if( rc )
3518             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3519         break;
3520
3521
3522       case aPrimegen:
3523         {   int mode = argc < 2 ? 0 : atoi(*argv);
3524
3525             if( mode == 1 && argc == 2 ) {
3526                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3527             }
3528             else if( mode == 2 && argc == 3 ) {
3529                 mpi_print( stdout, generate_elg_prime(
3530                                              0, atoi(argv[1]),
3531                                              atoi(argv[2]), NULL,NULL ), 1);
3532             }
3533             else if( mode == 3 && argc == 3 ) {
3534                 MPI *factors;
3535                 mpi_print( stdout, generate_elg_prime(
3536                                              1, atoi(argv[1]),
3537                                              atoi(argv[2]), NULL,&factors ), 1);
3538                 putchar('\n');
3539                 mpi_print( stdout, factors[0], 1 ); /* print q */
3540             }
3541             else if( mode == 4 && argc == 3 ) {
3542                 MPI g = mpi_alloc(1);
3543                 mpi_print( stdout, generate_elg_prime(
3544                                                  0, atoi(argv[1]),
3545                                                  atoi(argv[2]), g, NULL ), 1);
3546                 putchar('\n');
3547                 mpi_print( stdout, g, 1 );
3548                 mpi_free(g);
3549             }
3550             else
3551                 wrong_args("--gen-prime mode bits [qbits] ");
3552             putchar('\n');
3553         }
3554         break;
3555
3556       case aGenRandom:
3557         {
3558             int level = argc ? atoi(*argv):0;
3559             int count = argc > 1 ? atoi(argv[1]): 0;
3560             int endless = !count;
3561
3562             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3563                 wrong_args("--gen-random 0|1|2 [count]");
3564
3565             while( endless || count ) {
3566                 byte *p;
3567                 /* Wee need a multiple of 3, so that in case of
3568                    armored output we get a correct string.  No
3569                    linefolding is done, as it is best to levae this to
3570                    other tools */
3571                 size_t n = !endless && count < 99? count : 99;
3572
3573                 p = get_random_bits( n*8, level, 0);
3574 #ifdef HAVE_DOSISH_SYSTEM
3575                 setmode ( fileno(stdout), O_BINARY );
3576 #endif
3577                 if (opt.armor) {
3578                     char *tmp = make_radix64_string (p, n);
3579                     fputs (tmp, stdout);
3580                     xfree (tmp);
3581                     if (n%3 == 1)
3582                       putchar ('=');
3583                     if (n%3)
3584                       putchar ('=');
3585                 } else {
3586                     fwrite( p, n, 1, stdout );
3587                 }
3588                 xfree(p);
3589                 if( !endless )
3590                     count -= n;
3591             }
3592             if (opt.armor)
3593                 putchar ('\n');
3594         }
3595         break;
3596
3597       case aPrintMD:
3598         if( argc < 1)
3599             wrong_args("--print-md algo [files]");
3600         {
3601             int all_algos = (**argv=='*' && !(*argv)[1]);
3602             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3603
3604             if( !algo && !all_algos )
3605                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3606             else {
3607                 argc--; argv++;
3608                 if( !argc )
3609                     print_mds(NULL, algo);
3610                 else {
3611                     for(; argc; argc--, argv++ )
3612                         print_mds(*argv, algo);
3613                 }
3614             }
3615         }
3616         break;
3617
3618       case aPrintMDs: /* old option */
3619         if( !argc )
3620             print_mds(NULL,0);
3621         else {
3622             for(; argc; argc--, argv++ )
3623                 print_mds(*argv,0);
3624         }
3625         break;
3626
3627       case aListTrustDB:
3628         if( !argc )
3629             list_trustdb(NULL);
3630         else {
3631             for( ; argc; argc--, argv++ )
3632                 list_trustdb( *argv );
3633         }
3634         break;
3635
3636       case aUpdateTrustDB:
3637         if( argc )
3638             wrong_args("--update-trustdb");
3639         update_trustdb();
3640         break;
3641
3642       case aCheckTrustDB:
3643         /* Old versions allowed for arguments - ignore them */
3644         check_trustdb();
3645         break;
3646
3647       case aFixTrustDB:
3648         log_error("this command is not yet implemented.\n");
3649         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3650         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3651         break;
3652
3653       case aListTrustPath:
3654         if( !argc )
3655             wrong_args("--list-trust-path <user-ids>");
3656         for( ; argc; argc--, argv++ ) {
3657             username = make_username( *argv );
3658             list_trust_path( username );
3659             xfree(username);
3660         }
3661         break;
3662
3663       case aExportOwnerTrust:
3664         if( argc )
3665             wrong_args("--export-ownertrust");
3666         export_ownertrust();
3667         break;
3668
3669       case aImportOwnerTrust:
3670         if( argc > 1 )
3671             wrong_args("--import-ownertrust [file]");
3672         import_ownertrust( argc? *argv:NULL );
3673         break;
3674       
3675       case aPipeMode:
3676         if ( argc )
3677             wrong_args ("--pipemode");
3678         run_in_pipemode ();
3679         break;
3680
3681       case aRebuildKeydbCaches:
3682         if (argc)
3683             wrong_args ("--rebuild-keydb-caches");
3684         keydb_rebuild_caches (1);
3685         break;
3686
3687 #ifdef ENABLE_CARD_SUPPORT
3688       case aCardStatus:
3689         if (argc)
3690             wrong_args ("--card-status");
3691         card_status (stdout, NULL, 0);
3692         break;
3693
3694       case aCardEdit:
3695         if (argc) {
3696             sl = NULL;
3697             for (argc--, argv++ ; argc; argc--, argv++)
3698                 append_to_strlist (&sl, *argv);
3699             card_edit (sl);
3700             free_strlist (sl);
3701         }
3702         else
3703             card_edit (NULL);
3704         break;
3705
3706       case aChangePIN:
3707         if (!argc)
3708             change_pin (0,1);
3709         else if (argc == 1)
3710             change_pin (atoi (*argv),1);
3711         else
3712         wrong_args ("--change-pin [no]");
3713         break;
3714 #endif /* ENABLE_CARD_SUPPORT*/
3715
3716       case aListConfig:
3717         {
3718           char *str=collapse_args(argc,argv);
3719           list_config(str);
3720           xfree(str);
3721         }
3722         break;
3723
3724       case aListPackets:
3725         opt.list_packets=2;
3726       default:
3727         if( argc > 1 )
3728             wrong_args(_("[filename]"));
3729         /* Issue some output for the unix newbie */
3730         if( !fname && !opt.outfile && isatty( fileno(stdin) )
3731                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
3732             log_info(_("Go ahead and type your message ...\n"));
3733
3734         a = iobuf_open(fname);
3735         if (a && is_secured_file (iobuf_get_fd (a)))
3736           {
3737             iobuf_close (a);
3738             a = NULL;
3739             errno = EPERM;
3740           }
3741         if( !a )
3742             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
3743         else {
3744
3745             if( !opt.no_armor ) {
3746                 if( use_armor_filter( a ) ) {
3747                     memset( &afx, 0, sizeof afx);
3748                     iobuf_push_filter( a, armor_filter, &afx );
3749                 }
3750             }
3751             if( cmd == aListPackets ) {
3752                 set_packet_list_mode(1);
3753                 opt.list_packets=1;
3754             }
3755             rc = proc_packets(NULL, a );
3756             if( rc )
3757                 log_error("processing message failed: %s\n", g10_errstr(rc) );
3758             iobuf_close(a);
3759         }
3760         break;
3761       }
3762
3763     /* cleanup */
3764     FREE_STRLIST(remusr);
3765     FREE_STRLIST(locusr);
3766     g10_exit(0);
3767     return 8; /*NEVER REACHED*/
3768 }
3769
3770
3771 void
3772 g10_exit( int rc )
3773 {
3774 #ifdef ENABLE_CARD_SUPPORT
3775     card_close ();
3776 #endif
3777     update_random_seed_file();
3778     if( opt.debug & DBG_MEMSTAT_VALUE ) {
3779         m_print_stats("on exit");
3780         random_dump_stats();
3781     }
3782     if( opt.debug )
3783         secmem_dump_stats();
3784     secmem_term();
3785     rc = rc? rc : log_get_errorcount(0)? 2 :
3786                         g10_errors_seen? 1 : 0;
3787     exit(rc );
3788 }
3789
3790
3791 /* Pretty-print hex hashes.  This assumes at least an 80-character
3792    display, but there are a few other similar assumptions in the
3793    display code. */
3794 static void
3795 print_hex( MD_HANDLE md, int algo, const char *fname )
3796 {
3797   int i,n,count,indent=0;
3798   const byte *p;
3799
3800   if(fname)
3801     indent=printf("%s: ",fname);
3802
3803   if(indent>40)
3804     {
3805       printf("\n");
3806       indent=0;
3807     }
3808
3809   if(algo==DIGEST_ALGO_RMD160)
3810     indent+=printf("RMD160 = ");
3811   else if(algo>0)
3812     indent+=printf("%6s = ",digest_algo_to_string(algo));
3813   else
3814     algo=abs(algo);
3815
3816   count=indent;
3817
3818   p = md_read( md, algo );
3819   n = md_digest_length(algo);
3820
3821   count+=printf("%02X",*p++);
3822
3823   for(i=1;i<n;i++,p++)
3824     {
3825       if(n==16)
3826         {
3827           if(count+2>79)
3828             {
3829               printf("\n%*s",indent," ");
3830               count=indent;
3831             }
3832           else
3833             count+=printf(" ");
3834
3835           if(!(i%8))
3836             count+=printf(" ");
3837         }
3838       else if (n==20)
3839         {
3840           if(!(i%2))
3841             {
3842               if(count+4>79)
3843                 {
3844                   printf("\n%*s",indent," ");
3845                   count=indent;
3846                 }
3847               else
3848                 count+=printf(" ");
3849             }
3850
3851           if(!(i%10))
3852             count+=printf(" ");
3853         }
3854       else
3855         {
3856           if(!(i%4))
3857             {
3858               if(count+8>79)
3859                 {
3860                   printf("\n%*s",indent," ");
3861                   count=indent;
3862                 }
3863               else
3864                 count+=printf(" ");
3865             }
3866         }
3867
3868       count+=printf("%02X",*p);
3869     }
3870
3871   printf("\n");
3872 }
3873
3874 static void
3875 print_hashline( MD_HANDLE md, int algo, const char *fname )
3876 {
3877     int i, n;
3878     const byte *p;
3879     
3880     if ( fname ) {
3881         for (p = fname; *p; p++ ) {
3882             if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
3883                 printf("%%%02X", *p );
3884             else 
3885                 putchar( *p );
3886         }
3887     }
3888     putchar(':');
3889     printf("%d:", algo );
3890     p = md_read( md, algo );
3891     n = md_digest_length(algo);
3892     for(i=0; i < n ; i++, p++ ) 
3893         printf("%02X", *p );
3894     putchar(':');
3895     putchar('\n');
3896 }
3897
3898 static void
3899 print_mds( const char *fname, int algo )
3900 {
3901     FILE *fp;
3902     char buf[1024];
3903     size_t n;
3904     MD_HANDLE md;
3905
3906     if( !fname ) {
3907         fp = stdin;
3908 #ifdef HAVE_DOSISH_SYSTEM
3909         setmode ( fileno(fp) , O_BINARY );
3910 #endif
3911     }
3912     else {
3913         fp = fopen( fname, "rb" );
3914         if (fp && is_secured_file (fileno (fp)))
3915           {
3916             fclose (fp);
3917             fp = NULL;
3918             errno = EPERM;
3919           }
3920     }
3921     if( !fp ) {
3922         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3923         return;
3924     }
3925
3926     md = md_open( 0, 0 );
3927     if( algo )
3928         md_enable( md, algo );
3929     else {
3930         md_enable( md, DIGEST_ALGO_MD5 );
3931         md_enable( md, DIGEST_ALGO_SHA1 );
3932         md_enable( md, DIGEST_ALGO_RMD160 );
3933 #ifdef USE_SHA256
3934         md_enable( md, DIGEST_ALGO_SHA224 );
3935         md_enable( md, DIGEST_ALGO_SHA256 );
3936 #endif
3937 #ifdef USE_SHA512
3938         md_enable( md, DIGEST_ALGO_SHA384 );
3939         md_enable( md, DIGEST_ALGO_SHA512 );
3940 #endif
3941     }
3942
3943     while( (n=fread( buf, 1, DIM(buf), fp )) )
3944         md_write( md, buf, n );
3945     if( ferror(fp) )
3946         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3947     else {
3948         md_final(md);
3949         if ( opt.with_colons ) {
3950             if ( algo ) 
3951                 print_hashline( md, algo, fname );
3952             else {
3953                 print_hashline( md, DIGEST_ALGO_MD5, fname );
3954                 print_hashline( md, DIGEST_ALGO_SHA1, fname );
3955                 print_hashline( md, DIGEST_ALGO_RMD160, fname );
3956 #ifdef USE_SHA256
3957                 print_hashline( md, DIGEST_ALGO_SHA224, fname );
3958                 print_hashline( md, DIGEST_ALGO_SHA256, fname );
3959 #endif
3960 #ifdef USE_SHA512
3961                 print_hashline( md, DIGEST_ALGO_SHA384, fname );
3962                 print_hashline( md, DIGEST_ALGO_SHA512, fname );
3963 #endif
3964             }
3965         }
3966         else {
3967             if( algo )
3968                print_hex(md,-algo,fname);
3969             else {
3970                 print_hex( md, DIGEST_ALGO_MD5, fname );
3971                 print_hex( md, DIGEST_ALGO_SHA1, fname );
3972                 print_hex( md, DIGEST_ALGO_RMD160, fname );
3973 #ifdef USE_SHA256
3974                 print_hex( md, DIGEST_ALGO_SHA224, fname );
3975                 print_hex( md, DIGEST_ALGO_SHA256, fname );
3976 #endif
3977 #ifdef USE_SHA512
3978                 print_hex( md, DIGEST_ALGO_SHA384, fname );
3979                 print_hex( md, DIGEST_ALGO_SHA512, fname );
3980 #endif
3981             }
3982         }
3983     }
3984     md_close(md);
3985
3986     if( fp != stdin )
3987         fclose(fp);
3988 }
3989
3990
3991 /****************
3992  * Check the supplied name,value string and add it to the notation
3993  * data to be used for signatures.  which==0 for sig notations, and 1
3994  * for cert notations.
3995 */
3996 static void
3997 add_notation_data( const char *string, int which )
3998 {
3999   struct notation *notation;
4000
4001   notation=string_to_notation(string,utf8_strings);
4002   if(notation)
4003     {
4004       if(which)
4005         {
4006           notation->next=opt.cert_notations;
4007           opt.cert_notations=notation;
4008         }
4009       else
4010         {
4011           notation->next=opt.sig_notations;
4012           opt.sig_notations=notation;
4013         }
4014     }
4015 }
4016
4017 static void
4018 add_policy_url( const char *string, int which )
4019 {
4020   unsigned int i,critical=0;
4021   STRLIST sl;
4022
4023   if(*string=='!')
4024     {
4025       string++;
4026       critical=1;
4027     }
4028
4029   for(i=0;i<strlen(string);i++)
4030     if( !isascii (string[i]) || iscntrl(string[i]))
4031       break;
4032
4033   if(i==0 || i<strlen(string))
4034     {
4035       if(which)
4036         log_error(_("the given certification policy URL is invalid\n"));
4037       else
4038         log_error(_("the given signature policy URL is invalid\n"));
4039     }
4040
4041   if(which)
4042     sl=add_to_strlist( &opt.cert_policy_url, string );
4043   else
4044     sl=add_to_strlist( &opt.sig_policy_url, string );
4045
4046   if(critical)
4047     sl->flags |= 1;    
4048 }
4049
4050 static void
4051 add_keyserver_url( const char *string, int which )
4052 {
4053   unsigned int i,critical=0;
4054   STRLIST sl;
4055
4056   if(*string=='!')
4057     {
4058       string++;
4059       critical=1;
4060     }
4061
4062   for(i=0;i<strlen(string);i++)
4063     if( !isascii (string[i]) || iscntrl(string[i]))
4064       break;
4065
4066   if(i==0 || i<strlen(string))
4067     {
4068       if(which)
4069         BUG();
4070       else
4071         log_error(_("the given preferred keyserver URL is invalid\n"));
4072     }
4073
4074   if(which)
4075     BUG();
4076   else
4077     sl=add_to_strlist( &opt.sig_keyserver_url, string );
4078
4079   if(critical)
4080     sl->flags |= 1;    
4081 }