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