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