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