* options.h, g10.c (main), compress-bz2.c (init_uncompress): Add
[gnupg.git] / g10 / g10.c
index 34c8076..f449dde 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -1,5 +1,6 @@
 /* g10.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -80,11 +81,13 @@ enum cmd_and_opt_values
     oShowNotation,
     oNoShowNotation,
     aEncrFiles,
-    aDecryptFiles,                          
+    aEncrSym,
+    aDecryptFiles,
     aClearsign,
     aStore,
     aKeygen,
     aSignEncr,
+    aSignEncrSym,
     aSignSym,
     aSignKey,
     aLSignKey,
@@ -187,6 +190,9 @@ enum cmd_and_opt_values
     oDigestAlgo,
     oCertDigestAlgo,
     oCompressAlgo,
+    oCompressLevel,
+    oBZ2CompressLevel,
+    oBZ2CompressLowmem,
     oPasswdFD,
 #ifdef __riscos__
     oPasswdFile,
@@ -415,7 +421,10 @@ static ARGPARSE_OPTS opts[] = {
     { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
-    { oCompress, NULL,       1, N_("|N|set compress level N (0 disables)") },
+    { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
+    { oCompressLevel, "compress-level", 1, "@" },
+    { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
+    { oBZ2CompressLowmem, "bzip2-compress-lowmem", 0, "@" },
     { oTextmodeShort, NULL,   0, "@"},
     { oTextmode, "textmode",  0, N_("use canonical text mode")},
     { oNoTextmode, "no-textmode",  0, "@"},
@@ -628,6 +637,11 @@ static ARGPARSE_OPTS opts[] = {
     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
+    /* Aliases.  I constantly mistype these, and assume other people
+       do as well. */
+    { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
+    { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
+    { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
     { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
     { oDisplay,    "display",     2, "@" },
     { oTTYname,    "ttyname",     2, "@" },
@@ -866,8 +880,18 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
        cmd = aSignSym;
     else if( cmd == aSym && new_cmd == aSign )
        cmd = aSignSym;
+    else if( cmd == aSym && new_cmd == aEncr )
+       cmd = aEncrSym;
+    else if( cmd == aEncr && new_cmd == aSym )
+       cmd = aEncrSym;
     else if( cmd == aKMode && new_cmd == aSym )
        cmd = aKModeC;
+    else if (cmd == aSignEncr && new_cmd == aSym)
+        cmd = aSignEncrSym;
+    else if (cmd == aSignSym && new_cmd == aEncr)
+        cmd = aSignEncrSym;
+    else if (cmd == aEncrSym && new_cmd == aSign)
+        cmd = aSignEncrSym;
     else if(   ( cmd == aSign     && new_cmd == aClearsign )
             || ( cmd == aClearsign && new_cmd == aSign )  )
        cmd = aClearsign;
@@ -1143,7 +1167,7 @@ main( int argc, char **argv )
     const char *trustdb_name = NULL;
     char *def_cipher_string = NULL;
     char *def_digest_string = NULL;
-    char *def_compress_string = NULL;
+    char *compress_algo_string = NULL;
     char *cert_digest_string = NULL;
     char *s2k_cipher_string = NULL;
     char *s2k_digest_string = NULL;
@@ -1177,12 +1201,12 @@ main( int argc, char **argv )
     create_dotlock(NULL); /* register locking cleanup */
     i18n_init();
     opt.command_fd = -1; /* no command fd */
-    opt.compress = -1; /* defaults to standard compress level */
+    opt.compress_level = -1; /* defaults to standard compress level */
     /* note: if you change these lines, look at oOpenPGP */
     opt.def_cipher_algo = 0;
     opt.def_digest_algo = 0;
     opt.cert_digest_algo = 0;
-    opt.def_compress_algo = -1;
+    opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
     opt.s2k_mode = 3; /* iterated+salted */
     opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
 #ifdef USE_CAST5
@@ -1206,7 +1230,7 @@ main( int argc, char **argv )
     opt.keyserver_options.include_revoked=1;
     opt.keyserver_options.try_dns_srv=1;
     opt.verify_options=
-      VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER;
+      VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
     opt.trust_model=TM_AUTO;
     opt.mangle_dos_filenames = 0;
 #if defined (_WIN32)
@@ -1218,6 +1242,14 @@ main( int argc, char **argv )
     if( !*opt.homedir )
        set_homedir ( GNUPG_HOMEDIR );
 
+#ifdef ENABLE_CARD_SUPPORT
+# ifdef _WIN32
+    opt.pcsc_driver = "winscard.dll"; 
+#else
+    opt.pcsc_driver = "libpcsclite.so"; 
+#endif
+#endif /*ENABLE_CARD_SUPPORT*/
+
     /* check whether we have a config file on the commandline */
     orig_argc = argc;
     orig_argv = argv;
@@ -1286,17 +1318,37 @@ main( int argc, char **argv )
 
     set_native_charset (NULL); /* Try to auto set the character set */
 
+    /* Try for a version specific config file first */
     if( default_config )
       {
-       /* Try for a version specific config file first */
-       configname = make_filename(opt.homedir,
-                                  "gpg" EXTSEP_S "conf-" SAFE_VERSION, NULL );
-       if(access(configname,R_OK))
+       char *name=m_strdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
+       char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
+
+       do
          {
-           m_free(configname);
-           configname = make_filename(opt.homedir,
-                                      "gpg" EXTSEP_S "conf", NULL );
+           if(configname)
+             {
+               char *tok;
+
+               m_free(configname);
+               configname=NULL;
+
+               if((tok=strrchr(ver,SAFE_VERSION_DASH)))
+                 *tok='\0';
+               else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
+                 *tok='\0';
+               else
+                 break;
+             }
+
+           configname = make_filename(opt.homedir,name,NULL);
          }
+       while(access(configname,R_OK));
+
+       m_free(name);
+
+       if(!configname)
+         configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
         if (!access (configname, R_OK))
           { /* Print a warning when both config files are present. */
             char *p = make_filename(opt.homedir, "options", NULL );
@@ -1366,7 +1418,10 @@ main( int argc, char **argv )
          case aSearchKeys: set_cmd( &cmd, aSearchKeys); break;
          case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break;
          case aExport: set_cmd( &cmd, aExport); break;
-         case aExportAll: set_cmd( &cmd, aExportAll); break;
+         case aExportAll:
+           opt.export_options|=EXPORT_INCLUDE_NON_RFC;
+           set_cmd(&cmd,aExport);
+           break;
          case aListKeys: set_cmd( &cmd, aListKeys); break;
          case aListSigs: set_cmd( &cmd, aListSigs); break;
          case aExportSecret: set_cmd( &cmd, aExportSecret); break;
@@ -1608,7 +1663,7 @@ main( int argc, char **argv )
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
            opt.cert_digest_algo = 0;
-           opt.def_compress_algo = -1;
+           opt.compress_algo = -1;
             opt.s2k_mode = 3; /* iterated+salted */
            opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
            opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
@@ -1642,23 +1697,26 @@ main( int argc, char **argv )
          case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
           case oShowPolicyURL:
            deprecated_warning(configname,configlineno,"--show-policy-url",
-                              "--list-options ","show-policy-url");
+                              "--list-options ","show-policy-urls");
            deprecated_warning(configname,configlineno,"--show-policy-url",
-                              "--verify-options ","show-policy-url");
-           opt.list_options|=LIST_SHOW_POLICY;
-           opt.verify_options|=VERIFY_SHOW_POLICY;
+                              "--verify-options ","show-policy-urls");
+           opt.list_options|=LIST_SHOW_POLICY_URLS;
+           opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
            break;
          case oNoShowPolicyURL:
            deprecated_warning(configname,configlineno,"--no-show-policy-url",
-                              "--list-options ","no-show-policy-url");
+                              "--list-options ","no-show-policy-urls");
            deprecated_warning(configname,configlineno,"--no-show-policy-url",
-                              "--verify-options ","no-show-policy-url");
-           opt.list_options&=~LIST_SHOW_POLICY;
-           opt.verify_options&=~VERIFY_SHOW_POLICY;
+                              "--verify-options ","no-show-policy-urls");
+           opt.list_options&=~LIST_SHOW_POLICY_URLS;
+           opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
            break;
          case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
          case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
-         case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break;
+         case oComment:
+           if(pargs.r.ret_str[0])
+             add_to_strlist(&opt.comments,pargs.r.ret_str);
+           break;
          case oDefaultComment:
            deprecated_warning(configname,configlineno,
                               "--default-comment","--no-comments","");
@@ -1728,7 +1786,13 @@ main( int argc, char **argv )
          case oUser: /* store the local users */
            add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
            break;
-         case oCompress: opt.compress = pargs.r.ret_int; break;
+         case oCompress:
+           /* this is the -z command line option */
+           opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
+           break;
+         case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
+         case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
+         case oBZ2CompressLowmem: opt.bz2_compress_lowmem=1; break;
          case oPasswdFD:
             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
             opt.use_agent = 0;
@@ -1764,12 +1828,12 @@ main( int argc, char **argv )
 
              if(*pt=='\0')
                {
-                 def_compress_string=m_alloc(strlen(pargs.r.ret_str)+2);
-                 strcpy(def_compress_string,"Z");
-                 strcat(def_compress_string,pargs.r.ret_str);
+                 compress_algo_string=m_alloc(strlen(pargs.r.ret_str)+2);
+                 strcpy(compress_algo_string,"Z");
+                 strcat(compress_algo_string,pargs.r.ret_str);
                }
              else
-               def_compress_string = m_strdup(pargs.r.ret_str);
+               compress_algo_string = m_strdup(pargs.r.ret_str);
            }
            break;
          case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
@@ -1826,11 +1890,11 @@ main( int argc, char **argv )
              struct parse_options lopts[]=
                {
                  {"show-photos",LIST_SHOW_PHOTOS},
-                 {"show-policy-url",LIST_SHOW_POLICY},
-                 {"show-notation",LIST_SHOW_NOTATION},
-                 {"show-keyserver-url",LIST_SHOW_KEYSERVER},
+                 {"show-policy-urls",LIST_SHOW_POLICY_URLS},
+                 {"show-notations",LIST_SHOW_NOTATIONS},
+                 {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS},
                  {"show-validity",LIST_SHOW_VALIDITY},
-                 {"show-long-keyid",LIST_SHOW_LONG_KEYID},
+                 {"show-long-keyids",LIST_SHOW_LONG_KEYIDS},
                  {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS},
                  {"show-keyring",LIST_SHOW_KEYRING},
                  {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
@@ -1852,11 +1916,11 @@ main( int argc, char **argv )
              struct parse_options vopts[]=
                {
                  {"show-photos",VERIFY_SHOW_PHOTOS},
-                 {"show-policy-url",VERIFY_SHOW_POLICY},
-                 {"show-notation",VERIFY_SHOW_NOTATION},
-                 {"show-keyserver-url",VERIFY_SHOW_KEYSERVER},
+                 {"show-policy-urls",VERIFY_SHOW_POLICY_URLS},
+                 {"show-notations",VERIFY_SHOW_NOTATIONS},
+                 {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS},
                  {"show-validity",VERIFY_SHOW_VALIDITY},
-                 {"show-long-keyid",VERIFY_SHOW_LONG_KEYID},
+                 {"show-long-keyids",VERIFY_SHOW_LONG_KEYIDS},
                  {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS},
                  {NULL,0}
                };
@@ -1886,19 +1950,19 @@ main( int argc, char **argv )
          case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
          case oShowNotation:
            deprecated_warning(configname,configlineno,"--show-notation",
-                              "--list-options ","show-notation");
+                              "--list-options ","show-notations");
            deprecated_warning(configname,configlineno,"--show-notation",
-                              "--verify-options ","show-notation");
-           opt.list_options|=LIST_SHOW_NOTATION;
-           opt.verify_options|=VERIFY_SHOW_NOTATION;
+                              "--verify-options ","show-notations");
+           opt.list_options|=LIST_SHOW_NOTATIONS;
+           opt.verify_options|=VERIFY_SHOW_NOTATIONS;
            break;
          case oNoShowNotation:
            deprecated_warning(configname,configlineno,"--no-show-notation",
-                              "--list-options ","no-show-notation");
+                              "--list-options ","no-show-notations");
            deprecated_warning(configname,configlineno,"--no-show-notation",
-                              "--verify-options ","no-show-notation");
-           opt.list_options&=~LIST_SHOW_NOTATION;
-           opt.verify_options&=~VERIFY_SHOW_NOTATION;
+                              "--verify-options ","no-show-notations");
+           opt.list_options&=~LIST_SHOW_NOTATIONS;
+           opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
            break;
          case oUtf8Strings: utf8_strings = 1; break;
          case oNoUtf8Strings: utf8_strings = 0; break;
