From 2f94810a11e0e3cdeb4bed695a4bf9eb9ce41c34 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Thu, 8 Jun 2006 20:19:53 +0000 Subject: 2006-06-07 Guilhem Lavaux * Merged HEAD as of 2006-06-06. * native/jni/native-lib/cpproc.h (CPIO_EXEC_NUM_PIPES): Compilation fix. --- tools/.cvsignore | 1 + tools/Makefile.am | 53 +- tools/appletviewer.c | 235 -------- tools/appletviewer.in | 19 +- .../classpath/tools/appletviewer/AppletTag.java | 22 +- tools/gnu/classpath/tools/appletviewer/Main.java | 180 +++--- .../tools/getopt/ClasspathToolParser.java | 16 +- .../tools/getopt/FileArgumentCallback.java | 3 +- tools/gnu/classpath/tools/getopt/Messages.java | 67 +++ tools/gnu/classpath/tools/getopt/Option.java | 1 - tools/gnu/classpath/tools/getopt/OptionGroup.java | 150 ++++- tools/gnu/classpath/tools/getopt/Parser.java | 176 +++++- tools/gnu/classpath/tools/giop/GRMIC.java | 23 +- tools/gnu/classpath/tools/giop/GRMIC.txt | 24 +- .../tools/giop/grmic/GiopRmicCompiler.java | 94 +++- tools/gnu/classpath/tools/jar/Action.java | 3 +- tools/gnu/classpath/tools/jar/Creator.java | 89 ++- tools/gnu/classpath/tools/jar/Extractor.java | 53 +- tools/gnu/classpath/tools/jar/Indexer.java | 144 +++++ tools/gnu/classpath/tools/jar/Lister.java | 48 +- tools/gnu/classpath/tools/jar/Main.java | 133 +++-- tools/gnu/classpath/tools/jar/Messages.java | 67 +++ tools/gnu/classpath/tools/jar/Updater.java | 44 +- tools/gnu/classpath/tools/jar/WorkSet.java | 86 +++ tools/gnu/classpath/tools/jarsigner/JarSigner.java | 2 +- tools/gnu/classpath/tools/jarsigner/Main.java | 269 ++++++--- tools/gnu/classpath/tools/jarsigner/Messages.java | 4 +- tools/gnu/classpath/tools/jarsigner/jarsigner.txt | 116 ---- tools/gnu/classpath/tools/keytool/CertReqCmd.java | 169 ++++-- tools/gnu/classpath/tools/keytool/Command.java | 63 ++- tools/gnu/classpath/tools/keytool/DeleteCmd.java | 116 ++-- tools/gnu/classpath/tools/keytool/ExportCmd.java | 170 ++++-- tools/gnu/classpath/tools/keytool/GenKeyCmd.java | 199 +++++-- .../gnu/classpath/tools/keytool/IdentityDBCmd.java | 128 +++-- tools/gnu/classpath/tools/keytool/ImportCmd.java | 333 ++++++++--- tools/gnu/classpath/tools/keytool/KeyCloneCmd.java | 162 ++++-- .../gnu/classpath/tools/keytool/KeyPasswdCmd.java | 143 +++-- tools/gnu/classpath/tools/keytool/ListCmd.java | 132 +++-- tools/gnu/classpath/tools/keytool/Main.java | 231 +++++--- tools/gnu/classpath/tools/keytool/Messages.java | 4 +- .../gnu/classpath/tools/keytool/PrintCertCmd.java | 73 ++- tools/gnu/classpath/tools/keytool/SelfCertCmd.java | 196 ++++--- .../classpath/tools/keytool/StorePasswdCmd.java | 116 ++-- tools/gnu/classpath/tools/keytool/keytool.txt | 616 --------------------- .../gnu/classpath/tools/native2ascii/Messages.java | 67 +++ .../classpath/tools/native2ascii/Native2ASCII.java | 185 +++++++ tools/gnu/classpath/tools/rmi/RMIC.java | 25 +- tools/gnu/classpath/tools/rmi/RMIC.txt | 36 +- tools/gnu/classpath/tools/serialver/Messages.java | 68 +++ tools/gnu/classpath/tools/serialver/SerialVer.java | 163 ++++++ tools/jarsigner.in | 18 +- tools/keytool.in | 18 +- tools/toolwrapper.c | 220 ++++++++ 53 files changed, 3662 insertions(+), 2111 deletions(-) delete mode 100644 tools/appletviewer.c create mode 100644 tools/gnu/classpath/tools/getopt/Messages.java create mode 100644 tools/gnu/classpath/tools/jar/Indexer.java create mode 100644 tools/gnu/classpath/tools/jar/Messages.java create mode 100644 tools/gnu/classpath/tools/jar/WorkSet.java delete mode 100644 tools/gnu/classpath/tools/jarsigner/jarsigner.txt delete mode 100644 tools/gnu/classpath/tools/keytool/keytool.txt create mode 100644 tools/gnu/classpath/tools/native2ascii/Messages.java create mode 100644 tools/gnu/classpath/tools/native2ascii/Native2ASCII.java create mode 100644 tools/gnu/classpath/tools/serialver/Messages.java create mode 100644 tools/gnu/classpath/tools/serialver/SerialVer.java create mode 100644 tools/toolwrapper.c (limited to 'tools') diff --git a/tools/.cvsignore b/tools/.cvsignore index 75730de04..cf3688511 100644 --- a/tools/.cvsignore +++ b/tools/.cvsignore @@ -3,3 +3,4 @@ keytool Makefile.in Makefile tools.zip +appletviewer diff --git a/tools/Makefile.am b/tools/Makefile.am index 7a8f1ce97..201939832 100755 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -21,8 +21,46 @@ endif endif endif -bin_SCRIPTS = jarsigner keytool -EXTRA_DIST = jarsigner.in keytool.in +if CREATE_WRAPPERS +bin_SCRIPTS = +bin_PROGRAMS = appletviewer jarsigner keytool + +if FOUND_GCJ +LIBJVM = -lgcj +else +if FOUND_CACAO +LIBJVM = -ljvm +else +LIBJVM = +endif +endif + +appletviewer_SOURCES = toolwrapper.c +appletviewer_CFLAGS = -Wall \ + -DDATA_DIR="\"$(datadir)\"" \ + -DPACKAGE="\"$(PACKAGE)\"" \ + -DTOOLNAME="\"appletviewer\"" +appletviewer_LDFLAGS = -L$(libdir) $(LIBJVM) + +jarsigner_SOURCES = toolwrapper.c +jarsigner_CFLAGS = -Wall \ + -DDATA_DIR="\"$(datadir)\"" \ + -DPACKAGE="\"$(PACKAGE)\"" \ + -DTOOLNAME="\"jarsigner\"" +jarsigner_LDFLAGS = -L$(libdir) $(LIBJVM) + +keytool_SOURCES = toolwrapper.c +keytool_CFLAGS = -Wall \ + -DDATA_DIR="\"$(datadir)\"" \ + -DPACKAGE="\"$(PACKAGE)\"" \ + -DTOOLNAME="\"keytool\"" +keytool_LDFLAGS = -L$(libdir) $(LIBJVM) + +else +bin_SCRIPTS = appletviewer jarsigner keytool +bin_PROGRAMS = +endif +EXTRA_DIST = toolwrapper.c appletviewer.in jarsigner.in keytool.in # All our example java source files TOOLS_JAVA_FILES = $(srcdir)/gnu/classpath/tools/*.java $(srcdir)/gnu/classpath/tools/*/*.java $(srcdir)/gnu/classpath/tools/*/*/*.java @@ -43,10 +81,8 @@ TOOLS_TEMPLATES = $(GRMIC_TEMPLATES) $(RMIC_TEMPLATES) # This covers the built-in help texts, both for giop and rmic subpackages. GIOP_HELPS = $(srcdir)/gnu/classpath/tools/giop/*.txt RMI_HELPS = $(srcdir)/gnu/classpath/tools/rmi/*.txt -JARSIGNER_HELPS = $(srcdir)/gnu/classpath/tools/jarsigner/*.txt -KEYTOOL_HELPS = $(srcdir)/gnu/classpath/tools/keytool/*.txt -TOOLS_HELPS = $(GIOP_HELPS) $(RMI_HELPS) $(JARSIGNER_HELPS) $(KEYTOOL_HELPS) +TOOLS_HELPS = $(GIOP_HELPS) $(RMI_HELPS) # The tool specific README files. READMES = $(srcdir)/gnu/classpath/tools/giop/README @@ -81,14 +117,13 @@ dist-hook: $(TOOLS_ZIP): $(TOOLS_JAVA_FILES) mkdir -p classes/gnu/classpath/tools/giop/grmic/templates mkdir -p classes/gnu/classpath/tools/rmi/rmic/templates + mkdir -p classes/gnu/classpath/tools/appletviewer mkdir -p classes/gnu/classpath/tools/jarsigner mkdir -p classes/gnu/classpath/tools/keytool cp $(RMIC_TEMPLATES) classes/gnu/classpath/tools/rmi/rmic/templates cp $(GRMIC_TEMPLATES) classes/gnu/classpath/tools/giop/grmic/templates cp $(RMI_HELPS) classes/gnu/classpath/tools/rmi/ cp $(GIOP_HELPS) classes/gnu/classpath/tools/giop/ - cp $(JARSIGNER_HELPS) classes/gnu/classpath/tools/jarsigner/ - cp $(KEYTOOL_HELPS) classes/gnu/classpath/tools/keytool/ $(JCOMPILER) -d classes $(TOOLS_JAVA_FILES) (cd classes; \ if test "$(ZIP)" != ""; then $(ZIP) -r ../$(TOOLS_ZIP) .; fi; \ @@ -99,3 +134,7 @@ $(TOOLS_ZIP): $(TOOLS_JAVA_FILES) # Zip file be gone! (and make sure the classes are gone too) clean-local: rm -rf $(TOOLS_ZIP) classes + +# FIXME: remove this when GNU Classpath includes a bootstrap VM. +installcheck-binSCRIPTS: + : diff --git a/tools/appletviewer.c b/tools/appletviewer.c deleted file mode 100644 index 2609ccaf6..000000000 --- a/tools/appletviewer.c +++ /dev/null @@ -1,235 +0,0 @@ -/* appletviewer.c -- a native appletviewer wrapper for VMs that - support the JNI invocation interface - Copyright (C) 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -#include -#include -#include -#include -#include "config.h" - -#ifndef JNI_VERSION_1_2 -# error JNI version 1.2 or greater required -#endif - -union env_union -{ - void *void_env; - JNIEnv *jni_env; -}; - -int -main (int argc, const char** argv) -{ - union env_union tmp; - JNIEnv* env; - JavaVM* jvm; - JavaVMInitArgs vm_args; - jint result; - jclass class_id; - jmethodID method_id; - jstring str; - jclass string_class_id; - jobjectArray args_array; - char** non_vm_argv; - int non_vm_argc; - int i; - int classpath_found = 0; - - env = NULL; - jvm = NULL; - - vm_args.nOptions = 0; - vm_args.options = NULL; - - non_vm_argc = 0; - non_vm_argv = NULL; - - if (argc > 1) - { - for (i = 1; i < argc; i++) - { - if (!strncmp (argv[i], "-J", 2)) - { - if (!strncmp (argv[i], "-J-Djava.class.path=", 20)) - classpath_found = 1; - - /* A virtual machine option. */ - vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); - - if (vm_args.options == NULL) - { - g_printerr ("appletviewer: realloc failed.\n"); - goto destroy; - } - - if (strlen (argv[i]) == 2) - { - g_printerr ("appletviewer: the -J option must not be followed by a space.\n"); - goto destroy; - } - else - vm_args.options[vm_args.nOptions++].optionString = g_strdup (argv[i] + 2); - } - else if (!strncmp (argv[i], "--version", 9) - && argv[i][9] == '\0') - { - g_print ("appletviewer (GCJ Applet Viewer) " PACKAGE_VERSION "\n"); - exit (0); - } - else if (!strncmp (argv[i], "-debug", 6) - && argv[i][6] == '\0') - { - /* FIXME: Ignore for now. The debug option will be - unsupported until we have the ability to debug - bytecode. For now, just strip it out of the argument - list. */ - } - else - { - non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*)); - if (non_vm_argv == NULL) - { - g_printerr ("appletviewer: realloc failed.\n"); - goto destroy; - } - non_vm_argv[non_vm_argc++] = g_strdup (argv[i]); - } - } - } - - if (!classpath_found) - { - /* Set the invocation classpath. */ - vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); - - if (vm_args.options == NULL) - { - g_printerr ("appletviewer: realloc failed.\n"); - goto destroy; - } - - vm_args.options[vm_args.nOptions++].optionString = "-Djava.class.path=" "@datadir@/@PACKAGE@/tools.zip"; - } - - /* Terminate vm_args.options with a NULL element. */ - vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); - if (vm_args.options == NULL) - { - g_printerr ("appletviewer: realloc failed.\n"); - goto destroy; - } - vm_args.options[vm_args.nOptions].optionString = NULL; - - /* Terminate non_vm_argv with a NULL element. */ - non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*)); - if (non_vm_argv == NULL) - { - g_printerr ("appletviewer: realloc failed.\n"); - goto destroy; - } - non_vm_argv[non_vm_argc] = NULL; - - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - - result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args); - - if (result < 0) - { - g_printerr ("appletviewer: couldn't create virtual machine\n"); - goto destroy; - } - - env = tmp.jni_env; - - string_class_id = (*env)->FindClass (env, "java/lang/String"); - if (string_class_id == NULL) - { - g_printerr ("appletviewer: FindClass failed.\n"); - goto destroy; - } - - args_array = (*env)->NewObjectArray (env, non_vm_argc, string_class_id, NULL); - if (args_array == NULL) - { - g_printerr ("appletviewer: NewObjectArray failed.\n"); - goto destroy; - } - - for (i = 0; i < non_vm_argc; i++) - { - str = (*env)->NewStringUTF (env, non_vm_argv[i]); - if (str == NULL) - { - g_printerr ("appletviewer: NewStringUTF failed.\n"); - goto destroy; - } - - (*env)->SetObjectArrayElement (env, args_array, i, str); - } - - class_id = (*env)->FindClass (env, "gnu/classpath/tools/appletviewer/Main"); - if (class_id == NULL) - { - g_printerr ("appletviewer: FindClass failed.\n"); - goto destroy; - } - - method_id = (*env)->GetStaticMethodID (env, class_id, "main", "([Ljava/lang/String;)V"); - - if (method_id == NULL) - { - g_printerr ("appletviewer: GetStaticMethodID failed.\n"); - goto destroy; - } - - (*env)->CallStaticVoidMethod (env, class_id, method_id, args_array); - - destroy: - - if (env != NULL) - { - if ((*env)->ExceptionOccurred (env)) - (*env)->ExceptionDescribe (env); - - if (jvm != NULL) - (*jvm)->DestroyJavaVM (jvm); - } - - return 1; -} diff --git a/tools/appletviewer.in b/tools/appletviewer.in index 61571d906..81e39ad91 100644 --- a/tools/appletviewer.in +++ b/tools/appletviewer.in @@ -36,7 +36,6 @@ ## obligated to do so. If you do not wish to do so, delete this ## exception statement from your version. ## -## ## A simple shell script to launch the GNU Classpath appletviewer tool. ## @@ -44,20 +43,4 @@ prefix=@prefix@ tools_dir=@datadir@/@PACKAGE@ tools_cp=${tools_dir}/tools.zip -# find the java executable... -if [ -z "${JAVA}" ] ; then - if [ -n "${JAVA_HOME}" ] ; then - if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then - JAVA="${JAVA_HOME}/jre/sh/java" - else - JAVA="${JAVA_HOME}/bin/java" - fi - else - JAVA=`which java 2> /dev/null ` - if [ -z "${JAVA}" ] ; then - JAVA=java - fi - fi -fi - -exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.appletviewer.Main $@ +exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.appletviewer.Main $@ diff --git a/tools/gnu/classpath/tools/appletviewer/AppletTag.java b/tools/gnu/classpath/tools/appletviewer/AppletTag.java index b2d7ccb2b..80d572857 100644 --- a/tools/gnu/classpath/tools/appletviewer/AppletTag.java +++ b/tools/gnu/classpath/tools/appletviewer/AppletTag.java @@ -451,15 +451,19 @@ class AppletTag else { String dirname = documentbase.getFile(); - - // Determine dirname for file by stripping everything - // past the last file separator. - dirname = dirname.substring(0, - dirname.lastIndexOf(File.separatorChar) + 1); - - fullcodebase = new URL(documentbase.getProtocol(), - documentbase.getHost(), - documentbase.getPort(), dirname); + if (dirname.indexOf(".") < 0) + fullcodebase = new URL(documentbase + File.separator); + else + { + // Determine dirname for file by stripping everything + // past the last file separator. + dirname = dirname.substring(0, + dirname.lastIndexOf(File.separatorChar) + 1); + + fullcodebase = new URL(documentbase.getProtocol(), + documentbase.getHost(), + documentbase.getPort(), dirname); + } } } else diff --git a/tools/gnu/classpath/tools/appletviewer/Main.java b/tools/gnu/classpath/tools/appletviewer/Main.java index 878b2be8a..1d9fed2b0 100644 --- a/tools/gnu/classpath/tools/appletviewer/Main.java +++ b/tools/gnu/classpath/tools/appletviewer/Main.java @@ -125,118 +125,108 @@ class Main public static void main(String[] args) throws IOException { parser = new ClasspathToolParser("appletviewer", true); - parser.setHeader("usage: appletviewer [OPTION] --code=FILE | URL..."); - + parser.setHeader("usage: appletviewer [OPTION] -code CODE | URL..."); + OptionGroup attributeGroup = new OptionGroup("Applet tag options"); attributeGroup.add(new Option("code", Main.messages.getString ("gcjwebplugin.code_description"), - "") - { - public void parsed(String argument) throws OptionException - { - code = argument; - } - }); + "CODE") + { + public void parsed(String argument) throws OptionException + { + code = argument; + } + }); attributeGroup.add(new Option("codebase", Main.messages.getString - ("gcjwebplugin.codebase_description"), - "") - { - public void parsed(String argument) throws OptionException - { - codebase = argument; - } - }); + ("gcjwebplugin.codebase_description"), + "CODEBASE") + { + public void parsed(String argument) throws OptionException + { + codebase = argument; + } + }); attributeGroup.add(new Option("archive", Main.messages.getString - ("gcjwebplugin.archive_description"), - "") - { - public void parsed(String argument) throws OptionException - { - archive = argument; - } - }); + ("gcjwebplugin.archive_description"), + "ARCHIVE") + { + public void parsed(String argument) throws OptionException + { + archive = argument; + } + }); attributeGroup.add(new Option("width", Main.messages.getString - ("gcjwebplugin.width_description"), - "") - { - public void parsed(String argument) throws OptionException - { - dimensions.width = Integer.parseInt(argument); - } - }); + ("gcjwebplugin.width_description"), + "WIDTH") + { + public void parsed(String argument) throws OptionException + { + dimensions.width = Integer.parseInt(argument); + } + }); attributeGroup.add(new Option("height", Main.messages.getString - ("gcjwebplugin.height_description"), - "") - { - public void parsed(String argument) throws OptionException - { - dimensions.height = Integer.parseInt(argument); - } - }); + ("gcjwebplugin.height_description"), + "HEIGHT") + { + public void parsed(String argument) throws OptionException + { + dimensions.height = Integer.parseInt(argument); + } + }); attributeGroup.add(new Option("param", Main.messages.getString - ("gcjwebplugin.param_description"), - ",") - { - public void parsed(String argument) throws OptionException - { - parameters.add(argument); - } - }); + ("gcjwebplugin.param_description"), + "NAME,VALUE") + { + public void parsed(String argument) throws OptionException + { + parameters.add(argument); + } + }); OptionGroup pluginGroup = new OptionGroup("Plugin option"); pluginGroup.add(new Option("plugin", Main.messages.getString - ("gcjwebplugin.plugin_description"), - ",") - { - public void parsed(String argument) throws OptionException - { - pluginMode = true; - int comma = argument.indexOf(','); - pipeInName = argument.substring(0, comma); - pipeOutName = argument.substring(comma + 1); - } - }); + ("gcjwebplugin.plugin_description"), + "INPUT,OUTPUT") + { + public void parsed(String argument) throws OptionException + { + pluginMode = true; + int comma = argument.indexOf(','); + pipeInName = argument.substring(0, comma); + pipeOutName = argument.substring(comma + 1); + } + }); OptionGroup debuggingGroup = new OptionGroup("Debugging option"); - debuggingGroup.add(new Option ("verbose", Main.messages.getString - ("gcjwebplugin.verbose_description"), - null) - { - public void parsed(String argument) throws OptionException - { - verbose = true; - } - }); + debuggingGroup.add(new Option("verbose", Main.messages.getString + ("gcjwebplugin.verbose_description"), + (String) null) + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); OptionGroup compatibilityGroup = new OptionGroup("Compatibility options"); compatibilityGroup.add(new Option("debug", Main.messages.getString ("gcjwebplugin.debug_description"), - null) - { - public void parsed(String argument) throws OptionException - { - // Currently ignored. - } - }); + (String) null) + { + public void parsed(String argument) throws OptionException + { + // Currently ignored. + } + }); compatibilityGroup.add(new Option("encoding", Main.messages.getString ("gcjwebplugin.encoding_description"), - "") - { - public void parsed(String argument) throws OptionException - { - // FIXME: We should probably be using - // java.nio.charset.CharsetDecoder to handle the encoding. What - // is the status of Classpath's implementation? - } - }); - compatibilityGroup.add(new Option('J', Main.messages.getString - ("gcjwebplugin.j_description"), - "") - { - public void parsed(String argument) throws OptionException - { - // -J should be handled by the appletviewer wrapper binary. - // We add it here so that it shows up in the --help output. - } - }); + "CHARSET") + { + public void parsed(String argument) throws OptionException + { + // FIXME: We should probably be using + // java.nio.charset.CharsetDecoder to handle the encoding. What + // is the status of Classpath's implementation? + } + }); parser.add(attributeGroup); parser.add(pluginGroup); parser.add(debuggingGroup); diff --git a/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java b/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java index be382a7a4..e712056ef 100644 --- a/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java +++ b/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.classpath.tools.getopt; +import java.text.MessageFormat; + import gnu.classpath.Configuration; /** @@ -50,13 +52,13 @@ public class ClasspathToolParser { private static String getVersionString(String programName) { - return (programName + " (GNU Classpath) " - + Configuration.CLASSPATH_VERSION - + "\n\n" - + "Copyright 2006 Free Software Foundation, Inc.\n" - + "This is free software; see the source for copying conditions. There is NO\n" - + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); - + String fmt = (Messages.getString("ClasspathToolParser.VersionFormat")); //$NON-NLS-1$ + return MessageFormat.format(fmt, + new Object[] + { + programName, + Configuration.CLASSPATH_VERSION + }); } public ClasspathToolParser(String programName) diff --git a/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java b/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java index 0c44745c9..455389127 100644 --- a/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java +++ b/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java @@ -57,5 +57,6 @@ public abstract class FileArgumentCallback * * @param fileArgument the file name */ - public abstract void notifyFile(String fileArgument); + public abstract void notifyFile(String fileArgument) + throws OptionException; } diff --git a/tools/gnu/classpath/tools/getopt/Messages.java b/tools/gnu/classpath/tools/getopt/Messages.java new file mode 100644 index 000000000..3c963d786 --- /dev/null +++ b/tools/gnu/classpath/tools/getopt/Messages.java @@ -0,0 +1,67 @@ +/* Messages.java -- i18n support for getopt + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.getopt; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages +{ + private static final String BUNDLE_NAME + = "gnu.classpath.tools.getopt.Messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE + = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String getString(String key) + { + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/tools/gnu/classpath/tools/getopt/Option.java b/tools/gnu/classpath/tools/getopt/Option.java index e54aaa103..6f775e4a1 100644 --- a/tools/gnu/classpath/tools/getopt/Option.java +++ b/tools/gnu/classpath/tools/getopt/Option.java @@ -184,7 +184,6 @@ public abstract class Option */ public String getDescription() { - // FIXME: localization. return description; } diff --git a/tools/gnu/classpath/tools/getopt/OptionGroup.java b/tools/gnu/classpath/tools/getopt/OptionGroup.java index d83b273ba..f7d966d94 100644 --- a/tools/gnu/classpath/tools/getopt/OptionGroup.java +++ b/tools/gnu/classpath/tools/getopt/OptionGroup.java @@ -39,8 +39,10 @@ package gnu.classpath.tools.getopt; import java.io.PrintStream; +import java.text.BreakIterator; import java.util.ArrayList; import java.util.Iterator; +import java.util.Locale; /** * An option group holds a collection of Options. It also has a name. Option @@ -48,6 +50,9 @@ import java.util.Iterator; */ public class OptionGroup { + /** An 80-character string of whitespaces to use as a source for padding. */ + private static final String FILLER = " " + + " "; private String name; ArrayList options = new ArrayList(); @@ -69,6 +74,85 @@ public class OptionGroup this.name = name; } + /** + * Print a designated text to a {@link PrintStream}, eventually wrapping the + * lines of text so as to ensure that the width of each line does not overflow + * {@link Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a + * {@link BreakIterator} using the default {@link Locale}. + *

