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