@@ -2121,7 +2185,7 @@ main( int argc, char **argv )
            opt.ask_cert_expire = 0;
            m_free(def_digest_string);
            def_digest_string = m_strdup("md5");
-           opt.def_compress_algo = 1;
+           opt.compress_algo = COMPRESS_ALGO_ZIP;
          }
       }
     else if(PGP6)
@@ -2161,10 +2225,10 @@ main( int argc, char **argv )
        if( check_digest_algo(opt.def_digest_algo) )
            log_error(_("selected digest algorithm is invalid\n"));
     }
-    if( def_compress_string ) {
-       opt.def_compress_algo = string_to_compress_algo(def_compress_string);
-       m_free(def_compress_string); def_compress_string = NULL;
-       if( check_compress_algo(opt.def_compress_algo) )
+    if( compress_algo_string ) {
+       opt.compress_algo = string_to_compress_algo(compress_algo_string);
+       m_free(compress_algo_string); compress_algo_string = NULL;
+       if( check_compress_algo(opt.compress_algo) )
            log_error(_("selected compression algorithm is invalid\n"));
     }
     if( cert_digest_string ) {
@@ -2244,6 +2308,9 @@ main( int argc, char **argv )
          case aSym:
            cmdname="--symmetric";
            break;
+         case aEncrSym:
+           cmdname="--symmetric --encrypt";
+           break;
          case aStore:
            cmdname="--store";
            break;
@@ -2285,10 +2352,10 @@ main( int argc, char **argv )
            badalg=digest_algo_to_string(opt.cert_digest_algo);
            badtype=PREFTYPE_HASH;
          }
-       else if(opt.def_compress_algo!=-1
-               && !algo_available(PREFTYPE_ZIP,opt.def_compress_algo,NULL))
+       else if(opt.compress_algo!=-1
+               && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
          {
-           badalg=compress_algo_to_string(opt.def_compress_algo);
+           badalg=compress_algo_to_string(opt.compress_algo);
            badtype=PREFTYPE_ZIP;
          }
 
@@ -2345,10 +2412,6 @@ main( int argc, char **argv )
        g10_opt_verbose = opt.verbose;
     }
 
-    /* Compression algorithm 0 means no compression at all */
-    if( opt.def_compress_algo == 0)
-        opt.compress = 0;
-
     /* kludge to let -sat generate a clear text signature */
     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
        cmd = aClearsign;
@@ -2439,12 +2502,33 @@ main( int argc, char **argv )
          {
            if( argc > 1 )
              wrong_args(_("--encrypt [filename]"));
-           if( (rc = encode_crypt(fname,remusr)) )
+           if( (rc = encode_crypt(fname,remusr,0)) )
              log_error("%s: encryption failed: %s\n",
                        print_fname_stdin(fname), g10_errstr(rc) );
          }
        break;
-          
+
+      case aEncrSym:
+       /* This works with PGP 8 in the sense that it acts just like a
+          symmetric message.  It doesn't work at all with 2 or 6.  It
+          might work with 7, but alas, I don't have a copy to test
+          with right now. */
+       if( argc > 1 )
+         wrong_args(_("--symmetric --encrypt [filename]"));
+       else if(opt.s2k_mode==0)
+         log_error(_("you cannot use --symmetric --encrypt"
+                     " with --s2k-mode 0\n"));
+       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+         log_error(_("you cannot use --symmetric --encrypt"
+                     " while in %s mode\n"),compliance_option_string());
+       else
+         {
+           if( (rc = encode_crypt(fname,remusr,1)) )
+             log_error("%s: encryption failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
+         }
+       break;
+
       case aSign: /* sign the given file */
        sl = NULL;
        if( detached_sig ) { /* sign all files */
@@ -2474,10 +2558,36 @@ main( int argc, char **argv )
        else
            sl = NULL;
        if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
-           log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
+           log_error("%s: sign+encrypt failed: %s\n",
+                     print_fname_stdin(fname), g10_errstr(rc) );
        free_strlist(sl);
        break;
 
+      case aSignEncrSym: /* sign and encrypt the given file */
+       if( argc > 1 )
+           wrong_args(_("--symmetric --sign --encrypt [filename]"));
+       else if(opt.s2k_mode==0)
+         log_error(_("you cannot use --symmetric --sign --encrypt"
+                     " with --s2k-mode 0\n"));
+       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+         log_error(_("you cannot use --symmetric --sign --encrypt"
+                     " while in %s mode\n"),compliance_option_string());
+       else
+         {
+           if( argc )
+             {
+               sl = m_alloc_clear( sizeof *sl + strlen(fname));
+               strcpy(sl->d, fname);
+             }
+           else
+             sl = NULL;
+           if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
+             log_error("%s: symmetric+sign+encrypt failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
+           free_strlist(sl);
+         }
+       break;
+
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
            wrong_args(_("--sign --symmetric [filename]"));
@@ -2648,7 +2758,6 @@ main( int argc, char **argv )
        break;
 
       case aExport:
-      case aExportAll:
       case aSendKeys:
       case aRecvKeys:
        sl = NULL;
@@ -2676,7 +2785,6 @@ main( int argc, char **argv )
        sl = NULL;
        for( ; argc; argc--, argv++ )
          append_to_strlist2( &sl, *argv, utf8_strings );
-
        rc=keyserver_search( sl );
        if(rc)
          log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
@@ -2911,7 +3019,7 @@ main( int argc, char **argv )
       case aCardStatus:
         if (argc)
             wrong_args ("--card-status");
-        card_status (stdout);
+        card_status (stdout, NULL, 0);
         break;
 
       case aCardEdit:
@@ -2980,6 +3088,9 @@ main( int argc, char **argv )
 void
 g10_exit( int rc )
 {
+#ifdef ENABLE_CARD_SUPPORT
+    card_close ();
+#endif
     update_random_seed_file();
     if( opt.debug & DBG_MEMSTAT_VALUE ) {
        m_print_stats("on exit");