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