+ * The text to print may contain \n characters. This method will + * force a line-break for each such character. + * + * @param out the {@link PrintStream} destination of the formatted text. + * @param text the text to print. + * @param leftMargin a positive value indicating the column position of the + * start of the first line. Continuation lines, if they exist, are + * printed starting at leftMargin + 2 as per GNU + * convention. + * @see Parser#MAX_LINE_LENGTH + */ + protected static void formatText(PrintStream out, String text, int leftMargin) + { + formatText(out, text, leftMargin, Locale.getDefault()); + } + + /** + * Similar to the method with the same name and three arguments, except that + * the caller MUST specify a non-null {@link Locale} instance. + *

+ * Print a designated text to a {@link PrintStream}, eventually wrapping the + * lines of text so as to ensure that the width of each line does not overflow + * {@link Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a + * {@link BreakIterator} using the designated {@link Locale}. + *

+ * The text to print may contain \n characters. This method will + * force a line-break for each such character. + * + * @param out the {@link PrintStream} destination of the formatted text. + * @param text the text to print. + * @param leftMargin a positive value indicating the column position of the + * start of the first line. Continuation lines, if they exist, are + * printed starting at leftMargin + 2 as per GNU + * convention. + * @param aLocale the {@link Locale} instance to use when constructing the + * {@link BreakIterator}. + * @see Parser#MAX_LINE_LENGTH + */ + protected static void formatText(PrintStream out, String text, int leftMargin, + Locale aLocale) + { + BreakIterator bit = BreakIterator.getLineInstance(aLocale); + String[] lines = text.split("\n"); + int length = leftMargin; + String leftPadding = FILLER.substring(0, leftMargin + 2); + for (int i = 0; i < lines.length; i++) + { + text = lines[i]; + bit.setText(text); + int start = bit.first(); + int finish; + while ((finish = bit.next()) != BreakIterator.DONE) + { + String word = text.substring(start, finish); + length += word.length(); + if (length >= Parser.MAX_LINE_LENGTH) + { + out.println(); + out.print(leftPadding); + length = word.length() + leftMargin + 2; + } + out.print(word); + start = finish; + } + out.println(); + if (i != lines.length - 1) + { + length = leftMargin + 2; + out.print(leftPadding); + } + } + } + /** * Add an option to this option group. * @@ -84,12 +168,26 @@ public class OptionGroup * * @param out the stream to which to print */ - public void printHelp(PrintStream out) + public void printHelp(PrintStream out, boolean longOnly) { // Compute maximum lengths. int maxArgLen = 0; - int maxShortLen = 0; - Iterator it = options.iterator(); + boolean shortOptionSeen = false; + Iterator it; + + // The first pass only looks to see if we have a short option. + it = options.iterator(); + while (it.hasNext()) + { + Option option = (Option) it.next(); + if (option.getShortName() != '\0') + { + shortOptionSeen = true; + break; + } + } + + it = options.iterator(); while (it.hasNext()) { Option option = (Option) it.next(); @@ -100,21 +198,16 @@ public class OptionGroup // a short option if there is also a long name for // the option. int thisArgLen = 2; - if (option.getShortName() != '\0') - { - // The name of the option plus some padding. - thisArgLen += 4; - } - maxShortLen = Math.max(thisArgLen, maxShortLen); + if (shortOptionSeen) + thisArgLen += 4; if (option.getLongName() != null) { - // FIXME: different if parsing in 'long option only' - // mode. - thisArgLen += 2 + option.getLongName().length(); + // Handle either '-' or '--'. + thisArgLen += 1 + option.getLongName().length(); + if (! longOnly) + ++thisArgLen; } - // We only need to add the argument name in once, - // and we don't let it contribute to the width of - // the short name. + // Add in the width of the argument name. if (argName != null) thisArgLen += 1 + argName.length(); maxArgLen = Math.max(maxArgLen, thisArgLen); @@ -138,9 +231,16 @@ public class OptionGroup { if (argName != null) { - out.print(' '); + // This is a silly hack just for '-J'. We don't + // support joined options in general, but this option + // is filtered out before argument processing can see it. + if (option.getShortName() != 'J') + { + out.print(' '); + ++column; + } out.print(argName); - column += 1 + argName.length(); + column += argName.length(); } out.print(" "); } @@ -148,24 +248,24 @@ public class OptionGroup out.print(", "); column += 2; } - for (; column < maxShortLen; ++column) + // Indent the long option past the short options, if one + // was seen. + for (; column < (shortOptionSeen ? 6 : 2); ++column) out.print(' '); if (option.getLongName() != null) { - out.print("--"); + out.print(longOnly ? "-" : "--"); out.print(option.getLongName()); - column += 2 + option.getLongName().length(); + column += (longOnly ? 1 : 2) + option.getLongName().length(); if (argName != null) { - out.print("=" + argName); + out.print(" " + argName); column += 1 + argName.length(); } } - for (; column < maxArgLen; ++column) - out.print(' '); // FIXME: should have a better heuristic for padding. - out.print(" "); - out.println(option.getDescription()); + out.print(FILLER.substring(0, maxArgLen + 4 - column)); + formatText(out, option.getDescription(), maxArgLen + 4); } } } diff --git a/tools/gnu/classpath/tools/getopt/Parser.java b/tools/gnu/classpath/tools/getopt/Parser.java index 8d70c01d0..082cf8945 100644 --- a/tools/gnu/classpath/tools/getopt/Parser.java +++ b/tools/gnu/classpath/tools/getopt/Parser.java @@ -39,8 +39,11 @@ package gnu.classpath.tools.getopt; import java.io.PrintStream; +import java.text.BreakIterator; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; +import java.util.Locale; /** * An instance of this class is used to parse command-line options. It does "GNU @@ -52,6 +55,9 @@ import java.util.Iterator; */ public class Parser { + /** The maximum right column position. */ + public static final int MAX_LINE_LENGTH = 80; + private String programName; private String headerText; @@ -83,6 +89,69 @@ public class Parser this(programName, versionString, false); } + /** + * Print a designated text to a {@link PrintStream}, eventually wrapping the + * lines of text so as to ensure that the width of each line does not overflow + * {@link #MAX_LINE_LENGTH} columns. The line-wrapping is done with a + * {@link BreakIterator} using the default {@link Locale}. + *

+ * The text to print may contain \n characters. This method will + * force a line-break for each such character. + * + * @param out the {@link PrintStream} destination of the formatted text. + * @param text the text to print. + * @see Parser#MAX_LINE_LENGTH + */ + protected static void formatText(PrintStream out, String text) + { + formatText(out, text, Locale.getDefault()); + } + + /** + * Similar to the method with the same name and two arguments, except that the + * caller MUST specify a non-null {@link Locale} instance. + *

+ * Print a designated text to a {@link PrintStream}, eventually wrapping the + * lines of text so as to ensure that the width of each line does not overflow + * {@link #MAX_LINE_LENGTH} columns. The line-wrapping is done with a + * {@link BreakIterator} using the designated {@link Locale}. + *

+ * The text to print may contain \n characters. This method will + * force a line-break for each such character. + * + * @param out the {@link PrintStream} destination of the formatted text. + * @param text the text to print. + * @param aLocale the {@link Locale} instance to use when constructing the + * {@link BreakIterator}. + * @see Parser#MAX_LINE_LENGTH + */ + protected static void formatText(PrintStream out, String text, Locale aLocale) + { + BreakIterator bit = BreakIterator.getLineInstance(aLocale); + String[] lines = text.split("\n"); //$NON-NLS-1$ + for (int i = 0; i < lines.length; i++) + { + text = lines[i]; + bit.setText(text); + int length = 0; + int finish; + int start = bit.first(); + while ((finish = bit.next()) != BreakIterator.DONE) + { + String word = text.substring(start, finish); + length += word.length(); + if (length >= MAX_LINE_LENGTH) + { + out.println(); + length = word.length(); + } + out.print(word); + start = finish; + } + out.println(); + } + } + /** * Create a new parser. The program name is used when printing error messages. * The version string is printed verbatim in response to "--version". @@ -95,7 +164,10 @@ public class Parser { this.programName = programName; this.longOnly = longOnly; - defaultGroup.add(new Option("help", "print this help, then exit") + + // Put standard options in their own section near the end. + OptionGroup finalGroup = new OptionGroup(Messages.getString("Parser.StdOptions")); //$NON-NLS-1$ + finalGroup.add(new Option("help", Messages.getString("Parser.PrintHelp")) //$NON-NLS-1$ //$NON-NLS-2$ { public void parsed(String argument) throws OptionException { @@ -103,7 +175,7 @@ public class Parser System.exit(0); } }); - defaultGroup.add(new Option("version", "print version number, then exit") + finalGroup.add(new Option("version", Messages.getString("Parser.PrintVersion")) //$NON-NLS-1$ //$NON-NLS-2$ { public void parsed(String argument) throws OptionException { @@ -111,6 +183,17 @@ public class Parser System.exit(0); } }); + finalGroup.add(new Option('J', Messages.getString("Parser.JArgument"), Messages.getString("Parser.JName")) //$NON-NLS-1$ //$NON-NLS-2$ + { + public void parsed(String argument) throws OptionException + { + // -J should be handled by the appletviewer wrapper binary. + // We add it here so that it shows up in the --help output. + // Note that there is a special case for this in OptionGroup. + } + }); + add(finalGroup); + add(defaultGroup); } @@ -155,14 +238,24 @@ public class Parser public synchronized void add(OptionGroup group) { options.addAll(group.options); - optionGroups.add(group); + // This ensures that the final group always appears at the end + // of the options. + if (optionGroups.isEmpty()) + optionGroups.add(group); + else + optionGroups.add(optionGroups.size() - 1, group); + } + + public void printHelp() + { + this.printHelp(System.out); } void printHelp(PrintStream out) { if (headerText != null) { - out.println(headerText); + formatText(out, headerText); out.println(); } @@ -170,19 +263,49 @@ public class Parser while (it.hasNext()) { OptionGroup group = (OptionGroup) it.next(); - group.printHelp(out); - out.println(); + // An option group might be empty, in which case we don't + // want to print it.. + if (! group.options.isEmpty()) + { + group.printHelp(out, longOnly); + out.println(); + } } if (footerText != null) - out.println(footerText); + formatText(out, footerText); + } + + /** + * This method can be overridden by subclassses to provide some option + * validation. It is called by the parser after all options have been + * parsed. If an option validation problem is encountered, this should + * throw an {@link OptionException} whose message should be shown to + * the user. + *

+ * It is better to do validation here than after {@link #parse(String[])} + * returns, because the parser will print a message referring the + * user to the --help option. + *

+ * The base implementation does nothing. + * + * @throws OptionException the error encountered + */ + protected void validate() throws OptionException + { + // Base implementation does nothing. } private String getArgument(String request) throws OptionException { ++currentIndex; if (currentIndex >= args.length) - throw new OptionException("option '" + request + "' requires an argument"); + { + String message + = MessageFormat.format(Messages.getString("Parser.ArgReqd"), //$NON-NLS-1$ + new Object[] { request }); + throw new OptionException(request); + } return args[currentIndex]; } @@ -204,7 +327,11 @@ public class Parser } } if (found == null) - throw new OptionException("unrecognized option '" + real + "'"); + { + String msg = MessageFormat.format(Messages.getString("Parser.Unrecognized"), //$NON-NLS-1$ + new Object[] { real }); + throw new OptionException(msg); + } String argument = null; if (found.getTakesArgument()) { @@ -215,8 +342,10 @@ public class Parser } else if (eq != - 1) { - throw new OptionException("option '" + real.substring(0, eq + index) - + "' doesn't allow an argument"); + String msg + = MessageFormat.format(Messages.getString("Parser.NoArg"), //$NON-NLS-1$ + new Object[] { real.substring(0, eq + index) }); + throw new OptionException(msg); } found.parsed(argument); } @@ -234,10 +363,14 @@ public class Parser } } if (found == null) - throw new OptionException("unrecognized option '-" + option + "'"); + { + String msg = MessageFormat.format(Messages.getString("Parser.UnrecDash"), //$NON-NLS-1$ + new Object[] { "" + option }); //$NON-NLS-1$ + throw new OptionException(msg); + } String argument = null; if (found.getTakesArgument()) - argument = getArgument("-" + option); + argument = getArgument("-" + option); //$NON-NLS-1$ found.parsed(argument); } @@ -266,12 +399,12 @@ public class Parser { if (args[currentIndex].length() == 0 || args[currentIndex].charAt(0) != '-' - || "-".equals(args[currentIndex])) + || "-".equals(args[currentIndex])) //$NON-NLS-1$ { files.notifyFile(args[currentIndex]); continue; } - if ("--".equals(args[currentIndex])) + if ("--".equals(args[currentIndex])) //$NON-NLS-1$ break; if (args[currentIndex].charAt(1) == '-') handleLongOption(args[currentIndex], 2); @@ -283,12 +416,19 @@ public class Parser // Add remaining arguments to leftovers. for (++currentIndex; currentIndex < args.length; ++currentIndex) files.notifyFile(args[currentIndex]); + // See if something went wrong. + validate(); } catch (OptionException err) { - System.err.println(programName + ": " + err.getMessage()); - System.err.println(programName + ": Try '" + programName - + " --help' for more information."); + System.err.println(programName + ": " + err.getMessage()); //$NON-NLS-1$ + String fmt; + if (longOnly) + fmt = Messages.getString("Parser.TryHelpShort"); //$NON-NLS-1$ + else + fmt = Messages.getString("Parser.TryHelpLong"); //$NON-NLS-1$ + String msg = MessageFormat.format(fmt, new Object[] { programName }); + System.err.println(programName + ": " + msg); //$NON-NLS-1$ System.exit(1); } } diff --git a/tools/gnu/classpath/tools/giop/GRMIC.java b/tools/gnu/classpath/tools/giop/GRMIC.java index a372cfd66..c910d7083 100644 --- a/tools/gnu/classpath/tools/giop/GRMIC.java +++ b/tools/gnu/classpath/tools/giop/GRMIC.java @@ -104,6 +104,17 @@ public class GRMIC else HelpPrinter.printHelpAndExit(HelpPath); } + else if (c.equals("-classpath")) + { + int f = i + 1; + if (f < args.length) + { + compiler.setClassPath(args[f]); + i++; + } + else + HelpPrinter.printHelpAndExit(HelpPath); + } else if (c.charAt(0) != '-') // No more options - start of class list. { @@ -124,17 +135,7 @@ public class GRMIC if (args[i].charAt(0) != '-') { compiler.reset(); - Class c = null; - try - { - c = Thread.currentThread().getContextClassLoader().loadClass( - args[i]); - } - catch (ClassNotFoundException e) - { - System.err.println(args[i] + " class not found."); - System.exit(1); - } + Class c = compiler.loadClass(args[i]); compiler.compile(c); String packag = compiler.getPackageName().replace('.', '/'); diff --git a/tools/gnu/classpath/tools/giop/GRMIC.txt b/tools/gnu/classpath/tools/giop/GRMIC.txt index 08aaf148f..875bcdbcf 100644 --- a/tools/gnu/classpath/tools/giop/GRMIC.txt +++ b/tools/gnu/classpath/tools/giop/GRMIC.txt @@ -9,18 +9,20 @@ Please report bugs at http://www.gnu.org/software/classpath/bugs.html Usage: grmic where includes: - -poa Generate the Servant based ties (default) - -impl Generate the obsoleted ObjectImpl based ties - (for backward compatibility) - -nowarn Show no warnings - -nowrite Do not write any files (check for errors only) - -d Place generated files into the given folder + -poa Generate the Servant based ties (default) + -impl Generate the obsoleted ObjectImpl based ties + (for backward compatibility) + -nowarn Show no warnings + -nowrite Do not write any files (check for errors only) + -d Place generated files into the given folder + -classpath Specifies the path, where to find the classes being + compiled - -help Print this help text - -v Print version - -verbose Verbose output - -force Try to generate code even if the input classes seem not - consistent with RMI specification. + -help Print this help text + -v Print version + -verbose Verbose output + -force Try to generate code even if the input classes seem not + consistent with RMI specification. and can include one or more non abstract classes that implement diff --git a/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java index 4beba1c9f..6d895a14c 100644 --- a/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java +++ b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java @@ -23,7 +23,11 @@ package gnu.classpath.tools.giop.grmic; import gnu.classpath.tools.AbstractMethodGenerator; +import java.io.File; import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.ArrayList; @@ -33,6 +37,7 @@ import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; +import java.util.StringTokenizer; import java.util.TreeSet; /** @@ -104,6 +109,11 @@ public class GiopRmicCompiler * Force mode - do not check the exceptions */ protected boolean force = false; + + /** + * The class loader to load the class being compiled. + */ + ClassLoader classLoader; /** * Clear data, preparing for the next compilation. @@ -116,6 +126,78 @@ public class GiopRmicCompiler methods.clear(); vars.clear(); } + + /** + * Set the class path (handle the -classpath key) + * + * @param classPath the class path to set. + */ + public void setClassPath(String classPath) + { + classLoader = Thread.currentThread().getContextClassLoader(); + StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator, + true); + ArrayList urls = new ArrayList(tok.countTokens()); + String s = null; + try + { + while (tok.hasMoreTokens()) + { + s = tok.nextToken(); + if (s.equals(File.pathSeparator)) + urls.add(new File(".").toURL()); + else + { + urls.add(new File(s).toURL()); + if (tok.hasMoreTokens()) + { + // Skip the separator. + tok.nextToken(); + // If the classpath ended with a separator, + // append the current directory. + if (! tok.hasMoreTokens()) + urls.add(new File(".").toURL()); + } + } + } + } + catch (MalformedURLException ex) + { + System.err.println("Malformed path '" + s + "' in classpath '" + + classPath + "'"); + System.exit(1); + } + URL[] u = new URL[urls.size()]; + for (int i = 0; i < u.length; i++) + { + u[i] = (URL) urls.get(i); + } + + classLoader = new URLClassLoader(u, classLoader); + } + + /** + * Loads the class with the given name (uses class path, if applicable) + * + * @param name the name of the class. + */ + public Class loadClass(String name) + { + ClassLoader loader = classLoader; + if (loader == null) + loader = Thread.currentThread().getContextClassLoader(); + try + { + return loader.loadClass(name); + } + catch (ClassNotFoundException e) + { + System.err.println(name+" not found on "+loader); + System.exit(1); + // Unreacheable code. + return null; + } + } /** * Compile the given class (the instance of Remote), generating the stub and @@ -193,12 +275,12 @@ public class GiopRmicCompiler remEx = true; break; } - if (! remEx && !force) - throw new CompilationError(m[i].getName() + ", defined in " - + c.getName() - + ", does not throw " - + RemoteException.class.getName()); - } + } + if (! remEx && !force) + throw new CompilationError(m[i].getName() + ", defined in " + + c.getName() + + ", does not throw " + + RemoteException.class.getName()); AbstractMethodGenerator mm = createMethodGenerator(m[i]); methods.add(mm); } diff --git a/tools/gnu/classpath/tools/jar/Action.java b/tools/gnu/classpath/tools/jar/Action.java index fea60f797..6363157ae 100644 --- a/tools/gnu/classpath/tools/jar/Action.java +++ b/tools/gnu/classpath/tools/jar/Action.java @@ -46,5 +46,6 @@ public abstract class Action { } - public abstract void run(Main parameters) throws IOException; + public abstract void run(Main parameters) + throws IOException; } diff --git a/tools/gnu/classpath/tools/jar/Creator.java b/tools/gnu/classpath/tools/jar/Creator.java index a636fca6b..55159660d 100644 --- a/tools/gnu/classpath/tools/jar/Creator.java +++ b/tools/gnu/classpath/tools/jar/Creator.java @@ -46,16 +46,23 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.text.MessageFormat; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; import java.util.zip.CRC32; import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; public class Creator extends Action { - ZipOutputStream outputStream; + JarOutputStream outputStream; + HashSet writtenItems = new HashSet(); + // The manifest to use, or null if we don't want a manifest. + Manifest manifest; private long copyFile(CRC32 crc, InputStream is, OutputStream output) throws IOException @@ -76,8 +83,20 @@ public class Creator } protected void writeFile(boolean isDirectory, InputStream inputFile, - String filename, boolean verbose) throws IOException + String filename, boolean verbose) + throws IOException { + if (writtenItems.contains(filename)) + { + if (verbose) + { + String msg = MessageFormat.format(Messages.getString("Creator.Ignoring"), //$NON-NLS-1$ + new Object[] { filename }); + System.err.println(msg); + } + return; + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); CRC32 crc = new CRC32(); long size; @@ -97,6 +116,7 @@ public class Creator outputStream.putNextEntry(entry); out.writeTo(outputStream); outputStream.closeEntry(); + writtenItems.add(filename); if (verbose) { @@ -106,8 +126,15 @@ public class Creator perc = 0; else perc = 100 - (100 * csize) / size; - System.out.println("adding: " + filename + " (in=" + size + ") (out=" - + entry.getSize() + ") (stored " + perc + "%)"); + String msg = MessageFormat.format(Messages.getString("Creator.Adding"), //$NON-NLS-1$ + new Object[] + { + filename, + Long.valueOf(size), + Long.valueOf(entry.getSize()), + Long.valueOf(perc) + }); + System.err.println(msg); } } @@ -140,7 +167,7 @@ public class Creator String[] files = entry.file.list(); for (int i = 0; i < files.length; ++i) addEntries(result, new Entry(new File(entry.file, files[i]), - entry.name + '/' + files[i])); + entry.name + files[i])); } else result.add(entry); @@ -158,35 +185,63 @@ public class Creator return allEntries; } - protected ArrayList writeCommandLineEntries(Main parameters, File zipFile) + private void writeCommandLineEntries(Main parameters) throws IOException { - outputStream = new ZipOutputStream( - new BufferedOutputStream( - new FileOutputStream( - zipFile))); - outputStream.setMethod(parameters.storageMode); + // We've already written the manifest, make sure to mark it. + writtenItems.add("META-INF/"); //$NON-NLS-1$ + writtenItems.add(JarFile.MANIFEST_NAME); + ArrayList allEntries = getAllEntries(parameters); - Iterator it = parameters.entries.iterator(); + Iterator it = allEntries.iterator(); while (it.hasNext()) { Entry entry = (Entry) it.next(); writeFile(entry.file, entry.name, parameters.verbose); } - return allEntries; + } + + protected Manifest createManifest(Main parameters) + throws IOException + { + if (! parameters.wantManifest) + return null; + if (parameters.manifestFile != null) + { + // User specified a manifest file. + InputStream contents = new FileInputStream(parameters.manifestFile); + return new Manifest(contents); + } + return new Manifest(); + } + + protected void writeCommandLineEntries(Main parameters, OutputStream os) + throws IOException + { + manifest = createManifest(parameters); + outputStream = new JarOutputStream(os, manifest); + // FIXME: in Classpath this sets the method too late for the + // manifest file. + outputStream.setMethod(parameters.storageMode); + writeCommandLineEntries(parameters); } protected void close() throws IOException { - // FIXME: handle manifest options here. - // FIXME: handle index file here ...? outputStream.finish(); outputStream.close(); } public void run(Main parameters) throws IOException { - writeCommandLineEntries(parameters, parameters.archiveFile); + if (parameters.archiveFile == null || parameters.archiveFile.equals("-")) //$NON-NLS-1$ + writeCommandLineEntries(parameters, System.out); + else + { + OutputStream os + = new BufferedOutputStream(new FileOutputStream(parameters.archiveFile)); + writeCommandLineEntries(parameters, os); + } close(); } } diff --git a/tools/gnu/classpath/tools/jar/Extractor.java b/tools/gnu/classpath/tools/jar/Extractor.java index 245f5e36c..203ff0566 100644 --- a/tools/gnu/classpath/tools/jar/Extractor.java +++ b/tools/gnu/classpath/tools/jar/Extractor.java @@ -38,17 +38,22 @@ package gnu.classpath.tools.jar; +import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Enumeration; +import java.text.MessageFormat; import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; public class Extractor extends Action { + // This is a set of all the items specified on the command line. + private WorkSet allItems; + private void copyFile(InputStream input, File output) throws IOException { FileOutputStream os = new FileOutputStream(output); @@ -65,18 +70,38 @@ public class Extractor public void run(Main parameters) throws IOException { - ZipFile zip = new ZipFile(parameters.archiveFile); - Enumeration e = zip.entries(); - while (e.hasMoreElements()) + // Figure out what we want to extract. + allItems = new WorkSet(parameters.entries); + // Open the input file. + ZipInputStream zis; + File zfile = parameters.archiveFile; + if (zfile == null || "-".equals(zfile.getName())) //$NON-NLS-1$ + zis = new ZipInputStream(System.in); + else { - ZipEntry entry = (ZipEntry) e.nextElement(); + InputStream ins = new BufferedInputStream(new FileInputStream(zfile)); + zis = new ZipInputStream(ins); + } + // Extract stuff. + while (true) + { + ZipEntry entry = zis.getNextEntry(); + if (entry == null) + break; + if (! allItems.contains(entry.getName())) + continue; File file = new File(entry.getName()); if (entry.isDirectory()) { if (file.mkdirs()) { if (parameters.verbose) - System.out.println(" created: " + file); + { + String msg + = MessageFormat.format(Messages.getString("Extractor.Created"), //$NON-NLS-1$ + new Object[] { file }); + System.err.println(msg); + } } continue; } @@ -85,15 +110,17 @@ public class Extractor if (parent != null) parent.mkdirs(); - InputStream input = zip.getInputStream(entry); - copyFile(input, file); - input.close(); + copyFile(zis, file); if (parameters.verbose) { - String leader = (entry.getMethod() == ZipEntry.STORED ? " extracted" - : " inflated"); - System.out.println(leader + ": " + file); + String fmt; + if (entry.getMethod() == ZipEntry.STORED) + fmt = Messages.getString("Extractor.Extracted"); //$NON-NLS-1$ + else + fmt = Messages.getString("Extractor.Inflated"); //$NON-NLS-1$ + String msg = MessageFormat.format(fmt, new Object[] { file }); + System.err.println(msg); } } } diff --git a/tools/gnu/classpath/tools/jar/Indexer.java b/tools/gnu/classpath/tools/jar/Indexer.java new file mode 100644 index 000000000..aae25f821 --- /dev/null +++ b/tools/gnu/classpath/tools/jar/Indexer.java @@ -0,0 +1,144 @@ +/* Indexer.java -- add index.list file to jar + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.jar; + +import gnu.java.net.IndexListParser; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.StringTokenizer; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +public class Indexer + extends Updater +{ + private void indexJarFile(StringBuffer result, File fileName, + boolean verbose) + throws IOException + { + if (verbose) + { + String msg = MessageFormat.format(Messages.getString("Indexer.Indexing"), //$NON-NLS-1$ + new Object[] { fileName }); + System.err.println(msg); + } + JarFile jf = new JarFile(fileName); + + // Index the files in this jar. + // The results look a little better if we keep them + // in insertion order. + LinkedHashSet entries = new LinkedHashSet(); + Enumeration e = jf.entries(); + while (e.hasMoreElements()) + { + JarEntry entry = (JarEntry) e.nextElement(); + String name = entry.getName(); + if (name.startsWith("META-INF/")) //$NON-NLS-1$ + continue; + int index = name.lastIndexOf('/'); + if (index != -1) + name = name.substring(0, index); + entries.add(name); + } + if (! entries.isEmpty()) + { + result.append(fileName); + // Any line ending will do. + result.append('\n'); + Iterator i = entries.iterator(); + while (i.hasNext()) + { + result.append(i.next()); + result.append('\n'); + } + // Paragraph break. + result.append('\n'); + } + + // Now read pointed-to jars. + Manifest m = jf.getManifest(); + if (m != null) + { + File parent = fileName.getParentFile(); + Attributes attrs = m.getMainAttributes(); + String jars = attrs.getValue(Attributes.Name.CLASS_PATH); + if (jars != null) + { + StringTokenizer st = new StringTokenizer(jars, " "); //$NON-NLS-1$ + while (st.hasMoreTokens()) + { + String name = st.nextToken(); + indexJarFile(result, new File(parent, name), verbose); + } + } + } + + jf.close(); + } + + protected void writeCommandLineEntries(Main parameters, OutputStream os) + throws IOException + { + // This is a pretty lame design. We know the super call will + // only have side effects and won't actually write anything important. + super.writeCommandLineEntries(parameters, os); + + // Now compute our index file and write it. + StringBuffer contents = new StringBuffer(); + indexJarFile(contents, parameters.archiveFile, parameters.verbose); + if (contents.length() != 0) + { + // Insert in reverse order to avoid computing anything. + contents.insert(0, "1.0\n\n"); //$NON-NLS-1$ + contents.insert(0, IndexListParser.JAR_INDEX_VERSION_KEY); + ByteArrayInputStream in + = new ByteArrayInputStream(contents.toString().getBytes()); + writeFile(false, in, IndexListParser.JAR_INDEX_FILE, parameters.verbose); + } + } +} diff --git a/tools/gnu/classpath/tools/jar/Lister.java b/tools/gnu/classpath/tools/jar/Lister.java index fe5792e76..98275f789 100644 --- a/tools/gnu/classpath/tools/jar/Lister.java +++ b/tools/gnu/classpath/tools/jar/Lister.java @@ -38,32 +38,54 @@ package gnu.classpath.tools.jar; +import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.text.MessageFormat; import java.util.Date; -import java.util.Enumeration; import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; public class Lister extends Action { - private void listJar(File jarFile, boolean verbose) throws IOException + private WorkSet allItems; + + private long readUntilEnd(InputStream is) throws IOException + { + byte[] buffer = new byte[5 * 1024]; + long result = 0; + while (true) + { + int r = is.read(buffer); + if (r == -1) + break; + result += r; + } + return result; + } + + private void listJar(ZipInputStream zis, boolean verbose) throws IOException { - ZipFile zipFile = new ZipFile(jarFile); - Enumeration i = zipFile.entries(); MessageFormat format = null; if (verbose) format = new MessageFormat(" {0,date,E M dd HH:mm:ss z yyyy} {1}"); - while (i.hasMoreElements()) + while (true) { - ZipEntry entry = (ZipEntry) i.nextElement(); + ZipEntry entry = zis.getNextEntry(); + if (entry == null) + break; + if (! allItems.contains(entry.getName())) + continue; if (verbose) { + // Read the stream; entry.getSize() is unreliable. + // (Also, we're just going to read it anyway.) + long size = readUntilEnd(zis); // No easy way to right-justify the size using // MessageFormat -- how odd. - long size = entry.getSize(); String s = " " + size; int index = Math.min(s.length() - 5, 5); System.out.print(s.substring(index)); @@ -74,11 +96,17 @@ public class Lister else System.out.println(entry.getName()); } - zipFile.close(); } public void run(Main parameters) throws IOException { - listJar(parameters.archiveFile, parameters.verbose); + allItems = new WorkSet(parameters.entries); + File file = parameters.archiveFile; + ZipInputStream zis; + if (file == null || "-".equals(file.getName())) + zis = new ZipInputStream(System.in); + else + zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(file))); + listJar(zis, parameters.verbose); } } diff --git a/tools/gnu/classpath/tools/jar/Main.java b/tools/gnu/classpath/tools/jar/Main.java index ee4da3c27..8ea770bb6 100644 --- a/tools/gnu/classpath/tools/jar/Main.java +++ b/tools/gnu/classpath/tools/jar/Main.java @@ -47,41 +47,53 @@ import gnu.classpath.tools.getopt.Parser; import java.io.File; import java.io.IOException; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.zip.ZipOutputStream; public class Main { - // The mode of operation. This is the class representing - // the action; we make a new instance before using it. It - // must be a subclass of Action. 'null' means the mode - // has not yet been set. + /** The mode of operation. This is the class representing + * the action; we make a new instance before using it. It + * must be a subclass of Action. 'null' means the mode + * has not yet been set. */ Class operationMode; - // The archive file name. + /** The archive file name. */ File archiveFile; - // The zip storage mode. + /** The zip storage mode. */ int storageMode = ZipOutputStream.DEFLATED; - // True if we should read file names from stdin. + /** True if we should read file names from stdin. */ boolean readNamesFromStdin = false; - // True for verbose mode. + /** True for verbose mode. */ boolean verbose = false; - // True if we want a manifest file. + /** True if we want a manifest file. */ boolean wantManifest = true; - // Name of manifest file to use. + /** Name of manifest file to use. */ File manifestFile; - // A list of Entry objects, each describing a file to write. + /** A list of Entry objects, each describing a file to write. */ ArrayList entries = new ArrayList(); - // Used only while parsing. + /** Used only while parsing, holds the first argument for -C. */ String changedDirectory; + void setArchiveFile(String filename) throws OptionException + { + if (archiveFile != null) + { + String fmt = MessageFormat.format(Messages.getString("Main.ArchiveAlreadySet"), //$NON-NLS-1$ + new Object[] { archiveFile }); + throw new OptionException(fmt); + } + archiveFile = new File(filename); + } + class HandleFile extends FileArgumentCallback { @@ -112,57 +124,96 @@ public class Main this.mode = mode; } + public ModeOption(char shortName, String description, String argName, + Class mode) + { + super(shortName, description, argName); + this.mode = mode; + } + public void parsed(String argument) throws OptionException { if (operationMode != null) - throw new OptionException("operation mode already specified"); + throw new OptionException(Messages.getString("Main.ModeAlreaySet")); //$NON-NLS-1$ operationMode = mode; + // We know this is only the case for -i. + if (argument != null) + setArchiveFile(argument); + } + } + + private class JarParser extends ClasspathToolParser + { + public JarParser(String name) + { + super(name); + } + + protected void validate() throws OptionException + { + if (operationMode == null) + throw new OptionException(Messages.getString("Main.MustSpecify")); //$NON-NLS-1$ + if (changedDirectory != null) + throw new OptionException(Messages.getString("Main.TwoArgsReqd")); //$NON-NLS-1$ + if (! wantManifest && manifestFile != null) + throw new OptionException(Messages.getString("Main.CantHaveBoth")); //$NON-NLS-1$ + if (operationMode == Indexer.class) + { + // Some extra validation for -i. + if (! entries.isEmpty()) + throw new OptionException(Messages.getString("Main.NoFilesWithi")); //$NON-NLS-1$ + if (! wantManifest) + throw new OptionException(Messages.getString("Main.NoMAndi")); //$NON-NLS-1$ + if (manifestFile != null) + throw new OptionException(Messages.getString("Main.AnotherNomAndi")); //$NON-NLS-1$ + } } } private Parser initializeParser() { - Parser p = new ClasspathToolParser("jar"); - p.setHeader("Usage: jar -ctxu [OPTIONS] jar-file [-C DIR FILE] FILE..."); - - OptionGroup grp = new OptionGroup("Operation mode"); - grp.add(new ModeOption('c', "create a new archive", Creator.class)); - grp.add(new ModeOption('x', "extract from archive", Extractor.class)); - grp.add(new ModeOption('t', "list archive contents", Lister.class)); - grp.add(new ModeOption('u', "update archive", Updater.class)); + Parser p = new JarParser("jar"); //$NON-NLS-1$ + p.setHeader(Messages.getString("Main.Usage")); //$NON-NLS-1$ + + OptionGroup grp = new OptionGroup(Messages.getString("Main.OpMode")); //$NON-NLS-1$ + grp.add(new ModeOption('c', Messages.getString("Main.Create"), Creator.class)); //$NON-NLS-1$ + grp.add(new ModeOption('x', Messages.getString("Main.Extract"), Extractor.class)); //$NON-NLS-1$ + grp.add(new ModeOption('t', Messages.getString("Main.List"), Lister.class)); //$NON-NLS-1$ + grp.add(new ModeOption('u', Messages.getString("Main.Update"), Updater.class)); //$NON-NLS-1$ + // Note that -i works in-place and explicitly requires a file name. + grp.add(new ModeOption('i', Messages.getString("Main.Index"), Messages.getString("Main.FileArg"), Indexer.class)); //$NON-NLS-1$ //$NON-NLS-2$ p.add(grp); - grp = new OptionGroup("Operation modifiers"); - grp.add(new Option('f', "specify archive file name", "FILE") + grp = new OptionGroup(Messages.getString("Main.OpMods")); //$NON-NLS-1$ + grp.add(new Option('f', Messages.getString("Main.ArchiveName"), Messages.getString("Main.FileArg2")) //$NON-NLS-1$ //$NON-NLS-2$ { public void parsed(String argument) throws OptionException { - // FIXME: error if already set. - archiveFile = new File(argument); + setArchiveFile(argument); } }); - grp.add(new Option('0', "store only; no ZIP compression") + grp.add(new Option('0', Messages.getString("Main.NoZip")) //$NON-NLS-1$ { public void parsed(String argument) throws OptionException { storageMode = ZipOutputStream.STORED; } }); - grp.add(new Option('v', "verbose operation") + grp.add(new Option('v', Messages.getString("Main.Verbose")) //$NON-NLS-1$ { public void parsed(String argument) throws OptionException { verbose = true; } }); - grp.add(new Option('M', "do not create a manifest file") + grp.add(new Option('M', Messages.getString("Main.NoManifest")) //$NON-NLS-1$ { public void parsed(String argument) throws OptionException { wantManifest = false; } }); - grp.add(new Option('m', "specify manifest file", "FILE") + grp.add(new Option('m', Messages.getString("Main.ManifestName"), Messages.getString("Main.ManifestArgName")) //$NON-NLS-1$ //$NON-NLS-2$ { public void parsed(String argument) throws OptionException { @@ -172,9 +223,9 @@ public class Main // -@ p.add(grp); - grp = new OptionGroup("File name selection"); - grp.add(new Option('C', "change to directory before the next file", - "DIR FILE") + grp = new OptionGroup(Messages.getString("Main.FileNameGroup")); //$NON-NLS-1$ + grp.add(new Option('C', Messages.getString("Main.ChangeDir"), //$NON-NLS-1$ + Messages.getString("Main.ChangeDirArg")) //$NON-NLS-1$ { public void parsed(String argument) throws OptionException { @@ -182,23 +233,18 @@ public class Main } }); p.add(grp); - // -i - need to parse classes return p; } - private void run(String[] args) throws OptionException, - InstantiationException, IllegalAccessException, IOException + private void run(String[] args) + throws InstantiationException, IllegalAccessException, IOException { Parser p = initializeParser(); // Special hack to emulate old tar-style commands. - if (args[0].charAt(0) != '-') + if (args.length > 0 && args[0].charAt(0) != '-') args[0] = '-' + args[0]; p.parse(args, new HandleFile()); - if (operationMode == null) - throw new OptionException("must specify one of -t, -c, -u, or -x"); - if (changedDirectory != null) - throw new OptionException("-C argument requires both directory and filename"); Action t = (Action) operationMode.newInstance(); t.run(this); } @@ -210,14 +256,9 @@ public class Main { jarprogram.run(args); } - catch (OptionException arg) - { - System.err.println("jar: " + arg.getMessage()); - System.exit(1); - } catch (Exception e) { - System.err.println("jar: internal error:"); + System.err.println(Messages.getString("Main.InternalError")); //$NON-NLS-1$ e.printStackTrace(System.err); System.exit(1); } diff --git a/tools/gnu/classpath/tools/jar/Messages.java b/tools/gnu/classpath/tools/jar/Messages.java new file mode 100644 index 000000000..ea54bd08f --- /dev/null +++ b/tools/gnu/classpath/tools/jar/Messages.java @@ -0,0 +1,67 @@ +/* Messages.java -- localization support for jar + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.jar; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages +{ + private static final String BUNDLE_NAME + = "gnu.classpath.tools.jar.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE + = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String getString(String key) + { + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/tools/gnu/classpath/tools/jar/Updater.java b/tools/gnu/classpath/tools/jar/Updater.java index 9046b42b0..29586befd 100644 --- a/tools/gnu/classpath/tools/jar/Updater.java +++ b/tools/gnu/classpath/tools/jar/Updater.java @@ -38,41 +38,51 @@ package gnu.classpath.tools.jar; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; -import java.util.ArrayList; +import java.io.OutputStream; import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; +import java.util.jar.JarFile; +import java.util.jar.Manifest; import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; public class Updater extends Creator { + JarFile inputJar; + + protected Manifest createManifest(Main parameters) throws IOException + { + Manifest result = inputJar.getManifest(); + if (result == null) + return super.createManifest(parameters); + if (parameters.manifestFile != null) + result.read(new FileInputStream(parameters.manifestFile)); + return result; + } + public void run(Main parameters) throws IOException { + // Set this early so that createManifest can use it. + inputJar = new JarFile(parameters.archiveFile); + // Write all the new entries to a temporary file. File tmpFile = File.createTempFile("jarcopy", null); - ArrayList newEntries = writeCommandLineEntries(parameters, tmpFile); - HashSet set = new HashSet(); - Iterator it = newEntries.iterator(); - while (it.hasNext()) - { - Entry entry = (Entry) it.next(); - set.add(entry.name); - } + OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile)); + writeCommandLineEntries(parameters, os); // Now read the old file and copy extra entries to the new file. - ZipFile zip = new ZipFile(parameters.archiveFile); - Enumeration e = zip.entries(); + Enumeration e = inputJar.entries(); while (e.hasMoreElements()) { ZipEntry entry = (ZipEntry) e.nextElement(); - if (set.contains(entry.getName())) + if (writtenItems.contains(entry.getName())) continue; - writeFile(entry.isDirectory(), zip.getInputStream(entry), - zip.getName(), parameters.verbose); + writeFile(entry.isDirectory(), inputJar.getInputStream(entry), + entry.getName(), parameters.verbose); } close(); diff --git a/tools/gnu/classpath/tools/jar/WorkSet.java b/tools/gnu/classpath/tools/jar/WorkSet.java new file mode 100644 index 000000000..ff0b48786 --- /dev/null +++ b/tools/gnu/classpath/tools/jar/WorkSet.java @@ -0,0 +1,86 @@ +/* WorkSet.java -- Helper to track what files to work on + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.tools.jar; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +public class WorkSet +{ + private HashSet allItems; + + private void initSet(ArrayList entries) + { + if (entries == null || entries.isEmpty()) + return; + allItems = new HashSet(); + Iterator it = entries.iterator(); + while (it.hasNext()) + { + Entry entry = (Entry) it.next(); + int len = entry.name.length(); + while (len > 0 && entry.name.charAt(len - 1) == '/') + --len; + String name = entry.name.substring(0, len); + allItems.add(name); + } + } + + public WorkSet(ArrayList entries) + { + initSet(entries); + } + + public boolean contains(String filename) + { + if (allItems == null) + return true; + while (filename.length() > 0) + { + if (allItems.contains(filename)) + return true; + int index = filename.lastIndexOf('/'); + if (index == -1) + break; + filename = filename.substring(0, index); + } + return false; + } +} diff --git a/tools/gnu/classpath/tools/jarsigner/JarSigner.java b/tools/gnu/classpath/tools/jarsigner/JarSigner.java index 40bee9fe9..8d3bc31af 100644 --- a/tools/gnu/classpath/tools/jarsigner/JarSigner.java +++ b/tools/gnu/classpath/tools/jarsigner/JarSigner.java @@ -141,7 +141,7 @@ public class JarSigner main.isInternalSF()); log.finer("Created .DSA file"); //$NON-NLS-1$ if (main.isVerbose()) - System.out.println(Messages.getString("JarSigner.11") + dsaFileName); //$NON-NLS-1$ + System.out.println(Messages.getString("JarSigner.8") + dsaFileName); //$NON-NLS-1$ // cleanup outSignedJarFile.close(); diff --git a/tools/gnu/classpath/tools/jarsigner/Main.java b/tools/gnu/classpath/tools/jarsigner/Main.java index f460a96cc..6928bce59 100644 --- a/tools/gnu/classpath/tools/jarsigner/Main.java +++ b/tools/gnu/classpath/tools/jarsigner/Main.java @@ -39,9 +39,13 @@ exception statement from your version. */ package gnu.classpath.tools.jarsigner; import gnu.classpath.SystemProperties; -import gnu.classpath.tools.HelpPrinter; import gnu.classpath.tools.common.CallbackUtil; import gnu.classpath.tools.common.ProviderUtil; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.FileArgumentCallback; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; import gnu.java.security.OID; import gnu.java.security.Registry; import gnu.javax.security.auth.callback.ConsoleCallbackHandler; @@ -61,6 +65,7 @@ import java.security.Security; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.util.ArrayList; import java.util.Locale; import java.util.jar.Attributes.Name; import java.util.logging.Logger; @@ -81,8 +86,8 @@ import javax.security.auth.callback.UnsupportedCallbackException; */ public class Main { - private static final Logger log = Logger.getLogger(Main.class.getName()); - private static final String HELP_PATH = "jarsigner/jarsigner.txt"; //$NON-NLS-1$ + protected static final Logger log = Logger.getLogger(Main.class.getName()); + static final String KEYTOOL_TOOL = "jarsigner"; //$NON-NLS-1$ private static final Locale EN_US_LOCALE = new Locale("en", "US"); //$NON-NLS-1$ //$NON-NLS-2$ static final String DIGEST = "SHA1-Digest"; //$NON-NLS-1$ static final String DIGEST_MANIFEST = "SHA1-Digest-Manifest"; //$NON-NLS-1$ @@ -91,20 +96,20 @@ public class Main static final OID DSA_SIGNATURE_OID = new OID(Registry.DSA_OID_STRING); static final OID RSA_SIGNATURE_OID = new OID(Registry.RSA_OID_STRING); - private boolean verify; - private String ksURL; - private String ksType; - private String password; - private String ksPassword; - private String sigFileName; - private String signedJarFileName; - private boolean verbose; - private boolean certs; - private boolean internalSF; - private boolean sectionsOnly; - private String providerClassName; - private String jarFileName; - private String alias; + protected boolean verify; + protected String ksURL; + protected String ksType; + protected String password; + protected String ksPassword; + protected String sigFileName; + protected String signedJarFileName; + protected boolean verbose; + protected boolean certs; + protected boolean internalSF; + protected boolean sectionsOnly; + protected String providerClassName; + protected String jarFileName; + protected String alias; protected Provider provider; private boolean providerInstalled; @@ -115,6 +120,9 @@ public class Main private Certificate[] signerCertificateChain; /** The callback handler to use when needing to interact with user. */ private CallbackHandler handler; + /** The command line parser. */ + private ToolParser cmdLineParser; + protected ArrayList fileAndAlias = new ArrayList();; private Main() { @@ -126,10 +134,12 @@ public class Main log.entering(Main.class.getName(), "main", args); //$NON-NLS-1$ Main tool = new Main(); + int result = 1; try { tool.processArgs(args); tool.start(); + result = 0; } catch (SecurityException x) { @@ -141,11 +151,13 @@ public class Main log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$ System.err.println(Messages.getString("Main.9") + x); //$NON-NLS-1$ } + finally + { + tool.teardown(); + } - tool.teardown(); - - log.exiting(Main.class.getName(), "main"); //$NON-NLS-1$ - // System.exit(0); + log.exiting(Main.class.getName(), "main", Integer.valueOf(result)); //$NON-NLS-1$ + System.exit(result); } // helper methods ----------------------------------------------------------- @@ -155,65 +167,15 @@ public class Main * preparation for the user desired action. * * @param args an array of options (strings). - * @throws Exception if an exceptio occurs during the process. + * @throws Exception if an exception occurs during the process. */ private void processArgs(String[] args) throws Exception { log.entering(this.getClass().getName(), "processArgs", args); //$NON-NLS-1$ - HelpPrinter.checkHelpKey(args, HELP_PATH); - if (args == null || args.length == 0) - HelpPrinter.printHelpAndExit(HELP_PATH); - - int limit = args.length; - log.finest("args.length=" + limit); //$NON-NLS-1$ - int i = 0; - String opt; - while (i < limit) - { - opt = args[i++]; - log.finest("args[" + (i - 1) + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-verify".equals(opt)) // -verify //$NON-NLS-1$ - verify = true; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - ksURL = args[i++]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - ksType = args[i++]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - ksPassword = args[i++]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - password = args[i++]; - else if ("-sigfile".equals(opt)) // -sigfile NAME //$NON-NLS-1$ - sigFileName = args[i++]; - else if ("-signedjar".equals(opt)) // -signedjar FILE_NAME //$NON-NLS-1$ - signedJarFileName = args[i++]; - else if ("-verbose".equals(opt)) // -verbose //$NON-NLS-1$ - verbose = true; - else if ("-certs".equals(opt)) // -certs //$NON-NLS-1$ - certs = true; - else if ("-internalsf".equals(opt)) // -internalsf //$NON-NLS-1$ - internalSF = true; - else if ("-sectionsonly".equals(opt)) // -sectionsonly //$NON-NLS-1$ - sectionsOnly = true; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - providerClassName = args[i++]; - else - { - jarFileName = opt; - if (! verify) - alias = args[i++]; - - break; - } - } - - if (i < limit) // more options than needed - log.fine("Last argument is assumed at index #" + (i - 1) //$NON-NLS-1$ - + ". Remaining arguments (" + args[i] //$NON-NLS-1$ - + "...) will be ignored"); //$NON-NLS-1$ + cmdLineParser = new ToolParser(); + cmdLineParser.initializeParser(); + cmdLineParser.parse(args, new ToolParserCallback()); setupCommonParams(); if (verify) @@ -319,9 +281,6 @@ public class Main { log.entering(this.getClass().getName(), "setupCommonParams"); //$NON-NLS-1$ - if (jarFileName == null) - HelpPrinter.printHelpAndExit(HELP_PATH); - File jar = new File(jarFileName); if (! jar.exists()) throw new FileNotFoundException(jarFileName); @@ -429,9 +388,6 @@ public class Main InputStream stream = url.openStream(); store.load(stream, ksPasswordChars); - if (alias == null) - HelpPrinter.printHelpAndExit(HELP_PATH); - if (! store.containsAlias(alias)) throw new SecurityException(Messages.getFormattedString("Main.6", alias)); //$NON-NLS-1$ @@ -564,4 +520,155 @@ public class Main return handler; } + + private class ToolParserCallback + extends FileArgumentCallback + { + public void notifyFile(String fileArgument) + { + fileAndAlias.add(fileArgument); + } + } + + private class ToolParser + extends ClasspathToolParser + { + public ToolParser() + { + super(KEYTOOL_TOOL, true); + } + + protected void validate() throws OptionException + { + if (fileAndAlias.size() < 1) + throw new OptionException(Messages.getString("Main.133")); //$NON-NLS-1$ + + jarFileName = (String) fileAndAlias.get(0); + if (! verify) // must have an ALIAS. use "mykey" if undefined + if (fileAndAlias.size() < 2) + { + log.finer("Missing ALIAS argument. Will use [mykey] instead"); //$NON-NLS-1$ + alias = "mykey"; //$NON-NLS-1$ + } + else + alias = (String) fileAndAlias.get(1); + } + + public void initializeParser() + { + setHeader(Messages.getString("Main.2")); //$NON-NLS-1$ + setFooter(Messages.getString("Main.1")); //$NON-NLS-1$ + OptionGroup signGroup = new OptionGroup(Messages.getString("Main.0")); //$NON-NLS-1$ + signGroup.add(new Option("keystore", //$NON-NLS-1$ + Messages.getString("Main.101"), //$NON-NLS-1$ + Messages.getString("Main.102")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + ksURL = argument; + } + }); + signGroup.add(new Option("storetype", //$NON-NLS-1$ + Messages.getString("Main.104"), //$NON-NLS-1$ + Messages.getString("Main.105")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + ksType = argument; + } + }); + signGroup.add(new Option("storepass", //$NON-NLS-1$ + Messages.getString("Main.107"), //$NON-NLS-1$ + Messages.getString("Main.108")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + ksPassword = argument; + } + }); + signGroup.add(new Option("keypass", //$NON-NLS-1$ + Messages.getString("Main.110"), //$NON-NLS-1$ + Messages.getString("Main.111")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + password = argument; + } + }); + signGroup.add(new Option("sigfile", //$NON-NLS-1$ + Messages.getString("Main.113"), //$NON-NLS-1$ + Messages.getString("Main.114")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + sigFileName = argument; + } + }); + signGroup.add(new Option("signedjar", //$NON-NLS-1$ + Messages.getString("Main.116"), //$NON-NLS-1$ + Messages.getString("Main.117")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + signedJarFileName = argument; + } + }); + add(signGroup); + + OptionGroup verifyGroup = new OptionGroup(Messages.getString("Main.118")); //$NON-NLS-1$ + verifyGroup.add(new Option("verify", //$NON-NLS-1$ + Messages.getString("Main.120")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verify = true; + } + }); + verifyGroup.add(new Option("certs", //$NON-NLS-1$ + Messages.getString("Main.122")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + certs = true; + } + }); + add(verifyGroup); + + OptionGroup commonGroup = new OptionGroup(Messages.getString("Main.123")); //$NON-NLS-1$ + commonGroup.add(new Option("verbose", //$NON-NLS-1$ + Messages.getString("Main.125")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + commonGroup.add(new Option("internalsf", //$NON-NLS-1$ + Messages.getString("Main.127")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + internalSF = true; + } + }); + commonGroup.add(new Option("sectionsonly", //$NON-NLS-1$ + Messages.getString("Main.129")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + sectionsOnly = true; + } + }); + commonGroup.add(new Option("provider", //$NON-NLS-1$ + Messages.getString("Main.131"), //$NON-NLS-1$ + Messages.getString("Main.132")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + providerClassName = argument; + } + }); + add(commonGroup); + } + } } diff --git a/tools/gnu/classpath/tools/jarsigner/Messages.java b/tools/gnu/classpath/tools/jarsigner/Messages.java index 284639115..35f461669 100644 --- a/tools/gnu/classpath/tools/jarsigner/Messages.java +++ b/tools/gnu/classpath/tools/jarsigner/Messages.java @@ -54,7 +54,7 @@ import java.util.logging.Logger; class Messages { private static final Logger log = Logger.getLogger(Messages.class.getName()); - private static final String BUNDLE_NAME = "gnu.classpath.tools.jarsigner.MessageBundle"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "gnu.classpath.tools.jarsigner.messages"; private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); private static final Map CACHED_FORMATS = new HashMap(5); @@ -88,7 +88,7 @@ class Messages CACHED_FORMATS.put(key, mf); } - // if the argument is not an array, then build one consisiting of the + // if the argument is not an array, then build one consisting of the // sole argument before passing it to the format() method try { diff --git a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt b/tools/gnu/classpath/tools/jarsigner/jarsigner.txt deleted file mode 100644 index e615609c1..000000000 --- a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt +++ /dev/null @@ -1,116 +0,0 @@ -NAME - jarsigner - Java ARchive (JAR) file signing and verification tool - -SYNOPSIS - jarsigner [OPTION]... FILE ALIAS - jarsigner -verify [OPTION]... FILE - -DESCRIPTION - When the first form is used, the tool signs the designated JAR file. - The second form, on the other hand, is used to verify a previously - signed JAR file. - - FILE is the .JAR file to process; i.e. to sign if the first syntax form - is used, or to verify if the second syntax form is used instead. - - ALIAS must be a known Alias of a Key Entry in the designated key store. - The private key material associated with this Alias is then used for - signing the designated .JAR file. - -SIGNING OPTIONS - -keystore URL - Use this option to specify the location of the key store to use. - The default value is a file URL referencing the file named - ".keystore" (all lower case and without the enclosing quotes) - located in the path returned by the call to - java.lang.System#getProperty(String) using "user.home" as - argument. - - If a URL was specified, but was found to be malformed --e.g. - missing protocol element-- the tool will attempt to use the URL - value as a file-name (with absolute or relative path-name) of a - key store --as if the protocol was "file:". - - -storetype STORE_TYPE - Use this option to specify the type of the key store to use. - The default value, if this option is omitted, is that of the - property "keystore.type" in the security properties file, which - is obtained by invoking the static method call getDefaultType() - in java.security.KeyStore. - - -storepass PASSWORD - Use this option to specify the password which will be used to - unlock the key store. If this option is missing, the User will - be prompted to provide a password. - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to unlock the Key Entry associated with the designated Alias. - - If this option is omitted, the tool will first attempt to unlock - the Key Entry using the same password protecting the key store. - If this fails, you will then be prompted to provide a password. - - -sigfile NAME - Use this option to designate a literal that will be used to - construct file names for both the .SF and .DSA signature files. - These files will be generated, by the tool, and placed in the - META-INF directory of the signed JAR. Permissible characters - for NAME must be in the range "a-zA-Z0-9_-". All characters - will be converted to upper-case ones. - - If this option is missing, the first eight characters of the - ALIAS argument will be used. When this is the case, any - character in ALIAS that is outside the permissible range of - characters will be replaced by an underscore. - - -signedjar FILE_NAME - Use this option to specify the file name of the signed JAR. If - this option is omitted, then the signed JAR will be named the - same as FILE; i.e. the input JAR file will be replaced with the - signed copy. - -VERIFICATION OPTIONS - -verify - Use this option to indicate that the tool is to be used for - verification purposes. - - -certs This option is used in conjunction with the -verbose option. - When present, along with the -verbose option, the tool will - print more detailed information about the certificates of the - signer(s) being processed. - -COMMON OPTIONS - -verbose - Use this option to force the tool to generate more verbose - messages, during its processing. - - -internalsf - When present, the tool will include --which otherwise it does - not-- the .SF file in the .DSA generated file. - - -sectionsonly - When present, the tool will include in the .SF generated file - --which otherwise it does not-- a header containing a hash of - the whole manifest file. When that header is included, the - tool can quickly check, during verification, if the hash (in - the header) matches or not the manifest file. - - -provider PROVIDER_CLASS_NAME - A fully qualified class name of a Security Provider to add to - the current list of Security Providers already installed in the - JVM in-use. If a provider class is specified with this option, - and was successfully added to the runtime --i.e. it was not - already installed-- then the tool will attempt to remove this - Security Provider before exiting. - - -help Prints this help text. - -REPORTING BUGS - Please report bugs at http://www.gnu.org/software/classpath/bugs.html - -COPYRIGHT - Copyright (C) 2006 Free Software Foundation, Inc. - This is free software; see the source for copying conditions. There is - NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/tools/gnu/classpath/tools/keytool/CertReqCmd.java b/tools/gnu/classpath/tools/keytool/CertReqCmd.java index 0c64246e8..fc85e6abd 100644 --- a/tools/gnu/classpath/tools/keytool/CertReqCmd.java +++ b/tools/gnu/classpath/tools/keytool/CertReqCmd.java @@ -38,6 +38,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.OID; import gnu.java.security.der.BitString; import gnu.java.security.der.DER; @@ -123,7 +128,7 @@ import javax.security.auth.x500.X500Principal; * *

-keypass PASSWORD
* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -170,15 +175,16 @@ import javax.security.auth.x500.X500Principal; class CertReqCmd extends Command { private static final Logger log = Logger.getLogger(CertReqCmd.class.getName()); - private String _alias; - private String _sigAlgorithm; - private String _certReqFileName; - private String _password; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; - private boolean nullAttributes; + private static final String ATTRIBUTES_OPT = "attributes"; //$NON-NLS-1$ + protected String _alias; + protected String _sigAlgorithm; + protected String _certReqFileName; + protected String _password; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; + protected boolean nullAttributes; // default 0-arguments constructor @@ -246,60 +252,19 @@ class CertReqCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM //$NON-NLS-1$ - _sigAlgorithm = args[++i]; - else if ("-file".equals(opt)) // -file FILE_NAME //$NON-NLS-1$ - _certReqFileName = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - _password = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else if ("-attributes".equals(opt)) //$NON-NLS-1$ - nullAttributes = true; - else - break; - } - - return i; - } - void setup() throws Exception { setOutputStreamParam(_certReqFileName); setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setAliasParam(_alias); setKeyPasswordNoPrompt(_password); -// setSignatureAlgorithm(_sigAlgorithm); log.finer("-certreq handler will use the following options:"); //$NON-NLS-1$ log.finer(" -alias=" + alias); //$NON-NLS-1$ log.finer(" -sigalg=" + _sigAlgorithm); //$NON-NLS-1$ log.finer(" -file=" + _certReqFileName); //$NON-NLS-1$ - log.finer(" -keypass=" + _password); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ log.finer(" -attributes=" + nullAttributes); //$NON-NLS-1$ @@ -346,6 +311,108 @@ class CertReqCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.CERTREQ_CMD, true); + result.setHeader(Messages.getString("CertReqCmd.25")); //$NON-NLS-1$ + result.setFooter(Messages.getString("CertReqCmd.24")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("CertReqCmd.23")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("CertReqCmd.22"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.21")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.SIGALG_OPT, + Messages.getString("CertReqCmd.20"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.19")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _sigAlgorithm = argument; + } + }); + options.add(new Option(Main.FILE_OPT, + Messages.getString("CertReqCmd.18"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.17")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _certReqFileName = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("CertReqCmd.16"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("CertReqCmd.14"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.13")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("CertReqCmd.12"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.11")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("CertReqCmd.10"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("CertReqCmd.8"), //$NON-NLS-1$ + Messages.getString("CertReqCmd.7")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("CertReqCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + options.add(new Option(ATTRIBUTES_OPT, + Messages.getString("CertReqCmd.5")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + nullAttributes = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * @param aliasName * @param publicKey diff --git a/tools/gnu/classpath/tools/keytool/Command.java b/tools/gnu/classpath/tools/keytool/Command.java index a59614644..0811074b8 100644 --- a/tools/gnu/classpath/tools/keytool/Command.java +++ b/tools/gnu/classpath/tools/keytool/Command.java @@ -42,6 +42,7 @@ import gnu.classpath.SystemProperties; import gnu.classpath.tools.common.CallbackUtil; import gnu.classpath.tools.common.ProviderUtil; import gnu.classpath.tools.common.SecurityProviderInfo; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.OID; import gnu.java.security.Registry; import gnu.java.security.der.BitString; @@ -167,10 +168,17 @@ abstract class Command private int providerNdx = -2; /** The callback handler to use when needing to interact with user. */ private CallbackHandler handler; + /** The shutdown hook. */ + private ShutdownHook shutdownThread; // Constructor(s) ----------------------------------------------------------- - // default 0-arguments constructor + protected Command() + { + super(); + shutdownThread = new ShutdownHook(); + Runtime.getRuntime().addShutdownHook(shutdownThread); + } // Methods ------------------------------------------------------------------ @@ -193,14 +201,16 @@ abstract class Command public void doCommand() throws Exception { try - { - setup(); - start(); - } + { + setup(); + start(); + } finally - { - teardown(); - } + { + teardown(); + if (shutdownThread != null) + Runtime.getRuntime().removeShutdownHook(shutdownThread); + } } /** @@ -228,11 +238,18 @@ abstract class Command * * @param args an array of options for this handler and possibly other * commands and their options. - * @param startIndex the index of the first argument in args to - * process. - * @return the index of the first unprocessed argument in args. + * @return the remaining un-processed args. */ - abstract int processArgs(String[] args, int startIndex); + String[] processArgs(String[] args) + { + log.entering(this.getClass().getName(), "processArgs", args); //$NON-NLS-1$ + + Parser cmdOptionsParser = getParser(); + String[] result = cmdOptionsParser.parse(args); + + log.exiting(this.getClass().getName(), "processArgs", result); //$NON-NLS-1$ + return result; + } /** * Initialize this concrete command handler for later invocation of the @@ -345,6 +362,12 @@ abstract class Command // parameter setup and validation methods ----------------------------------- + /** + * @return a {@link Parser} that knows how to parse the concrete command's + * options. + */ + abstract Parser getParser(); + /** * Convenience method to setup the key store given its type, its password, its * location and portentially a specialized security provider. @@ -486,7 +509,6 @@ abstract class Command storePasswordChars = pcb.getPassword(); pcb.clearPassword(); } - log.finest("storePasswordChars = [" + String.valueOf(storePasswordChars)+ "]"); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -575,7 +597,7 @@ abstract class Command catch (IOException x) { log.fine("Exception while closing the key store input stream: " + x //$NON-NLS-1$ - + ". Ignore"); //$NON-NLS-1$ + + ". Ignore"); //$NON-NLS-1$ } } @@ -970,7 +992,7 @@ abstract class Command protected void saveKeyStore(char[] password) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException { - log.entering(this.getClass().getName(), "saveKeyStore", String.valueOf(password)); //$NON-NLS-1$ + log.entering(this.getClass().getName(), "saveKeyStore"); //$NON-NLS-1$ URLConnection con = storeURL.openConnection(); con.setDoOutput(true); @@ -1144,4 +1166,15 @@ abstract class Command return handler; } + + // Inner class(es) ========================================================== + + private class ShutdownHook + extends Thread + { + public void run() + { + teardown(); + } + } } diff --git a/tools/gnu/classpath/tools/keytool/DeleteCmd.java b/tools/gnu/classpath/tools/keytool/DeleteCmd.java index 968af50f8..4c32ee1e6 100644 --- a/tools/gnu/classpath/tools/keytool/DeleteCmd.java +++ b/tools/gnu/classpath/tools/keytool/DeleteCmd.java @@ -38,6 +38,12 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; + import java.io.IOException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -64,7 +70,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * omitted from the command line. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -106,11 +112,11 @@ import javax.security.auth.callback.UnsupportedCallbackException; class DeleteCmd extends Command { private static final Logger log = Logger.getLogger(DeleteCmd.class.getName()); - private String _alias; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _alias; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; // default 0-arguments constructor @@ -148,36 +154,6 @@ class DeleteCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); @@ -187,7 +163,6 @@ class DeleteCmd extends Command log.finer(" -alias=" + alias); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -206,6 +181,73 @@ class DeleteCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.DELETE_CMD, true); + result.setHeader(Messages.getString("DeleteCmd.18")); //$NON-NLS-1$ + result.setFooter(Messages.getString("DeleteCmd.17")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("DeleteCmd.16")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("DeleteCmd.15"), //$NON-NLS-1$ + Messages.getString("DeleteCmd.14")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("DeleteCmd.13"), //$NON-NLS-1$ + Messages.getString("DeleteCmd.12")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("DeleteCmd.11"), //$NON-NLS-1$ + Messages.getString("DeleteCmd.10")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("DeleteCmd.9"), //$NON-NLS-1$ + Messages.getString("DeleteCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("DeleteCmd.7"), //$NON-NLS-1$ + Messages.getString("DeleteCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("DeleteCmd.5")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * Set the alias to delete from the key store. *

diff --git a/tools/gnu/classpath/tools/keytool/ExportCmd.java b/tools/gnu/classpath/tools/keytool/ExportCmd.java index c1c0d4f83..46f7acdf0 100644 --- a/tools/gnu/classpath/tools/keytool/ExportCmd.java +++ b/tools/gnu/classpath/tools/keytool/ExportCmd.java @@ -38,6 +38,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.util.Base64; import java.io.IOException; @@ -69,7 +74,7 @@ import java.util.logging.Logger; * exported to. If omitted, STDOUT will be used instead. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -119,13 +124,13 @@ import java.util.logging.Logger; class ExportCmd extends Command { private static final Logger log = Logger.getLogger(ExportCmd.class.getName()); - private String _alias; - private String _certFileName; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; - private boolean rfc; + protected String _alias; + protected String _certFileName; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; + protected boolean rfc; // default 0-arguments constructor @@ -178,72 +183,37 @@ class ExportCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS - _alias = args[++i]; - else if ("-file".equals(opt)) // -file FILE_NAME - _certFileName = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME - _providerClassName = args[++i]; - else if ("-rfc".equals(opt)) - rfc = true; - else if ("-v".equals(opt)) - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setOutputStreamParam(_certFileName); setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setAliasParam(_alias); - log.finer("-export handler will use the following options:"); - log.finer(" -alias=" + alias); - log.finer(" -file=" + _certFileName); - log.finer(" -storetype=" + storeType); - log.finer(" -keystore=" + storeURL); - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); - log.finer(" -provider=" + provider); - log.finer(" -rfc=" + rfc); - log.finer(" -v=" + verbose); + log.finer("-export handler will use the following options:"); //$NON-NLS-1$ + log.finer(" -alias=" + alias); //$NON-NLS-1$ + log.finer(" -file=" + _certFileName); //$NON-NLS-1$ + log.finer(" -storetype=" + storeType); //$NON-NLS-1$ + log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ + log.finer(" -provider=" + provider); //$NON-NLS-1$ + log.finer(" -rfc=" + rfc); //$NON-NLS-1$ + log.finer(" -v=" + verbose); //$NON-NLS-1$ } void start() throws KeyStoreException, CertificateEncodingException, IOException { - log.entering(this.getClass().getName(), "start"); + log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$ ensureStoreContainsAlias(); Certificate certificate; if (store.isCertificateEntry(alias)) { - log.fine("Alias [" + alias + "] is a trusted certificate"); + log.finer("Alias [" + alias + "] is a trusted certificate"); //$NON-NLS-1$ //$NON-NLS-2$ certificate = store.getCertificate(alias); } else { - log.fine("Alias [" + alias + "] is a key entry"); + log.finer("Alias [" + alias + "] is a key entry"); //$NON-NLS-1$ //$NON-NLS-2$ Certificate[] chain = store.getCertificateChain(alias); certificate = chain[0]; } @@ -253,14 +223,100 @@ class ExportCmd extends Command { String encoded = Base64.encode(derBytes, 0, derBytes.length, true); PrintWriter pw = new PrintWriter(outStream, true); - pw.println("-----BEGIN CERTIFICATE-----"); + pw.println("-----BEGIN CERTIFICATE-----"); //$NON-NLS-1$ pw.println(encoded); - pw.println("-----END CERTIFICATE-----"); + pw.println("-----END CERTIFICATE-----"); //$NON-NLS-1$ } else outStream.write(derBytes); // stream is closed in Command.teardown() - log.exiting(this.getClass().getName(), "start"); + log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$ + } + + // own methods -------------------------------------------------------------- + + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.EXPORT_CMD, true); + result.setHeader(Messages.getString("ExportCmd.17")); //$NON-NLS-1$ + result.setFooter(Messages.getString("ExportCmd.18")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("ExportCmd.19")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("ExportCmd.20"), //$NON-NLS-1$ + Messages.getString("ExportCmd.21")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.FILE_OPT, + Messages.getString("ExportCmd.22"), //$NON-NLS-1$ + Messages.getString("ExportCmd.23")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _certFileName = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("ExportCmd.24"), //$NON-NLS-1$ + Messages.getString("ExportCmd.25")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("ExportCmd.26"), //$NON-NLS-1$ + Messages.getString("ExportCmd.27")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("ExportCmd.28"), //$NON-NLS-1$ + Messages.getString("ExportCmd.29")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("ExportCmd.30"), //$NON-NLS-1$ + Messages.getString("ExportCmd.31")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.RFC_OPT, + Messages.getString("ExportCmd.32")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + rfc = true; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("ExportCmd.33")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; } } diff --git a/tools/gnu/classpath/tools/keytool/GenKeyCmd.java b/tools/gnu/classpath/tools/keytool/GenKeyCmd.java index 2d92134c2..6da0f58b6 100644 --- a/tools/gnu/classpath/tools/keytool/GenKeyCmd.java +++ b/tools/gnu/classpath/tools/keytool/GenKeyCmd.java @@ -38,6 +38,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.util.Util; import gnu.java.security.x509.X500DistinguishedName; @@ -153,7 +158,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * *
-validity DAY_COUNT
* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -198,19 +203,20 @@ class GenKeyCmd extends Command /** Default key size in bits. */ private static final int DEFAULT_KEY_SIZE = 1024; - private String _alias; - private String _keyAlgorithm; - private String _keySizeStr; - private String _sigAlgorithm; - private String _dName; - private String _password; - private String _validityStr; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _alias; + protected String _keyAlgorithm; + protected String _keySizeStr; + protected String _sigAlgorithm; + protected String _dName; + protected String _password; + protected String _validityStr; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private int keySize; private X500DistinguishedName distinguishedName; + private Parser cmdOptionsParser; // default 0-arguments constructor @@ -294,48 +300,6 @@ class GenKeyCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-keyalg".equals(opt)) // -keyalg ALGORITHM //$NON-NLS-1$ - _keyAlgorithm = args[++i]; - else if ("-keysize".equals(opt)) // -keysize KEY_SIZE //$NON-NLS-1$ - _keySizeStr = args[++i]; - else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM //$NON-NLS-1$ - _sigAlgorithm = args[++i]; - else if ("-dname".equals(opt)) // -dname NAME //$NON-NLS-1$ - _dName = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - _password = args[++i]; - else if ("-validity".equals(opt)) // -validity DAY_COUNT //$NON-NLS-1$ - _validityStr = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); @@ -352,11 +316,9 @@ class GenKeyCmd extends Command log.finer(" -keysize=" + keySize); //$NON-NLS-1$ log.finer(" -sigalg=" + signatureAlgorithm.getAlgorithm()); //$NON-NLS-1$ log.finer(" -dname=" + distinguishedName); //$NON-NLS-1$ - log.finer(" -keypass=" + String.valueOf(keyPasswordChars)); //$NON-NLS-1$ log.finer(" -validity=" + validityInDays); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -368,14 +330,14 @@ class GenKeyCmd extends Command log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$ // 1. generate a new key-pair - log.fine("About to generate key-pair..."); + log.finer("About to generate key-pair..."); //$NON-NLS-1$ keyPairGenerator.initialize(keySize); KeyPair kp = keyPairGenerator.generateKeyPair(); PublicKey publicKey = kp.getPublic(); PrivateKey privateKey = kp.getPrivate(); // 2. generate a self-signed certificate - log.fine("About to generate a self-signed certificate..."); + log.finer("About to generate a self-signed certificate..."); //$NON-NLS-1$ byte[] derBytes = getSelfSignedCertificate(distinguishedName, publicKey, privateKey); @@ -398,6 +360,127 @@ class GenKeyCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.GENKEY_CMD, true); + result.setHeader(Messages.getString("GenKeyCmd.57")); //$NON-NLS-1$ + result.setFooter(Messages.getString("GenKeyCmd.58")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("GenKeyCmd.59")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("GenKeyCmd.60"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.61")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.KEYALG_OPT, + Messages.getString("GenKeyCmd.62"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _keyAlgorithm = argument; + } + }); + options.add(new Option(Main.KEYSIZE_OPT, + Messages.getString("GenKeyCmd.64"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.65")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _keySizeStr = argument; + } + }); + options.add(new Option(Main.SIGALG_OPT, + Messages.getString("GenKeyCmd.66"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _sigAlgorithm = argument; + } + }); + options.add(new Option(Main.DNAME_OPT, + Messages.getString("GenKeyCmd.68"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.69")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _dName = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("GenKeyCmd.70"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option(Main.VALIDITY_OPT, + Messages.getString("GenKeyCmd.72"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.73")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _validityStr = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("GenKeyCmd.74"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.75")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("GenKeyCmd.76"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.77")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("GenKeyCmd.78"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("GenKeyCmd.80"), //$NON-NLS-1$ + Messages.getString("GenKeyCmd.81")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("GenKeyCmd.82")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * @param size the desired key size as a string. * @throws NumberFormatException if the string does not represent a valid diff --git a/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java b/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java index cb6b6dac2..46c5b9769 100644 --- a/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java +++ b/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java @@ -38,6 +38,12 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; + import java.util.logging.Logger; /** @@ -55,7 +61,7 @@ import java.util.logging.Logger; * option is omitted, the tool will process STDIN. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -97,11 +103,11 @@ import java.util.logging.Logger; class IdentityDBCmd extends Command { private static final Logger log = Logger.getLogger(IdentityDBCmd.class.getName()); - private String _idbFileName; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _idbFileName; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; // default 0-arguments constructor @@ -139,47 +145,85 @@ class IdentityDBCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) + void setup() throws Exception { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); - if (opt == null || opt.length() == 0) - continue; - - if ("-file".equals(opt)) // -file FILE_NAME - _idbFileName = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME - _providerClassName = args[++i]; - else if ("-v".equals(opt)) - verbose = true; - else - break; - } + setInputStreamParam(_idbFileName); + setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); - return i; + log.finer("-identitydb handler will use the following options:"); //$NON-NLS-1$ + log.finer(" -file=" + _idbFileName); //$NON-NLS-1$ + log.finer(" -storetype=" + storeType); //$NON-NLS-1$ + log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ + log.finer(" -provider=" + provider); //$NON-NLS-1$ + log.finer(" -v=" + verbose); //$NON-NLS-1$ } - void setup() throws Exception + // own methods -------------------------------------------------------------- + + Parser getParser() { - setInputStreamParam(_idbFileName); - setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.IDENTITYDB_CMD, true); + result.setHeader(Messages.getString("IdentityDBCmd.7")); //$NON-NLS-1$ + result.setFooter(Messages.getString("IdentityDBCmd.8")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("IdentityDBCmd.9")); //$NON-NLS-1$ + options.add(new Option(Main.FILE_OPT, + Messages.getString("IdentityDBCmd.10"), //$NON-NLS-1$ + Messages.getString("IdentityDBCmd.11")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _idbFileName = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("IdentityDBCmd.12"), //$NON-NLS-1$ + Messages.getString("IdentityDBCmd.13")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("IdentityDBCmd.14"), //$NON-NLS-1$ + Messages.getString("IdentityDBCmd.15")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("IdentityDBCmd.16"), //$NON-NLS-1$ + Messages.getString("IdentityDBCmd.17")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("IdentityDBCmd.18"), //$NON-NLS-1$ + Messages.getString("IdentityDBCmd.19")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("IdentityDBCmd.20")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); - log.finer("-identitydb handler will use the following options:"); - log.finer(" -file=" + _idbFileName); - log.finer(" -storetype=" + storeType); - log.finer(" -keystore=" + storeURL); - log.finer(" -storepass=" + new String(storePasswordChars)); - log.finer(" -provider=" + provider); - log.finer(" -v=" + verbose); + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; } } diff --git a/tools/gnu/classpath/tools/keytool/ImportCmd.java b/tools/gnu/classpath/tools/keytool/ImportCmd.java index b5058b581..2e01bc0e4 100644 --- a/tools/gnu/classpath/tools/keytool/ImportCmd.java +++ b/tools/gnu/classpath/tools/keytool/ImportCmd.java @@ -39,6 +39,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; import gnu.classpath.SystemProperties; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.x509.X509CertPath; import java.io.FileInputStream; @@ -47,6 +52,7 @@ import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.Principal; import java.security.PublicKey; import java.security.UnrecoverableKeyException; import java.security.cert.CertPathValidator; @@ -57,11 +63,14 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.Collection; import java.util.LinkedList; +import java.util.ListIterator; import java.util.logging.Level; import java.util.logging.Logger; @@ -139,7 +148,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * should be considered when trying to establish chain-of-trusts. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -181,17 +190,37 @@ import javax.security.auth.callback.UnsupportedCallbackException; class ImportCmd extends Command { private static final Logger log = Logger.getLogger(ImportCmd.class.getName()); - private String _alias; - private String _certFileName; - private String _password; - private boolean noPrompt; - private boolean trustCACerts; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + private static final String GKR = "gkr"; //$NON-NLS-1$ + private static final String JKS = "jks"; //$NON-NLS-1$ + private static final String LIB = "lib"; //$NON-NLS-1$ + private static final String SECURITY = "security"; //$NON-NLS-1$ + private static final String CACERTS = "cacerts"; //$NON-NLS-1$ + private static final String CACERTS_GKR = CACERTS + "." + GKR; //$NON-NLS-1$ + protected String _alias; + protected String _certFileName; + protected String _password; + protected boolean noPrompt; + protected boolean trustCACerts; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private CertificateFactory x509Factory; private boolean imported; + /** + * Pathname to a GKR-type cacerts file to use when trustCACerts is true. This + * is usually a file named "cacerts.gkr" located in lib/security in the folder + * specified by the system-property "gnu.classpath.home". + */ + private String gkrCaCertsPathName; + /** + * Pathname to a JKS-type cacerts file to use when trustCACerts is true. This + * is usually a file named "cacerts" located in lib/security in the folder + * specified by the system-property "java.home". + */ + private String jksCaCertsPathName; + /** Alias self-signed certificate. used when importing certificate replies. */ + private X509Certificate selfSignedCertificate; // default 0-arguments constructor @@ -259,44 +288,6 @@ class ImportCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-file".equals(opt)) // -file FILE_NAME //$NON-NLS-1$ - _certFileName = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - _password = args[++i]; - else if ("-noprompt".equals(opt)) //$NON-NLS-1$ - noPrompt = true; - else if ("-trustcacerts".equals(opt)) //$NON-NLS-1$ - trustCACerts = true; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setInputStreamParam(_certFileName); @@ -307,12 +298,10 @@ class ImportCmd extends Command log.finer("-import handler will use the following options:"); //$NON-NLS-1$ log.finer(" -alias=" + alias); //$NON-NLS-1$ log.finer(" -file=" + _certFileName); //$NON-NLS-1$ - log.finer(" -keypass=" + _password); //$NON-NLS-1$ log.finer(" -noprompt=" + noPrompt); //$NON-NLS-1$ log.finer(" -trustcacerts=" + trustCACerts); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -323,6 +312,20 @@ class ImportCmd extends Command { log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$ + if (trustCACerts) + { + String fs = SystemProperties.getProperty("file.separator"); //$NON-NLS-1$ + String classpathHome = SystemProperties.getProperty("gnu.classpath.home"); //$NON-NLS-1$ + gkrCaCertsPathName = new StringBuilder(classpathHome).append(fs) + .append(LIB).append(fs) + .append(SECURITY).append(fs) + .append(CACERTS_GKR).toString(); + String javaHome = SystemProperties.getProperty("java.home"); //$NON-NLS-1$ + jksCaCertsPathName = new StringBuilder(javaHome).append(fs) + .append(LIB).append(fs) + .append(SECURITY).append(fs) + .append(CACERTS).toString(); + } x509Factory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$ // the alias will tell us whether we're dealing with // a new trusted certificate or a certificate reply @@ -339,6 +342,107 @@ class ImportCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.IMPORT_CMD, true); + result.setHeader(Messages.getString("ImportCmd.27")); //$NON-NLS-1$ + result.setFooter(Messages.getString("ImportCmd.26")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("ImportCmd.25")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("ImportCmd.24"), //$NON-NLS-1$ + Messages.getString("ImportCmd.23")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.FILE_OPT, + Messages.getString("ImportCmd.22"), //$NON-NLS-1$ + Messages.getString("ImportCmd.21")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _certFileName = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("ImportCmd.20"), //$NON-NLS-1$ + Messages.getString("ImportCmd.19")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option("noprompt", //$NON-NLS-1$ + Messages.getString("ImportCmd.18")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + noPrompt = true; + } + }); + options.add(new Option("trustcacerts", //$NON-NLS-1$ + Messages.getString("ImportCmd.17")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + trustCACerts = true; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("ImportCmd.16"), //$NON-NLS-1$ + Messages.getString("ImportCmd.15")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("ImportCmd.14"), //$NON-NLS-1$ + Messages.getString("ImportCmd.13")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("ImportCmd.12"), //$NON-NLS-1$ + Messages.getString("ImportCmd.11")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("ImportCmd.10"), //$NON-NLS-1$ + Messages.getString("ImportCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("ImportCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * When importing a new trusted certificate, alias MUST NOT yet exist * in the key store. @@ -542,8 +646,8 @@ class ImportCmd extends Command if (chain == null) throw new IllegalArgumentException(Messages.getFormattedString("ImportCmd.37", //$NON-NLS-1$ alias)); - Certificate anchor = chain[0]; - PublicKey anchorPublicKey = anchor.getPublicKey(); + selfSignedCertificate = (X509Certificate) chain[0]; + PublicKey anchorPublicKey = selfSignedCertificate.getPublicKey(); PublicKey certPublicKey = certificate.getPublicKey(); boolean sameKey; if (anchorPublicKey instanceof DSAPublicKey) @@ -598,17 +702,54 @@ class ImportCmd extends Command } /** - * @param chain + * Given a collection of certificates returned as a certificate-reply, this + * method sorts the certificates in the collection so that the Issuer + * of the certificate at position i is the Subject of + * the certificate at position i + 1. + *

+ * This method uses selfSignedCertificate to discover the first + * certificate in the chain. The Trust Anchor of the chain; i.e. the + * self-signed CA certificate, if it exsits, will be discovered/established + * later by an appropriate Certificate Path Validator. + *

+ * An exception is thrown if (a) no initial certificate is found in the + * designated collection which can be used as the start of the chain, or (b) + * if a chain can not be constructed using all the certificates in the + * designated collection. + * + * @param chain a collection of certificates, not necessarily ordered, but + * assumed to include a CA certificate authenticating our alias + * public key, which is the subject of the alias self-signed + * certificate. * @return the input collection, ordered with own certificate first, and CA's * self-signed certificate last. */ private LinkedList orderChain(Collection chain) { log.entering(this.getClass().getName(), "orderChain"); //$NON-NLS-1$ - + LinkedList in = new LinkedList(chain); + int initialCount = in.size(); LinkedList result = new LinkedList(); - - + Principal issuer = selfSignedCertificate.getIssuerDN(); + ListIterator it; + outer: while (in.size() > 0) + { + for (it = in.listIterator(); it.hasNext();) + { + X509Certificate certificate = (X509Certificate) it.next(); + if (issuer.equals(certificate.getSubjectDN())) + { + it.remove(); + result.addLast(certificate); + issuer = certificate.getIssuerDN(); + continue outer; + } + } + throw new IllegalArgumentException( + Messages.getFormattedString(Messages.getString("ImportCmd.7"), //$NON-NLS-1$ + new Object[] { Integer.valueOf(result.size()), + Integer.valueOf(initialCount) })); + } log.entering(this.getClass().getName(), "orderChain", result); //$NON-NLS-1$ return result; } @@ -646,13 +787,19 @@ class ImportCmd extends Command CertificateEncodingException { log.entering(this.getClass().getName(), "findTrustAndUpdate"); //$NON-NLS-1$ - - X509CertPath certPath = new X509CertPath(reply); CertPathValidator validator = CertPathValidator.getInstance("PKIX"); //$NON-NLS-1$ + X509CertPath certPath = new X509CertPath(reply); PKIXCertPathValidatorResult cpvr = findTrustInStore(certPath, validator); - if (cpvr == null && trustCACerts) - cpvr = findTrustInCACerts(certPath, validator); - + if (cpvr == null && trustCACerts) // try cacerts.gkr - a GKR key store + { + PKIXParameters params = getCertPathParameters(GKR, gkrCaCertsPathName); + cpvr = validate(validator, certPath, params); + if (cpvr == null) // try cacerts - a JKS key store + { + params = getCertPathParameters(JKS, jksCaCertsPathName); + cpvr = validate(validator, certPath, params); + } + } boolean result = false; if (cpvr == null) { @@ -671,12 +818,12 @@ class ImportCmd extends Command } else { - log.fine("Found a chain-of-trust anchored by " + cpvr.getTrustAnchor()); //$NON-NLS-1$ - Certificate trustedCert = cpvr.getTrustAnchor().getTrustedCert(); + TrustAnchor anchor = cpvr.getTrustAnchor(); + log.fine("Found a chain-of-trust anchored by " + anchor); //$NON-NLS-1$ + Certificate trustedCert = anchor.getTrustedCert(); reply.addLast(trustedCert); result = true; } - log.entering(this.getClass().getName(), "findTrustAndUpdate", //$NON-NLS-1$ Boolean.valueOf(result)); return result; @@ -705,33 +852,32 @@ class ImportCmd extends Command return result; } - private PKIXCertPathValidatorResult findTrustInCACerts(X509CertPath certPath, - CertPathValidator validator) + /** + * Return an instance of {@link PKIXParameters} constructed using a key store + * of the designated type and located at the designated path. + * + * @param type the type of the key-store to load. + * @param pathName the local File System fully qualified path name to the key + * store. + * @return an instance of CertPathParameters to use for + * validating certificates and certificate replies. + */ + private PKIXParameters getCertPathParameters(String type, String pathName) { - log.entering(this.getClass().getName(), "findTrustInCACerts"); //$NON-NLS-1$ - + log.entering(this.getClass().getName(), "getCertPathParameters", //$NON-NLS-1$ + new Object[] { type, pathName }); FileInputStream stream = null; - PKIXCertPathValidatorResult result = null; + PKIXParameters result = null; try { - KeyStore cacerts = KeyStore.getInstance("jks"); //$NON-NLS-1$ - String cacertsPath = SystemProperties.getProperty("java.home"); - String fs = SystemProperties.getProperty("file.separator"); //$NON-NLS-1$ - cacertsPath = new StringBuilder(cacertsPath).append(fs) - .append("lib").append(fs) //$NON-NLS-1$ - .append("security").append(fs) //$NON-NLS-1$ - .append("cacerts").toString(); //$NON-NLS-1$ - stream = new FileInputStream(cacertsPath); + KeyStore cacerts = KeyStore.getInstance(type); + stream = new FileInputStream(pathName); cacerts.load(stream, "changeit".toCharArray()); //$NON-NLS-1$ - PKIXParameters params = new PKIXParameters(cacerts); - result = (PKIXCertPathValidatorResult) validator.validate(certPath, - params); + result = new PKIXParameters(cacerts); } catch (Exception x) { - log.log(Level.FINE, - "Exception in findTrustInCACerts(). Ignore + Return NULL", //$NON-NLS-1$ - x); + log.log(Level.FINE, "Exception in getCertPathParameters(). Ignore", x); //$NON-NLS-1$ } finally { @@ -744,8 +890,27 @@ class ImportCmd extends Command { } } + log.exiting(this.getClass().getName(), "getCertPathParameters", result); //$NON-NLS-1$ + return result; + } - log.exiting(this.getClass().getName(), "findTrustInCACerts", result); //$NON-NLS-1$ + private PKIXCertPathValidatorResult validate(CertPathValidator validator, + X509CertPath certPath, + PKIXParameters params) + { + log.entering(this.getClass().getName(), "validate"); //$NON-NLS-1$ + PKIXCertPathValidatorResult result = null; + if (params != null) + try + { + result = (PKIXCertPathValidatorResult) validator.validate(certPath, + params); + } + catch (Exception x) + { + log.log(Level.FINE, "Exception in validate(). Ignore", x); //$NON-NLS-1$ + } + log.exiting(this.getClass().getName(), "validate", result); //$NON-NLS-1$ return result; } } diff --git a/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java b/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java index 5936719f7..61a8eb880 100644 --- a/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java +++ b/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java @@ -38,6 +38,12 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; + import java.io.IOException; import java.security.Key; import java.security.KeyStoreException; @@ -90,7 +96,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * material of the newly cloned copy of the Key Entry. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -132,14 +138,14 @@ import javax.security.auth.callback.UnsupportedCallbackException; class KeyCloneCmd extends Command { private static final Logger log = Logger.getLogger(KeyCloneCmd.class.getName()); - private String _alias; - private String _destAlias; - private String _password; - private String _newPassword; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _alias; + protected String _destAlias; + protected String _password; + protected String _newPassword; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private String destinationAlias; private char[] newKeyPasswordChars; @@ -197,58 +203,18 @@ class KeyCloneCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-dest".equals(opt)) // -dest ALIAS //$NON-NLS-1$ - _destAlias = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - _password = args[++i]; - else if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$ - _newPassword = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setAliasParam(_alias); setKeyPasswordNoPrompt(_password); setDestinationAlias(_destAlias); -// setNewKeyPassword(_newPassword); log.finer("-keyclone handler will use the following options:"); //$NON-NLS-1$ log.finer(" -alias=" + alias); //$NON-NLS-1$ log.finer(" -dest=" + destinationAlias); //$NON-NLS-1$ - log.finer(" -keypass=" + _password); //$NON-NLS-1$ - log.finer(" -new=" + _newPassword); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -276,6 +242,100 @@ class KeyCloneCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.KEYCLONE_CMD, true); + result.setHeader(Messages.getString("KeyCloneCmd.22")); //$NON-NLS-1$ + result.setFooter(Messages.getString("KeyCloneCmd.21")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("KeyCloneCmd.20")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("KeyCloneCmd.19"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.16")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.DEST_OPT, + Messages.getString("KeyCloneCmd.17"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.16")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _destAlias = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("KeyCloneCmd.15"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option(Main.NEW_OPT, + Messages.getString("KeyCloneCmd.13"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _newPassword = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("KeyCloneCmd.11"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.10")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("KeyCloneCmd.9"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("KeyCloneCmd.7"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("KeyCloneCmd.5"), //$NON-NLS-1$ + Messages.getString("KeyCloneCmd.4")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("KeyCloneCmd.3")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + private void setDestinationAlias(String name) throws IOException, UnsupportedCallbackException { @@ -294,9 +354,9 @@ class KeyCloneCmd extends Command private void setNewKeyPassword(String password) throws IOException, UnsupportedCallbackException { - if (password != null) // ask user to provide one + if (password != null) newKeyPasswordChars = password.toCharArray(); - else + else // ask user to provide one { boolean ok = false; Callback[] prompts = new Callback[1]; diff --git a/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java b/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java index 9dc7b8164..83beb161b 100644 --- a/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java +++ b/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java @@ -39,6 +39,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; import gnu.classpath.SystemProperties; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import java.io.IOException; import java.security.Key; @@ -86,7 +91,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * private key material of the designated Key Entry. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -128,13 +133,13 @@ import javax.security.auth.callback.UnsupportedCallbackException; class KeyPasswdCmd extends Command { private static final Logger log = Logger.getLogger(KeyPasswdCmd.class.getName()); - private String _alias; - private String _password; - private String _newPassword; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _alias; + protected String _password; + protected String _newPassword; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private char[] newPasswordChars; // default 0-arguments constructor @@ -185,54 +190,17 @@ class KeyPasswdCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$ - _password = args[++i]; - else if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$ - _newPassword = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setAliasParam(_alias); setKeyPasswordNoPrompt(_password); -// setNewKeyPassword(_newPassword); log.finer("-keypasswd handler will use the following options:"); //$NON-NLS-1$ log.finer(" -alias=" + alias); //$NON-NLS-1$ - log.finer(" -keypass=" + _password); //$NON-NLS-1$ log.finer(" -new=" + _newPassword); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -259,6 +227,91 @@ class KeyPasswdCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.KEYPASSWD_CMD, true); + result.setHeader(Messages.getString("KeyPasswdCmd.23")); //$NON-NLS-1$ + result.setFooter(Messages.getString("KeyPasswdCmd.22")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("KeyPasswdCmd.21")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("KeyPasswdCmd.20"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.19")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("KeyPasswdCmd.18"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option(Main.NEW_OPT, + Messages.getString("KeyPasswdCmd.16"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _newPassword = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("KeyPasswdCmd.14"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.13")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("KeyPasswdCmd.12"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.11")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("KeyPasswdCmd.10"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("KeyPasswdCmd.8"), //$NON-NLS-1$ + Messages.getString("KeyPasswdCmd.7")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("KeyPasswdCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * Set the new password to use for protecting Alias's private key. * diff --git a/tools/gnu/classpath/tools/keytool/ListCmd.java b/tools/gnu/classpath/tools/keytool/ListCmd.java index 655242785..99fcfa2cf 100644 --- a/tools/gnu/classpath/tools/keytool/ListCmd.java +++ b/tools/gnu/classpath/tools/keytool/ListCmd.java @@ -38,6 +38,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.util.Base64; import java.io.IOException; @@ -64,7 +69,7 @@ import java.util.logging.Logger; * omitted from the command line. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -113,12 +118,12 @@ import java.util.logging.Logger; class ListCmd extends Command { private static final Logger log = Logger.getLogger(ListCmd.class.getName()); - private String _alias; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; - private boolean rfc; + protected String _alias; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; + protected boolean rfc; private boolean all; // default 0-arguments constructor @@ -166,44 +171,11 @@ class ListCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$ - _alias = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else if ("-rfc".equals(opt)) //$NON-NLS-1$ - rfc = true; - else - break; - } - - all = _alias == null; - - return i; - } - void setup() throws Exception { setOutputStreamParam(null); // use stdout setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); + all = _alias == null; if (! all) setAliasParam(_alias); @@ -218,7 +190,6 @@ class ListCmd extends Command log.finer(" -alias=" + alias); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ log.finer(" -rfc=" + rfc); //$NON-NLS-1$ @@ -254,6 +225,81 @@ class ListCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.LIST_CMD, true); + result.setHeader(Messages.getString("ListCmd.20")); //$NON-NLS-1$ + result.setFooter(Messages.getString("ListCmd.19")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("ListCmd.18")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("ListCmd.17"), //$NON-NLS-1$ + Messages.getString("ListCmd.16")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("ListCmd.15"), //$NON-NLS-1$ + Messages.getString("ListCmd.14")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("ListCmd.13"), //$NON-NLS-1$ + Messages.getString("ListCmd.12")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("ListCmd.11"), //$NON-NLS-1$ + Messages.getString("ListCmd.10")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("ListCmd.9"), //$NON-NLS-1$ + Messages.getString("ListCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("ListCmd.7")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + options.add(new Option(Main.RFC_OPT, + Messages.getString("ListCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + rfc = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + /** * Prints the certificate(s) associated with the designated alias. * @@ -312,7 +358,7 @@ class ListCmd extends Command private void print1Chain(Certificate[] chain, PrintWriter writer) throws CertificateEncodingException { - if (!verbose && !rfc) + if (! verbose && ! rfc) fingerprint(chain[0], writer); else { diff --git a/tools/gnu/classpath/tools/keytool/Main.java b/tools/gnu/classpath/tools/keytool/Main.java index fb7aa4509..582aba082 100644 --- a/tools/gnu/classpath/tools/keytool/Main.java +++ b/tools/gnu/classpath/tools/keytool/Main.java @@ -38,8 +38,12 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; -import gnu.classpath.tools.HelpPrinter; import gnu.classpath.tools.common.ProviderUtil; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.Registry; import gnu.javax.crypto.jce.GnuCrypto; import gnu.javax.security.auth.callback.GnuCallbacks; @@ -57,8 +61,51 @@ import java.util.logging.Logger; public class Main { private static final Logger log = Logger.getLogger(Main.class.getName()); - /** The relative file path to the command tool's help text. */ - private static final String HELP_PATH = "keytool/keytool.txt"; //$NON-NLS-1$ + static final String KEYTOOL_TOOL = "keytool"; //$NON-NLS-1$ + static final String GENKEY_CMD = "genkey"; //$NON-NLS-1$ + static final String IMPORT_CMD = "import"; //$NON-NLS-1$ + static final String SELFCERT_CMD = "selfcert"; //$NON-NLS-1$ + static final String IDENTITYDB_CMD = "identitydb"; //$NON-NLS-1$ + static final String CERTREQ_CMD = "certreq"; //$NON-NLS-1$ + static final String EXPORT_CMD = "export"; //$NON-NLS-1$ + static final String LIST_CMD = "list"; //$NON-NLS-1$ + static final String PRINTCERT_CMD = "printcert"; //$NON-NLS-1$ + static final String KEYCLONE_CMD = "keyclone"; //$NON-NLS-1$ + static final String STOREPASSWD_CMD = "storepasswd"; //$NON-NLS-1$ + static final String KEYPASSWD_CMD = "keypasswd"; //$NON-NLS-1$ + static final String DELETE_CMD = "delete"; //$NON-NLS-1$ + + static final String _GENKEY = "-" + GENKEY_CMD; //$NON-NLS-1$ + static final String _IMPORT = "-" + IMPORT_CMD; //$NON-NLS-1$ + static final String _SELFCERT = "-" + SELFCERT_CMD; //$NON-NLS-1$ + static final String _IDENTITYDB = "-" + IDENTITYDB_CMD; //$NON-NLS-1$ + static final String _CERTREQ = "-" + CERTREQ_CMD; //$NON-NLS-1$ + static final String _EXPORT = "-" + EXPORT_CMD; //$NON-NLS-1$ + static final String _LIST = "-" + LIST_CMD; //$NON-NLS-1$ + static final String _PRINTCERT = "-" + PRINTCERT_CMD; //$NON-NLS-1$ + static final String _KEYCLONE = "-" + KEYCLONE_CMD; //$NON-NLS-1$ + static final String _STOREPASSWD = "-" + STOREPASSWD_CMD; //$NON-NLS-1$ + static final String _KEYPASSWD = "-" + KEYPASSWD_CMD; //$NON-NLS-1$ + static final String _DELETE = "-" + DELETE_CMD; //$NON-NLS-1$ + static final String _HELP = "-help"; //$NON-NLS-1$ + + static final String ALIAS_OPT = "alias"; //$NON-NLS-1$ + static final String SIGALG_OPT = "sigalg"; //$NON-NLS-1$ + static final String KEYALG_OPT = "keyalg"; //$NON-NLS-1$ + static final String KEYSIZE_OPT = "keysize"; //$NON-NLS-1$ + static final String KEYPASS_OPT = "keypass"; //$NON-NLS-1$ + static final String VALIDITY_OPT = "validity"; //$NON-NLS-1$ + static final String STORETYPE_OPT = "storetype"; //$NON-NLS-1$ + static final String STOREPASS_OPT = "storepass"; //$NON-NLS-1$ + static final String KEYSTORE_OPT = "keystore"; //$NON-NLS-1$ + static final String PROVIDER_OPT = "provider"; //$NON-NLS-1$ + static final String FILE_OPT = "file"; //$NON-NLS-1$ + static final String VERBOSE_OPT = "v"; //$NON-NLS-1$ + static final String DEST_OPT = "dest"; //$NON-NLS-1$ + static final String NEW_OPT = "new"; //$NON-NLS-1$ + static final String RFC_OPT = "rfc"; //$NON-NLS-1$ + static final String DNAME_OPT = "dname"; //$NON-NLS-1$ + /** The Preferences key name for the last issued certificate serial nbr. */ static final String LAST_SERIAL_NUMBER = "lastSerialNumber"; //$NON-NLS-1$ /** Constant denoting the X.509 certificate type. */ @@ -70,6 +117,8 @@ public class Main private int gnuCryptoProviderNdx = -2; /** The new position of GNU Callbacks provider if it is not already installed. */ private int gnuCallbacksNdx = -2; + /** The command line parser. */ + private Parser cmdLineParser; private Main() { @@ -81,117 +130,140 @@ public class Main log.entering(Main.class.getName(), "main", args); //$NON-NLS-1$ Main tool = new Main(); + int result = 1; try { tool.setup(); tool.start(args); + result = 0; + } + catch (OptionException x) + { + System.err.println(x.getMessage()); + if (tool.cmdLineParser != null) + tool.cmdLineParser.printHelp(); } catch (SecurityException x) { log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$ - System.err.println(Messages.getString("Main.6") + x.getMessage()); //$NON-NLS-1$ + System.err.println(Messages.getFormattedString("Main.6", //$NON-NLS-1$ + x.getMessage())); } catch (Exception x) { log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$ - System.err.println(Messages.getString("Main.8") + x); //$NON-NLS-1$ + System.err.println(Messages.getFormattedString("Main.8", x)); //$NON-NLS-1$ } finally - { - tool.teardown(); - } + { + tool.teardown(); + } - log.exiting(Main.class.getName(), "main"); //$NON-NLS-1$ - // System.exit(0); + log.exiting(Main.class.getName(), "main", Integer.valueOf(result)); //$NON-NLS-1$ + System.exit(result); } // helper methods ----------------------------------------------------------- + private void setup() + { + log.entering(this.getClass().getName(), "setup"); //$NON-NLS-1$ + + cmdLineParser = getParser(); + gnuCryptoProviderNdx = ProviderUtil.addProvider(new GnuCrypto()); + gnuCallbacksNdx = ProviderUtil.addProvider(new GnuCallbacks()); + + log.exiting(this.getClass().getName(), "setup"); //$NON-NLS-1$ + } + private void start(String[] args) throws Exception { - log.entering(this.getClass().getName(), "start", args); //$NON-NLS-1$ + log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$ - if (args == null) - args = new String[0]; + if (args == null || args.length == 0) + throw new OptionException(""); //$NON-NLS-1$ - int limit = args.length; - log.finest("args.length=" + limit); //$NON-NLS-1$ - int i = 0; String opt; Command cmd; - while (i < limit) + while (args.length > 0) { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - + opt = args[0]; cmd = null; - if ("-genkey".equals(opt)) //$NON-NLS-1$ + if (_GENKEY.equals(opt)) cmd = new GenKeyCmd(); - else if ("-import".equals(opt)) //$NON-NLS-1$ + else if (_IMPORT.equals(opt)) cmd = new ImportCmd(); - else if ("-selfcert".equals(opt)) //$NON-NLS-1$ + else if (_SELFCERT.equals(opt)) cmd = new SelfCertCmd(); - else if ("-identitydb".equals(opt)) //$NON-NLS-1$ + else if (_IDENTITYDB.equals(opt)) cmd = new IdentityDBCmd(); - else if ("-certreq".equals(opt)) //$NON-NLS-1$ + else if (_CERTREQ.equals(opt)) cmd = new CertReqCmd(); - else if ("-export".equals(opt)) //$NON-NLS-1$ + else if (_EXPORT.equals(opt)) cmd = new ExportCmd(); - else if ("-list".equals(opt)) //$NON-NLS-1$ + else if (_LIST.equals(opt)) cmd = new ListCmd(); - else if ("-printcert".equals(opt)) //$NON-NLS-1$ + else if (_PRINTCERT.equals(opt)) cmd = new PrintCertCmd(); - else if ("-keyclone".equals(opt)) //$NON-NLS-1$ + else if (_KEYCLONE.equals(opt)) cmd = new KeyCloneCmd(); - else if ("-storepasswd".equals(opt)) //$NON-NLS-1$ + else if (_STOREPASSWD.equals(opt)) cmd = new StorePasswdCmd(); - else if ("-keypasswd".equals(opt)) //$NON-NLS-1$ + else if (_KEYPASSWD.equals(opt)) cmd = new KeyPasswdCmd(); - else if ("-delete".equals(opt)) //$NON-NLS-1$ + else if (_DELETE.equals(opt)) cmd = new DeleteCmd(); - else if ("-help".equals(opt)) //$NON-NLS-1$ - { - printHelp(); - i++; - } + else if (_HELP.equals(opt)) + throw new OptionException(""); //$NON-NLS-1$ else - { - log.fine("Unknown command [" + opt + "] at index #" + i //$NON-NLS-1$ //$NON-NLS-2$ - + ". Arguments from that token onward will be ignored"); //$NON-NLS-1$ - break; - } - - if (cmd != null) - { - i = cmd.processArgs(args, i); - cmd.doCommand(); - } - } - - // the -help command is the default; i.e. - // keytool - // is equivalent to: - // keytool -help - if (i == 0) - printHelp(); + throw new OptionException(Messages.getFormattedString("Main.18", //$NON-NLS-1$ + opt)); - if (i < limit) // more options than needed - log.fine("Last recognized argument is assumed at index #" + (i - 1) //$NON-NLS-1$ - + ". Remaining arguments (" + args[i] + "...) will be ignored"); //$NON-NLS-1$ //$NON-NLS-2$ + String[] cmdArgs = new String[args.length - 1]; + System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length); + args = cmd.processArgs(cmdArgs); + cmd.doCommand(); + } log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$ } - private void setup() + private Parser getParser() { - log.entering(this.getClass().getName(), "setup"); //$NON-NLS-1$ - - gnuCryptoProviderNdx = ProviderUtil.addProvider(new GnuCrypto()); - gnuCallbacksNdx = ProviderUtil.addProvider(new GnuCallbacks()); - - log.exiting(this.getClass().getName(), "setup"); //$NON-NLS-1$ + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(KEYTOOL_TOOL, true); + result.setHeader(Messages.getString("Main.19")); //$NON-NLS-1$ + result.setFooter(Messages.getString("Main.20")); //$NON-NLS-1$ + OptionGroup cmdGroup = new OptionGroup(Messages.getString("Main.21")); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(GENKEY_CMD, + Messages.getString("Main.22"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(IMPORT_CMD, + Messages.getString("Main.23"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(SELFCERT_CMD, + Messages.getString("Main.24"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(IDENTITYDB_CMD, + Messages.getString("Main.25"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(CERTREQ_CMD, + Messages.getString("Main.26"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(EXPORT_CMD, + Messages.getString("Main.27"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(LIST_CMD, + Messages.getString("Main.28"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(PRINTCERT_CMD, + Messages.getString("Main.29"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(KEYCLONE_CMD, + Messages.getString("Main.30"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(STOREPASSWD_CMD, + Messages.getString("Main.31"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(KEYPASSWD_CMD, + Messages.getString("Main.32"))); //$NON-NLS-1$ + cmdGroup.add(new NoParseOption(DELETE_CMD, + Messages.getString("Main.33"))); //$NON-NLS-1$ + result.add(cmdGroup); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; } private void teardown() @@ -213,7 +285,28 @@ public class Main if (helpPrinted) return; - HelpPrinter.printHelp(HELP_PATH); helpPrinted = true; } + + // Inner class(es) + // ========================================================================== + + private class NoParseOption + extends Option + { + public NoParseOption(String name, String description) + { + super(name, description); + } + + public NoParseOption(String name, String description, String param) + { + super(name, description, param); + } + + public void parsed(String argument) throws OptionException + { + // do nothing + } + } } diff --git a/tools/gnu/classpath/tools/keytool/Messages.java b/tools/gnu/classpath/tools/keytool/Messages.java index e3308e021..7ecaa1c37 100644 --- a/tools/gnu/classpath/tools/keytool/Messages.java +++ b/tools/gnu/classpath/tools/keytool/Messages.java @@ -54,7 +54,7 @@ import java.util.logging.Logger; class Messages { private static final Logger log = Logger.getLogger(Messages.class.getName()); - private static final String BUNDLE_NAME = "gnu.classpath.tools.keytool.MessageBundle"; //$NON-NLS-1$ + private static final String BUNDLE_NAME = "gnu.classpath.tools.keytool.messages"; private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); private static final Map CACHED_FORMATS = new HashMap(5); @@ -88,7 +88,7 @@ class Messages CACHED_FORMATS.put(key, mf); } - // if the argument is not an array, then build one consisiting of the + // if the argument is not an array, then build one consisting of the // sole argument before passing it to the format() method try { diff --git a/tools/gnu/classpath/tools/keytool/PrintCertCmd.java b/tools/gnu/classpath/tools/keytool/PrintCertCmd.java index 9ba1d5970..d259258e7 100644 --- a/tools/gnu/classpath/tools/keytool/PrintCertCmd.java +++ b/tools/gnu/classpath/tools/keytool/PrintCertCmd.java @@ -38,6 +38,12 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; + import java.io.PrintWriter; import java.security.cert.Certificate; import java.security.cert.CertificateException; @@ -63,7 +69,7 @@ import java.util.logging.Logger; class PrintCertCmd extends Command { private static final Logger log = Logger.getLogger(PrintCertCmd.class.getName()); - private String _certFileName; + protected String _certFileName; // default 0-arguments constructor @@ -77,40 +83,18 @@ class PrintCertCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); - if (opt == null || opt.length() == 0) - continue; - - if ("-file".equals(opt)) // -file FILE_NAME - _certFileName = args[++i]; - else if ("-v".equals(opt)) - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setInputStreamParam(_certFileName); - log.finer("-printcert handler will use the following options:"); - log.finer(" -file=" + _certFileName); - log.finer(" -v=" + verbose); + log.finer("-printcert handler will use the following options:"); //$NON-NLS-1$ + log.finer(" -file=" + _certFileName); //$NON-NLS-1$ + log.finer(" -v=" + verbose); //$NON-NLS-1$ } void start() throws CertificateException { - log.entering(getClass().getName(), "start"); + log.entering(getClass().getName(), "start"); //$NON-NLS-1$ CertificateFactory x509Factory = CertificateFactory.getInstance(Main.X_509); Certificate certificate = x509Factory.generateCertificate(inStream); @@ -118,6 +102,39 @@ class PrintCertCmd extends Command writer.println(); printVerbose(certificate, writer); - log.exiting(getClass().getName(), "start"); + log.exiting(getClass().getName(), "start"); //$NON-NLS-1$ + } + + // own methods -------------------------------------------------------------- + + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.PRINTCERT_CMD, true); + result.setHeader(Messages.getString("PrintCertCmd.5")); //$NON-NLS-1$ + result.setFooter(Messages.getString("PrintCertCmd.6")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("PrintCertCmd.7")); //$NON-NLS-1$ + options.add(new Option(Main.FILE_OPT, + Messages.getString("PrintCertCmd.8"), //$NON-NLS-1$ + Messages.getString("PrintCertCmd.9")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _certFileName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("PrintCertCmd.10")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; } } diff --git a/tools/gnu/classpath/tools/keytool/SelfCertCmd.java b/tools/gnu/classpath/tools/keytool/SelfCertCmd.java index db7d45994..db700a164 100644 --- a/tools/gnu/classpath/tools/keytool/SelfCertCmd.java +++ b/tools/gnu/classpath/tools/keytool/SelfCertCmd.java @@ -38,6 +38,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import gnu.java.security.x509.X500DistinguishedName; import java.io.ByteArrayInputStream; @@ -129,7 +134,7 @@ import javax.security.auth.x500.X500Principal; * *
-keypass PASSWORD
* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -171,15 +176,15 @@ import javax.security.auth.x500.X500Principal; class SelfCertCmd extends Command { private static final Logger log = Logger.getLogger(SelfCertCmd.class.getName()); - private String _alias; - private String _sigAlgorithm; - private String _dName; - private String _password; - private String _validityStr; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _alias; + protected String _sigAlgorithm; + protected String _dName; + protected String _password; + protected String _validityStr; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private X500DistinguishedName distinguishedName; private int validityInDays; @@ -253,71 +258,29 @@ class SelfCertCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); - if (opt == null || opt.length() == 0) - continue; - - if ("-alias".equals(opt)) // -alias ALIAS - _alias = args[++i]; - else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM - _sigAlgorithm = args[++i]; - else if ("-dname".equals(opt)) // -dname NAME - _dName = args[++i]; - else if ("-keypass".equals(opt)) // -keypass PASSWORD - _password = args[++i]; - else if ("-validity".equals(opt)) // -validity DAY_COUNT - _validityStr = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME - _providerClassName = args[++i]; - else if ("-v".equals(opt)) - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setAliasParam(_alias); setKeyPasswordNoPrompt(_password); -// setDName(_dName); setValidityParam(_validityStr); -// setSignatureAlgorithm(_sigAlgorithm); - - log.finer("-selfcert handler will use the following options:"); - log.finer(" -alias=" + alias); - log.finer(" -sigalg=" + _sigAlgorithm); - log.finer(" -dname=" + _dName); - log.finer(" -keypass=" + _password); - log.finer(" -validity=" + validityInDays); - log.finer(" -storetype=" + storeType); - log.finer(" -keystore=" + storeURL); - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); - log.finer(" -provider=" + provider); - log.finer(" -v=" + verbose); + + log.finer("-selfcert handler will use the following options:"); //$NON-NLS-1$ + log.finer(" -alias=" + alias); //$NON-NLS-1$ + log.finer(" -sigalg=" + _sigAlgorithm); //$NON-NLS-1$ + log.finer(" -dname=" + _dName); //$NON-NLS-1$ + log.finer(" -validity=" + validityInDays); //$NON-NLS-1$ + log.finer(" -storetype=" + storeType); //$NON-NLS-1$ + log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ + log.finer(" -provider=" + provider); //$NON-NLS-1$ + log.finer(" -v=" + verbose); //$NON-NLS-1$ } void start() throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, IOException, UnsupportedCallbackException, InvalidKeyException, SignatureException, CertificateException { - log.entering(getClass().getName(), "start"); + log.entering(getClass().getName(), "start"); //$NON-NLS-1$ // 1. get the key entry and certificate chain associated to alias Key privateKey = getAliasPrivateKey(); @@ -337,7 +300,7 @@ class SelfCertCmd extends Command byte[] derBytes = getSelfSignedCertificate(distinguishedName, publicKey, (PrivateKey) privateKey); - CertificateFactory x509Factory = CertificateFactory.getInstance("X.509"); + CertificateFactory x509Factory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$ ByteArrayInputStream bais = new ByteArrayInputStream(derBytes); Certificate certificate = x509Factory.generateCertificate(bais); @@ -348,11 +311,114 @@ class SelfCertCmd extends Command // 7. persist the key store saveKeyStore(); - log.exiting(getClass().getName(), "start"); + log.exiting(getClass().getName(), "start"); //$NON-NLS-1$ } // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.SELFCERT_CMD, true); + result.setHeader(Messages.getString("SelfCertCmd.14")); //$NON-NLS-1$ + result.setFooter(Messages.getString("SelfCertCmd.15")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("SelfCertCmd.16")); //$NON-NLS-1$ + options.add(new Option(Main.ALIAS_OPT, + Messages.getString("SelfCertCmd.17"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.18")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _alias = argument; + } + }); + options.add(new Option(Main.SIGALG_OPT, + Messages.getString("SelfCertCmd.19"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.20")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _sigAlgorithm = argument; + } + }); + options.add(new Option(Main.DNAME_OPT, + Messages.getString("SelfCertCmd.21"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.22")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _dName = argument; + } + }); + options.add(new Option(Main.KEYPASS_OPT, + Messages.getString("SelfCertCmd.23"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.24")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _password = argument; + } + }); + options.add(new Option(Main.VALIDITY_OPT, + Messages.getString("SelfCertCmd.25"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.26")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _validityStr = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("SelfCertCmd.27"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.28")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("SelfCertCmd.29"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.30")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("SelfCertCmd.31"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.32")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("SelfCertCmd.33"), //$NON-NLS-1$ + Messages.getString("SelfCertCmd.34")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("SelfCertCmd.35")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + private void setDName(String name, X500Principal defaultName) { if (name != null && name.trim().length() > 0) diff --git a/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java b/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java index 1eb053c1c..6c4dfddb9 100644 --- a/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java +++ b/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java @@ -39,6 +39,11 @@ exception statement from your version. */ package gnu.classpath.tools.keytool; import gnu.classpath.SystemProperties; +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.OptionGroup; +import gnu.classpath.tools.getopt.Parser; import java.io.IOException; import java.security.KeyStoreException; @@ -65,7 +70,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; * designated key store. *

* - *
-storetype STORE_TYP}
+ *
-storetype STORE_TYPE
*
Use this option to specify the type of the key store to use. The * default value, if this option is omitted, is that of the property * keystore.type in the security properties file, which is @@ -107,11 +112,11 @@ import javax.security.auth.callback.UnsupportedCallbackException; class StorePasswdCmd extends Command { private static final Logger log = Logger.getLogger(StorePasswdCmd.class.getName()); - private String _newPassword; - private String _ksType; - private String _ksURL; - private String _ksPassword; - private String _providerClassName; + protected String _newPassword; + protected String _ksType; + protected String _ksURL; + protected String _ksPassword; + protected String _providerClassName; private char[] newStorePasswordChars; // default 0-arguments constructor @@ -150,46 +155,14 @@ class StorePasswdCmd extends Command // life-cycle methods ------------------------------------------------------- - int processArgs(String[] args, int i) - { - int limit = args.length; - String opt; - while (++i < limit) - { - opt = args[i]; - log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$ - if (opt == null || opt.length() == 0) - continue; - - if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$ - _newPassword = args[++i]; - else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$ - _ksType = args[++i]; - else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$ - _ksURL = args[++i]; - else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$ - _ksPassword = args[++i]; - else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$ - _providerClassName = args[++i]; - else if ("-v".equals(opt)) //$NON-NLS-1$ - verbose = true; - else - break; - } - - return i; - } - void setup() throws Exception { setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL); setNewKeystorePassword(_newPassword); log.finer("-storepasswd handler will use the following options:"); //$NON-NLS-1$ - log.finer(" -new=" + String.valueOf(newStorePasswordChars)); //$NON-NLS-1$ log.finer(" -storetype=" + storeType); //$NON-NLS-1$ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$ - log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$ log.finer(" -provider=" + provider); //$NON-NLS-1$ log.finer(" -v=" + verbose); //$NON-NLS-1$ } @@ -206,6 +179,73 @@ class StorePasswdCmd extends Command // own methods -------------------------------------------------------------- + Parser getParser() + { + log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$ + + Parser result = new ClasspathToolParser(Main.STOREPASSWD_CMD, true); + result.setHeader(Messages.getString("StorePasswdCmd.18")); //$NON-NLS-1$ + result.setFooter(Messages.getString("StorePasswdCmd.17")); //$NON-NLS-1$ + OptionGroup options = new OptionGroup(Messages.getString("StorePasswdCmd.16")); //$NON-NLS-1$ + options.add(new Option(Main.NEW_OPT, + Messages.getString("StorePasswdCmd.15"), //$NON-NLS-1$ + Messages.getString("StorePasswdCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _newPassword = argument; + } + }); + options.add(new Option(Main.STORETYPE_OPT, + Messages.getString("StorePasswdCmd.13"), //$NON-NLS-1$ + Messages.getString("StorePasswdCmd.12")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksType = argument; + } + }); + options.add(new Option(Main.KEYSTORE_OPT, + Messages.getString("StorePasswdCmd.11"), //$NON-NLS-1$ + Messages.getString("StorePasswdCmd.10")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksURL = argument; + } + }); + options.add(new Option(Main.STOREPASS_OPT, + Messages.getString("StorePasswdCmd.9"), //$NON-NLS-1$ + Messages.getString("StorePasswdCmd.8")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _ksPassword = argument; + } + }); + options.add(new Option(Main.PROVIDER_OPT, + Messages.getString("StorePasswdCmd.7"), //$NON-NLS-1$ + Messages.getString("StorePasswdCmd.6")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + _providerClassName = argument; + } + }); + options.add(new Option(Main.VERBOSE_OPT, + Messages.getString("StorePasswdCmd.5")) //$NON-NLS-1$ + { + public void parsed(String argument) throws OptionException + { + verbose = true; + } + }); + result.add(options); + + log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$ + return result; + } + protected void setNewKeystorePassword(String password) throws IOException, UnsupportedCallbackException { diff --git a/tools/gnu/classpath/tools/keytool/keytool.txt b/tools/gnu/classpath/tools/keytool/keytool.txt deleted file mode 100644 index 15f9b96f9..000000000 --- a/tools/gnu/classpath/tools/keytool/keytool.txt +++ /dev/null @@ -1,616 +0,0 @@ -NAME - keytool - manage private keys and public certificates - -SYNOPSIS - keytool [COMMAND]... - -DESCRIPTION - A Java-based tool for managing both Key Entries as well as Trusted - Certificates. - - Multiple COMMANDs may be specified at once, each complete with its own - options. keytool will parse all the arguments, before processing, and - executing, each COMMAND. If an exception occurs while executing one - COMMAND keytool will abort. - - A COMMAND can be one of the followings: - - -genkey [OPTION]... - Generate a new Key Entry, eventually creating a new key store. - - -import [OPTION]... - Add, to a key store, Key Entries (private keys and certificate - chains authenticating the public keys) and Trusted Certificates - (3rd party certificates which can be used as Trust anchors when - building chains-of-trust). - - -selfcert [OPTION]... - Generate a new self-signed Trusted Certificate. - - -identitydb [OPTION]... - NOT IMPLEMENTED YET. - Import a JDK 1.1 style Identity Database. - - -certreq [OPTION]... - Issue a Certificate Signing Request (CSR) which can be then sent - to a Certification Authority (CA) to issue a certificate signed - (by the CA) and authenticating the Subject of the request. - - -export [OPTION]... - Export a Certificate from a key store. - - -list [OPTION]... - Print one or all Certificates in a key store to STDOUT. - - -printcert [OPTION]... - Print a human-readable form of a Certificate in a designated - file to STDOUT. - - -keyclone [OPTION]... - Clone a Key Entry in a key store. - - -storepasswd [OPTION]... - Change the password protecting a key store. - - -keypasswd [OPTION]... - Change the password protecting a Key Entry in a key store. - - -delete [OPTION]... - Delete a Key Entry or a Trusted Certificate from a key store. - - -help Display this text. - -OPTIONS COMMON TO MORE THAN ONE COMMAND - The following OPTIONs are used in more than one COMMAND. They are - described here to reduce redundancy. - - -alias ALIAS - Every entry, be it a Key Entry or a Trusted Certificate, in a - key store is uniquely identified by a user-defined Alias string. - Use this option to specify the Alias to use when referring to an - entry in the key store. Unless specified otherwise, a default - value of "mykey" (all lower case, without the enclosing quotes) - shall be used when this option is omitted from the command line. - - -keyalg ALGORITHM - Use this option to specify the canonical name of the key-pair - generation algorithm. The default value for this option is - "DSS" (a synonym for the Digital Signature Algorithm also known - as DSA). - - -keysize SIZE - Use this option to specify the number of bits of the shared - modulus (for both the public and private keys) to use when - generating new keys. A default value of 1024 will be used if - this option is omitted from the command line. - - -validity DAY_COUNT - Use this option to specify the number of days a newly generated - certificate will be valid for. The default value is 90 (days) - if this option is omitted from the command line. - - -storetype STORE_TYPE - Use this option to specify the type of the key store to use. - The default value, if this option is omitted, is that of the - property "keystore.type" in the security properties file, which - is obtained by invoking the static method call getDefaultType() - in java.security.KeyStore. - - -storepass PASSWORD - Use this option to specify the password protecting the key - store. If this option is omitted from the command line, you - will be prompted to provide a password. - - -keystore URL - Use this option to specify the location of the key store to use. - The default value is a file URL referencing the file named - ".keystore" (all lower case and without the enclosing quotes) - located in the path returned by the call to - java.lang.System#getProperty(String) using "user.home" as - argument. - - If a URL was specified, but was found to be malformed --e.g. - missing protocol element-- the tool will attempt to use the URL - value as a file-name (with absolute or relative path-name) of a - key store --as if the protocol was "file:". - - -provider PROVIDER_CLASS_NAME - A fully qualified class name of a Security Provider to add to - the current list of Security Providers already installed in the - JVM in-use. If a provider class is specified with this option, - and was successfully added to the runtime --i.e. it was not - already installed-- then the tool will attempt to remove this - Security Provider before exiting. - - -file FILE_NAME - Use this option to designate a file to use with a command. When - specified with this option, the value is expected to be the - fully qualified path of a file accessible by the File System. - Depending on the command, the file may be used as input or as - output. When this option is omitted from the command line, - STDIN will be used instead, as the source of input, and STDOUT - will be used instead as the output destination. - - -v Unless specified otherwise, use this option to enable more - verbose output. - -X.500 DISTINGUISHED NAME - A Distinguished Name (or DN) MUST be supplied with some of the COMMANDs - using a -dname option. The syntax of a valid value for this option MUST - follow RFC-2253 specifications. Namely the following components (with - their accepted meaning) will be recognized. Note that the component - name is case-insensitive: - - CN The Common Name; e.g. "host.domain.com" - OU The Organizational Unit; e.g. "IT Department" - O The Organization Name; e.g. "The Sample Company" - L The Locality Name; e.g. "Sydney" - ST The State Name; e.g. "New South Wales" - C The 2-letter Country identifier; e.g. "AU" - - When specified with a -dname option, each pair of component/value will - be separated from the other with a comma. Each component and value pair - MUST be separated by an equal sign. For example, the following is - a valid DN value: - - CN=host.domain.com, O=The Sample Company, L=Sydney, ST=NSW, C=AU - - If the Distinguished Name is required, and no valid default value can be - used, the tool will prompt you to enter the information through the - console. - --genkey COMMAND - Generate a new key-pair (both private and public keys), and save these - credentials in the key store as a Key Entry, associated with the - designated (if was specified in the -alias option) or default (if the - -alias option is omitted) Alias. - - The private key material will be protected with a user-defined password - (see -keypass option). The public key on the other hand will be part - of a self-signed X.509 certificate, which will form a 1-element chain - and will be saved in the key store. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keyalg ALGORITHM - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keysize KEY_SIZE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -sigalg ALGORITHM - The canonical name of the digital signature algorithm to use for - signing certificates. If this option is omitted, a default - value will be chosen based on the type of the key-pair; i.e. the - algorithm that ends up being used by the -keyalg option. If the - key-pair generation algorithm is "DSA", the value for the - signature algorithm will be "SHA1withDSA". If on the other hand - the key-pair generation algorithm is "RSA", then the tool will - use "MD5withRSA" as the signature algorithm. - - -dname NAME - This a mandatory value for the command. If no value is - specified --i.e. the -dname option is omitted-- the tool will - prompt you to enter a Distinguished Name to use as both the - Owner and Issuer of the generated self-signed certificate. - - (see X.500 DISTINGUISHED NAME) - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to protect the newly created Key Entry. - - If this option is omitted, you will be prompted to provide a - password. - - -validity DAY_COUNT - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --import COMMAND - Read an X.509 certificate, or a PKCS#7 Certificate Reply from a - designated input source and incorporate the certificates into the key - store. - - If the Alias does not already exist in the key store, the tool treats - the certificate read from the input source as a new Trusted Certificate. - It then attempts to discover a chain-of-trust, starting from that - certificate and ending at another Trusted Certificate, already stored in - the key store. If the -trustcacerts option is present, an additional - key store, of type "JKS" named "cacerts", and assumed to be present in - ${JAVA_HOME}/lib/security will also be consulted if found --${JAVA_HOME} - refers to the location of an installed Java Runtime Environment (JRE). - If no chain-of-trust can be established, and unless the -noprompt option - has been specified, the certificate is printed to STDOUT and the user is - prompted for a confirmation. - - If Alias exists in the key store, the tool will treat the certificate(s) - read from the input source as a Certificate Reply, which can be a chain - of certificates, that eventually would replace the chain of certificates - associated with the Key Entry of that Alias. The substitution of the - certificates only occurs if a chain-of-trust can be established between - the bottom certificate of the chain read from the input file and the - Trusted Certificates already present in the key store. Again, if the - -trustcacerts option is specified, additional Trusted Certificates in - the same "cacerts" key store will be considered. If no chain-of-trust - can be established, the operation will abort. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -file FILE_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to protect the Key Entry associated with the designated Alias, - when replacing this Alias' chain of certificates with that found - in the certificate reply. - - If this option is omitted, and the chain-of-trust for the - certificate reply has been established, the tool will first - attempt to unlock the Key Entry using the same password - protecting the key store. If this fails, you will then be - prompted to provide a password. - - -noprompt - Use this option to prevent the tool from prompting the user. - - -trustcacerts - Use this option to indicate to the tool that a key store, of - type "JKS", named "cacerts", and usually located in lib/security - in an installed Java Runtime Environment should be considered - when trying to establish chain-of-trusts. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --selfcert COMMAND - Generate a self-signed X.509 version 1 certificate. The newly generated - certificate will form a chain of one element which will replace the - previous chain associated with the designated Alias (if -alias option - was specified), or the default Alias (if -alias option was omitted). - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -sigalg ALGORITHM - The canonical name of the digital signature algorithm to use for - signing the certificate. If this option is omitted, a default - value will be chosen based on the type of the private key - associated with the designated Alias. If the private key is a - "DSA" one, the value for the signature algorithm will be - "SHA1withDSA". If on the other hand the private key is an "RSA" - one, then the tool will use "MD5withRSA" as the signature - algorithm. - - -dname NAME - Use this option to specify the Distinguished Name of the newly - generated self-signed certificate. If this option is omitted, - the existing Distinguished Name of the base certificate in the - chain associated with the designated Alias will be used instead. - - (see X.500 DISTINGUISHED NAME) - - -validity DAY_COUNT - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to unlock the Key Entry associated with the designated Alias. - - If this option is omitted, the tool will first attempt to unlock - the Key Entry using the same password protecting the key store. - If this fails, you will then be prompted to provide a password. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --identitydb COMMAND - NOT IMPLEMENTED YET. - - Import a JDK 1.1 style Identity Database. - - -file FILE_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --certreq COMMAND - Generate a PKCS#10 Certificate Signing Request (CSR) and writes it to - a designated output destination. The contents of the destination - should look something like the following: - - -----BEGIN NEW CERTIFICATE REQUEST----- - MIICYTCCAiECAQAwXzEUMBIGA1UEAwwLcnNuQGdudS5vcmcxGzAZBgNVBAoMElUg - Q29tcGFueTEPMA0GA1UEBwwGU3lkbmV5MQwwCgYDVQQIDANOU1cxCzAJBgNVBACC - ... - FCTlKlok8KwGuIVwNVOfQLRX+O5kAhQ/a4RTZme2L8PnpvgRwrf7Eg8D6w== - -----END NEW CERTIFICATE REQUEST----- - - IMPORTANT: Some documentation (e.g. RSA examples) claims that the - Attributes field, in the CSR is OPTIONAL while RFC-2986 implies the - opposite. This implementation considers this field, by default, as - OPTIONAL, unless the option -attributes is specified on the command - line. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -sigalg ALGORITHM - The canonical name of the digital signature algorithm to use for - signing the certificate. If this option is omitted, a default - value will be chosen based on the type of the private key - associated with the designated Alias. If the private key is a - "DSA" one, the value for the signature algorithm will be - "SHA1withDSA". If on the other hand the private key is an "RSA" - one, then the tool will use "MD5withRSA" as the signature - algorithm. - - -file FILE_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to unlock the Key Entry associated with the designated Alias. - - If this option is omitted, the tool will first attempt to unlock - the Key Entry using the same password protecting the key store. - If this fails, you will then be prompted to provide a password. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -attributes - Use this option to force the tool to encode a NULL DER value in - the CSR as the value of the Attributes field. - --export COMMAND - Export a certificate stored in the key store to a designated output - destination, either in binary format (if the -v option is specified), - or in RFC-1421 compliant encoding (if the -rfc option is specified - instead). - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -file FILE_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -rfc Use RFC-1421 specifications when encoding the output. - - -v Output the certificate in binary DER encoding. This is the - default output format of the command if neither -rfc nor -v - options were detected on the command line. If both this option - and the -rfc option are detected on the command line, the tool - will opt for the RFC-1421 style encoding. - --list COMMAND - Print one or all of the key store entries to STDOUT. Usually this - command will only print a fingerprint of the certificate, unless either - the -rfc or the -v option is specified. - - -alias ALIAS - If this option is omitted, the tool will print ALL the entries - found in the key store. - - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -rfc Use RFC-1421 specifications when encoding the output. - - -v Output the certificate in human-readable format. If both this - option and the -rfc option are detected on the command line, - the tool will opt for the human-readable form and will not - abort the command. - --printcert COMMAND - Read a certificate from a designated input source and print it to STDOUT - in a human-readable form. - - -file FILE_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --keyclone COMMAND - Clone an existing Key Entry and store it under a new (different) Alias - protecting, its private key material with possibly a new password. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -dest ALIAS - Use this option to specify the new Alias which will be used to - identify the cloned copy of the Key Entry. - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to unlock the Key Entry associated with the designated Alias. - - If this option is omitted, the tool will first attempt to unlock - the Key Entry using the same password protecting the key store. - If this fails, you will then be prompted to provide a password. - - -new PASSWORD - Use this option to specify the password protecting the private - key material of the newly cloned copy of the Key Entry. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --storepasswd COMMAND - Change the password protecting a key store. - - -new PASSWORD - The new, and different, password which will be used to protect - the designated key store. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --keypasswd COMMAND - Change the password protecting the private key material of a designated - Key Entry. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keypass PASSWORD - Use this option to specify the password which the tool will use - to unlock the Key Entry associated with the designated Alias. - - If this option is omitted, the tool will first attempt to unlock - the Key Entry using the same password protecting the key store. - If this fails, you will then be prompted to provide a password. - - -new PASSWORD - The new, and different, password which will be used to protect - the private key material of the designated Key Entry. - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - --delete COMMAND - Delete a designated key store entry. - - -alias ALIAS - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storetype STORE_TYPE - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -keystore URL - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -storepass PASSWORD - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -provider PROVIDER_CLASS_NAME - (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - - -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND) - -REPORTING BUGS - Please report bugs at http://www.gnu.org/software/classpath/bugs.html - -COPYRIGHT - Copyright (C) 2006 Free Software Foundation, Inc. - This is free software; see the source for copying conditions. There is - NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/tools/gnu/classpath/tools/native2ascii/Messages.java b/tools/gnu/classpath/tools/native2ascii/Messages.java new file mode 100644 index 000000000..4c6bae4dc --- /dev/null +++ b/tools/gnu/classpath/tools/native2ascii/Messages.java @@ -0,0 +1,67 @@ +/* Messages.java -- translation support for native2ascii + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.native2ascii; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages +{ + private static final String BUNDLE_NAME + = "gnu.classpath.tools.native2ascii.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE + = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String getString(String key) + { + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java b/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java new file mode 100644 index 000000000..9508c103e --- /dev/null +++ b/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java @@ -0,0 +1,185 @@ +/* Native2ASCII.java - native2ascii program + Copyright (C) 2003 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.native2ascii; + +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.FileArgumentCallback; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.Parser; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; + +/** + * Native2ASCII main program. + * @author Ito Kazumitsu + */ +public class Native2ASCII +{ + // Input file. + String input; + // Output file. + String output; + // Encoding to use. + String encoding; + // True for reverse operation. + boolean reversed; + + private class HandleFile extends FileArgumentCallback + { + public HandleFile() + { + } + + public void notifyFile(String fileArgument) + throws OptionException + { + if (input == null) + input = fileArgument; + else if (output == null) + output = fileArgument; + else + throw new OptionException(Messages.getString("Native2ASCII.TooManyFiles")); //$NON-NLS-1$ + } + } + + private Parser createParser() + { + Parser result = new ClasspathToolParser("native2ascii", true); //$NON-NLS-1$ + result.setHeader(Messages.getString("Native2ASCII.Usage")); //$NON-NLS-1$ + + result.add(new Option("encoding", Messages.getString("Native2ASCII.EncodingHelp"), Messages.getString("Native2ASCII.EncodingArgName")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { + public void parsed(String argument) throws OptionException + { + if (encoding != null) + throw new OptionException(Messages.getString("Native2ASCII.EncodingSpecified")); //$NON-NLS-1$ + encoding = argument; + } + }); + result.add(new Option("reversed", Messages.getString("Native2ASCII.ReversedHelp")) //$NON-NLS-1$ //$NON-NLS-2$ + { + public void parsed(String argument) throws OptionException + { + reversed = true; + } + }); + + return result; + } + + private void run(String[] args) + { + Parser argParser = createParser(); + argParser.parse(args, new HandleFile()); + + if (encoding == null) + encoding = System.getProperty("file.encoding"); //$NON-NLS-1$ + try + { + InputStream is = (input == null ? System.in + : new FileInputStream(input)); + OutputStream os = (output == null ? (OutputStream) System.out + : new FileOutputStream(output)); + + BufferedReader rdr = new BufferedReader(new InputStreamReader(is, + encoding)); + PrintWriter wtr = new PrintWriter( + new BufferedWriter( + new OutputStreamWriter( + os, + encoding))); + while (true) + { + String s = rdr.readLine(); + if (s == null) + break; + StringBuffer sb = new StringBuffer(s.length() + 80); + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + if (reversed + && i + 6 < s.length() + && s.charAt(i) == '\\' + && s.charAt(i + 1) == 'u') + { + int num = Integer.parseInt(s.substring(i + 2, i + 6), 16); + sb.append((char) num); + i += 5; + } + else if ((int)c <= 127 || reversed) + { + sb.append(c); + } + else + { + sb.append("\\u"); //$NON-NLS-1$ + if ((int)c <= 0xff) + sb.append("00"); //$NON-NLS-1$ + else if ((int)c <= 0xfff) + sb.append("0"); //$NON-NLS-1$ + sb.append(Integer.toHexString((int) c)); + } + } + wtr.println(sb.toString()); + } + rdr.close(); + wtr.flush(); + wtr.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + new Native2ASCII().run(args); + String encoding = System.getProperty("file.encoding"); //$NON-NLS-1$ + } +} diff --git a/tools/gnu/classpath/tools/rmi/RMIC.java b/tools/gnu/classpath/tools/rmi/RMIC.java index c44453011..fa4d87c17 100644 --- a/tools/gnu/classpath/tools/rmi/RMIC.java +++ b/tools/gnu/classpath/tools/rmi/RMIC.java @@ -41,7 +41,7 @@ public class RMIC /** * The version of the compiler. */ - public static String VERSION = "0.0 alpha pre"; + public static String VERSION = "0.01 alpha pre"; /** * The GRMIC compiler methods @@ -112,6 +112,17 @@ public class RMIC else HelpPrinter.printHelpAndExit(HelpPath); } + else if (c.equals("-classpath")) + { + int f = i + 1; + if (f < args.length) + { + compiler.setClassPath(args[f]); + i++; + } + else + HelpPrinter.printHelpAndExit(HelpPath); + } else if (c.charAt(0) != '-') // No more options - start of class list. { @@ -132,17 +143,7 @@ public class RMIC if (args[i].charAt(0) != '-') { compiler.reset(); - Class c = null; - try - { - c = Thread.currentThread().getContextClassLoader().loadClass( - args[i]); - } - catch (ClassNotFoundException e) - { - System.err.println(args[i] + " class not found."); - System.exit(1); - } + Class c = compiler.loadClass(args[i]); compiler.compile(c); String packag = compiler.getPackageName().replace('.', '/'); diff --git a/tools/gnu/classpath/tools/rmi/RMIC.txt b/tools/gnu/classpath/tools/rmi/RMIC.txt index 7ec371e9a..882cca553 100644 --- a/tools/gnu/classpath/tools/rmi/RMIC.txt +++ b/tools/gnu/classpath/tools/rmi/RMIC.txt @@ -9,25 +9,29 @@ Please report bugs at http://www.gnu.org/software/classpath/bugs.html Usage: rmic where includes: - -nowarn Show no warnings - -nowrite Do not write any files (check for errors only) - -d Place generated files into the given folder + -nowarn Show no warnings + -nowrite Do not write any files (check for errors only) + -d Place generated files into the given folder + -classpath Specifies the path, where to find the classes being + compiled - -help Print this help text - -v Print version - -verbose Verbose output - -force Try to generate code even if the input classes seem not - consistent with RMI specification. + -help Print this help text + -v Print version + -verbose Verbose output + -force Try to generate code even if the input classes seem not + consistent with RMI specification. - -1.2 Generate v 1.2 stubs (default)* + -1.2 Generate v 1.2 stubs (default)* - -iiop Generate stubs and ties for the GIOP based RMI package extension, - javax.rmi. With this key, the two additional keys are accepted: - -poa Generate the Servant based ties (default) - -impl Generate the obsoleted ObjectImpl based ties - (for backward compatibility) - -help Show more details on the giop stub and tie generator options. - -giop Same as -iiop* + -iiop Generate stubs and ties for the GIOP based RMI package + extension, javax.rmi. With this key, the two additional + keys are accepted: + -poa Generate the Servant based ties (default) + -impl Generate the obsoleted ObjectImpl based ties + (for backward compatibility) + -help Show more details on the giop stub and tie generator + options. + -giop Same as -iiop* and can include one or more non abstract classes that implement diff --git a/tools/gnu/classpath/tools/serialver/Messages.java b/tools/gnu/classpath/tools/serialver/Messages.java new file mode 100644 index 000000000..a6ab67add --- /dev/null +++ b/tools/gnu/classpath/tools/serialver/Messages.java @@ -0,0 +1,68 @@ +/* Messages.java -- translations for serialver tool + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.serialver; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages +{ + private static final String BUNDLE_NAME + = "gnu.classpath.tools.serialver.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE + = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String getString(String key) + { + // TODO Auto-generated method stub + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/tools/gnu/classpath/tools/serialver/SerialVer.java b/tools/gnu/classpath/tools/serialver/SerialVer.java new file mode 100644 index 000000000..b5a12ec92 --- /dev/null +++ b/tools/gnu/classpath/tools/serialver/SerialVer.java @@ -0,0 +1,163 @@ +/* gnu.classpath.tools.SerialVer + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +package gnu.classpath.tools.serialver; + +import gnu.classpath.tools.getopt.ClasspathToolParser; +import gnu.classpath.tools.getopt.FileArgumentCallback; +import gnu.classpath.tools.getopt.Option; +import gnu.classpath.tools.getopt.OptionException; +import gnu.classpath.tools.getopt.Parser; + +import java.io.File; +import java.io.ObjectStreamClass; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.StringTokenizer; + +/** + * This class is an implementation of the `serialver' program. Any number of + * class names can be passed as arguments, and the serial version unique + * identitfier for each class will be printed in a manner suitable for cuting + * and pasting into a Java source file. + */ +public class SerialVer +{ + // List of classes to load. + ArrayList classes = new ArrayList(); + // The class path to use. + String classpath; + + // FIXME: taken from ClassLoader, should share it. + private static void addFileURL(ArrayList list, String file) + { + try + { + list.add(new File(file).toURL()); + } + catch(java.net.MalformedURLException x) + { + } + } + + private ClassLoader getClassLoader() + { + // FIXME: this code is taken from ClassLoader. + // We should share it somewhere. + URL[] urls; + if (classpath == null) + urls = new URL[0]; + else + { + StringTokenizer tok = new StringTokenizer(classpath, + File.pathSeparator, true); + ArrayList list = new ArrayList(); + while (tok.hasMoreTokens()) + { + String s = tok.nextToken(); + if (s.equals(File.pathSeparator)) + addFileURL(list, "."); //$NON-NLS-1$ + else + { + addFileURL(list, s); + if (tok.hasMoreTokens()) + { + // Skip the separator. + tok.nextToken(); + // If the classpath ended with a separator, + // append the current directory. + if (!tok.hasMoreTokens()) + addFileURL(list, "."); //$NON-NLS-1$ + } + } + } + urls = new URL[list.size()]; + urls = (URL[]) list.toArray(urls); + } + return new URLClassLoader(urls); + } + + private void printMessage(String format, String klass) + { + System.err.println(MessageFormat.format(format, new Object[] { klass })); + } + + public void run(String[] args) + { + Parser p = new ClasspathToolParser("serialver", true) //$NON-NLS-1$ + { + protected void validate() throws OptionException + { + if (classes.isEmpty()) + throw new OptionException(Messages.getString("SerialVer.NoClassesSpecd")); //$NON-NLS-1$ + } + }; + p.setHeader(Messages.getString("SerialVer.HelpHeader")); //$NON-NLS-1$ + + p.add(new Option(Messages.getString("SerialVer.5"), Messages.getString("SerialVer.ClasspathHelp"), "PATH") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { + public void parsed(String argument) throws OptionException + { + if (classpath != null) + throw new OptionException(Messages.getString("SerialVer.DupClasspath")); //$NON-NLS-1$ + classpath = argument; + } + }); + + p.parse(args, new FileArgumentCallback() + { + public void notifyFile(String fileArgument) throws OptionException + { + classes.add(fileArgument); + } + }); + + ClassLoader loader = getClassLoader(); + Iterator it = classes.iterator(); + while (it.hasNext()) + { + String name = (String) it.next(); + try + { + Class clazz = loader.loadClass(name); + ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); + if (osc != null) + System.out.println(clazz.getName() + ": " //$NON-NLS-1$ + + "static final long serialVersionUID = " //$NON-NLS-1$ + + osc.getSerialVersionUID() + "L;"); //$NON-NLS-1$ + else + printMessage(Messages.getString("SerialVer.ClassNotSerial"), name); //$NON-NLS-1$ + } + catch (ClassNotFoundException e) + { + printMessage(Messages.getString("SerialVer.ClassNotFound"), name); //$NON-NLS-1$ + } + } + } + + public static void main(String[] args) + { + new SerialVer().run(args); + } +} \ No newline at end of file diff --git a/tools/jarsigner.in b/tools/jarsigner.in index cea95a288..537b7faf0 100644 --- a/tools/jarsigner.in +++ b/tools/jarsigner.in @@ -44,20 +44,4 @@ prefix=@prefix@ tools_dir=@datadir@/@PACKAGE@ tools_cp=${tools_dir}/tools.zip -# find the java executable... -if [ -z "${JAVA}" ] ; then - if [ -n "${JAVA_HOME}" ] ; then - if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then - JAVA="${JAVA_HOME}/jre/sh/java" - else - JAVA="${JAVA_HOME}/bin/java" - fi - else - JAVA=`which java 2> /dev/null ` - if [ -z "${JAVA}" ] ; then - JAVA=java - fi - fi -fi - -exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.jarsigner.Main $@ +exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.jarsigner.Main $@ diff --git a/tools/keytool.in b/tools/keytool.in index 6c11dc407..613baf7fd 100644 --- a/tools/keytool.in +++ b/tools/keytool.in @@ -44,20 +44,4 @@ prefix=@prefix@ tools_dir=@datadir@/@PACKAGE@ tools_cp=${tools_dir}/tools.zip -# find the java executable... -if [ -z "${JAVA}" ] ; then - if [ -n "${JAVA_HOME}" ] ; then - if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then - JAVA="${JAVA_HOME}/jre/sh/java" - else - JAVA="${JAVA_HOME}/bin/java" - fi - else - JAVA=`which java 2> /dev/null ` - if [ -z "${JAVA}" ] ; then - JAVA=java - fi - fi -fi - -exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.keytool.Main $@ +exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.keytool.Main $@ diff --git a/tools/toolwrapper.c b/tools/toolwrapper.c new file mode 100644 index 000000000..de6556c63 --- /dev/null +++ b/tools/toolwrapper.c @@ -0,0 +1,220 @@ +/* toolwrapper.c -- a native tool wrapper for VMs that support the JNI + invocation interface + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include +#include +#include +#include "config.h" + +#ifndef JNI_VERSION_1_2 +# error JNI version 1.2 or greater required +#endif + +union env_union +{ + void *void_env; + JNIEnv *jni_env; +}; + +int +main (int argc, const char** argv) +{ + union env_union tmp; + JNIEnv* env; + JavaVM* jvm; + JavaVMInitArgs vm_args; + jint result; + jclass class_id; + jmethodID method_id; + jstring str; + jclass string_class_id; + jobjectArray args_array; + char** non_vm_argv; + int non_vm_argc; + int i; + int classpath_found = 0; + + env = NULL; + jvm = NULL; + + vm_args.nOptions = 0; + vm_args.options = NULL; + + non_vm_argc = 0; + non_vm_argv = NULL; + + if (argc > 1) + { + for (i = 1; i < argc; i++) + { + if (!strncmp (argv[i], "-J", 2)) + { + if (!strncmp (argv[i], "-J-Djava.class.path=", 20)) + classpath_found = 1; + + /* A virtual machine option. */ + vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); + + if (vm_args.options == NULL) + { + fprintf (stderr, TOOLNAME ": realloc failed.\n"); + goto destroy; + } + + if (strlen (argv[i]) == 2) + { + fprintf (stderr, TOOLNAME ": the -J option must not be followed by a space.\n"); + goto destroy; + } + else + vm_args.options[vm_args.nOptions++].optionString = strdup (argv[i] + 2); + } + else + { + non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*)); + if (non_vm_argv == NULL) + { + fprintf (stderr, TOOLNAME ": realloc failed.\n"); + goto destroy; + } + non_vm_argv[non_vm_argc++] = strdup (argv[i]); + } + } + } + + if (!classpath_found) + { + /* Set the invocation classpath. */ + vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); + + if (vm_args.options == NULL) + { + fprintf (stderr, TOOLNAME ": realloc failed.\n"); + goto destroy; + } + + vm_args.options[vm_args.nOptions++].optionString = "-Djava.class.path=" DATA_DIR "/" PACKAGE "/tools.zip"; + } + + /* Terminate vm_args.options with a NULL element. */ + vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption)); + if (vm_args.options == NULL) + { + fprintf (stderr, TOOLNAME ": realloc failed.\n"); + goto destroy; + } + vm_args.options[vm_args.nOptions].optionString = NULL; + + /* Terminate non_vm_argv with a NULL element. */ + non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*)); + if (non_vm_argv == NULL) + { + fprintf (stderr, TOOLNAME ": realloc failed.\n"); + goto destroy; + } + non_vm_argv[non_vm_argc] = NULL; + + vm_args.version = JNI_VERSION_1_2; + vm_args.ignoreUnrecognized = JNI_TRUE; + + result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args); + + if (result < 0) + { + fprintf (stderr, TOOLNAME ": couldn't create virtual machine\n"); + goto destroy; + } + + env = tmp.jni_env; + + string_class_id = (*env)->FindClass (env, "java/lang/String"); + if (string_class_id == NULL) + { + fprintf (stderr, TOOLNAME ": FindClass failed.\n"); + goto destroy; + } + + args_array = (*env)->NewObjectArray (env, non_vm_argc, string_class_id, NULL); + if (args_array == NULL) + { + fprintf (stderr, TOOLNAME ": NewObjectArray failed.\n"); + goto destroy; + } + + for (i = 0; i < non_vm_argc; i++) + { + str = (*env)->NewStringUTF (env, non_vm_argv[i]); + if (str == NULL) + { + fprintf (stderr, TOOLNAME ": NewStringUTF failed.\n"); + goto destroy; + } + + (*env)->SetObjectArrayElement (env, args_array, i, str); + } + + class_id = (*env)->FindClass (env, "gnu/classpath/tools/" TOOLNAME "/Main"); + if (class_id == NULL) + { + fprintf (stderr, TOOLNAME ": FindClass failed.\n"); + goto destroy; + } + + method_id = (*env)->GetStaticMethodID (env, class_id, "main", "([Ljava/lang/String;)V"); + + if (method_id == NULL) + { + fprintf (stderr, TOOLNAME ": GetStaticMethodID failed.\n"); + goto destroy; + } + + (*env)->CallStaticVoidMethod (env, class_id, method_id, args_array); + + destroy: + + if (env != NULL) + { + if ((*env)->ExceptionOccurred (env)) + (*env)->ExceptionDescribe (env); + + if (jvm != NULL) + (*jvm)->DestroyJavaVM (jvm); + } + + return 1; +} -- cgit v1.2.1