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