Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / drda / org / apache / derby / impl / drda / NetworkServerControlImpl.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/drda/org/apache/derby/impl/drda/NetworkServerControlImpl.java
new file mode 100644 (file)
index 0000000..ed939ee
--- /dev/null
@@ -0,0 +1,3798 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.drda.NetworkServerControlImpl\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.drda;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.DataOutputStream;\r
+import java.io.FilterOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.io.PrintStream;\r
+import java.io.PrintWriter;\r
+import java.net.InetAddress;\r
+import java.net.ServerSocket;\r
+import java.net.Socket;\r
+import javax.net.SocketFactory;\r
+import javax.net.ServerSocketFactory;\r
+import javax.net.ssl.SSLServerSocket;\r
+import javax.net.ssl.SSLSocket;\r
+import javax.net.ssl.SSLSocketFactory;\r
+import javax.net.ssl.SSLServerSocketFactory;\r
+import java.net.UnknownHostException;\r
+import java.security.AccessController;\r
+import java.security.PrivilegedAction;\r
+import java.security.PrivilegedActionException;\r
+import java.security.PrivilegedExceptionAction;\r
+import java.sql.Connection;\r
+import java.sql.Driver;\r
+import java.sql.DriverManager;\r
+import java.sql.SQLException;\r
+import java.sql.SQLWarning;\r
+import java.util.ArrayList;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Properties;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import org.apache.derby.drda.NetworkServerControl;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.jdbc.DRDAServerStarter;\r
+import org.apache.derby.iapi.reference.Attribute;\r
+import org.apache.derby.iapi.reference.DRDAConstants;\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.iapi.services.info.JVMInfo;\r
+import org.apache.derby.iapi.services.info.ProductGenusNames;\r
+import org.apache.derby.iapi.services.info.ProductVersionHolder;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.property.PropertyUtil;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.tools.i18n.LocalizedOutput;\r
+import org.apache.derby.iapi.tools.i18n.LocalizedResource;\r
+import org.apache.derby.iapi.util.CheapDateFormatter;\r
+import org.apache.derby.iapi.util.StringUtil;\r
+import org.apache.derby.impl.jdbc.EmbedSQLException;\r
+\r
+/** \r
+       \r
+       NetworkServerControlImpl does all the work for NetworkServerControl\r
+       @see NetworkServerControl for description\r
+\r
+*/\r
+public final class NetworkServerControlImpl {\r
+       private final static int NO_USAGE_MSGS= 12;\r
+       private final static String [] COMMANDS = \r
+       {"start","shutdown","trace","tracedirectory","ping", \r
+        "logconnections", "sysinfo", "runtimeinfo",  "maxthreads", "timeslice"};\r
+       // number of required arguments for each command\r
+       private final static int [] COMMAND_ARGS =\r
+       {0, 0, 1, 1, 0, 1, 0, 0, 1, 1};\r
+       public final static int COMMAND_START = 0;\r
+       public final static int COMMAND_SHUTDOWN = 1;\r
+       public final static int COMMAND_TRACE = 2;\r
+       public final static int COMMAND_TRACEDIRECTORY = 3;\r
+       public final static int COMMAND_TESTCONNECTION = 4;\r
+       public final static int COMMAND_LOGCONNECTIONS = 5;\r
+       public final static int COMMAND_SYSINFO = 6;\r
+       public final static int COMMAND_RUNTIME_INFO = 7;\r
+       public final static int COMMAND_MAXTHREADS = 8;\r
+       public final static int COMMAND_TIMESLICE = 9;\r
+       public final static int COMMAND_PROPERTIES = 10;\r
+       public final static int COMMAND_UNKNOWN = -1;\r
+       public final static String [] DASHARGS =\r
+       {"p","d","u","ld","ea","ep", "b", "h", "s", "noSecurityManager", "ssl"};\r
+       public final static int DASHARG_PORT = 0;\r
+       public final static int DASHARG_DATABASE = 1;\r
+       public final static int DASHARG_USER = 2;\r
+       public final static int DASHARG_LOADSYSIBM = 3;\r
+       public final static int DASHARG_ENCALG = 4;\r
+       public final static int DASHARG_ENCPRV = 5;\r
+       public final static int DASHARG_BOOTPASSWORD = 6;\r
+       public final static int DASHARG_HOST = 7;\r
+       public final static int DASHARG_SESSION = 8;\r
+       public final static int DASHARG_UNSECURE = 9;\r
+       private final static int DASHARG_SSL = 10;\r
+\r
+       // command protocol version - you need to increase this number each time\r
+       // the command protocol changes \r
+       private final static int PROTOCOL_VERSION = 1;\r
+       private final static String COMMAND_HEADER = "CMD:";\r
+       private final static String REPLY_HEADER = "RPY:";\r
+       private final static int REPLY_HEADER_LENGTH = REPLY_HEADER.length();\r
+       private final static int OK = 0;\r
+       private final static int WARNING = 1;\r
+       private final static int ERROR = 2;\r
+       private final static int SQLERROR = 3;\r
+       private final static int SQLWARNING = 4;\r
+\r
+       private final static String DRDA_PROP_MESSAGES = "org.apache.derby.loc.drda.messages";\r
+       private final static String DRDA_PROP_DEBUG = "derby.drda.debug";\r
+       private final static String CLOUDSCAPE_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";\r
+\r
+       public final static String UNEXPECTED_ERR = "Unexpected exception";\r
+\r
+       private final static int MIN_MAXTHREADS = -1;\r
+       private final static int MIN_TIMESLICE = -1;\r
+       private final static int USE_DEFAULT = -1;\r
+       private final static int DEFAULT_MAXTHREADS = 0; //for now create whenever needed\r
+       private final static int DEFAULT_TIMESLICE = 0; //for now never yield\r
+\r
+   private final static String DEFAULT_HOST = "localhost";\r
+       private final static String DRDA_MSG_PREFIX = "DRDA_";\r
+       private final static String DEFAULT_LOCALE= "en";\r
+       private final static String DEFAULT_LOCALE_COUNTRY="US";\r
+\r
+       // Check up to 10 seconds to see if shutdown occurred\r
+       private final static int SHUTDOWN_CHECK_ATTEMPTS = 100;\r
+       private final static int SHUTDOWN_CHECK_INTERVAL= 100;\r
+\r
+       // maximum reply size\r
+       private final static int MAXREPLY = 32767;\r
+\r
+       // Application Server Attributes.\r
+       protected static String att_srvclsnm;\r
+       protected final static String ATT_SRVNAM = "NetworkServerControl";\r
+\r
+       protected static String att_extnam;\r
+       protected static String att_srvrlslv; \r
+       protected static String prdId;\r
+    protected static byte[] prdIdBytes_;\r
+    \r
+       private static String buildNumber;\r
+       private static String versionString;\r
+       // we will use single or mixed, not double byte to reduce traffic on the\r
+       // wire, this is in keeping with JCC\r
+       // Note we specify UTF8 for the single byte encoding even though it can\r
+       // be multi-byte.\r
+       protected final static int CCSIDSBC = 1208; //use UTF8\r
+       protected final static int CCSIDMBC = 1208; //use UTF8\r
+       protected final static String DEFAULT_ENCODING = "UTF8"; // use UTF8 for writing\r
+       protected final static int DEFAULT_CCSID = 1208;\r
+       protected final static byte SPACE_CHAR = 32;\r
+                                                                                                               \r
+\r
+       // Application Server manager levels - this needs to be in sync\r
+       // with CodePoint.MGR_CODEPOINTS\r
+       protected final static int [] MGR_LEVELS = { 7, // AGENT\r
+                                                                                                4,     // CCSID Manager\r
+                                                                                                0, // CNMAPPC not implemented\r
+                                                                                                0, // CMNSYNCPT not implemented\r
+                                                                                                5, // CMNTCPIP\r
+                                                                                                0, // DICTIONARY\r
+                                                                                                7, // RDB\r
+                                                                                                0, // RSYNCMGR\r
+                                                                                                7, // SECMGR\r
+                                                                                                7, // SQLAM\r
+                                                                                                0, // SUPERVISOR\r
+                                                                                                0, // SYNCPTMGR\r
+                                                                                                7  // XAMGR\r
+                                                                                               };\r
+                                                                                       \r
+       \r
+       protected PrintWriter logWriter;                        // console\r
+       protected PrintWriter cloudscapeLogWriter;              // derby.log\r
+       private static Driver cloudscapeDriver;\r
+\r
+       // error types\r
+       private final static int ERRTYPE_SEVERE = 1;\r
+       private final static int ERRTYPE_USER = 2;\r
+       private final static int ERRTYPE_INFO = 3;\r
+       private final static int ERRTYPE_UNKNOWN = -1;\r
+\r
+       // command argument information\r
+       private Vector commandArgs = new Vector();\r
+       private String databaseArg;\r
+       private String userArg;\r
+       private String passwordArg;\r
+       private String bootPasswordArg;\r
+       private String encAlgArg;\r
+       private String encPrvArg;\r
+       private String hostArg = DEFAULT_HOST;  \r
+       private InetAddress hostAddress;\r
+       private int sessionArg;\r
+       private boolean unsecureArg;\r
+\r
+       // Used to debug memory in SanityManager.DEBUG mode\r
+       private memCheck mc;\r
+\r
+       // reply buffer\r
+       private byte [] replyBuffer;    \r
+       private int replyBufferCount;   //length of reply\r
+       private int replyBufferPos;             //current position in reply\r
+\r
+       //\r
+       // server configuration\r
+       //\r
+       // static values - set at start can't be changed once server has started\r
+       private int     portNumber = NetworkServerControl.DEFAULT_PORTNUMBER;   // port server listens to\r
+\r
+       // configurable values\r
+       private String traceDirectory;          // directory to place trace files in\r
+       private Object traceDirectorySync = new Object();// object to use for syncing\r
+       private boolean traceAll;                       // trace all sessions\r
+       private Object traceAllSync = new Object();     // object to use for syncing reading\r
+                                                                               // and changing trace all\r
+       private Object serverStartSync = new Object();  // for syncing start of server.\r
+       private boolean logConnections;         // log connects\r
+       private Object logConnectionsSync = new Object(); // object to use for syncing \r
+                                                                               // logConnections value\r
+       private int minThreads;                         // default minimum number of connection threads\r
+       private int maxThreads;                         // default maximum number of connection threads\r
+       private Object threadsSync = new Object(); // object to use for syncing reading\r
+                                                                               // and changing default min and max threads\r
+       private int timeSlice;                          // default time slice of a session to a thread\r
+       private Object timeSliceSync = new Object();// object to use for syncing reading\r
+                                                                               // and changing timeSlice\r
+\r
+       private boolean keepAlive = true;   // keepAlive value for client socket \r
+       private int minPoolSize;                        //minimum pool size for pooled connections\r
+       private int maxPoolSize;                        //maximum pool size for pooled connections\r
+       private Object poolSync = new Object(); // object to use for syning reading\r
+\r
+       protected boolean debugOutput = false;\r
+       private boolean cleanupOnStart = false; // Should we clean up when starting the server?\r
+       private boolean restartFlag = false;\r
+\r
+    protected final static int INVALID_OR_NOTSET_SECURITYMECHANISM = -1; \r
+    // variable to store value set to derby.drda.securityMechanism\r
+    // default value is -1 which indicates that this property isnt set or\r
+    // the value is invalid\r
+    private int allowOnlySecurityMechanism = INVALID_OR_NOTSET_SECURITYMECHANISM;\r
+       //\r
+       // variables for a client command session\r
+       //\r
+       private Socket clientSocket = null;\r
+       private InputStream clientIs = null;\r
+       private OutputStream clientOs = null;\r
+       private ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();\r
+       private DataOutputStream commandOs = new DataOutputStream(byteArrayOs);\r
+       \r
+       private Object shutdownSync = new Object();\r
+       private boolean shutdown;\r
+       private int connNum;            // number of connections since server started\r
+       private ServerSocket serverSocket;\r
+       private NetworkServerControlImpl serverInstance;\r
+       private LocalizedResource langUtil;\r
+       public String clientLocale;\r
+       ArrayList  localAddresses; // list of local addresses for checking admin\r
+                                     // commands. \r
+\r
+       // open sessions\r
+       private Hashtable sessionTable = new Hashtable();\r
+\r
+       // current session\r
+       private Session currentSession;\r
+       // DRDAConnThreads\r
+       private Vector threadList = new Vector();\r
+\r
+       // queue of sessions waiting for a free thread - the queue is managed\r
+       // in a simple first come, first serve manner - no priorities\r
+       private Vector runQueue = new Vector();\r
+\r
+       // number of DRDAConnThreads waiting for something to do\r
+       private int freeThreads;\r
+\r
+       // known application requesters\r
+       private Hashtable appRequesterTable = new Hashtable();\r
+\r
+       // accessed by inner classes for privileged action\r
+       private String propertyFileName;\r
+       private NetworkServerControlImpl thisControl = this;\r
+\r
+       // if the server is started from the command line, it should shutdown the\r
+       // databases it has booted.\r
+       private boolean shutdownDatabasesOnShutdown = false;\r
+\r
+       // SSL related stuff\r
+       private static final int SSL_OFF = 0;\r
+       private static final int SSL_BASIC = 1;\r
+       private static final int SSL_PEER_AUTHENTICATION = 2;\r
+\r
+       private int sslMode = SSL_OFF;\r
+\r
+    /**\r
+     * Can EUSRIDPWD security mechanism be used with \r
+     * the current JVM\r
+     */\r
+    private static boolean SUPPORTS_EUSRIDPWD = false;\r
+\r
+    /*\r
+     * DRDA Specification for the EUSRIDPWD security mechanism\r
+     * requires DH algorithm support with a 32-byte prime to be\r
+     * used. Not all JCE implementations have support for this.\r
+     * Hence here we need to find out if EUSRIDPWD can be used\r
+     * with the current JVM.\r
+     */ \r
+    static\r
+    {\r
+        try\r
+        {\r
+            // The DecryptionManager class will instantiate objects of the required \r
+            // security algorithms that are needed for EUSRIDPWD\r
+            // An exception will be thrown if support is not available\r
+            // in the JCE implementation in the JVM in which the server\r
+            // is started.\r
+            new DecryptionManager();\r
+            SUPPORTS_EUSRIDPWD = true;\r
+        }catch(Exception e)\r
+        {\r
+            // if an exception is thrown, ignore exception.\r
+            // set SUPPORTS_EUSRIDPWD to false indicating that the server \r
+            // does not have support for EUSRIDPWD security mechanism\r
+            SUPPORTS_EUSRIDPWD = false;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the host where we listen for connections.\r
+     */\r
+    public  String  getHost() { return hostArg; }\r
+\r
+    /**\r
+     * Return true if the customer forcibly overrode our decision to install a\r
+     * default SecurityManager.\r
+     */\r
+    public  boolean runningUnsecure() { return unsecureArg; }\r
+    \r
+    // constructor\r
+       public NetworkServerControlImpl() throws Exception\r
+       {\r
+               init();\r
+               getPropertyInfo();\r
+    }\r
+\r
+\r
+       /**\r
+        * Internal constructor for NetworkServerControl API. \r
+        * @param address - InetAddress to listen on, May not be null.  Throws NPE if null\r
+        * @param portNumber - portNumber to listen on, -1 use propert or default.\r
+        * @throws Exception on error\r
+        * @see NetworkServerControl\r
+        */\r
+       public NetworkServerControlImpl(InetAddress address, int portNumber) throws Exception\r
+       {\r
+               init();\r
+               getPropertyInfo();\r
+               this.hostAddress = address;\r
+               this.portNumber = (portNumber <= 0) ?\r
+                       this.portNumber: portNumber;\r
+               this.hostArg = address.getHostAddress();\r
+       }\r
+\r
+    private void init() throws Exception\r
+    {\r
+\r
+        // adjust the application in accordance with derby.ui.locale and derby.ui.codeset\r
+               langUtil = new LocalizedResource(null,null,DRDA_PROP_MESSAGES);\r
+\r
+               serverInstance = this;\r
+               \r
+               //set Server attributes to be used in EXCSAT\r
+               ProductVersionHolder myPVH = getNetProductVersionHolder();\r
+               att_extnam = ATT_SRVNAM + " " + java.lang.Thread.currentThread().getName();\r
+               \r
+               att_srvclsnm = myPVH.getProductName();\r
+               versionString = myPVH.getVersionBuildString(true);\r
+               \r
+               String majorStr = String.valueOf(myPVH.getMajorVersion());\r
+               String minorStr = String.valueOf(myPVH.getMinorVersion());\r
+               // Maintenance version. Server protocol version.\r
+               // Only changed if client needs to recognize a new server version.\r
+               String drdaMaintStr = String.valueOf(myPVH.getDrdaMaintVersion());\r
+\r
+               // PRDID format as JCC expects it: CSSMMmx\r
+               // MM = major version\r
+               // mm = minor version\r
+               // x = drda MaintenanceVersion\r
+\r
+               prdId = DRDAConstants.DERBY_DRDA_SERVER_ID;\r
+               if (majorStr.length() == 1)\r
+                       prdId += "0";\r
+               prdId += majorStr;\r
+\r
+               if (minorStr.length() == 1)\r
+                       prdId += "0";\r
+\r
+               prdId += minorStr;\r
+               \r
+               prdId += drdaMaintStr;\r
+               att_srvrlslv = prdId + "/" + myPVH.getVersionBuildString(true);\r
+                // Precompute this to save some cycles\r
+                prdIdBytes_ = prdId.getBytes(DEFAULT_ENCODING);\r
\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (majorStr.length() > 2  || \r
+                               minorStr.length() > 2 || \r
+                               drdaMaintStr.length() > 1)\r
+                               SanityManager.THROWASSERT("version values out of expected range  for PRDID");\r
+               }\r
+\r
+               buildNumber = myPVH.getBuildNumber();\r
+       }\r
+\r
+    private PrintWriter makePrintWriter( OutputStream out)\r
+    {\r
+               if (out != null)\r
+                       return new PrintWriter(out, true /* flush the buffer at the end of each line */);\r
+               else\r
+                       return null;\r
+    }\r
+\r
+       protected static Driver getDriver()\r
+       {\r
+               return cloudscapeDriver;\r
+       }\r
+       \r
+\r
+       /********************************************************************************\r
+        * Implementation of NetworkServerControl API\r
+        * The server commands throw exceptions for errors, so that users can handle\r
+        * them themselves in addition to having the errors written to the console\r
+        * and possibly derby.log.  To turn off logging the errors to the console,\r
+        * set the output writer to null.\r
+        ********************************************************************************/\r
+\r
+\r
+       /**\r
+        * Set the output stream for console messages\r
+        * If this is set to null, no messages will be written to the console\r
+        *\r
+        * @param outWriter     output stream for console messages\r
+        */\r
+       public void setLogWriter(PrintWriter outWriter)\r
+       {\r
+        // wrap the user-set outWriter with, autoflush to true.\r
+        // this will ensure that messages to console will be \r
+        // written out to the outWriter on a println.\r
+        // DERBY-1466\r
+        if ( outWriter != null )\r
+            logWriter = new PrintWriter(outWriter,true);\r
+        else\r
+            logWriter = outWriter;\r
+    }\r
+\r
+\r
+       \r
+       /**\r
+        * Write an error message to console output stream\r
+        * and throw an exception for this error\r
+        *\r
+        * @param msg   error message\r
+        * @exception Exception\r
+        */\r
+       public void consoleError(String msg)\r
+               throws Exception\r
+       {\r
+               consoleMessage(msg);\r
+               throw new Exception(msg);\r
+       }\r
+\r
+       /**\r
+        * Write an exception to console output stream,\r
+        * but only if debugOutput is true.\r
+        *\r
+        * @param e     exception \r
+        */\r
+       public void consoleExceptionPrint(Exception e)\r
+       {\r
+               if (debugOutput == true)\r
+                       consoleExceptionPrintTrace(e);\r
+\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * Write an exception (with trace) to console\r
+        * output stream.\r
+        *\r
+        * @param e     exception \r
+        */\r
+       public void consoleExceptionPrintTrace(Throwable e)\r
+       {\r
+               consoleMessage(e.getMessage());\r
+               if (logWriter != null)\r
+               {\r
+                       synchronized (logWriter) {\r
+                               e.printStackTrace(logWriter);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+               if (cloudscapeLogWriter != null)\r
+               {\r
+                       synchronized(cloudscapeLogWriter) {\r
+                               e.printStackTrace(cloudscapeLogWriter);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+\r
+\r
+       /**\r
+        * Write a message to console output stream\r
+        *\r
+        * @param msg   message\r
+        */\r
+       public void consoleMessage(String msg)\r
+       {\r
+               // print to console if we have one\r
+               if (logWriter != null)\r
+               {\r
+//                     //Added by Jeff HUANG\r
+//                     try {\r
+//                             Thread.sleep(1000);\r
+//                     } catch (InterruptedException e) {\r
+//                             // TODO Auto-generated catch block\r
+//                             e.printStackTrace();\r
+//                     }\r
+                       \r
+                       synchronized(logWriter) {\r
+                               logWriter.println(msg);\r
+                       }\r
+               }\r
+               // always print to derby.log\r
+               if (cloudscapeLogWriter != null)\r
+                       synchronized(cloudscapeLogWriter)\r
+                       {\r
+                               Monitor.logMessage(msg);\r
+                       }\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * Start a network server.  Launches a separate thread with \r
+        * DRDAServerStarter.  Want to use Monitor.startModule,\r
+        * so it can all get shutdown when Derby shuts down, but \r
+        * can't get it working right now.\r
+        *\r
+        * @param consoleWriter   PrintWriter to which server console will be \r
+        *                        output. Null will disable console output.\r
+        *\r
+        *                 \r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void start(PrintWriter consoleWriter)\r
+               throws Exception\r
+       {\r
+               DRDAServerStarter starter = new DRDAServerStarter();\r
+               starter.setStartInfo(hostAddress,portNumber,consoleWriter);\r
+        this.setLogWriter(consoleWriter);\r
+               startNetworkServer();\r
+               starter.boot(false,null);\r
+       }\r
+\r
+       /**\r
+        * Create the right kind of server socket\r
+        */\r
+       \r
+       private ServerSocket createServerSocket()\r
+               throws IOException\r
+       {\r
+               if (hostAddress == null)\r
+                       hostAddress = InetAddress.getByName(hostArg);\r
+               // Make a list of valid\r
+               // InetAddresses for NetworkServerControl\r
+               // admin commands.\r
+               buildLocalAddressList(hostAddress);\r
+                                                                                       \r
+               // Create the right kind of socket\r
+               switch (getSSLMode()) {\r
+               case SSL_OFF:\r
+               default:\r
+                       ServerSocketFactory sf =\r
+                               ServerSocketFactory.getDefault();\r
+                       return sf.createServerSocket(portNumber\r
+                                                                                ,0,\r
+                                                                                hostAddress);\r
+               case SSL_BASIC:\r
+                       SSLServerSocketFactory ssf =\r
+                               (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();\r
+                       return (SSLServerSocket)ssf.createServerSocket(portNumber,\r
+                                                                                                                  0,\r
+                                                                                                                  hostAddress);\r
+               case SSL_PEER_AUTHENTICATION:\r
+                       SSLServerSocketFactory ssf2 =\r
+                               (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();\r
+                       SSLServerSocket sss2= \r
+                               (SSLServerSocket)ssf2.createServerSocket(portNumber,\r
+                                                                                                                0,\r
+                                                                                                                hostAddress);\r
+                       sss2.setNeedClientAuth(true);\r
+                       return sss2;\r
+               }\r
+       }\r
+       \r
+\r
+       /**\r
+        * Start a network server\r
+        *\r
+        * @param consoleWriter   PrintWriter to which server console will be \r
+        *                        output. Null will disable console output.\r
+        *\r
+        *                 \r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void blockingStart(PrintWriter consoleWriter)\r
+               throws Exception\r
+       {\r
+               startNetworkServer();\r
+               setLogWriter(consoleWriter);\r
+               cloudscapeLogWriter = Monitor.getStream().getPrintWriter();\r
+               if (SanityManager.DEBUG && debugOutput)\r
+               {\r
+                       memCheck.showmem();\r
+                       mc = new memCheck(200000);\r
+                       mc.start();\r
+               }\r
+               // Open a server socket listener          \r
+               try{\r
+                       serverSocket = \r
+                               (ServerSocket) \r
+                               AccessController.doPrivileged(new PrivilegedExceptionAction() {\r
+                                               public Object run() throws IOException\r
+                                               {\r
+                                                       return createServerSocket();\r
+                                               }\r
+                                       });\r
+               } catch (PrivilegedActionException e) {\r
+                       Exception e1 = e.getException();\r
+\r
+                       // Test for UnknownHostException first since it's a\r
+                       // subbclass of IOException (and consolePropertyMessage\r
+                       // throws an exception when the severity is S (or U).\r
+                       if (e1 instanceof UnknownHostException) {\r
+                               consolePropertyMessage("DRDA_UnknownHost.S", hostArg);\r
+                       } else if (e1 instanceof IOException) {\r
+                               consolePropertyMessage("DRDA_ListenPort.S", \r
+                                                                          new String [] {\r
+                                                                                  Integer.toString(portNumber), \r
+                                                                                  hostArg,\r
+                                                                                  // Since SocketException\r
+                                                                                  // is used for a phletora\r
+                                                                                  // of situations, we need\r
+                                                                                  // to communicate the\r
+                                                                                  // underlying exception\r
+                                                                                  // string to the user.\r
+                                                                                  e1.toString()}); \r
+                       } else {\r
+                               throw e1;\r
+                       }\r
+               } catch (Exception e) {\r
+               // If we find other (unexpected) errors, we ultimately exit--so make\r
+               // sure we print the error message before doing so (Beetle 5033).\r
+                       throwUnexpectedException(e);\r
+               }\r
+\r
+               switch (getSSLMode()) {\r
+               default:\r
+               case SSL_OFF:\r
+                       consolePropertyMessage("DRDA_Ready.I", new String [] \r
+                               {Integer.toString(portNumber), att_srvclsnm, versionString,\r
+                                getFormattedTimestamp()});\r
+                       break;\r
+               case SSL_BASIC:\r
+                       consolePropertyMessage("DRDA_SSLReady.I", new String [] \r
+                               {Integer.toString(portNumber), att_srvclsnm, versionString,\r
+                                getFormattedTimestamp()});\r
+                       break;\r
+               case SSL_PEER_AUTHENTICATION:\r
+                       consolePropertyMessage("DRDA_SSLClientAuthReady.I", new String [] \r
+                               {Integer.toString(portNumber), att_srvclsnm, versionString,\r
+                                getFormattedTimestamp()});\r
+                       break;\r
+               }\r
+               \r
+               // We accept clients on a separate thread so we don't run into a problem\r
+               // blocking on the accept when trying to process a shutdown\r
+               final ClientThread clientThread =        \r
+                       (ClientThread) AccessController.doPrivileged(\r
+                                                               new PrivilegedExceptionAction() {\r
+                                                                       public Object run() throws Exception\r
+                                                                       {\r
+                                                                               return new ClientThread(thisControl, \r
+                                                                                                                               serverSocket);\r
+                                                                       }\r
+                                                               }\r
+                                                       );\r
+               clientThread.start();//let's see what the client thread  doing?\r
+                       \r
+               // wait until we are told to shutdown or someone sends an InterruptedException\r
+        synchronized(shutdownSync) {\r
+            try {\r
+                               shutdownSync.wait();\r
+            }\r
+            catch (InterruptedException e)\r
+            {\r
+                shutdown = true;\r
+            }\r
+        }\r
+\r
+        //oh, it takes so long a procedure to close the service\r
+        \r
+        AccessController.doPrivileged(\r
+                new PrivilegedAction() {\r
+                    public Object run()  {\r
+                    // Need to interrupt the memcheck thread if it is sleeping.\r
+                        if (mc != null)\r
+                            mc.interrupt();\r
+\r
+                        //interrupt client thread\r
+                        clientThread.interrupt();\r
+\r
+                        return null;\r
+                    }\r
+                });\r
+               \r
+               // Close out the sessions\r
+               synchronized(sessionTable) {\r
+                       for (Enumeration e = sessionTable.elements(); e.hasMoreElements(); )\r
+                       {       \r
+                               Session session = (Session) e.nextElement();\r
+                               session.close();\r
+                       }\r
+               }\r
+\r
+               synchronized (threadList)\r
+               {\r
+                       //interrupt any connection threads still active\r
+                       for (int i = 0; i < threadList.size(); i++)\r
+                       {\r
+                               final DRDAConnThread threadi = (DRDAConnThread)threadList.get(i);\r
+                \r
+                               threadi.close();\r
+                               AccessController.doPrivileged(\r
+                                                       new PrivilegedAction() {\r
+                                                               public Object run() {\r
+                                                                       threadi.interrupt();\r
+                                                                       return null;\r
+                                                               }\r
+                                                       });\r
+                       }\r
+                       threadList.clear();\r
+               }\r
+          \r
\r
+\r
+       \r
+           // close the listener socket\r
+           try{\r
+              serverSocket.close();\r
+           }catch(IOException e){\r
+                       consolePropertyMessage("DRDA_ListenerClose.S");\r
+           }\r
+\r
+\r
+               // Wake up those waiting on sessions, so\r
+               // they can close down\r
+               synchronized (runQueue) {\r
+                       runQueue.notifyAll();\r
+               }                                               \r
+\r
+               if (shutdownDatabasesOnShutdown) {\r
+\r
+                       // Shutdown Derby\r
+                       try {\r
+                               if (cloudscapeDriver != null)\r
+                                       cloudscapeDriver.connect("jdbc:derby:;shutdown=true",\r
+                                                                                        (Properties) null);\r
+                       } catch (SQLException sqle) {\r
+                               // If we can't shutdown Derby. Perhaps authentication is\r
+                               // set to true or some other reason. We will just print a\r
+                               // message to the console and proceed.\r
+                               String expectedState =\r
+                                       StandardException.getSQLStateFromIdentifier(\r
+                                                       SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);\r
+                               if (!expectedState.equals(sqle.getSQLState())) {\r
+                                       consolePropertyMessage("DRDA_ShutdownWarning.I",\r
+                                                                                  sqle.getMessage());\r
+                               }\r
+                       }\r
+               }\r
+\r
+               consolePropertyMessage("DRDA_ShutdownSuccess.I", new String [] \r
+                                                       {att_srvclsnm, versionString, \r
+                                                               getFormattedTimestamp()});\r
+               \r
+\r
+    }\r
+       \r
+       /** \r
+        * Load Derby and save driver for future use.\r
+        * We can't call Driver Manager when the client connects, \r
+        * because they might be holding the DriverManager lock.\r
+        *\r
+        * \r
+        */\r
+\r
+       \r
+\r
+\r
+       protected void startNetworkServer() throws Exception\r
+       {\r
+\r
+               // we start the Derby server here.\r
+               boolean restartCheck = this.restartFlag;\r
+               synchronized (serverStartSync) {\r
+\r
+                       if (restartCheck == this.restartFlag) {\r
+                       // then we can go ahead and restart the server (odds\r
+                       // that some else has just done so are very slim (but not\r
+                       // impossible--however, even if it does happen, things\r
+                       // should still work correctly, just not as efficiently...))\r
+\r
+                               try {\r
+       \r
+                                       if (cleanupOnStart) {\r
+                                       // we're restarting the server (probably after a shutdown\r
+                                       // exception), so we need to clean up first.\r
+\r
+                                               // Close and remove sessions on runQueue.\r
+                                               synchronized (runQueue) {\r
+                                                       for (int i = 0; i < runQueue.size(); i++) {\r
+                                                               Session s = (Session) runQueue.get(i);\r
+                                                               s.close();\r
+                                                               removeFromSessionTable(s.getConnNum());\r
+                                                       }\r
+                                                       runQueue.clear();\r
+                                               }\r
+\r
+                                               // DERBY-1326: There could be active threads that\r
+                                               // contain old/invalid sessions. These sessions won't\r
+                                               // be cleaned up until there is some activity on\r
+                                               // them. We could optimize this by going through\r
+                                               // sessionTable and closing the sessions' socket\r
+                                               // streams.\r
+\r
+                                               // Unload driver, then restart the server.\r
+                                               cloudscapeDriver = null;        // so it gets collected.\r
+                                               System.gc();\r
+                                       }\r
+\r
+                                       // start the server.\r
+                                       Class.forName(CLOUDSCAPE_DRIVER).newInstance();//start the embedded driver, it starts two daemon threads: derby.antiGC and Time-0\r
+                                       \r
+                                       //Added by Jeff Huang\r
+                                       new org.apache.derby.jdbc.EmbeddedDriver();\r
+                                       \r
+                                       cloudscapeDriver = DriverManager.getDriver(Attribute.PROTOCOL);\r
+\r
+                               }\r
+                               catch (Exception e) {\r
+                    this.consoleExceptionPrintTrace(e);\r
+                                       consolePropertyMessage("DRDA_LoadException.S", e.getMessage());\r
+                               }\r
+                               cleanupOnStart = true;\r
+                               this.restartFlag = !this.restartFlag;\r
+                       }\r
+                       // else, multiple threads hit this synchronize block at the same\r
+                       // time, but one of them already executed it--so all others just\r
+                       // return and do nothing (no need to restart the server multiple\r
+                       // times in a row).\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Shutdown a network server\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void shutdown()\r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_SHUTDOWN);\r
+               send();\r
+               readResult();\r
+               // Wait up to 10 seconds for things to really shut down\r
+               // need a quiet ping so temporarily disable the logwriter\r
+               PrintWriter savWriter = logWriter;\r
+               // DERBY-1571: If logWriter is null, stack traces are printed to\r
+               // System.err. Set logWriter to a silent stream to suppress stack\r
+               // traces too.\r
+               FilterOutputStream silentStream = new FilterOutputStream(null) {\r
+                               public void write(int b) { }\r
+                               public void flush() { }\r
+                               public void close() { }\r
+                       };\r
+               setLogWriter(new PrintWriter(silentStream));\r
+               int ntry;\r
+               for (ntry = 0; ntry < SHUTDOWN_CHECK_ATTEMPTS; ntry++)\r
+               {\r
+                       Thread.sleep(SHUTDOWN_CHECK_INTERVAL);\r
+                       try {\r
+                pingWithNoOpen();\r
+                       } catch (Exception e) \r
+                       {\r
+                // as soon as we can't ping return\r
+                               break;\r
+                       }\r
+               }\r
+        closeSocket();\r
+        \r
+        \r
+        if (ntry == SHUTDOWN_CHECK_ATTEMPTS)\r
+            consolePropertyMessage("DRDA_ShutdownError.S", new String [] {\r
+                Integer.toString(portNumber), \r
+                hostArg}); \r
+        \r
+               logWriter= savWriter;\r
+               return;\r
+       }\r
+\r
+       /*\r
+        Shutdown the server directly (If you have the original object)\r
+        No Network communication needed.\r
+       */\r
+       public void directShutdown()    {\r
+               shutdown = true;\r
+               synchronized(shutdownSync) {                                            \r
+                       // wake up the server thread\r
+                       shutdownSync.notifyAll();\r
+               }\r
+               \r
+       }\r
+\r
+\r
+       /**\r
+        */\r
+       public boolean isServerStarted() throws Exception\r
+       {\r
+               try {\r
+                       ping();\r
+               }\r
+               catch (Exception e) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+    /**\r
+     * Ping opening an new socket and close it.\r
+     * @throws Exception\r
+     */\r
+       public void ping() throws Exception\r
+       {\r
+        setUpSocket();\r
+        pingWithNoOpen();\r
+        closeSocket();\r
+    }\r
+    \r
+    /**\r
+     * Ping the server using the client socket that is already open.\r
+     */\r
+    private void pingWithNoOpen() throws Exception\r
+    {\r
+    \r
+               // database no longer used, but don't change the protocol \r
+               // in case we add\r
+               // authorization  later.\r
+               String database = null; // no longer used but don't change the protocol\r
+               String user = null;\r
+               String password = null;\r
+\r
+                       \r
+                       writeCommandHeader(COMMAND_TESTCONNECTION);\r
+                       writeLDString(database);\r
+                       writeLDString(user);\r
+                       writeLDString(password);\r
+                       send();\r
+                       readResult();\r
+       }\r
+\r
+\r
+       /**\r
+        * Turn tracing on or off for all sessions\r
+        *\r
+        * @param on                    true to turn tracing on, false to turn tracing off\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void trace(boolean on)\r
+               throws Exception\r
+       {\r
+               trace(0, on);\r
+       }\r
+\r
+       /**\r
+        * Turn tracing on or off for one session or all sessions\r
+        *\r
+        * @param connNum       the connNum of the session, 0 if all sessions\r
+        * @param on                    true to turn tracing on, false to turn tracing off\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void trace(int connNum, boolean on)\r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_TRACE);\r
+               commandOs.writeInt(connNum);\r
+               writeByte(on ? 1 : 0);\r
+               send();\r
+               readResult();\r
+               consoleTraceMessage(connNum, on);\r
+        closeSocket();\r
+       }\r
+\r
+       /**\r
+        * Print trace change message to console\r
+        *\r
+        * @param on                    true to print tracing on, false to print tracing off\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void consoleTraceMessage(int connNum, boolean on)\r
+               throws Exception\r
+       {\r
+               if (connNum == 0)\r
+                       consolePropertyMessage("DRDA_TraceChangeAll.I", on ? "DRDA_ON.I" : "DRDA_OFF.I");\r
+               else\r
+               {\r
+                       String[] args = new String[2];\r
+                       args[0] = on ? "DRDA_ON.I" : "DRDA_OFF.I";\r
+                       args[1] = new Integer(connNum).toString();\r
+                       consolePropertyMessage("DRDA_TraceChangeOne.I", args);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Turn logging connections on or off. When logging is turned on a message is\r
+        * written to derby.log each time a connection is made.\r
+        *\r
+        * @param on                    true to turn on, false to turn  off\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void logConnections(boolean on)\r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_LOGCONNECTIONS);\r
+               writeByte(on ? 1 : 0);\r
+               send();\r
+               readResult();\r
+        closeSocket();\r
+       }\r
+\r
+       /**\r
+        *@see NetworkServerControl#setTraceDirectory\r
+        */\r
+       public void sendSetTraceDirectory(String traceDirectory)\r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_TRACEDIRECTORY);\r
+               writeLDString(traceDirectory);\r
+               send();\r
+               readResult();\r
+        closeSocket();\r
+       }\r
+\r
+       /**\r
+        *@see NetworkServerControl#getSysinfo\r
+        */\r
+       public String sysinfo()\r
+               throws Exception\r
+       {\r
+               try {\r
+            setUpSocket();\r
+            writeCommandHeader(COMMAND_SYSINFO);\r
+            send();\r
+            return readStringReply("DRDA_SysInfoError.S");\r
+        } finally {\r
+            closeSocket();\r
+        }\r
+       }\r
+\r
+       /**\r
+        *@see NetworkServerControl#getRuntimeInfo\r
+        */\r
+       public String runtimeInfo()\r
+       throws Exception \r
+       {\r
+               try {\r
+            setUpSocket();\r
+            writeCommandHeader(COMMAND_RUNTIME_INFO);\r
+            send();\r
+            return readStringReply("DRDA_RuntimeInfoError.S");\r
+        } finally {\r
+            closeSocket();\r
+        }\r
+       }\r
+\r
+       /**\r
+        * Display usage information\r
+        *\r
+        */\r
+       public void usage()\r
+       {\r
+               try {\r
+               for (int i = 1; i <= NO_USAGE_MSGS; i++)\r
+                       consolePropertyMessage("DRDA_Usage"+i+".I");\r
+               } catch (Exception e) {}        // ignore exceptions - there shouldn't be any\r
+       }\r
+\r
+       /**\r
+        * Connect to  network server and set connection maxthread parameter\r
+        *\r
+        * @param max           maximum number of connections, if 0, connections \r
+        *                                              created when no free connection available\r
+        *                                              if -1, use default\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void netSetMaxThreads(int max) throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_MAXTHREADS);\r
+               commandOs.writeInt(max);\r
+               send();\r
+               readResult();\r
+               int newval = readInt();\r
+               consolePropertyMessage("DRDA_MaxThreadsChange.I", \r
+                                       new Integer(newval).toString());\r
+        closeSocket();\r
+       }\r
+\r
+       /**\r
+        * Set network server connection timeslice parameter\r
+        *\r
+        * @param timeslice     amount of time given to each session before yielding to \r
+        *                                              another session, if 0, never yield. if -1, use default.\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public void netSetTimeSlice(int timeslice)\r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_TIMESLICE);\r
+               commandOs.writeInt(timeslice);\r
+               send();\r
+               readResult();\r
+               int newval = readInt();\r
+               consolePropertyMessage("DRDA_TimeSliceChange.I", \r
+                                                                          new Integer(newval).toString());\r
+        closeSocket();\r
+       }\r
+\r
+       /**\r
+        * Get current properties\r
+        *\r
+        * @return Properties object containing properties\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       public Properties getCurrentProperties() \r
+               throws Exception\r
+       {\r
+               setUpSocket();\r
+               writeCommandHeader(COMMAND_PROPERTIES);\r
+               send();\r
+               byte [] val = readBytesReply("DRDA_PropertyError.S");\r
+        closeSocket();\r
+               Properties p = new Properties();\r
+               try {\r
+                       ByteArrayInputStream bs = new ByteArrayInputStream(val);\r
+                       p.load(bs);\r
+               } catch (IOException io) {\r
+                       consolePropertyMessage("DRDA_IOException.S", \r
+                                               io.getMessage());\r
+               }\r
+               return p;\r
+       }\r
+\r
+       /**\r
+        * Set a thread name to be something that is both meaningful and unique (primarily\r
+        * for debugging purposes).\r
+        *\r
+     * The received thread's name is set to a new string of the form\r
+     *  [newName + "_n"], where 'n' is a unique thread id originally generated\r
+     *  by the jvm Thread constructor.  If the default name of the thread has\r
+     *  been changed before getting here, then nothing is done.\r
+     *\r
+        * @param thrd An instance of a Thread object that still has its default\r
+        *  thread name (as generated by the jvm Thread constructor).  This should\r
+        *  always be of the form "Thread-N", where N is a unique thread id\r
+        *  generated by the jvm.  Ex. "Thread-0", "Thread-1", etc.\r
+        *\r
+        **/\r
+       public static void setUniqueThreadName(Thread thrd, String newName) {\r
+\r
+               // First, pull off the unique thread id already found in thrd's default name;\r
+               // we do so by searching for the '-' character, and then counting everything\r
+               // after it as a N.\r
+               if (thrd.getName().indexOf("Thread-") == -1) {\r
+               // default name has been changed; don't do anything.\r
+                       return;\r
+               }\r
+               else {\r
+                       String oldName = thrd.getName();\r
+                       thrd.setName(newName + "_" +\r
+                         oldName.substring(oldName.indexOf("-")+1, oldName.length()));\r
+               } // end else.\r
+\r
+               return;\r
+\r
+       }\r
+\r
+       /*******************************************************************************/\r
+       /*        Protected methods                                                    */\r
+       /*******************************************************************************/\r
+       /**\r
+        * Remove session from session table\r
+        *\r
+        * @param sessionid     id of session to be removed\r
+        */\r
+       protected void removeFromSessionTable(int sessionid)\r
+       {\r
+               sessionTable.remove(new Integer(sessionid));\r
+       }\r
+\r
+       /**\r
+        *      processCommands reads and processes NetworkServerControlImpl commands sent\r
+        *      to the network server over the socket.  The protocol used is\r
+        *              4 bytes         - String CMD:\r
+        *              2 bytes         - Protocol version\r
+        *              1 byte          - length of locale (0 for default)\r
+        *                      n bytes - locale\r
+        *              1 byte          - length of codeset (0 for default)\r
+        *                      n bytes - codeset\r
+        *              1 byte          - command\r
+        *              n bytes         - parameters for the command\r
+        *      The server returns\r
+        *              4 bytes         - String RPY:\r
+        *      for most commands\r
+        *              1 byte          - command result, 0 - OK, 1 - warning, 2 - error\r
+        *       if warning or error\r
+        *              1 bytes         - length of message key\r
+        *              n bytes         - message key\r
+        *              1 byte          - number of parameters to message\r
+        *              {2 bytes                - length of parameter\r
+        *              n bytes         - parameter} for each parameter\r
+        *  for sysinfo\r
+        *              1 byte          - command result, 0 - OK, 1 - warning, 2 - error\r
+        *   if OK \r
+        *              2 bytes         - length of sysinfo\r
+        *              n bytes         - sysinfo\r
+        *              \r
+        *              \r
+        *      Note, the 3rd byte of the command must not be 'D0' to distinquish it \r
+        *      from DSS structures.\r
+        *      The protocol for the parameters for each command follows:\r
+        *\r
+        *      Command: trace <connection id> {on | off}\r
+        *      Protocol:\r
+        *              4 bytes         - connection id - connection id of 0 means all sessions\r
+        *              1 byte          - 0 off, 1 on\r
+        * \r
+        *      Command: logConnections {on | off}\r
+        *      Protocol:\r
+        *              1 byte          - 0 off, 1 on\r
+        * \r
+        *      Command: shutdown\r
+        *      No parameters\r
+        * \r
+        *      Command: sysinfo\r
+        *      No parameters\r
+        * \r
+        *      Command: dbstart\r
+        *      Protocol:\r
+        *              2 bytes         - length of database name\r
+        *              n bytes         - database name\r
+        *              2 bytes         - length of boot password\r
+        *              n bytes         - boot password \r
+        *              2 bytes         - length of encryption algorithm\r
+        *              n bytes         - encryption algorithm\r
+        *              2 bytes         - length of encryption provider\r
+        *              n bytes         - encryption provider\r
+        *              2 bytes         - length of user name\r
+        *              n bytes         - user name\r
+        *              2 bytes         - length of password\r
+        *              n bytes         - password\r
+        *\r
+        *      Command: dbshutdown\r
+        *      Protocol:\r
+        *              2 bytes         - length of database name\r
+        *              n bytes         - database name\r
+        *              2 bytes         - length of user name\r
+        *              n bytes         - user name\r
+        *              2 bytes         - length of password\r
+        *              n bytes         - password\r
+        *\r
+        *      Command: connpool\r
+        *      Protocol:\r
+        *              2 bytes         - length of database name, if 0, default for all databases\r
+        *                                              is set\r
+        *              n bytes         - database name\r
+        *              2 bytes         - minimum number of connections, if 0, connection pool not used\r
+        *                                              if value is -1 use default\r
+        *              2 bytes         - maximum number of connections, if 0, connections are created\r
+        *                                              as needed, if value is -1 use default\r
+        *\r
+        *      Command: maxthreads\r
+        *      Protocol:\r
+        *              2 bytes         - maximum number of threads\r
+        *\r
+        *      Command: timeslice \r
+        *      Protocol:\r
+        *              4 bytes         - timeslice value\r
+        *\r
+        *      Command: tracedirectory\r
+        *      Protocol:\r
+        *              2 bytes         - length of directory name\r
+        *              n bytes         - directory name\r
+        *\r
+        *      Command: test connection\r
+        *      Protocol:\r
+        *              2 bytes         - length of database name if 0, just the connection\r
+        *                                              to the network server is tested and user name and \r
+        *                                              password aren't sent\r
+        *              n bytes         - database name\r
+        *              2 bytes         - length of user name (optional)\r
+        *              n bytes         - user name\r
+        *              2 bytes         - length of password  (optional)\r
+        *              n bytes         - password\r
+        *\r
+        *      The calling routine is synchronized so that multiple threads don't clobber each\r
+        *      other. This means that configuration commands will be serialized.\r
+        *      This shouldn't be a problem since they should be fairly rare.\r
+        *              \r
+        * @param reader        input reader for command\r
+        * @param writer output writer for command\r
+        * @param session       session information\r
+        *\r
+        * @exception Throwable throws an exception if an error occurs\r
+        */\r
+       protected synchronized void processCommands(DDMReader reader, DDMWriter writer, \r
+               Session session) throws Throwable\r
+       {\r
+               try {\r
+                       String protocolStr = reader.readCmdString(4);\r
+                       String locale = DEFAULT_LOCALE;\r
+                       String codeset = null;\r
+                       // get the version\r
+                       int version = reader.readNetworkShort();\r
+                       if (version <= 0 || version > PROTOCOL_VERSION)\r
+                               throw new Throwable(langUtil.getTextMessage("DRDA_UnknownProtocol.S",  new Integer(version).toString()));\r
+                       int localeLen = reader.readByte();\r
+                       if (localeLen > 0)\r
+                       {\r
+                               currentSession = session;\r
+                               locale = reader.readCmdString(localeLen);\r
+                               session.langUtil = new LocalizedResource(codeset,locale,DRDA_PROP_MESSAGES);\r
+                       }\r
+                       String notLocalMessage = null;\r
+                       // for now codesetLen is always 0\r
+                       int codesetLen = reader.readByte();\r
+                       int command = reader.readByte();\r
+                       if (command !=  COMMAND_TESTCONNECTION)\r
+                       {\r
+                               try {\r
+                                       checkAddressIsLocal(session.clientSocket.getInetAddress());\r
+                               }catch (Exception e)\r
+                               {\r
+                                       notLocalMessage = e.getMessage();\r
+                               }\r
+                       }\r
+                       if (notLocalMessage != null)\r
+                       {\r
+                               sendMessage(writer, ERROR,notLocalMessage);\r
+                               session.langUtil = null;\r
+                               currentSession = null;\r
+                               return;\r
+                       }\r
+\r
+                       switch(command)\r
+                       {\r
+                               case COMMAND_SHUTDOWN:\r
+                                       sendOK(writer);\r
+                                       directShutdown();\r
+                                       break;\r
+                               case COMMAND_TRACE:\r
+                                       sessionArg = reader.readNetworkInt();\r
+                                       boolean on = (reader.readByte() == 1);\r
+                                       if (setTrace(on))\r
+                                       {\r
+                                               sendOK(writer);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                           if (sessionArg != 0)\r
+                                                       sendMessage(writer, ERROR,  \r
+                                                           localizeMessage("DRDA_SessionNotFound.U", \r
+                                                                           (session.langUtil == null) ? langUtil : session.langUtil,\r
+                                                                           new String [] {new Integer(sessionArg).toString()}));\r
+                                           else\r
+                                                       sendMessage(writer, ERROR,  \r
+                                                                               localizeMessage("DRDA_ErrorStartingTracing.S",null));          \r
+                                       }\r
+                                       break;\r
+                               case COMMAND_TRACEDIRECTORY:\r
+                                       setTraceDirectory(reader.readCmdString());\r
+                                       sendOK(writer);\r
+                                       consolePropertyMessage("DRDA_TraceDirectoryChange.I", traceDirectory);\r
+                                       break;\r
+                               case COMMAND_TESTCONNECTION:\r
+                                       databaseArg = reader.readCmdString();\r
+                                       userArg = reader.readCmdString();\r
+                                       passwordArg = reader.readCmdString();\r
+                                       if (databaseArg != null)\r
+                                               connectToDatabase(writer, databaseArg, userArg, passwordArg);\r
+                                       else\r
+                                               sendOK(writer);\r
+                                       break;\r
+                               case COMMAND_LOGCONNECTIONS:\r
+                                       boolean log = (reader.readByte() == 1);\r
+                                       setLogConnections(log);\r
+                                       sendOK(writer);\r
+                                       consolePropertyMessage("DRDA_LogConnectionsChange.I",\r
+                                               (log ? "DRDA_ON.I" : "DRDA_OFF.I"));\r
+                                       break;\r
+                               case COMMAND_SYSINFO:\r
+                                       sendSysInfo(writer);\r
+                                       break;\r
+                               case COMMAND_PROPERTIES:\r
+                                       sendPropInfo(writer);\r
+                                       break;\r
+                               case COMMAND_RUNTIME_INFO:\r
+                                       sendRuntimeInfo(writer);\r
+                                       break;\r
+                               case COMMAND_MAXTHREADS:\r
+                                       int max = reader.readNetworkInt();\r
+                                       try {\r
+                                               setMaxThreads(max);\r
+                                       }catch (Exception e) {\r
+                                               sendMessage(writer, ERROR, e.getMessage());\r
+                                               return;\r
+                                       }\r
+                                       int newval = getMaxThreads();\r
+                                       sendOKInt(writer, newval);\r
+                                       consolePropertyMessage("DRDA_MaxThreadsChange.I", \r
+                                               new Integer(newval).toString());\r
+                                       break;\r
+                               case COMMAND_TIMESLICE:\r
+                                       int timeslice = reader.readNetworkInt();\r
+                                       try {\r
+                                               setTimeSlice(timeslice);\r
+                                       }catch (Exception e) {\r
+                                               sendMessage(writer, ERROR, e.getMessage());\r
+                                               return;\r
+                                       }\r
+                                       newval = getTimeSlice();\r
+                                       sendOKInt(writer, newval);\r
+                                       consolePropertyMessage("DRDA_TimeSliceChange.I", \r
+                                               new Integer(newval).toString());\r
+                                       break;\r
+                       }\r
+               } catch (DRDAProtocolException e) {\r
+                       //we need to handle this since we aren't in DRDA land here\r
+                       consoleExceptionPrintTrace(e);\r
+\r
+               } catch (Exception e) {\r
+                       consoleExceptionPrintTrace(e);\r
+               }\r
+               finally {\r
+                       session.langUtil = null;\r
+                       currentSession = null;\r
+               }\r
+       }\r
+       /**\r
+        * Get the next session for the thread to work on\r
+        * Called from DRDAConnThread after session completes or timeslice\r
+        * exceeded.   \r
+        *\r
+        * If there is a waiting session, pick it up and put currentSession \r
+        * at the back of the queue if there is one.\r
+        * @param currentSession        session thread is currently working on\r
+        *\r
+        * @return  next session to work on, could be same as current session\r
+        */\r
+       protected Session getNextSession(Session currentSession)\r
+       {\r
+               Session retval = null;\r
+               if (shutdown == true)\r
+                       return retval;\r
+               synchronized (runQueue)\r
+               {\r
+                       try {\r
+                               // nobody waiting - go on with current session\r
+                               if (runQueue.size() == 0)\r
+                               {\r
+                                       // no current session - wait for some work\r
+                                       if (currentSession == null)\r
+                                       {\r
+                                               while (runQueue.size() == 0)\r
+                                               {\r
+                                                       // This thread has nothing to do now so \r
+                                                       // we will add it to freeThreads\r
+                                                       freeThreads++;\r
+                                                       runQueue.wait();\r
+                                                       if (shutdown == true)\r
+                                                               return null;\r
+                                                       freeThreads--;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                               return currentSession;\r
+                               }\r
+                               retval = (Session) runQueue.elementAt(0);\r
+                               runQueue.removeElementAt(0);\r
+                               if (currentSession != null)\r
+                                       runQueueAdd(currentSession);\r
+                       } catch (InterruptedException e) {\r
+                       // If for whatever reason (ex. database shutdown) a waiting thread is\r
+                       // interrupted while in this method, that thread is going to be\r
+                       // closed down, so we need to decrement the number of threads\r
+                       // that will be available for use.\r
+                               freeThreads--;\r
+                       }\r
+               }\r
+               return retval;\r
+       }\r
+       /**\r
+        * Get the stored application requester or store if we haven't seen it yet\r
+        *\r
+        * @param appRequester Application Requester to look for\r
+        *\r
+        * @return  stored application requester\r
+        */\r
+       protected AppRequester getAppRequester(AppRequester appRequester)\r
+       {\r
+               AppRequester s = null;\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       if (appRequester == null)\r
+                               SanityManager.THROWASSERT("null appRequester in getAppRequester");\r
+               }\r
+\r
+               if (!appRequesterTable.isEmpty())\r
+                       s = (AppRequester)appRequesterTable.get(appRequester.prdid);\r
+\r
+               if (s == null)\r
+               {\r
+                       appRequesterTable.put(appRequester.prdid, appRequester);\r
+                       return appRequester;\r
+               }\r
+               else\r
+               {\r
+                       //compare just in case there are some differences\r
+                       //if they are different use the one we just read in\r
+                       if (s.equals(appRequester))\r
+                               return s;\r
+                       else\r
+                               return appRequester;\r
+               }\r
+       }\r
+       /**\r
+        * Get the server manager level for a given manager\r
+        *\r
+        * @param manager codepoint for manager\r
+        * @return manager level\r
+        */\r
+       protected int getManagerLevel(int manager)\r
+       {\r
+               int mindex = CodePoint.getManagerIndex(manager);\r
+               if (SanityManager.DEBUG) {\r
+                       if (mindex == CodePoint.UNKNOWN_MANAGER)\r
+                       SanityManager.THROWASSERT("manager out of bounds");\r
+               }\r
+               return MGR_LEVELS[mindex];\r
+       }\r
+       /**\r
+        * Check whether a CCSID code page is supported\r
+        *\r
+        * @param ccsid CCSID to check\r
+        * @return true if supported; false otherwise\r
+        */\r
+       protected boolean supportsCCSID(int ccsid)\r
+       {\r
+               try {\r
+                       CharacterEncodings.getJavaEncoding(ccsid);\r
+                       }\r
+               catch (Exception e) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * Put property message on console\r
+        *\r
+        * @param msgProp               message property key\r
+        *\r
+        * @throws Exception if an error occurs\r
+        */\r
+       protected void consolePropertyMessage(String msgProp)\r
+               throws Exception\r
+       {\r
+               consolePropertyMessageWork(msgProp, null);\r
+       }\r
+       /**\r
+        * Put property message on console\r
+        *\r
+        * @param msgProp               message property key\r
+        * @param arg                   argument for message\r
+        *\r
+        * @throws Exception if an error occurs\r
+        */\r
+       protected void consolePropertyMessage(String msgProp, String arg)\r
+               throws Exception\r
+       {\r
+               consolePropertyMessageWork(msgProp, new String [] {arg});\r
+       }\r
+       /**\r
+        * Put property message on console\r
+        *\r
+        * @param msgProp               message property key\r
+        * @param args                  argument array for message\r
+        *\r
+        * @throws Exception if an error occurs\r
+        */\r
+       protected void consolePropertyMessage(String msgProp, String [] args)\r
+               throws Exception\r
+       {\r
+               consolePropertyMessageWork(msgProp, args);\r
+       }\r
+       /**\r
+        * Is this the command protocol\r
+        * \r
+        * @param  val\r
+        */\r
+       protected static boolean isCmd(String val)\r
+       {\r
+               if (val.equals(COMMAND_HEADER))\r
+                       return true;\r
+               else\r
+                       return false;\r
+       }\r
+\r
+       /*******************************************************************************/\r
+       /*        Private methods                                                      */\r
+       /*******************************************************************************/\r
+       /**\r
+        * Write Command reply\r
+        *\r
+        * @param writer        writer to use \r
+        *\r
+        * @throws Exception if a problem occurs sending OK\r
+        */\r
+       private void writeCommandReplyHeader(DDMWriter writer) throws Exception\r
+       {\r
+               writer.setCMDProtocol();\r
+               writer.writeString(REPLY_HEADER);\r
+       }\r
+        \r
+       /**\r
+        * Send OK from server to client after processing a command\r
+        *\r
+        * @param writer        writer to use for sending OK\r
+        *\r
+        * @throws Exception if a problem occurs sending OK\r
+        */\r
+       private void sendOK(DDMWriter writer) throws Exception\r
+       {\r
+               writeCommandReplyHeader(writer);\r
+               writer.writeByte(OK);\r
+               writer.flush();\r
+       }\r
+       /**\r
+        * Send OK and int value\r
+        *\r
+        * @param writer writer to use for sending\r
+        * @param val   int val to send\r
+        * \r
+        * @throws Exception if a problem occurs\r
+        */\r
+       private void sendOKInt(DDMWriter writer, int val) throws Exception\r
+       {\r
+               writeCommandReplyHeader(writer);\r
+               writer.writeByte(OK);\r
+               writer.writeNetworkInt(val);\r
+               writer.flush();\r
+       }\r
+       /**\r
+        * Send Error or Warning from server to client after processing a command\r
+        *\r
+        * @param writer        writer to use for sending message\r
+        * @param messageType   1 for Warning, 2 for Error 3 for SQLError\r
+        * @param message       message \r
+        *\r
+        * @throws Exception if a problem occurs sending message\r
+        */\r
+       private void sendMessage(DDMWriter writer, int messageType, String message) \r
+               throws Exception\r
+       {\r
+               writeCommandReplyHeader(writer);\r
+               writer.writeByte(messageType);\r
+               writer.writeLDString(message);\r
+               writer.flush();\r
+       }\r
+       /**\r
+        * Send SQL Exception from server to client after processing a command\r
+        *\r
+        * @param writer        writer to use for sending message\r
+        * @param se            Derby exception\r
+        * @param type          type of exception, SQLERROR or SQLWARNING\r
+        *\r
+        * @throws Exception if a problem occurs sending message\r
+        */\r
+       private void sendSQLMessage(DDMWriter writer, SQLException se, int type)\r
+               throws Exception\r
+       {\r
+               StringBuffer locMsg = new StringBuffer();\r
+               //localize message if necessary\r
+               while (se != null)\r
+               {\r
+                       if (currentSession != null && currentSession.langUtil != null &&\r
+                               se instanceof EmbedSQLException)\r
+                       {\r
+                               locMsg.append(se.getSQLState()+":"+ \r
+                                       MessageService.getLocalizedMessage(\r
+                                       currentSession.langUtil.getLocale(), ((EmbedSQLException)se).getMessageId(), \r
+                                       ((EmbedSQLException)se).getArguments()));\r
+                       }\r
+                       else\r
+                               locMsg.append(se.getSQLState()+":"+se.getMessage());\r
+                       se = se.getNextException();\r
+                       if (se != null)\r
+                               locMsg.append("\n");\r
+               }\r
+               sendMessage(writer, type, locMsg.toString());\r
+       }\r
+       /**\r
+        * Send SysInfo information from server to client\r
+        *\r
+        * @param writer        writer to use for sending sysinfo\r
+        *\r
+        * @throws Exception if a problem occurs sending value\r
+        */\r
+       private void sendSysInfo(DDMWriter writer) throws Exception\r
+       {\r
+               StringBuffer sysinfo = new StringBuffer();\r
+               sysinfo.append(getNetSysInfo());\r
+               sysinfo.append(getCLSSysInfo());\r
+               try {\r
+                       writeCommandReplyHeader(writer);\r
+                       writer.writeByte(0);    //O.K.\r
+                       writer.writeLDString(sysinfo.toString());\r
+               } catch (DRDAProtocolException e) {\r
+                       consolePropertyMessage("DRDA_SysInfoWriteError.S", e.getMessage());\r
+               }\r
+               writer.flush();\r
+       }\r
+       \r
+       /**\r
+        * Send RuntimeInfo information from server to client\r
+        *\r
+        * @param writer        writer to use for sending sysinfo\r
+        *\r
+        * @throws Exception if a problem occurs sending value\r
+        */\r
+       private void sendRuntimeInfo(DDMWriter writer) throws Exception\r
+       {\r
+               try {\r
+                       writeCommandReplyHeader(writer);\r
+                       writer.writeByte(0);    //O.K.\r
+                       writer.writeLDString(getRuntimeInfo());\r
+                               } catch (DRDAProtocolException e) {\r
+                       consolePropertyMessage("DRDA_SysInfoWriteError.S", e.getMessage());\r
+               }\r
+               writer.flush();\r
+       }\r
+\r
+       \r
+\r
+       /**\r
+        * Send property information from server to client\r
+        *\r
+        * @param writer        writer to use for sending sysinfo\r
+        *\r
+        * @throws Exception if a problem occurs sending value\r
+        */\r
+       private void sendPropInfo(DDMWriter writer) throws Exception\r
+       {\r
+               try {\r
+                       ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+                       Properties p = getPropertyValues();\r
+                       p.store(out, "NetworkServerControl properties");\r
+                       try {\r
+                               writeCommandReplyHeader(writer);\r
+                               writer.writeByte(0);            //O.K.\r
+                               writer.writeLDBytes(out.toByteArray());\r
+                       } catch (DRDAProtocolException e) {\r
+                               consolePropertyMessage("DRDA_PropInfoWriteError.S", e.getMessage());\r
+                       }\r
+                       writer.flush();\r
+               } \r
+               catch (Exception e) {\r
+                       consoleExceptionPrintTrace(e);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get Net Server information\r
+        *\r
+        * @return system information for the Network Server\r
+        */\r
+       private String getNetSysInfo() \r
+       {\r
+               StringBuffer sysinfo = new StringBuffer();\r
+               LocalizedResource localLangUtil = langUtil;\r
+               if (currentSession != null && currentSession.langUtil != null)\r
+               localLangUtil = currentSession.langUtil;\r
+               sysinfo.append(localLangUtil.getTextMessage("DRDA_SysInfoBanner.I")+ "\n");\r
+               sysinfo.append(localLangUtil.getTextMessage("DRDA_SysInfoVersion.I")+ " " + att_srvrlslv);\r
+               sysinfo.append("  ");\r
+               sysinfo.append(localLangUtil.getTextMessage("DRDA_SysInfoBuild.I")+ " " + buildNumber);\r
+               sysinfo.append("  ");\r
+               sysinfo.append(localLangUtil.getTextMessage("DRDA_SysInfoDrdaPRDID.I")+ " " + prdId);\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       sysinfo.append("  ** SANE BUILD **");\r
+               }\r
+               sysinfo.append("\n");\r
+               // add property information\r
+               Properties p = getPropertyValues();\r
+               ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
+               PrintStream ps =  new PrintStream(bos);\r
+               p.list(ps);\r
+               sysinfo.append(bos.toString());\r
+               return sysinfo.toString();\r
+       }\r
+\r
+       /**\r
+        * @see NetworkServerControl#getRuntimeInfo\r
+        */\r
+       private String getRuntimeInfo() \r
+       {\r
+               return buildRuntimeInfo(langUtil);\r
+       }\r
+\r
+       /**\r
+        * Get Derby information\r
+        *\r
+        * @return system information for Derby\r
+        *\r
+        * @throws IOException if a problem occurs encoding string\r
+        */\r
+       private String getCLSSysInfo() throws IOException\r
+       {\r
+               ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
+               LocalizedResource localLangUtil = langUtil;\r
+               if (currentSession != null && currentSession.langUtil != null)\r
+               localLangUtil = currentSession.langUtil;\r
+               LocalizedOutput aw = localLangUtil.getNewOutput(bos);\r
+               org.apache.derby.impl.tools.sysinfo.Main.getMainInfo(aw, false);\r
+               return bos.toString();\r
+       }\r
+\r
+\r
+    /**\r
+     * Parse the command-line arguments. As a side-effect, fills in various instance\r
+     * fields. This method was carved out of executeWork() so that\r
+     * NetworkServerControl can figure out whether to install a security manager\r
+     * before the server actually comes up. This is part of the work for DERBY-2196.\r
+     *\r
+     * @param args     array of arguments indicating command to be executed\r
+     *\r
+     * @return the command to be executed\r
+     */\r
+    public int parseArgs(String args[]) throws Exception\r
+    {\r
+        // For convenience just use NetworkServerControlImpls log writer for user messages\r
+        logWriter = makePrintWriter(System.out);\r
+\r
+        int command = COMMAND_START; \r
+        if (args.length > 0)\r
+            command = findCommand(args);\r
+        else\r
+        {\r
+            consolePropertyMessage("DRDA_NoArgs.U");\r
+        }\r
+\r
+        return command;\r
+    }\r
+\r
+       /**\r
+        * Execute the command given on the command line\r
+        *\r
+        * @param command   The command to execute. The command itself was determined by an earlier call to parseArgs().\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        * see class comments for more information\r
+        */\r
+       public void executeWork(int command) throws Exception\r
+       {\r
+               // if we didn't have a valid command just return - error already generated\r
+               if (command == COMMAND_UNKNOWN)\r
+                       return;\r
+\r
+               // check that we have the right number of required arguments\r
+               if (commandArgs.size() != COMMAND_ARGS[command])\r
+                       consolePropertyMessage("DRDA_InvalidNoArgs.U", COMMANDS[command]);\r
+               int min;\r
+               int max;\r
+\r
+\r
+               switch (command)\r
+               {\r
+                       case COMMAND_START:\r
+                               // the server was started from the command line, shutdown the\r
+                               // databases when the server is shutdown\r
+                               shutdownDatabasesOnShutdown = true;\r
+                               blockingStart(makePrintWriter(System.out));\r
+                               break;\r
+                       case COMMAND_SHUTDOWN:\r
+                               shutdown();\r
+                               consolePropertyMessage("DRDA_ShutdownSuccess.I", new String [] \r
+                                                               {att_srvclsnm, versionString, \r
+                                                               getFormattedTimestamp()});\r
+                               break;\r
+                       case COMMAND_TRACE:\r
+                               {\r
+                                       boolean on = isOn((String)commandArgs.elementAt(0));\r
+                                       trace(sessionArg, on);\r
+                                       consoleTraceMessage(sessionArg, on);\r
+                                       break;\r
+                               }\r
+                       case COMMAND_TRACEDIRECTORY:\r
+                               setTraceDirectory((String) commandArgs.elementAt(0));\r
+                               consolePropertyMessage("DRDA_TraceDirectoryChange.I", traceDirectory);\r
+                               break;\r
+                       case COMMAND_TESTCONNECTION:\r
+                               ping();\r
+                               consolePropertyMessage("DRDA_ConnectionTested.I", new String [] \r
+                                       {hostArg, (new Integer(portNumber)).toString()});\r
+                               break;\r
+                       case COMMAND_LOGCONNECTIONS:\r
+                               {\r
+                                       boolean on = isOn((String)commandArgs.elementAt(0));\r
+                                       logConnections(on);\r
+                                       consolePropertyMessage("DRDA_LogConnectionsChange.I", on ? "DRDA_ON.I" : "DRDA_OFF.I");\r
+                                       break;\r
+                               }\r
+                       case COMMAND_SYSINFO:\r
+                               {\r
+                                       String info = sysinfo();\r
+                                       consoleMessage(info);\r
+                                       break;\r
+                               }\r
+                       case COMMAND_MAXTHREADS:\r
+                               max = 0;\r
+                               try{\r
+                                       max = Integer.parseInt((String)commandArgs.elementAt(0));\r
+                               }catch(NumberFormatException e){\r
+                                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                                               {(String)commandArgs.elementAt(0), "maxthreads"});\r
+                               }\r
+                               if (max < MIN_MAXTHREADS)\r
+                                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                                               {new Integer(max).toString(), "maxthreads"});\r
+                               netSetMaxThreads(max);\r
+\r
+                               break;\r
+                       case COMMAND_RUNTIME_INFO:\r
+                               String reply = runtimeInfo();\r
+                               consoleMessage(reply);\r
+                               break;\r
+                       case COMMAND_TIMESLICE:\r
+                               int timeslice = 0;\r
+                               String timeSliceArg = (String)commandArgs.elementAt(0);\r
+               try{\r
+                       timeslice = Integer.parseInt(timeSliceArg);\r
+               }catch(NumberFormatException e){\r
+                                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                                               {(String)commandArgs.elementAt(0), "timeslice"});\r
+               }\r
+                               if (timeslice < MIN_TIMESLICE)\r
+                                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                                               {new Integer(timeslice).toString(), "timeslice"});\r
+                               netSetTimeSlice(timeslice);\r
+                               \r
+                               break;\r
+                       default:\r
+                               //shouldn't get here\r
+                               if (SanityManager.DEBUG)\r
+                                       SanityManager.THROWASSERT("Invalid command in switch:"+ command);\r
+               }\r
+       }\r
+\r
+  \r
+       /**\r
+        * Add session to the run queue\r
+        *\r
+        * @param clientSession session needing work\r
+        */\r
+       private void runQueueAdd(Session clientSession)\r
+       {\r
+               synchronized(runQueue)\r
+               {\r
+                       runQueue.addElement(clientSession);\r
+                       runQueue.notify();\r
+               }\r
+       }\r
+       /**\r
+        * Go through the arguments and find the command and save the dash arguments\r
+        *      and arguments to the command.  Only one command is allowed in the argument\r
+        *      list.\r
+        *\r
+        * @param args  arguments to search\r
+        *\r
+        * @return  command\r
+        */\r
+       private int findCommand(String [] args) throws Exception\r
+       {\r
+               try {\r
+                       // process the dashArgs and pull out the command args \r
+                       int i = 0;\r
+                       int newpos = 0;\r
+                       while (i < args.length)\r
+                       {\r
+                               if (args[i].startsWith("-"))\r
+                               {\r
+                                       newpos = processDashArg(i, args);\r
+                                       if (newpos == i)\r
+                                               commandArgs.addElement(args[i++]);\r
+                                       else\r
+                                               i = newpos;\r
+                               }\r
+                               else\r
+                                       commandArgs.addElement(args[i++]);\r
+                       }\r
+                                       \r
+                       // look up command\r
+                       if (commandArgs.size() > 0)\r
+                       {\r
+                               for (i = 0; i < COMMANDS.length; i++)\r
+                               {\r
+                                       if (StringUtil.SQLEqualsIgnoreCase(COMMANDS[i], \r
+                                                                                                          (String)commandArgs.firstElement()))\r
+                                       {\r
+                                               commandArgs.removeElementAt(0);\r
+                                               return i;\r
+                                       }\r
+                               }\r
+                       }\r
+                       // didn't find command\r
+                       consolePropertyMessage("DRDA_UnknownCommand.U", \r
+                               (String) commandArgs.firstElement());\r
+               } catch (Exception e) {\r
+                       if (e.getMessage().equals(NetworkServerControlImpl.UNEXPECTED_ERR))\r
+                               throw e;\r
+                       //Ignore expected exceptions, they will have been\r
+                                                                       //handled by the consolePropertyMessage routine\r
+               }\r
+               return COMMAND_UNKNOWN;\r
+       }\r
+       /**\r
+        * Get the dash argument. Optional arguments are formated as -x value.\r
+        *\r
+        * @param pos   starting point\r
+        * @param args  arguments to search\r
+        *\r
+        * @return  command\r
+        *\r
+        * @exception Exception thrown if an error occurs\r
+        */\r
+       private int processDashArg(int pos, String[] args)\r
+               throws Exception\r
+       {\r
+               //check for a negative number\r
+               char c = args[pos].charAt(1);\r
+               if (c >= '0' && c <= '9')\r
+                       return pos;\r
+               int dashArg = -1;\r
+               for (int i = 0; i < DASHARGS.length; i++)\r
+               {\r
+                       if (DASHARGS[i].equals(args[pos].substring(1)))\r
+                       {\r
+                               dashArg = i;\r
+                               if ( dashArg != DASHARG_UNSECURE ) { pos++ ; }\r
+                               break;\r
+                       }\r
+               }\r
+               if (dashArg == -1)\r
+                       consolePropertyMessage("DRDA_UnknownArgument.U", args[pos]);\r
+               switch (dashArg)\r
+               {\r
+                       case DASHARG_PORT:\r
+                               if (pos < args.length)\r
+                               {\r
+                       try{\r
+                               portNumber = Integer.parseInt(args[pos]);\r
+                       }catch(NumberFormatException e){\r
+                                               consolePropertyMessage("DRDA_InvalidValue.U", \r
+                                                       new String [] {args[pos], "DRDA_PortNumber.I"});\r
+                       }\r
+                               }\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", "DRDA_PortNumber.I");\r
+                               break;\r
+                       case DASHARG_HOST:\r
+                               if (pos < args.length)\r
+                               {\r
+                                       hostArg = args[pos];\r
+                               }\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", "DRDA_Host.I");\r
+                               break;\r
+                       case DASHARG_DATABASE:\r
+                               if (pos < args.length)\r
+                                       databaseArg = args[pos];\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", \r
+                                               "DRDA_DatabaseDirectory.I");\r
+                               break;\r
+                       case DASHARG_USER:\r
+                               if (pos < args.length)\r
+                               {\r
+                                       userArg = args[pos++];\r
+                                       if (pos < args.length)\r
+                                               passwordArg = args[pos];\r
+                                       else\r
+                                               consolePropertyMessage("DRDA_MissingValue.U", \r
+                                                       "DRDA_Password.I");\r
+                               }\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", "DRDA_User.I");\r
+                               break;\r
+                       case DASHARG_ENCALG:\r
+                               if (pos < args.length)\r
+                                       encAlgArg = args[pos];\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", \r
+                                               "DRDA_EncryptionAlgorithm.I");\r
+                               break;\r
+                       case DASHARG_ENCPRV:\r
+                               if (pos < args.length)\r
+                                       encPrvArg = args[pos];\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", \r
+                                               "DRDA_EncryptionProvider.I");\r
+                               break;\r
+                       case DASHARG_LOADSYSIBM:\r
+                               break;\r
+                       case DASHARG_SESSION:\r
+                               if (pos < args.length)\r
+                       try{\r
+                               sessionArg = Integer.parseInt(args[pos]);\r
+                       }catch(NumberFormatException e){\r
+                                               consolePropertyMessage("DRDA_InvalidValue.U", \r
+                                                       new String [] {args[pos], "DRDA_Session.I"});\r
+                       }\r
+                               else\r
+                                       consolePropertyMessage("DRDA_MissingValue.U", "DRDA_Session.I");\r
+                               break;\r
+                       case DASHARG_UNSECURE:\r
+                               unsecureArg = true;\r
+                               break;\r
+\r
+                       case DASHARG_SSL:\r
+                               if (pos < args.length) {\r
+                                       setSSLMode(getSSLModeValue(args[pos]));\r
+                               } else {\r
+                                       setSSLMode(SSL_OFF);\r
+                               }\r
+                               break;\r
+\r
+                       default:\r
+                               //shouldn't get here\r
+               }\r
+               return pos+1;\r
+       }\r
+\r
+       /**\r
+        * Is string "on" or "off"\r
+        *\r
+        * @param arg   string to check\r
+        *\r
+        * @return  true if string is "on", false if string is "off"\r
+        *\r
+        * @exception Exception thrown if string is not one of "on" or "off"\r
+        */\r
+       private boolean isOn(String arg)\r
+               throws Exception\r
+       {\r
+               if (StringUtil.SQLEqualsIgnoreCase(arg, "on"))\r
+                       return true;\r
+               else if (!StringUtil.SQLEqualsIgnoreCase(arg, "off"))\r
+                       consolePropertyMessage("DRDA_OnOffValue.U", arg);\r
+               return false;\r
+       }\r
+    \r
+    /**\r
+     * Close the resources associated with the opened socket.\r
+     * @throws IOException\r
+     */\r
+    private void closeSocket() throws IOException\r
+    {\r
+        try {\r
+            if (clientIs != null)\r
+                clientIs.close();\r
+            if (clientOs != null)\r
+                clientOs.close();\r
+            if (clientSocket != null)\r
+                clientSocket.close();\r
+        } finally {\r
+            clientIs = null;\r
+            clientOs = null;\r
+            clientSocket = null;\r
+        }\r
+    }\r
+\r
+       /**\r
+        * Set up client socket to send a command to the network server\r
+        *\r
+        * @exception Exception thrown if exception encountered\r
+        */\r
+       private void setUpSocket() throws Exception\r
+       {\r
+               \r
+               try {\r
+                       clientSocket = (Socket) AccessController.doPrivileged(\r
+                                                               new PrivilegedExceptionAction() {\r
+                                                                               \r
+                                                                       public Object run() \r
+                                                                               throws UnknownHostException,\r
+                                                                                          IOException, \r
+                                                                                          java.security.NoSuchAlgorithmException,\r
+                                                                                          java.security.KeyManagementException,\r
+                                               java.security.NoSuchProviderException,\r
+                                               java.security.KeyStoreException,\r
+                                               java.security.UnrecoverableKeyException,\r
+                                               java.security.cert.CertificateException\r
+                                                                       {\r
+                                                                               if (hostAddress == null)\r
+                                                                                       hostAddress = InetAddress.getByName(hostArg);\r
+\r
+                                                                               // JDK131 can't connect with a client\r
+                                                                               // socket with 0.0.0.0 (all addresses) so we will\r
+                                                                               // getLocalHost() which will suffice.\r
+                                                                               InetAddress connectAddress;\r
+                                                                               if (JVMInfo.JDK_ID <= JVMInfo.J2SE_13 &&\r
+                                                                                       hostAddress.getHostAddress().equals("0.0.0.0"))\r
+                                                                                       connectAddress = InetAddress.getLocalHost();\r
+                                                                               else\r
+                                                                                       connectAddress = hostAddress;\r
+\r
+                                                                               switch(getSSLMode()) {\r
+                                                                               case SSL_BASIC:\r
+                                                                                       SSLSocket s1 = (SSLSocket)NaiveTrustManager.getSocketFactory().\r
+                                                                                               createSocket(connectAddress, portNumber);\r
+                                                                                       // Need to handshake now to get proper error reporting.\r
+                                                                                       s1.startHandshake();\r
+                                                                                       return s1;\r
+\r
+                                                                               case SSL_PEER_AUTHENTICATION:\r
+                                                                                       SSLSocket s2 = (SSLSocket)SSLSocketFactory.getDefault().\r
+                                                                                               createSocket(connectAddress, portNumber);\r
+                                                                                       // Need to handshake now to get proper error reporting.\r
+                                                                                       s2.startHandshake();\r
+                                                                                       return s2;\r
+\r
+                                                                               case SSL_OFF:\r
+                                                                               default:\r
+                                                                                       return SocketFactory.getDefault().\r
+                                                                                               createSocket(connectAddress, portNumber);\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+                                                       );\r
+               } catch (PrivilegedActionException pae) {\r
+                       Exception e1 = pae.getException();\r
+                       if (e1 instanceof UnknownHostException) {\r
+                                       consolePropertyMessage("DRDA_UnknownHost.S", hostArg);\r
+                       }\r
+                       else if (e1 instanceof IOException) {\r
+                                       consolePropertyMessage("DRDA_NoIO.S",\r
+                                                                                  new String [] {hostArg, \r
+                                                                                                                 (new Integer(portNumber)).toString(), \r
+                                                                                                                 e1.getMessage()});\r
+                       }\r
+               } catch (Exception e) {\r
+               // If we find other (unexpected) errors, we ultimately exit--so make\r
+               // sure we print the error message before doing so (Beetle 5033).\r
+                       throwUnexpectedException(e);\r
+               }\r
+\r
+               try\r
+               {\r
+                  clientIs = clientSocket.getInputStream();\r
+              clientOs = clientSocket.getOutputStream();\r
+               } catch (IOException e) {\r
+                       consolePropertyMessage("DRDA_NoInputStream.I");\r
+                       throw e;\r
+        }\r
+       }\r
+\r
+       \r
+       private void checkAddressIsLocal(InetAddress inetAddr) throws UnknownHostException,Exception\r
+       {\r
+               for(int i = 0; i < localAddresses.size(); i++)\r
+               {\r
+                       if (inetAddr.equals((InetAddress)localAddresses.get(i)))\r
+                       {\r
+                               return;\r
+                       }\r
+               }\r
+               consolePropertyMessage("DRDA_NeedLocalHost.S", new String[] {inetAddr.getHostName(),serverSocket.getInetAddress().getHostName()});\r
+\r
+       }\r
+\r
+\r
+       /**\r
+        * Build local address list to allow admin commands.\r
+        *\r
+        * @param bindAddr Address on which server was started\r
+        * \r
+        * Note: Some systems may not support localhost.\r
+        * In that case a console message will print for the localhost entries,\r
+        * but the server will continue to start.\r
+        **/\r
+       private void buildLocalAddressList(InetAddress bindAddr) \r
+       {\r
+                       localAddresses = new ArrayList(3);\r
+                       localAddresses.add(bindAddr);\r
+                       try {\r
+                               localAddresses.add(InetAddress.getLocalHost());\r
+                               localAddresses.add(InetAddress.getByName("localhost"));\r
+                       }catch(UnknownHostException uhe)\r
+                       {\r
+                               try {\r
+                                       consolePropertyMessage("DRDA_UnknownHostWarning.I",uhe.getMessage());\r
+                               } catch (Exception e)\r
+                               { // just a warning shouldn't actually throw an exception\r
+                               }\r
+                       }                       \r
+       }\r
+       \r
+       /**\r
+        * Routines for writing commands for NetworkServerControlImpl being used as a client\r
+        * to a server\r
+        */\r
+\r
+       /**\r
+        * Write command header consisting of command header string and protocol\r
+        * version and command\r
+        *\r
+        * @param command       command to be written\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void writeCommandHeader(int command) throws Exception\r
+       {\r
+               try {\r
+                       writeString(COMMAND_HEADER);\r
+                       commandOs.writeByte((byte)((PROTOCOL_VERSION & 0xf0) >> 8 ));\r
+                       commandOs.writeByte((byte)(PROTOCOL_VERSION & 0x0f));\r
+\r
+                       if (clientLocale != null && clientLocale != DEFAULT_LOCALE)\r
+                       {\r
+                               commandOs.writeByte(clientLocale.length());\r
+                               commandOs.writeBytes(clientLocale);\r
+                       }\r
+                       else\r
+                               commandOs.writeByte((byte) 0);\r
+                       commandOs.writeByte((byte) 0);\r
+                       commandOs.writeByte((byte) command);\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+       }\r
+       /**\r
+        * Write length delimited string string\r
+        *\r
+        * @param msg   string to be written\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void writeLDString(String msg) throws Exception\r
+       {\r
+               try {\r
+                       if (msg == null)\r
+                       {\r
+                               commandOs.writeShort(0);\r
+                       }\r
+                       else\r
+                       {\r
+                               commandOs.writeShort(msg.length());\r
+                               writeString(msg);\r
+                       }\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+       }\r
+\r
+       /** Write string\r
+        *\r
+        * @param msg String to write\r
+        */\r
+\r
+       protected void writeString(String msg) throws Exception\r
+       {\r
+               byte[] msgBytes = msg.getBytes(DEFAULT_ENCODING);\r
+               commandOs.write(msgBytes,0,msgBytes.length);\r
+       }\r
+\r
+       /**\r
+        * Write short\r
+        *\r
+        * @param value value to be written\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void writeShort(int value) throws Exception\r
+       {\r
+               try {\r
+                       commandOs.writeByte((byte)((value & 0xf0) >> 8 ));\r
+                       commandOs.writeByte((byte)(value & 0x0f));\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+       }\r
+       /**\r
+        * Write byte\r
+        *\r
+        * @param value value to be written\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void writeByte(int value) throws Exception\r
+       {\r
+               try {\r
+                       commandOs.writeByte((byte)(value & 0x0f));\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+       }\r
+       /**\r
+        * Send client message to server\r
+        *\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void send() throws Exception\r
+       {\r
+               try {\r
+                       byteArrayOs.writeTo(clientOs);\r
+                       commandOs.flush();\r
+                       byteArrayOs.reset();    //discard anything currently in the byte array\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+       }\r
+       /**\r
+        * Stream error writing to client socket\r
+        */\r
+       private void clientSocketError(IOException e) throws IOException\r
+       {\r
+               try {\r
+                       consolePropertyMessage("DRDA_ClientSocketError.S", e.getMessage());\r
+               } catch (Exception ce) {} // catch the exception consolePropertyMessage will\r
+                                                                // throw since we also want to print a stack trace\r
+               consoleExceptionPrintTrace(e);\r
+                       throw e;\r
+       }\r
+       /**\r
+        * Read result from sending client message to server\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void readResult() throws Exception\r
+       {\r
+               fillReplyBuffer();\r
+               readCommandReplyHeader();\r
+               if (replyBufferPos >= replyBufferCount)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               int messageType = replyBuffer[replyBufferPos++] & 0xFF;\r
+               if (messageType == OK)          // O.K.\r
+                       return;\r
+               // get error and display and throw exception\r
+               String message =  readLDString();\r
+               if (messageType == SQLERROR)\r
+                       wrapSQLError(message);\r
+               else if (messageType == SQLWARNING)\r
+                       wrapSQLWarning(message);\r
+               else\r
+                       consolePropertyMessage(message);\r
+       }\r
+\r
+       \r
+\r
+       /**\r
+        * Ensure the reply buffer is at large enought to hold all the data;\r
+        * don't just rely on OS level defaults\r
+        *\r
+        *\r
+        * @param minimumBytesNeeded    size of buffer required \r
+        * @exception Exception throws an exception if a problem reading the reply\r
+        */\r
+       private void ensureDataInBuffer(int minimumBytesNeeded) throws Exception\r
+       {\r
+               // make sure the buffer is large enough\r
+               while ((replyBufferCount - replyBufferPos) < minimumBytesNeeded)\r
+               {\r
+                       try {\r
+                               int bytesRead = clientIs.read(replyBuffer, replyBufferCount, replyBuffer.length - replyBufferCount);\r
+                               replyBufferCount += bytesRead;\r
+               \r
+                       } catch (IOException e)\r
+                       {\r
+                               clientSocketError(e);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Fill the reply buffer with the reply allocates a reply buffer if one doesn't\r
+        * exist\r
+        *\r
+        *\r
+        * @exception Exception throws an exception if a problem reading the reply\r
+        */\r
+       private void fillReplyBuffer() throws Exception\r
+       {\r
+               if (replyBuffer == null)\r
+                       replyBuffer = new byte[MAXREPLY];\r
+               try {\r
+                       replyBufferCount = clientIs.read(replyBuffer);\r
+               }\r
+               catch (IOException e)\r
+               {\r
+                       clientSocketError(e);\r
+               }\r
+               if (replyBufferCount == -1)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               replyBufferPos = 0;\r
+       }\r
+       /**\r
+        * Read the command reply header from the server\r
+        *\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private void readCommandReplyHeader() throws Exception\r
+       {\r
+               ensureDataInBuffer(REPLY_HEADER_LENGTH);\r
+               if (replyBufferCount < REPLY_HEADER_LENGTH)\r
+               {\r
+                       consolePropertyMessage("DRDA_InvalidReplyHeader1.S", Integer.toString(replyBufferCount));\r
+               }\r
+               String header =  new String(replyBuffer, 0, REPLY_HEADER_LENGTH, DEFAULT_ENCODING);\r
+               if (!header.equals(REPLY_HEADER))\r
+               {\r
+                       consolePropertyMessage("DRDA_InvalidReplyHeader2.S", header);\r
+               }\r
+               replyBufferPos += REPLY_HEADER_LENGTH;\r
+       }\r
+       /**\r
+        * Read short from buffer\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private int readShort() throws Exception\r
+       {\r
+               ensureDataInBuffer(2);\r
+               if (replyBufferPos + 2 > replyBufferCount)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               return ((replyBuffer[replyBufferPos++] & 0xff) << 8) + \r
+                           (replyBuffer[replyBufferPos++] & 0xff);\r
+       }\r
+       /**\r
+        * Read int from buffer\r
+        * @exception Exception throws an exception if an error occurs\r
+        */\r
+       private int readInt() throws Exception\r
+       {\r
+               ensureDataInBuffer(4);\r
+               if (replyBufferPos + 4 > replyBufferCount)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               return ((replyBuffer[replyBufferPos++] & 0xff) << 24) + \r
+                       ((replyBuffer[replyBufferPos++] & 0xff) << 16) + \r
+                       ((replyBuffer[replyBufferPos++] & 0xff) << 8) + \r
+                           (replyBuffer[replyBufferPos++] & 0xff);\r
+       }\r
+       /**\r
+        * Read String reply\r
+        *\r
+        * @param msgKey        error message key\r
+        * @return string value or null \r
+        * @exception Exception throws an error if problems reading reply\r
+        */\r
+       private String readStringReply(String msgKey) throws Exception\r
+       {\r
+               fillReplyBuffer();\r
+               readCommandReplyHeader();\r
+               if (replyBuffer[replyBufferPos++] == 0)         // O.K.\r
+                       return readLDString();\r
+               else\r
+                       consolePropertyMessage(msgKey);\r
+               return null;\r
+                       \r
+       }\r
+\r
+\r
+\r
+       \r
+       /**\r
+        * Read length delimited string from a buffer\r
+        *\r
+        * @return string value from buffer\r
+        * @exception Exception throws an error if problems reading reply\r
+        */\r
+       private String readLDString() throws Exception\r
+       {\r
+               int strlen = readShort();\r
+               ensureDataInBuffer(strlen);\r
+               if (replyBufferPos + strlen > replyBufferCount)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               String retval= new String(replyBuffer, replyBufferPos, strlen, DEFAULT_ENCODING);\r
+               replyBufferPos += strlen;\r
+               return retval;\r
+       }\r
+       /**\r
+        * Read Bytes reply\r
+        *\r
+        * @param msgKey        error message key\r
+        * @return string value or null \r
+        * @exception Exception throws an error if problems reading reply\r
+        */\r
+       private byte [] readBytesReply(String msgKey) throws Exception\r
+       {\r
+               fillReplyBuffer();\r
+               readCommandReplyHeader();\r
+               if (replyBuffer[replyBufferPos++] == 0)         // O.K.\r
+                       return readLDBytes();\r
+               else\r
+                       consolePropertyMessage(msgKey);\r
+               return null;\r
+                       \r
+       }\r
+       /**\r
+        * Read length delimited bytes from a buffer\r
+        *\r
+        * @return byte array from buffer\r
+        * @exception Exception throws an error if problems reading reply\r
+        */\r
+       private byte[] readLDBytes() throws Exception\r
+       {\r
+               int len = readShort();\r
+               ensureDataInBuffer(len);\r
+               if (replyBufferPos + len > replyBufferCount)\r
+                       consolePropertyMessage("DRDA_InvalidReplyTooShort.S");\r
+               byte [] retval =  new byte[len];\r
+               for (int i = 0; i < len; i++)\r
+                       retval[i] = replyBuffer[replyBufferPos++];\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Initialize fields from system properties\r
+        *\r
+        */\r
+       private void  getPropertyInfo() throws Exception\r
+       {\r
+               //set values according to properties\r
+               \r
+               String directory = PropertyUtil.getSystemProperty(Property.SYSTEM_HOME_PROPERTY);\r
+               String propval = PropertyUtil.getSystemProperty(\r
+                       Property.DRDA_PROP_LOGCONNECTIONS);\r
+               if (propval != null && StringUtil.SQLEqualsIgnoreCase(propval,"true"))  \r
+                       setLogConnections(true);\r
+               propval = PropertyUtil.getSystemProperty(Property.DRDA_PROP_TRACEALL);\r
+               if (propval != null && StringUtil.SQLEqualsIgnoreCase(propval, \r
+                                                                                                                         "true"))  \r
+                       setTraceAll(true);\r
+\r
+               //If the derby.system.home property has been set, it is the default. \r
+               //Otherwise, the default is the current directory. \r
+               //If derby.system.home is not set, directory will be null and trace files will get\r
+               //created in current directory.\r
+               propval = PropertyUtil.getSystemProperty(Property.DRDA_PROP_TRACEDIRECTORY,directory);\r
+               if(propval != null){\r
+                       if(propval.equals(""))\r
+                               propval = directory;\r
+                       setTraceDirectory(propval);\r
+               }\r
+\r
+               //DERBY-375 If a system property is specified without any value, getProperty returns \r
+               //an empty string. Use default values in such cases.\r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_MINTHREADS);\r
+               if (propval != null){\r
+                       if(propval.equals(""))\r
+                               propval = "0";\r
+                       setMinThreads(getIntPropVal(Property.DRDA_PROP_MINTHREADS, propval));\r
+               }\r
+\r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_MAXTHREADS);\r
+               if (propval != null){\r
+                       if(propval.equals(""))\r
+                               propval = "0";\r
+                       setMaxThreads(getIntPropVal(Property.DRDA_PROP_MAXTHREADS, propval));\r
+               }\r
+\r
+\r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_TIMESLICE);\r
+               if (propval != null){\r
+                       if(propval.equals(""))\r
+                               propval = "0";\r
+                       setTimeSlice(getIntPropVal(Property.DRDA_PROP_TIMESLICE, propval));\r
+               }\r
+\r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_PORTNUMBER);\r
+               if (propval != null){\r
+                       if(propval.equals(""))\r
+                               propval = String.valueOf(NetworkServerControl.DEFAULT_PORTNUMBER);\r
+                       portNumber = getIntPropVal(Property.DRDA_PROP_PORTNUMBER, propval);\r
+               }\r
+\r
+               propval = PropertyUtil.getSystemProperty(\r
+                       Property.DRDA_PROP_SSL_MODE);\r
+               setSSLMode(getSSLModeValue(propval));\r
+                                                                                                \r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_KEEPALIVE);\r
+               if (propval != null && \r
+                       StringUtil.SQLEqualsIgnoreCase(propval,"false"))\r
+                       keepAlive = false;\r
+               \r
+               propval = PropertyUtil.getSystemProperty( \r
+                       Property.DRDA_PROP_HOSTNAME);\r
+               if (propval != null){\r
+                       if(propval.equals(""))\r
+                               hostArg = DEFAULT_HOST; \r
+                       else\r
+                               hostArg = propval;\r
+               }       \r
+               propval = PropertyUtil.getSystemProperty(\r
+                                                NetworkServerControlImpl.DRDA_PROP_DEBUG);\r
+               if (propval != null      && StringUtil.SQLEqualsIgnoreCase(propval, "true"))\r
+                       debugOutput = true;\r
+\r
+               propval = PropertyUtil.getSystemProperty( \r
+                               Property.DRDA_PROP_SECURITYMECHANISM);\r
+               if (propval != null){\r
+                       setSecurityMechanism(propval);\r
+               }\r
+\r
+       }\r
+\r
+    /**\r
+     * Retrieve the SECMEC integer value from the\r
+     * user friendly security mechanism name\r
+     * @param s  security mechanism name\r
+     * @return integer value , return the SECMEC value for \r
+     * the security mechanism as defined by DRDA spec\r
+     * or INVALID_OR_NOTSET_SECURITYMECHANISM if 's'\r
+     * passed is invalid  or not supported security \r
+     * mechanism\r
+     */\r
+    private int getSecMecValue(String s)\r
+    {\r
+        int secmec = INVALID_OR_NOTSET_SECURITYMECHANISM;\r
+\r
+        if( StringUtil.SQLEqualsIgnoreCase(s,"USER_ONLY_SECURITY"))\r
+                secmec = CodePoint.SECMEC_USRIDONL;\r
+        else if( StringUtil.SQLEqualsIgnoreCase(s,"CLEAR_TEXT_PASSWORD_SECURITY"))\r
+                secmec = CodePoint.SECMEC_USRIDPWD;\r
+        else if( StringUtil.SQLEqualsIgnoreCase(s,"ENCRYPTED_USER_AND_PASSWORD_SECURITY"))\r
+                secmec = CodePoint.SECMEC_EUSRIDPWD;\r
+        else if( StringUtil.SQLEqualsIgnoreCase(s,"STRONG_PASSWORD_SUBSTITUTE_SECURITY"))\r
+                secmec = CodePoint.SECMEC_USRSSBPWD;\r
+        \r
+        return secmec;\r
+    }\r
+\r
+    /**\r
+     * Retrieve the string name for the integer\r
+     * secmec value\r
+     * @param secmecVal   secmec value\r
+     * @return String - return the string name corresponding \r
+     * to the secmec value if recognized else returns null\r
+     */\r
+    private String getStringValueForSecMec(int secmecVal)\r
+    {\r
+        switch(secmecVal)\r
+        {\r
+            case CodePoint.SECMEC_USRIDONL:\r
+                return "USER_ONLY_SECURITY";\r
+            \r
+            case CodePoint.SECMEC_USRIDPWD:\r
+                return "CLEAR_TEXT_PASSWORD_SECURITY";\r
+            \r
+            case CodePoint.SECMEC_EUSRIDPWD:\r
+                return "ENCRYPTED_USER_AND_PASSWORD_SECURITY";\r
+            \r
+            case CodePoint.SECMEC_USRSSBPWD:\r
+                return "STRONG_PASSWORD_SUBSTITUTE_SECURITY";\r
+        }\r
+        return null;\r
+    }\r
+   \r
+    /**\r
+     * This method returns whether EUSRIDPWD security mechanism\r
+     * is supported or not. See class static block for more\r
+     * info.\r
+     * @return true if EUSRIDPWD is supported, false otherwise\r
+     */ \r
+    boolean supportsEUSRIDPWD()\r
+    {\r
+        return SUPPORTS_EUSRIDPWD;\r
+    }\r
+    \r
+       /**\r
+        * Get the SSL-mode from a string.\r
+        * @param s the SSL-mode string ("off"/"false", "on"/"true" or\r
+        * "authenticate"/"auth"\r
+        * @return SSL_OFF, SSL_BASIC or SSL_PEER_AUTHENTICATION. Will default to\r
+        * SSL_OFF if the input does not match one of the four listed\r
+        * above.\r
+        **/\r
+\r
+       private int getSSLModeValue(String s)\r
+        throws Exception\r
+       {\r
+               if (s != null){\r
+                       if (StringUtil.SQLEqualsIgnoreCase(s,"off")) {\r
+                               return SSL_OFF;\r
+                       } else if (StringUtil.SQLEqualsIgnoreCase(s,"basic")) {\r
+                               return SSL_BASIC;\r
+                       } else if (StringUtil.SQLEqualsIgnoreCase(s,"peerAuthentication")) {\r
+                return SSL_PEER_AUTHENTICATION;\r
+                       } else {\r
+                               // Unknown value\r
+                consolePropertyMessage("DRDA_InvalidValue.U", \r
+                                       new String [] {s, Property.DRDA_PROP_SSL_MODE});\r
+                \r
+                               return SSL_OFF;\r
+                       }\r
+               } else {\r
+                       // Default\r
+                       return SSL_OFF;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the string value of the SSL-mode. This is the inverse of\r
+        * getSSLModeValue.\r
+        * @param i The SSL-mode value (SSL_OFF, SSL_BASIC or\r
+        * SSL_PEER_AUTHENTICATION)\r
+        * @return The string representation ("off","on" or\r
+        * "autneticate"). Will default to SSL_OFF for other values than\r
+        * those listed above.\r
+        */\r
+       \r
+       private String getSSLModeString(int i)\r
+       {\r
+               switch(i) {\r
+               case SSL_OFF:\r
+                       return "off";\r
+               case SSL_BASIC:\r
+                       return "basic";\r
+               case SSL_PEER_AUTHENTICATION:\r
+                       return "peerAuthentication";\r
+               default: \r
+                       // Assumes no SSL encryption for faulty values Anyway,\r
+                       // this should not happen thince the input values are\r
+                       // strings...\r
+                       return "off";\r
+               }\r
+       }\r
+\r
+       \r
+       /**\r
+        * Get integer property values\r
+        *\r
+        * @param propName      property name\r
+        * @param propVal       string property value\r
+        * @return integer value\r
+        *\r
+        * @exception Exception if not a valid integer\r
+        */\r
+       private int getIntPropVal(String propName, String propVal)\r
+               throws Exception\r
+       {\r
+               int val = 0;\r
+               try {\r
+                        val = (new Integer(propVal)).intValue();\r
+               } catch (Exception e)\r
+               {\r
+                       consolePropertyMessage("DRDA_InvalidPropVal.S", new String [] \r
+                               {propName, propVal});\r
+               }\r
+               return val;\r
+       }\r
+\r
+       /**\r
+        * Handle console error message\r
+        *      - display on console and if it is a user error, display usage\r
+        *  - if user error or severe error, throw exception with message key and message\r
+        *\r
+        * @param messageKey    message key\r
+        * @param args                  arguments to message\r
+        *\r
+        * @throws Exception if an error occurs\r
+        */\r
+       private void consolePropertyMessageWork(String messageKey, String [] args)\r
+               throws Exception\r
+       {\r
+               String locMsg = null;\r
+\r
+               int type = getMessageType(messageKey);\r
+\r
+               if (type == ERRTYPE_UNKNOWN)\r
+                       locMsg = messageKey;\r
+               else\r
+                       locMsg = localizeMessage(messageKey, langUtil, args);\r
+\r
+               //display on the console\r
+               consoleMessage(locMsg);\r
+\r
+               //if it is a user error display usage\r
+               if (type == ERRTYPE_USER)\r
+                       usage();\r
+\r
+               //we may want to use a different locale for throwing the exception\r
+               //since this can be sent to a browser with a different locale\r
+               if (currentSession != null && \r
+                               currentSession.langUtil != null &&\r
+                               type != ERRTYPE_UNKNOWN)\r
+                       locMsg = localizeMessage(messageKey, currentSession.langUtil, args);\r
+\r
+               // throw an exception for severe and user errors\r
+               if (type == ERRTYPE_SEVERE || type == ERRTYPE_USER)\r
+               {\r
+                       if (messageKey.equals("DRDA_SQLException.S"))\r
+                               throwSQLException(args[0]);\r
+                       else if (messageKey.equals("DRDA_SQLWarning.I"))\r
+                               throwSQLWarning(args[0]);\r
+                       else \r
+                               throw new Exception(messageKey+":"+locMsg);\r
+               }\r
+\r
+               // throw an exception with just the message if the error type is\r
+               // unknown\r
+               if (type == ERRTYPE_UNKNOWN)\r
+                       throw new Exception(locMsg);\r
+\r
+               return;\r
+\r
+       }\r
+       /**\r
+        * Throw a SQL Exception which was sent over by a server\r
+        * Format of the msg is SQLSTATE:localized message\nSQLSTATE:next localized message\r
+        *\r
+        * @param msg           msg containing SQL Exception\r
+        *\r
+        * @throws SQLException\r
+        */\r
+       private void throwSQLException(String msg) throws SQLException\r
+       {\r
+               SQLException se = null;\r
+               SQLException ne;\r
+               SQLException ce = null;\r
+               StringBuffer strbuf = new StringBuffer();\r
+               StringTokenizer tokenizer = new StringTokenizer(msg, "\n");\r
+               String sqlstate = null;\r
+               String str;\r
+               while (tokenizer.hasMoreTokens())\r
+               {\r
+                       str = tokenizer.nextToken();\r
+                       //start of the next message\r
+                       if (str.charAt(5) == ':')\r
+                       {\r
+                               if (strbuf.length() > 0)\r
+                               {\r
+                                       if (se == null)\r
+                                       {\r
+                                               se = new SQLException(strbuf.toString(), sqlstate);\r
+                                               ce = se;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ne = new SQLException(strbuf.toString(), sqlstate);\r
+                                               ce.setNextException(ne);\r
+                                               ce = ne;\r
+                                       }\r
+                                       strbuf = new StringBuffer();\r
+                               }\r
+                               strbuf.append(str.substring(6));\r
+                               sqlstate = str.substring(0,5);\r
+                       }\r
+                       else\r
+                               strbuf.append(str);\r
+               }\r
+               if (strbuf.length() > 0)\r
+               {\r
+                       if (se == null)\r
+                       {\r
+                               se = new SQLException(strbuf.toString(), sqlstate);\r
+                               ce = se;\r
+                       }\r
+                       else\r
+                       {\r
+                               ne = new SQLException(strbuf.toString(), sqlstate);\r
+                               ce.setNextException(ne);\r
+                               ce = ne;\r
+                       }\r
+               }\r
+               throw se;\r
+       }\r
+       /**\r
+        * Throw a SQL Warning which was sent over by a server\r
+        * Format of the msg is SQLSTATE:localized message\nSQLSTATE:next localized message\r
+        *\r
+        * @param msg           msg containing SQL Warning\r
+        *\r
+        * @throws SQLWarning\r
+        */\r
+       private void throwSQLWarning(String msg) throws SQLWarning\r
+       {\r
+               SQLWarning se = null;\r
+               SQLWarning ne;\r
+               SQLWarning ce = null;\r
+               StringBuffer strbuf = new StringBuffer();\r
+               StringTokenizer tokenizer = new StringTokenizer(msg, "\n");\r
+               String sqlstate = null;\r
+               String str;\r
+               while (tokenizer.hasMoreTokens())\r
+               {\r
+                       str = tokenizer.nextToken();\r
+                       //start of the next message\r
+                       if (str.charAt(5) == ':')\r
+                       {\r
+                               if (strbuf.length() > 0)\r
+                               {\r
+                                       if (se == null)\r
+                                       {\r
+                                               se = new SQLWarning(strbuf.toString(), sqlstate);\r
+                                               ce = se;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ne = new SQLWarning(strbuf.toString(), sqlstate);\r
+                                               ce.setNextException(ne);\r
+                                               ce = ne;\r
+                                       }\r
+                                       strbuf = new StringBuffer();\r
+                               }\r
+                               strbuf.append(str.substring(6));\r
+                               sqlstate = str.substring(0,5);\r
+                       }\r
+                       else\r
+                               strbuf.append(str);\r
+               }\r
+               if (strbuf.length() > 0)\r
+               {\r
+                       if (se == null)\r
+                       {\r
+                               se = new SQLWarning(strbuf.toString(), sqlstate);\r
+                               ce = se;\r
+                       }\r
+                       else\r
+                       {\r
+                               ne = new SQLWarning(strbuf.toString(), sqlstate);\r
+                               ce.setNextException(ne);\r
+                               ce = ne;\r
+                       }\r
+               }\r
+               throw se;\r
+       }\r
+\r
+       /**\r
+        * Print a trace for the (unexpected) exception received, then\r
+        * throw a generic exception indicating that 1) an unexpected\r
+        * exception was thrown, and 2) we've already printed the trace\r
+        * (so don't do it again).\r
+        * \r
+        * @param e An unexpected exception.\r
+        * @throws Exception with message UNEXPECTED_ERR.\r
+        */\r
+       private void throwUnexpectedException(Exception e)\r
+        throws Exception {\r
+\r
+               consoleExceptionPrintTrace(e);\r
+               throw new Exception(UNEXPECTED_ERR);\r
+\r
+       }\r
+\r
+    /**\r
+     * Convenience routine so that NetworkServerControl can localize messages.\r
+     *\r
+     * @param msgProp  message key\r
+     * @param args             arguments to message\r
+     *\r
+     */\r
+    public String localizeMessage( String msgProp, String[] args )\r
+    {\r
+        return localizeMessage( msgProp, langUtil, args );\r
+    }\r
+\r
+       /**\r
+        * Localize a message given a particular AppUI \r
+        *\r
+        * @param msgProp       message key\r
+        * @param localLangUtil LocalizedResource to use to localize message\r
+        * @param args          arguments to message\r
+        *\r
+        */\r
+       private String localizeMessage(String msgProp, LocalizedResource localLangUtil, String [] args)\r
+       {\r
+               String locMsg = null;\r
+               //check if the argument is a property\r
+               if (args != null)\r
+               {\r
+                       String [] argMsg = new String[args.length];\r
+                       for (int i = 0; i < args.length; i++)\r
+                       {\r
+                               if (isMsgProperty(args[i]))\r
+                                       argMsg[i] = localLangUtil.getTextMessage(args[i]);\r
+                               else\r
+                                       argMsg[i] = args[i];\r
+                       }\r
+                       switch (args.length)\r
+                       {\r
+                               case 1:\r
+                                       locMsg = localLangUtil.getTextMessage(msgProp, argMsg[0]);\r
+                                       break;\r
+                               case 2:\r
+                                       locMsg = localLangUtil.getTextMessage(msgProp, argMsg[0], argMsg[1]);\r
+                                       break;\r
+                               case 3:\r
+                                       locMsg = localLangUtil.getTextMessage(msgProp, argMsg[0], argMsg[1], argMsg[2]);\r
+                                       break;\r
+                               case 4:\r
+                                       locMsg = localLangUtil.getTextMessage(msgProp, argMsg[0], argMsg[1], argMsg[2], argMsg[3]);\r
+                                       break;\r
+                               default:\r
+                                       //shouldn't get here\r
+                       }\r
+               }\r
+               else\r
+                       locMsg = localLangUtil.getTextMessage(msgProp);\r
+               return locMsg;\r
+       }\r
+       /**\r
+        * Determine type of message\r
+        *\r
+        * @param msg           message \r
+        *\r
+        * @return message type\r
+        */\r
+       private int getMessageType(String msg)\r
+       {\r
+               //all property messages should start with DRDA_\r
+               if (!msg.startsWith(DRDA_MSG_PREFIX))\r
+                       return ERRTYPE_UNKNOWN;\r
+               int startpos = msg.indexOf('.')+1;\r
+               if (startpos >= msg.length())\r
+                       return ERRTYPE_UNKNOWN;\r
+               if (msg.length() > (startpos + 1))\r
+                       return ERRTYPE_UNKNOWN;\r
+               char type = msg.charAt(startpos);\r
+               if (type == 'S')\r
+                       return ERRTYPE_SEVERE;\r
+               if (type == 'U')\r
+                       return ERRTYPE_USER;\r
+               if (type == 'I')\r
+                       return ERRTYPE_INFO;\r
+               return ERRTYPE_UNKNOWN;\r
+       }\r
+       /**\r
+        * Determine whether string is a property key or not\r
+        *      property keys start with DRDA_MSG_PREFIX\r
+        *\r
+        * @param msg           message \r
+        *\r
+        * @return true if it is a property key; false otherwise\r
+        */\r
+       private boolean isMsgProperty(String msg)\r
+       {\r
+               if (msg.startsWith(DRDA_MSG_PREFIX))\r
+                       return true;\r
+               else\r
+                       return false;\r
+       }\r
+       /**\r
+        * Get the current value of logging connections\r
+        *\r
+        * @return true if logging connections is on; false otherwise\r
+        */\r
+       public boolean getLogConnections()\r
+       {\r
+               synchronized(logConnectionsSync) {\r
+                       return logConnections;\r
+               }\r
+       }\r
+       /**\r
+        * Set the current value of logging connections\r
+        *\r
+        * @param value true to turn logging connections on; false to turn it off\r
+        */\r
+       private void setLogConnections(boolean value)\r
+       {\r
+               synchronized(logConnectionsSync) {\r
+                       logConnections = value;\r
+               }\r
+               // update the value in all the threads\r
+               synchronized(threadList) {\r
+                       for (Enumeration e = threadList.elements(); e.hasMoreElements(); )\r
+                       {\r
+                               DRDAConnThread thread = (DRDAConnThread)e.nextElement();\r
+                               thread.setLogConnections(value);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+     * Set the security mechanism for derby.drda.securityMechanism\r
+     * If this property is set, server will only allow connections\r
+     * from client with this security mechanism.\r
+     * This method will map the user friendly string representing \r
+     * the security mechanism to the corresponding drda secmec value\r
+        * @param s security mechanism string value\r
+        * @throws Exception if  value to set is invalid\r
+     * @see Property#DRDA_PROP_SECURITYMECHANISM \r
+        */\r
+    private void setSecurityMechanism(String s)\r
+        throws Exception\r
+    {\r
+       allowOnlySecurityMechanism = getSecMecValue(s);\r
+       \r
+       // if server vm cannot support EUSRIDPWD, then do not allow \r
+       // derby.drda.securityMechanism to be set to EUSRIDPWD security\r
+       // mechanism\r
+       if ((allowOnlySecurityMechanism == INVALID_OR_NOTSET_SECURITYMECHANISM) ||\r
+              (allowOnlySecurityMechanism == CodePoint.SECMEC_EUSRIDPWD &&\r
+              !SUPPORTS_EUSRIDPWD))\r
+           consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                       {s, Property.DRDA_PROP_SECURITYMECHANISM});\r
+    }\r
+    \r
+    /**\r
+     * get the security mechanism (secmec value) that the server\r
+     * will accept connections from.\r
+     * @return the securitymechanism value. It is value that \r
+     * the derby.drda.securityMechanism was set to, if it is not set, then\r
+     * it is equal to INVALID_OR_NOTSET_SECURITYMECHANISM\r
+     * @see Property#DRDA_PROP_SECURITYMECHANISM \r
+     */\r
+    protected int getSecurityMechanism()\r
+    {\r
+        return allowOnlySecurityMechanism;\r
+    }\r
+       /**\r
+        * Set the trace on/off for all sessions, or one session, depending on\r
+        * whether we got -s argument.\r
+        *\r
+        * @param on    true to turn trace on; false to turn it off\r
+        * @return true if set false if an error occurred\r
+        */\r
+       private boolean setTrace(boolean on)\r
+       {\r
+        boolean setTraceSuccessful = true;\r
+               if (sessionArg == 0)\r
+               {\r
+                       synchronized(sessionTable) {\r
+                               for (Enumeration e = sessionTable.elements(); e.hasMoreElements(); )\r
+                               {\r
+                   \r
+                                   Session session = (Session) e.nextElement();\r
+                                       if (on)\r
+                                               try {\r
+                                                       session.setTraceOn(traceDirectory);\r
+                                               } catch (Exception te ) {\r
+                                                       consoleExceptionPrintTrace(te);\r
+                                                       setTraceSuccessful = false;\r
+                                                       session.setTraceOff();\r
+                                               }\r
+                                       else\r
+                                               session.setTraceOff();\r
+                               }\r
+                               if (setTraceSuccessful)\r
+                                       setTraceAll(on);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Session session = (Session) sessionTable.get(new Integer(sessionArg));\r
+                       if (session != null)\r
+                       {       \r
+                               if (on)\r
+                                       try {                         \r
+                                               session.setTraceOn(traceDirectory);\r
+                                       }catch (Exception te) {\r
+                                               consoleExceptionPrintTrace(te);\r
+                                               setTraceSuccessful = false;\r
+                                               session.setTraceOff();\r
+                                       }\r
+                               else\r
+                                       session.setTraceOff();\r
+                       }\r
+                       else\r
+                               return false;\r
+               }\r
+               return setTraceSuccessful;\r
+       }\r
+\r
+\r
+       /**\r
+        * Get the current value of the time slice\r
+        *\r
+        * @return time slice value\r
+        */\r
+       protected int getTimeSlice()\r
+       {\r
+                       return timeSlice;\r
+       }\r
+       /**\r
+        * Set the current value of  time slice\r
+        *\r
+        * @param value time slice value\r
+        * @exception Exception if value is < 0\r
+        */\r
+       private void setTimeSlice(int value)\r
+               throws Exception\r
+       {\r
+               if (value < MIN_TIMESLICE)\r
+                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                               {new Integer(value).toString(), "timeslice"});\r
+               if (value == USE_DEFAULT)\r
+                       value = DEFAULT_TIMESLICE;\r
+               synchronized(timeSliceSync) {\r
+                       timeSlice = value;\r
+               }\r
+       }\r
+       \r
+       /** \r
+        * Get the current value of keepAlive to configure how long the server\r
+        * should keep the socket alive for a disconnected client\r
+        */\r
+       protected boolean getKeepAlive()\r
+       {\r
+               return keepAlive;\r
+       }\r
+\r
+       /**\r
+        * Get the current value of minimum number of threads to create at start\r
+        *\r
+        * @return value of minimum number of threads\r
+        */\r
+       private int getMinThreads()\r
+       {\r
+               synchronized(threadsSync) {\r
+                       return minThreads;\r
+               }\r
+       }\r
+       /**\r
+        * Set the current value of minimum number of threads to create at start\r
+        *\r
+        * @param value  value of minimum number of threads\r
+        */\r
+       private void setMinThreads(int value)\r
+       {\r
+               synchronized(threadsSync) {\r
+                       minThreads = value;\r
+               }\r
+       }\r
+       /**\r
+        * Get the current value of maximum number of threads to create \r
+        *\r
+        * @return value of maximum number of threads\r
+        */\r
+       private int getMaxThreads()\r
+       {\r
+               synchronized(threadsSync) {\r
+                       return maxThreads;\r
+               }\r
+       }\r
+       /**\r
+        * Set the current value of maximum number of threads to create \r
+        *\r
+        * @param value value of maximum number of threads\r
+        * @exception Exception if value is less than 0\r
+        */\r
+       private void setMaxThreads(int value) throws Exception\r
+       {\r
+               if (value < MIN_MAXTHREADS)\r
+                       consolePropertyMessage("DRDA_InvalidValue.U", new String [] \r
+                               {new Integer(value).toString(), "maxthreads"});\r
+               if (value == USE_DEFAULT)\r
+                       value = DEFAULT_MAXTHREADS;\r
+               synchronized(threadsSync) {\r
+                       maxThreads = value;\r
+               }\r
+       }\r
+\r
+       protected void setSSLMode(int mode)\r
+       {\r
+               sslMode = mode;\r
+       }\r
+\r
+       protected int getSSLMode() \r
+       {\r
+               return sslMode;\r
+       }\r
+               \r
+       /**\r
+        * Get the current value of whether to trace all the sessions\r
+        *\r
+        * @return true if tracing is on for all sessions; false otherwise\r
+        */\r
+       protected boolean getTraceAll()\r
+       {\r
+               synchronized(traceAllSync) {\r
+                       return traceAll;\r
+               }\r
+       }\r
+       /**\r
+        * Set the current value of whether to trace all the sessions\r
+        *\r
+        * @param value true if tracing is on for all sessions; false otherwise\r
+        */\r
+       private void setTraceAll(boolean value)\r
+       {\r
+               synchronized(traceAllSync) {\r
+                       traceAll = value;\r
+               }\r
+       }\r
+       /**\r
+        * Get the current value of trace directory\r
+        *\r
+        * @return trace directory\r
+        */\r
+       protected String getTraceDirectory()\r
+       {\r
+               synchronized(traceDirectorySync) {\r
+                       return traceDirectory;\r
+               }\r
+       }\r
+       /**\r
+        * Set the current value of trace directory\r
+        *\r
+        * @param value trace directory\r
+        */\r
+       private void setTraceDirectory(String value)\r
+       {\r
+               synchronized(traceDirectorySync) {\r
+                       traceDirectory = value;\r
+               }\r
+       }\r
+\r
+    \r
+\r
+       /**\r
+        * Connect to a database to test whether a connection can be made\r
+        *\r
+        * @param writer        connection to send message to\r
+        * @param database      database directory to connect to\r
+        * @param user          user to use\r
+        * @param password      password to use\r
+        */\r
+       private void connectToDatabase(DDMWriter writer, String database, String user, \r
+               String password) throws Exception\r
+       {\r
+               Properties p = new Properties();\r
+               if (user != null)\r
+                       p.put("user", user);\r
+               if (password != null)\r
+                       p.put("password", password);\r
+               try {\r
+               Class.forName(CLOUDSCAPE_DRIVER);\r
+                       //Added by Jeff Huang\r
+                       new org.apache.derby.jdbc.EmbeddedDriver();\r
+               }\r
+               catch (Exception e) {\r
+                       sendMessage(writer, ERROR, e.getMessage());\r
+                       return;\r
+               }\r
+               try {\r
+                       //Note, we add database to the url so that we can allow additional\r
+                       //url attributes\r
+                       Connection conn = DriverManager.getConnection(Attribute.PROTOCOL+database, p);\r
+                       // send warnings\r
+                       SQLWarning warn = conn.getWarnings();\r
+                       if (warn != null)\r
+                               sendSQLMessage(writer, warn, SQLWARNING);\r
+                       else\r
+                               sendOK(writer);\r
+                       conn.close();\r
+                       return;\r
+               } catch (SQLException se) {\r
+                       sendSQLMessage(writer, se, SQLERROR);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Wrap SQL Error - display to console and raise exception\r
+        *\r
+        * @param messageKey    Derby SQL Exception message id\r
+        *\r
+        * @exception Exception raises exception for message\r
+        */\r
+       private void wrapSQLError(String messageKey)\r
+               throws Exception\r
+       {\r
+               consolePropertyMessage("DRDA_SQLException.S", messageKey);\r
+       }\r
+\r
+       /**\r
+        * Wrap SQL Warning - display to console and raise exception\r
+        *\r
+        * @param messageKey    Derby SQL Exception message id\r
+        *\r
+        * @exception Exception raises exception for message\r
+        */\r
+       private void wrapSQLWarning(String messageKey)\r
+               throws Exception\r
+       {\r
+               consolePropertyMessage("DRDA_SQLWarning.I", messageKey);\r
+       }\r
+       private Properties getPropertyValues()\r
+       {\r
+               Properties retval = new Properties();\r
+               retval.put(Property.DRDA_PROP_PORTNUMBER, new Integer(portNumber).toString());\r
+               retval.put(Property.DRDA_PROP_HOSTNAME, hostArg);\r
+               retval.put(Property.DRDA_PROP_KEEPALIVE, new Boolean(keepAlive).toString());\r
+\r
+               String tracedir = getTraceDirectory();\r
+               if (tracedir != null)\r
+                       retval.put(Property.DRDA_PROP_TRACEDIRECTORY, tracedir);\r
+               retval.put(Property.DRDA_PROP_TRACEALL, new Boolean(getTraceAll()).toString());\r
+               retval.put(Property.DRDA_PROP_MINTHREADS, new Integer(getMinThreads()).toString());\r
+               retval.put(Property.DRDA_PROP_MAXTHREADS, new Integer(getMaxThreads()).toString());\r
+               retval.put(Property.DRDA_PROP_TIMESLICE, new Integer(getTimeSlice()).toString());\r
+\r
+               retval.put(Property.DRDA_PROP_TIMESLICE, new  Integer(getTimeSlice()).toString());\r
+               retval.put(Property.DRDA_PROP_LOGCONNECTIONS, new Boolean(getLogConnections()).toString());\r
+               String startDRDA = PropertyUtil.getSystemProperty(Property.START_DRDA);\r
+               //DERBY-375 If a system property is specified without any value, getProperty returns \r
+               //an empty string. Use default values in such cases.\r
+               if(startDRDA!=null && startDRDA.equals(""))\r
+                       startDRDA = "false";\r
+\r
+               retval.put(Property.START_DRDA, (startDRDA == null)? "false" : startDRDA);\r
+\r
+               // DERBY-2108 SSL\r
+               retval.put(Property.DRDA_PROP_SSL_MODE, getSSLModeString(getSSLMode()));\r
+               \r
+        // if Property.DRDA_PROP_SECURITYMECHANISM has been set on server\r
+        // then put it in retval else the default behavior is as though \r
+        // it is not set\r
+        if ( getSecurityMechanism() != INVALID_OR_NOTSET_SECURITYMECHANISM )\r
+            retval.put( Property.DRDA_PROP_SECURITYMECHANISM, getStringValueForSecMec(getSecurityMechanism()));\r
+        \r
+               //get the trace value for each session if tracing for all is not set\r
+               if (!getTraceAll())\r
+               {\r
+                       synchronized(sessionTable) {\r
+                               for (Enumeration e = sessionTable.elements(); e.hasMoreElements(); )\r
+                               {       \r
+                                       Session session = (Session) e.nextElement();\r
+                                       if (session.isTraceOn())\r
+                                               retval.put(Property.DRDA_PROP_TRACE+"."+session.getConnNum(), "true");\r
+                               }\r
+                       }\r
+               }\r
+               return retval;\r
+       }\r
+\r
+\r
+       /**\r
+        * Add a session - for use by <code>ClientThread</code>. Put the session\r
+        * into the session table and the run queue. Start a new\r
+        * <code>DRDAConnThread</code> if there are more sessions waiting than\r
+        * there are free threads, and the maximum number of threads is not\r
+        * exceeded.\r
+        *\r
+        * <p><code>addSession()</code> should only be called from one thread at a\r
+        * time.\r
+        *\r
+        * @param clientSocket the socket to read from and write to\r
+        */\r
+       void addSession(Socket clientSocket) throws Exception {\r
+\r
+               int connectionNumber = ++connNum;\r
+\r
+               if (getLogConnections()) {\r
+                       consolePropertyMessage("DRDA_ConnNumber.I",\r
+                                                                  Integer.toString(connectionNumber));\r
+               }\r
+\r
+               // Note that we always re-fetch the tracing configuration because it\r
+               // may have changed (there are administrative commands which allow\r
+               // dynamic tracing reconfiguration).\r
+               Session session = new Session(connectionNumber, clientSocket,\r
+                                                                         getTraceDirectory(), getTraceAll());\r
+\r
+               sessionTable.put(new Integer(connectionNumber), session);\r
+\r
+               // Check whether there are enough free threads to service all the\r
+               // threads in the run queue in addition to the newly added session.\r
+               boolean enoughThreads;\r
+               synchronized (runQueue) {\r
+                       enoughThreads = (runQueue.size() < freeThreads);\r
+               }\r
+               // No need to hold the synchronization on runQueue any longer than\r
+               // this. Since no other threads can make runQueue grow, and no other\r
+               // threads will reduce the number of free threads without removing\r
+               // sessions from runQueue, (runQueue.size() < freeThreads) cannot go\r
+               // from true to false until addSession() returns.\r
+\r
+               DRDAConnThread thread = null;\r
+\r
+               // try to start a new thread if we don't have enough free threads\r
+               if (!enoughThreads) {\r
+                       // Synchronize on threadsSync to ensure that the value of\r
+                       // maxThreads doesn't change until the new thread is added to\r
+                       // threadList.\r
+                       synchronized (threadsSync) {\r
+                               // only start a new thread if we have no maximum number of\r
+                               // threads or the maximum number of threads is not exceeded\r
+                               if ((maxThreads == 0) || (threadList.size() < maxThreads)) {\r
+                                       thread = new DRDAConnThread(session, this, getTimeSlice(),\r
+                                                                                               getLogConnections());\r
+                                       threadList.add(thread);\r
+                                       thread.start();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // add the session to the run queue if we didn't start a new thread\r
+               if (thread == null) {\r
+                       runQueueAdd(session);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Remove a thread from the thread list. Should be called when a\r
+        * <code>DRDAConnThread</code> has been closed.\r
+        *\r
+        * @param thread the closed thread\r
+        */\r
+       void removeThread(DRDAConnThread thread) {\r
+               threadList.remove(thread);\r
+       }\r
+       \r
+       protected Object getShutdownSync() { return shutdownSync; } \r
+       protected boolean getShutdown() { return shutdown; } \r
+\r
+\r
+       public String buildRuntimeInfo(LocalizedResource locallangUtil)\r
+       {\r
+               \r
+               String s = locallangUtil.getTextMessage("DRDA_RuntimeInfoBanner.I")+ "\n";\r
+               int sessionCount = 0;\r
+               s += locallangUtil.getTextMessage("DRDA_RuntimeInfoSessionBanner.I") + "\n";\r
+               for (int i = 0; i < threadList.size(); i++)\r
+               {\r
+                       String sessionInfo  = ((DRDAConnThread)\r
+                                                                  threadList.get(i)).buildRuntimeInfo("",locallangUtil) ;\r
+                       if (!sessionInfo.equals(""))\r
+                       {\r
+                               sessionCount ++;\r
+                               s += sessionInfo + "\n";\r
+                       }\r
+               }\r
+               int waitingSessions = 0;\r
+               for (int i = 0; i < runQueue.size(); i++)\r
+               {\r
+                               s += ((Session)runQueue.get(i)).buildRuntimeInfo("", locallangUtil);\r
+                               waitingSessions ++;\r
+               }\r
+               s+= "-------------------------------------------------------------\n";\r
+               s += locallangUtil.getTextMessage("DRDA_RuntimeInfoNumThreads.I") +\r
+                       threadList.size() + "\n";\r
+               s += locallangUtil.getTextMessage("DRDA_RuntimeInfoNumActiveSessions.I") +\r
+                       sessionCount  +"\n";\r
+               s +=locallangUtil.getTextMessage("DRDA_RuntimeInfoNumWaitingSessions.I") +\r
+                       + waitingSessions + "\n\n";\r
+\r
+               Runtime rt = Runtime.getRuntime();\r
+               rt.gc();\r
+               long totalmem = rt.totalMemory();\r
+               long freemem = rt.freeMemory();\r
+               s += locallangUtil.getTextMessage("DRDA_RuntimeInfoTotalMemory.I") +\r
+                       + totalmem + "\t";\r
+               s += locallangUtil.getTextMessage("DRDA_RuntimeInfoFreeMemory.I") +\r
+                       + freemem + "\n\n";\r
+               \r
+               return s;\r
+       }\r
+\r
+\r
+       protected void setClientLocale(String locale)\r
+       {\r
+               clientLocale = locale;\r
+       }\r
+\r
+       /**\r
+        * Retrieve product version information\r
+        * We need to make sure that this method gets the stream and passes it to \r
+        * ProductVersionHolder, because it lives in the Network Server jar\r
+        * and won't be readily available to ProductVersionHolder when running\r
+        * under security manager.\r
+        */\r
+       private ProductVersionHolder getNetProductVersionHolder() throws Exception\r
+       {\r
+               ProductVersionHolder myPVH= null;\r
+               try {\r
+                       myPVH = (ProductVersionHolder) AccessController.doPrivileged(\r
+                                                               new PrivilegedExceptionAction() {\r
+                                                                               \r
+                                                                       public Object run() throws UnknownHostException,IOException\r
+                                                                       {\r
+                                                                               InputStream versionStream = getClass().getResourceAsStream(ProductGenusNames.NET_INFO);\r
+\r
+                                                                               return ProductVersionHolder.getProductVersionHolderFromMyEnv(versionStream);\r
+                                                                       }\r
+                                                                       });\r
+               \r
+}\r
+               catch(PrivilegedActionException e) {\r
+                       Exception e1 = e.getException();\r
+                       consolePropertyMessage("DRDA_ProductVersionReadError.S", e1.getMessage());                      \r
+               }\r
+               return myPVH;\r
+       }\r
+\r
+       /**\r
+        * This method returns a timestamp to be used in the messages. \r
+        * CheapDateFormatter class, which uses GMT, is used to format timestamps. \r
+        * This is to keep the formatting consistent with Derby boot message since\r
+        * network server messages and the boot message get written to derby.log.   \r
+        * \r
+        * @return current timestamp formatted in GMT\r
+        */\r
+       private String getFormattedTimestamp(){\r
+               long currentTime = System.currentTimeMillis();\r
+               return CheapDateFormatter.formatDate(currentTime);\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r