db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject svn commit: r410570 [3/4] - in /db/derby/code/trunk/java: drda/org/apache/derby/impl/drda/ engine/org/apache/derby/iapi/reference/
Date Wed, 31 May 2006 16:07:46 GMT
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=410570&r1=410569&r2=410570&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Wed May 31 09:07:45 2006
@@ -1,19 +1,19 @@
 /*
-  Derby - Class org.apache.derby.impl.drda.DRDAConnThread
+    Derby - Class org.apache.derby.impl.drda.DRDAConnThread
 
-  Copyright 2001, 2004 The Apache Software Foundation or its licensors, as applicable.
+   Copyright 2001, 2004 The Apache Software Foundation or its licensors, as applicable.
 
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+      http://www.apache.org/licenses/LICENSE-2.0
 
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
 
 */
 /**
@@ -63,103 +63,103 @@
 class DRDAConnThread extends Thread {
 
     private static final String leftBrace = "{";
-    private static final String rightBrace = "}";
-    private static final byte NULL_VALUE = (byte)0xff;
-    private static final String SYNTAX_ERR = "42X01";
-
-    // Manager Level 3 constant.
-    private static final int MGRLVL_3 = 0x03;
-
-    // Manager Level 4 constant.
-    private static final int MGRLVL_4 = 0x04;
-
-    // Manager Level 5 constant.
-    private static final int MGRLVL_5 = 0x05;
-
-    // Manager level 6 constant.
-    private static final int MGRLVL_6 = 0x06;
-
-    // Manager Level 7 constant.
-    private static final int MGRLVL_7 = 0x07;
-
-
-    // Commit or rollback UOWDSP values
-    private static final int COMMIT = 1;
-    private static final int ROLLBACK = 2;
-
-
-    protected CcsidManager ccsidManager = new EbcdicCcsidManager();
-    private int correlationID;
-    private InputStream sockis;
-    private OutputStream sockos;
-    private DDMReader reader;
-    private DDMWriter writer;
-    private DRDAXAProtocol xaProto;
-
-    private static int [] ACCRDB_REQUIRED = {CodePoint.RDBACCCL, 
-					     CodePoint.CRRTKN,
-					     CodePoint.PRDID,
-					     CodePoint.TYPDEFNAM,
-					     CodePoint.TYPDEFOVR};
-
-    private static int MAX_REQUIRED_LEN = 5;
-
-    private int currentRequiredLength = 0;
-    private int [] required = new int[MAX_REQUIRED_LEN];
-
-
-    private NetworkServerControlImpl server;			// server who created me
-    private Session	session;	// information about the session
-    private long timeSlice;				// time slice for this thread
-    private Object timeSliceSync = new Object(); // sync object for updating time slice 
-    private boolean logConnections;		// log connections to databases
-
-    private boolean	sendWarningsOnCNTQRY = false;	// Send Warnings for SELECT if true
-    private Object logConnectionsSync = new Object(); // sync object for log connect
-    private boolean close;				// end this thread
-    private Object closeSync = new Object();	// sync object for parent to close us down
-    private static HeaderPrintWriter logStream;
-    private AppRequester appRequester;	// pointer to the application requester
-    // for the session being serviced
-    private Database database; 	// pointer to the current database
-    private int sqlamLevel;		// SQLAM Level - determines protocol
-
-    // manager processing
-    private Vector unknownManagers;
-    private Vector knownManagers;
-    private Vector errorManagers;
-    private Vector errorManagersLevel;
-
-    // database accessed failed
-    private SQLException databaseAccessException;
-
-    // these fields are needed to feed back to jcc about a statement/procedure's PKGNAMCSN
-    /** The value returned by the previous call to
-     * <code>parsePKGNAMCSN()</code>. */
-    private Pkgnamcsn prevPkgnamcsn = null;
-    /** Current RDB Package Name. */
-    private DRDAString rdbnam = new DRDAString(ccsidManager);
-    /** Current RDB Collection Identifier. */
-    private DRDAString rdbcolid = new DRDAString(ccsidManager);
-    /** Current RDB Package Identifier. */
-    private DRDAString pkgid = new DRDAString(ccsidManager);
-    /** Current RDB Package Consistency Token. */
-    private DRDAString pkgcnstkn = new DRDAString(ccsidManager);
-    /** Current RDB Package Section Number. */
-    private int pkgsn;
+	private static final String rightBrace = "}";
+	private static final byte NULL_VALUE = (byte)0xff;
+	private static final String SYNTAX_ERR = "42X01";
+
+	// Manager Level 3 constant.
+	private static final int MGRLVL_3 = 0x03;
+
+	// Manager Level 4 constant.
+	private static final int MGRLVL_4 = 0x04;
+
+	// Manager Level 5 constant.
+	private static final int MGRLVL_5 = 0x05;
+
+	// Manager level 6 constant.
+	private static final int MGRLVL_6 = 0x06;
+
+	// Manager Level 7 constant.
+	private static final int MGRLVL_7 = 0x07;
+
+
+	// Commit or rollback UOWDSP values
+	private static final int COMMIT = 1;
+	private static final int ROLLBACK = 2;
+
+
+	protected CcsidManager ccsidManager = new EbcdicCcsidManager();
+	private int correlationID;
+	private InputStream sockis;
+	private OutputStream sockos;
+	private DDMReader reader;
+	private DDMWriter writer;
+	private DRDAXAProtocol xaProto;
+
+	private static int [] ACCRDB_REQUIRED = {CodePoint.RDBACCCL, 
+											 CodePoint.CRRTKN,
+											 CodePoint.PRDID,
+											 CodePoint.TYPDEFNAM,
+											 CodePoint.TYPDEFOVR};
+
+	private static int MAX_REQUIRED_LEN = 5;
+
+	private int currentRequiredLength = 0;
+	private int [] required = new int[MAX_REQUIRED_LEN];
+
+
+	private NetworkServerControlImpl server;			// server who created me
+	private Session	session;	// information about the session
+	private long timeSlice;				// time slice for this thread
+	private Object timeSliceSync = new Object(); // sync object for updating time slice 
+	private boolean logConnections;		// log connections to databases
+
+	private boolean	sendWarningsOnCNTQRY = false;	// Send Warnings for SELECT if true
+	private Object logConnectionsSync = new Object(); // sync object for log connect
+	private boolean close;				// end this thread
+	private Object closeSync = new Object();	// sync object for parent to close us down
+	private static HeaderPrintWriter logStream;
+	private AppRequester appRequester;	// pointer to the application requester
+										// for the session being serviced
+	private Database database; 	// pointer to the current database
+	private int sqlamLevel;		// SQLAM Level - determines protocol
+
+	// manager processing
+	private Vector unknownManagers;
+	private Vector knownManagers;
+	private Vector errorManagers;
+	private Vector errorManagersLevel;
+
+	// database accessed failed
+	private SQLException databaseAccessException;
+
+	// these fields are needed to feed back to jcc about a statement/procedure's PKGNAMCSN
+	/** The value returned by the previous call to
+	 * <code>parsePKGNAMCSN()</code>. */
+	private Pkgnamcsn prevPkgnamcsn = null;
+	/** Current RDB Package Name. */
+	private DRDAString rdbnam = new DRDAString(ccsidManager);
+	/** Current RDB Collection Identifier. */
+	private DRDAString rdbcolid = new DRDAString(ccsidManager);
+	/** Current RDB Package Identifier. */
+	private DRDAString pkgid = new DRDAString(ccsidManager);
+	/** Current RDB Package Consistency Token. */
+	private DRDAString pkgcnstkn = new DRDAString(ccsidManager);
+	/** Current RDB Package Section Number. */
+	private int pkgsn;
 
     private final static String TIMEOUT_STATEMENT = "SET STATEMENT_TIMEOUT ";
 
     private int pendingStatementTimeout; // < 0 means no pending timeout to set
 
-    // this flag is for an execute statement/procedure which actually returns a result set;
-    // do not commit the statement, otherwise result set is closed
+	// this flag is for an execute statement/procedure which actually returns a result set;
+	// do not commit the statement, otherwise result set is closed
 
-    // for decryption
-    private static DecryptionManager decryptionManager;
-    // public key generated by Deffie-Hellman algorithm, to be passed to the encrypter,
-    // as well as used to initialize the cipher
-    private byte[] myPublicKey;
+	// for decryption
+	private static DecryptionManager decryptionManager;
+	// public key generated by Deffie-Hellman algorithm, to be passed to the encrypter,
+	// as well as used to initialize the cipher
+	private byte[] myPublicKey;
 
     // Some byte[] constants that are frequently written into messages. It is more efficient to 
     // use these constants than to convert from a String each time 
@@ -170,375 +170,411 @@
     private static final byte[] errD4_D6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 12x0 
     private static final byte[] warn0_warnA = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };  // 11x ' '
 
-    // constructor
-    /**
-     * Create a new Thread for processing session requests
-     *
-     * @param session Session requesting processing
-     * @param server  Server starting thread
-     * @param timeSlice timeSlice for thread
-     * @param logConnections
-     **/
-
-    DRDAConnThread(Session session, NetworkServerControlImpl server, 
-		   long timeSlice,
-		   boolean logConnections) {
+	// constructor
+	/**
+	 * Create a new Thread for processing session requests
+	 *
+	 * @param session Session requesting processing
+	 * @param server  Server starting thread
+	 * @param timeSlice timeSlice for thread
+	 * @param logConnections
+	 **/
+
+	DRDAConnThread(Session session, NetworkServerControlImpl server, 
+						  long timeSlice,
+						  boolean logConnections) {
 	
    	super();
 
-	// Create a more meaningful name for this thread (but preserve its
-	// thread id from the default name).
-	NetworkServerControlImpl.setUniqueThreadName(this, "DRDAConnThread");
-
-	this.session = session;
-	this.server = server;
-	this.timeSlice = timeSlice;
-	this.logConnections = logConnections;
+		// Create a more meaningful name for this thread (but preserve its
+		// thread id from the default name).
+		NetworkServerControlImpl.setUniqueThreadName(this, "DRDAConnThread");
+
+		this.session = session;
+		this.server = server;
+		this.timeSlice = timeSlice;
+		this.logConnections = logConnections;
         this.pendingStatementTimeout = -1;
-	initialize();
+		initialize();
     }
 
-    /**
-     * Main routine for thread, loops until the thread is closed
-     * Gets a session, does work for the session
-     */
+	/**
+	 * Main routine for thread, loops until the thread is closed
+	 * Gets a session, does work for the session
+	 */
     public void run() {
-	if (SanityManager.DEBUG)
-	    trace("Starting new connection thread");
+		if (SanityManager.DEBUG)
+			trace("Starting new connection thread");
 
-	Session prevSession;
-	while(!closed()) {
+		Session prevSession;
+		while(!closed())
+		{
+
+			// get a new session
+			prevSession = session;
+			session = server.getNextSession(session);
+			if (session == null)
+				close();
+
+			if (closed())
+				break;
+			if (session != prevSession)
+			{
+				initializeForSession();
+			}
+			try {
+				long timeStart = System.currentTimeMillis();
 
-	    // get a new session
-	    prevSession = session;
-	    session = server.getNextSession(session);
-	    if (session == null)
-		close();
-
-	    if (closed())
-		break;
-	    if (session != prevSession) {
-		initializeForSession();
-	    }
-	    try {
-		long timeStart = System.currentTimeMillis();
-
-		switch (session.state) {
-		case Session.INIT:
-		    sessionInitialState();
-		    if (session == null)
-			break;
-		case Session.ATTEXC:
-		    long currentTimeSlice;
-
-		    do {
-			processCommands();
-			currentTimeSlice = getTimeSlice();
-		    } while ((currentTimeSlice == 0)  || 
-			     (System.currentTimeMillis() - timeStart < currentTimeSlice));
-
-		    break;
-		default:
-		    // this is an error
-		    agentError("Session in invalid state:" + session.state);
-		}
-	    } catch (Exception e) {
-		if (e instanceof DRDAProtocolException && 
-		    ((DRDAProtocolException)e).isDisconnectException()) {
-		    // client went away - this is O.K. here
-		    closeSession();
-		} else {
-		    handleException(e);
-		}
-	    }
-	}
-	if (SanityManager.DEBUG)
-	    trace("Ending connection thread");
-	server.getThreadList().removeElement(this);
+				switch (session.state)
+				{
+					case Session.INIT:
+						sessionInitialState();
+						if (session == null)
+							break;
+					case Session.ATTEXC:
+						long currentTimeSlice;
+
+						do {
+							processCommands();
+							currentTimeSlice = getTimeSlice();
+						} while ((currentTimeSlice == 0)  || 
+							(System.currentTimeMillis() - timeStart < currentTimeSlice));
+
+						break;
+					default:
+						// this is an error
+						agentError("Session in invalid state:" + session.state);
+				}
+			} catch (Exception e) {
+				if (e instanceof DRDAProtocolException && 
+						((DRDAProtocolException)e).isDisconnectException())
+				{
+				 	// client went away - this is O.K. here
+					closeSession();
+				}
+				else
+				{
+					handleException(e);
+				}
+			}
+		}
+		if (SanityManager.DEBUG)
+			trace("Ending connection thread");
+		server.getThreadList().removeElement(this);
 
-    }
-    /**
-     * Get input stream
-     *
-     * @return input stream
-     */
-    protected InputStream getInputStream() {
-	return sockis;
-    }
+	}
+	/**
+	 * Get input stream
+	 *
+	 * @return input stream
+	 */
+	protected InputStream getInputStream()
+	{
+		return sockis;
+	}
 
-    /**
-     * Get output stream
-     *
-     * @return output stream
-     */
-    protected OutputStream getOutputStream() {
-	return sockos;
-    }
+	/**
+	 * Get output stream
+	 *
+	 * @return output stream
+	 */
+	protected OutputStream getOutputStream()
+	{
+		return sockos;
+	}
 
-    /**
-     *  get DDMReader
-     * @return DDMReader for this thread
-     */
-    protected DDMReader getReader() {
-	return reader;
-    }
+	/**
+	 *  get DDMReader
+	 * @return DDMReader for this thread
+	 */
+	protected DDMReader getReader()
+	{
+		return reader;
+	}
 	
-    /** 
-     * get  DDMWriter 
-     * @return DDMWriter for this thread
-     */
-    protected DDMWriter getWriter() {
-	return writer;
-    }
+	/** 
+	 * get  DDMWriter 
+	 * @return DDMWriter for this thread
+	 */
+	protected DDMWriter getWriter()
+	{
+		return writer;
+	}
 
-    /**
-     * Get correlation id
-     *
-     * @return correlation id
-     */
-    protected int getCorrelationID () {
-	return correlationID;
-    }
+	/**
+	 * Get correlation id
+	 *
+	 * @return correlation id
+	 */
+	protected int getCorrelationID ()
+	{
+		return correlationID;
+	}
 
-    /**
-     * Get session we are working on
-     *
-     * @return session
-     */
-    protected Session getSession() {
-	return session;
-    }
+	/**
+	 * Get session we are working on
+	 *
+	 * @return session
+	 */
+	protected Session getSession()
+	{
+		return session;
+	}
 
-    /**
-     * Get Database we are working on
-     *
-     * @return database
-     */
-    protected Database getDatabase() {
-	return database;
-    }
-    /**
-     * Get server
-     *
-     * @return server
-     */
-    protected NetworkServerControlImpl getServer() {
-	return server;
-    }
-    /**
-     * Get correlation token
-     *
-     * @return crrtkn
-     */
-    protected byte[] getCrrtkn() {
-	if (database != null)
-	    return database.crrtkn;
-	return null;
-    }
-    /**
-     * Get database name
-     *
-     * @return database name
-     */
-    protected String getDbName() {
-	if (database != null)
-	    return database.dbName;
-	return null;
-    }
-    /**
-     * Close DRDA  connection thread
-     */
-    protected void close() {
-	synchronized (closeSync) {
-	    close = true;
+	/**
+	 * Get Database we are working on
+	 *
+	 * @return database
+	 */
+	protected Database getDatabase()
+	{
+		return database;
+	}
+	/**
+	 * Get server
+	 *
+	 * @return server
+	 */
+	protected NetworkServerControlImpl getServer()
+	{
+		return server;
+	}
+	/**
+	 * Get correlation token
+	 *
+	 * @return crrtkn
+	 */
+	protected byte[] getCrrtkn()
+	{
+		if (database != null)
+			return database.crrtkn;
+		return null;
+	}
+	/**
+	 * Get database name
+	 *
+	 * @return database name
+	 */
+	protected String getDbName()
+	{
+		if (database != null)
+			return database.dbName;
+		return null;
+	}
+	/**
+	 * Close DRDA  connection thread
+	 */
+	protected void close()
+	{
+		synchronized (closeSync)
+		{
+			close = true;
+		}
 	}
-    }
 
-    /**
-     * Set logging of connections
-     * 
-     * @param value value to set for logging connections
-     */
-    protected void setLogConnections(boolean value) {
-	synchronized(logConnectionsSync) {
-	    logConnections = value;
+	/**
+	 * Set logging of connections
+	 * 
+	 * @param value value to set for logging connections
+	 */
+	protected void setLogConnections(boolean value)
+	{
+		synchronized(logConnectionsSync) {
+			logConnections = value;
+		}
 	}
-    }
-    /**
-     * Set time slice value
-     *
-     * @param value new value for time slice
-     */
-    protected void setTimeSlice(long value) {
-	synchronized(timeSliceSync) {
-	    timeSlice = value;
+	/**
+	 * Set time slice value
+	 *
+	 * @param value new value for time slice
+	 */
+	protected void setTimeSlice(long value)
+	{
+		synchronized(timeSliceSync) {
+			timeSlice = value;
+		}
 	}
-    }
-    /**
-     * Indicate a communications failure
-     * 
-     * @param arg1 - info about the communications failure
-     * @param arg2 - info about the communications failure
-     * @param arg3 - info about the communications failure
-     * @param arg4 - info about the communications failure
-     *
-     * @exception DRDAProtocolException  disconnect exception always thrown
-     */
-    protected void markCommunicationsFailure(String arg1, String arg2, String arg3,
-					     String arg4) throws DRDAProtocolException {
-	Object[] oa = {arg1,arg2,arg3,arg4};
-	throw DRDAProtocolException.newDisconnectException(this,oa);
+	/**
+	 * Indicate a communications failure
+	 * 
+	 * @param arg1 - info about the communications failure
+	 * @param arg2 - info about the communications failure
+	 * @param arg3 - info about the communications failure
+	 * @param arg4 - info about the communications failure
+	 *
+	 * @exception DRDAProtocolException  disconnect exception always thrown
+	 */
+	protected void markCommunicationsFailure(String arg1, String arg2, String arg3,
+		String arg4) throws DRDAProtocolException
+	{
+		Object[] oa = {arg1,arg2,arg3,arg4};
+		throw DRDAProtocolException.newDisconnectException(this,oa);
 
-    }
-    /**
-     * Syntax error
-     *
-     * @param errcd		Error code
-     * @param cpArg  code point value
-     * @exception DRDAProtocolException
-     */
+	}
+	/**
+	 * Syntax error
+	 *
+	 * @param errcd		Error code
+	 * @param cpArg  code point value
+	 * @exception DRDAProtocolException
+	 */
 
-    protected  void throwSyntaxrm(int errcd, int cpArg)
-	throws DRDAProtocolException {
-	throw new
-	    DRDAProtocolException(DRDAProtocolException.DRDA_Proto_SYNTAXRM,
-				  this,
-				  cpArg,
-				  errcd);
-    }
-    /**
-     * Agent error - something very bad happened
-     *
-     * @param msg	Message describing error
-     *
-     * @exception DRDAProtocolException  newAgentError always thrown
-     */
-    protected void agentError(String msg) throws DRDAProtocolException {
+	protected  void throwSyntaxrm(int errcd, int cpArg)
+		throws DRDAProtocolException
+	{
+		throw new
+			DRDAProtocolException(DRDAProtocolException.DRDA_Proto_SYNTAXRM,
+								  this,
+								  cpArg,
+								  errcd);
+	}
+	/**
+	 * Agent error - something very bad happened
+	 *
+	 * @param msg	Message describing error
+	 *
+	 * @exception DRDAProtocolException  newAgentError always thrown
+	 */
+	protected void agentError(String msg) throws DRDAProtocolException
+	{
 
-	String dbname = null;
-	if (database != null)
-	    dbname = database.dbName;
-	throw DRDAProtocolException.newAgentError(this, CodePoint.SVRCOD_PRMDMG, 
-						  dbname, msg);
-    }
-    /**
-     * Missing code point
-     *
-     * @param codePoint  code point value
-     * @exception DRDAProtocolException
-     */
-    protected void missingCodePoint(int codePoint) throws DRDAProtocolException {
-	throwSyntaxrm(CodePoint.SYNERRCD_REQ_OBJ_NOT_FOUND, codePoint);
-    }
-    /**
-     * Print a line to the DB2j log
-     *
-     * @param dbname  database name
-     * @param drdaID	DRDA identifier
-     * @param msg	message
-     */
-    protected static void println2Log(String dbname, String drdaID, String msg) {
-	if (logStream == null)
-	    logStream = Monitor.getStream();
-
-	if (dbname != null) {
-	    int endOfName = dbname.indexOf(';');
-	    if (endOfName != -1)
-		dbname = dbname.substring(0, endOfName);
+		String dbname = null;
+		if (database != null)
+			dbname = database.dbName;
+		throw DRDAProtocolException.newAgentError(this, CodePoint.SVRCOD_PRMDMG, 
+			dbname, msg);
 	}
-	logStream.printlnWithHeader("(DATABASE = " + dbname + "), (DRDAID = " + drdaID + "), " + msg);
-    }
-    /**
-     * Write RDBNAM
-     *
-     * @param rdbnam 	database name
-     * @exception DRDAProtocolException
-     */
-    protected void writeRDBNAM(String rdbnam)
-	throws DRDAProtocolException {
-	int len = rdbnam.length();
-	if (len < CodePoint.RDBNAM_LEN)
-	    len = CodePoint.RDBNAM_LEN;
-	writer.writeScalarHeader(CodePoint.RDBNAM, len);
-	try {
-	    writer.writeScalarPaddedBytes(rdbnam.getBytes(server.DEFAULT_ENCODING),
-					  len, server.SPACE_CHAR);
-	} catch (UnsupportedEncodingException e) {
-	    agentError("Unsupported coding exception for server encoding "
-		       + server.DEFAULT_ENCODING);
+	/**
+	 * Missing code point
+	 *
+	 * @param codePoint  code point value
+	 * @exception DRDAProtocolException
+	 */
+	protected void missingCodePoint(int codePoint) throws DRDAProtocolException
+	{
+		throwSyntaxrm(CodePoint.SYNERRCD_REQ_OBJ_NOT_FOUND, codePoint);
 	}
-    }
-    /***************************************************************************
-     *                   Private methods
-     ***************************************************************************/
+	/**
+	 * Print a line to the DB2j log
+	 *
+	 * @param dbname  database name
+	 * @param drdaID	DRDA identifier
+	 * @param msg	message
+	 */
+	protected static void println2Log(String dbname, String drdaID, String msg)
+	{
+		if (logStream == null)
+			logStream = Monitor.getStream();
+
+		if (dbname != null)
+		{
+			int endOfName = dbname.indexOf(';');
+			if (endOfName != -1)
+				dbname = dbname.substring(0, endOfName);
+		}
+		logStream.printlnWithHeader("(DATABASE = " + dbname + "), (DRDAID = " + drdaID + "), " + msg);
+	}
+	/**
+	 * Write RDBNAM
+	 *
+	 * @param rdbnam 	database name
+	 * @exception DRDAProtocolException
+	 */
+	protected void writeRDBNAM(String rdbnam)
+		throws DRDAProtocolException
+	{
+		int len = rdbnam.length();
+		if (len < CodePoint.RDBNAM_LEN)
+			len = CodePoint.RDBNAM_LEN;
+		writer.writeScalarHeader(CodePoint.RDBNAM, len);
+		try {
+			writer.writeScalarPaddedBytes(rdbnam.getBytes(server.DEFAULT_ENCODING),
+				len, server.SPACE_CHAR);
+		}
+		catch (UnsupportedEncodingException e)
+		{
+			agentError("Unsupported coding exception for server encoding "
+				+ server.DEFAULT_ENCODING);
+		}
+	}
+	/***************************************************************************
+	 *                   Private methods
+	 ***************************************************************************/
 
-    /**
-     * Initialize class
-     */
-    private void initialize() {
-	// set input and output sockets
-	// this needs to be done before creating reader
-	sockis = session.sessionInput;
-	sockos = session.sessionOutput;
+	/**
+	 * Initialize class
+	 */
+	private void initialize()
+	{
+		// set input and output sockets
+		// this needs to be done before creating reader
+		sockis = session.sessionInput;
+		sockos = session.sessionOutput;
 
-	reader = new DDMReader(this, session.dssTrace);
-	writer = new DDMWriter(ccsidManager, this, session.dssTrace);
-    }
+		reader = new DDMReader(this, session.dssTrace);
+		writer = new DDMWriter(ccsidManager, this, session.dssTrace);
+	}
 
-    /**
-     * Initialize for a new session
-     */
-    private void initializeForSession() {
-	// set input and output sockets
-	sockis = session.sessionInput;
-	sockos = session.sessionOutput;
-
-	// intialize reader and writer
-	reader.initialize(this, session.dssTrace);
-	writer.reset(session.dssTrace);
-
-	// initialize local pointers to session info
-	database = session.database;
-	appRequester = session.appRequester;
-
-	// set sqlamLevel
-	if (session.state == Session.ATTEXC)
-	    sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM);
+	/**
+	 * Initialize for a new session
+	 */
+	private void initializeForSession()
+	{
+		// set input and output sockets
+		sockis = session.sessionInput;
+		sockos = session.sessionOutput;
+
+		// intialize reader and writer
+		reader.initialize(this, session.dssTrace);
+		writer.reset(session.dssTrace);
+
+		// initialize local pointers to session info
+		database = session.database;
+		appRequester = session.appRequester;
+
+		// set sqlamLevel
+		if (session.state == Session.ATTEXC)
+			sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM);
+
+	}
+	/**      
+	 * In initial state for a session, 
+	 * determine whether this is a command
+	 * session or a DRDA protocol session.  A command session is for changing
+	 * the configuration of the Net server, e.g., turning tracing on
+	 * If it is a command session, process the command and close the session.
+	 * If it is a DRDA session, exchange server attributes and change session
+	 * state.
+	 */
+	private void sessionInitialState()
+		throws Exception
+	{
+		// process NetworkServerControl commands - if it is not either valid protocol  let the 
+		// DRDA error handling handle it
+		if (reader.isCmd())
+		{
+			try {
+				server.processCommands(reader, writer, session);
+				// reset reader and writer
+				reader.initialize(this, null);
+				writer.reset(null);
+				closeSession();
+			} catch (Throwable t) {
+				if (t instanceof InterruptedException)
+					throw (InterruptedException)t;
+				else
+				{
+					server.consoleExceptionPrintTrace(t);
+				}
+			}
 
-    }
-    /**      
-     * In initial state for a session, 
-     * determine whether this is a command
-     * session or a DRDA protocol session.  A command session is for changing
-     * the configuration of the Net server, e.g., turning tracing on
-     * If it is a command session, process the command and close the session.
-     * If it is a DRDA session, exchange server attributes and change session
-     * state.
-     */
-    private void sessionInitialState()
-	throws Exception {
-	// process NetworkServerControl commands - if it is not either valid protocol  let the 
-	// DRDA error handling handle it
-	if (reader.isCmd()) {
-	    try {
-		server.processCommands(reader, writer, session);
-		// reset reader and writer
-		reader.initialize(this, null);
-		writer.reset(null);
-		closeSession();
-	    } catch (Throwable t) {
-		if (t instanceof InterruptedException)
-		    throw (InterruptedException)t;
-		else {
-		    server.consoleExceptionPrintTrace(t);
 		}
-	    }
-
-	} else {
-	    // exchange attributes with application requester
-	    exchangeServerAttributes();
+		else
+		{
+			// exchange attributes with application requester
+			exchangeServerAttributes();
+		}
 	}
-    }
 
     /**
      * Cleans up and closes a result set if an exception is thrown
@@ -554,7 +590,8 @@
     private void cleanUpAndCloseResultSet(DRDAStatement stmt,
                                           SQLException sqle,
                                           int writerMark)
-        throws DRDAProtocolException {
+        throws DRDAProtocolException
+    {
         if (stmt != null) {
             writer.clearDSSesBackToMark(writerMark);
             if (!stmt.rsIsClosed()) {
@@ -574,815 +611,879 @@
         errorInChain(sqle);
     }
 
-    /**
-     * Process DRDA commands we can receive once server attributes have been
-     * exchanged.
-     *
-     * @exception DRDAProtocolException
-     */
-    private void processCommands() throws DRDAProtocolException {
-	DRDAStatement stmt = null;
-	int updateCount = 0;
-	boolean PRPSQLSTTfailed = false;
-	boolean checkSecurityCodepoint = session.requiresSecurityCodepoint();
-	do {
-	    correlationID = reader.readDssHeader();
-	    int codePoint = reader.readLengthAndCodePoint();
-	    int writerMark = writer.markDSSClearPoint();
+	/**
+	 * Process DRDA commands we can receive once server attributes have been
+	 * exchanged.
+	 *
+	 * @exception DRDAProtocolException
+	 */
+	private void processCommands() throws DRDAProtocolException
+	{
+		DRDAStatement stmt = null;
+		int updateCount = 0;
+		boolean PRPSQLSTTfailed = false;
+		boolean checkSecurityCodepoint = session.requiresSecurityCodepoint();
+		do
+		{
+			correlationID = reader.readDssHeader();
+			int codePoint = reader.readLengthAndCodePoint();
+			int writerMark = writer.markDSSClearPoint();
 			
-	    if (checkSecurityCodepoint)
-		verifyInOrderACCSEC_SECCHK(codePoint,session.getRequiredSecurityCodepoint());
-
-	    switch(codePoint) {
-	    case CodePoint.CNTQRY:
-		try{
-		    stmt = parseCNTQRY();
-		    if (stmt != null) {
-			writeQRYDTA(stmt);
-			if (stmt.rsIsClosed()) {
-			    writeENDQRYRM(CodePoint.SVRCOD_WARNING);
-			    writeNullSQLCARDobject();
-			}
-			// Send any warnings if JCC can handle them
-			checkWarning(null, null, stmt.getResultSet(), 0, false, sendWarningsOnCNTQRY);
-		    }
-		}
-		catch(SQLException e) {
-		    // if we got a SQLException we need to clean up and
-		    // close the result set Beetle 4758
-		    cleanUpAndCloseResultSet(stmt, e, writerMark);
-		}
-		break;
-	    case CodePoint.EXCSQLIMM:
-		try {
-		    updateCount = parseEXCSQLIMM();
-		    // RESOLVE: checking updateCount is not sufficient
-		    // since it will be 0 for creates, we need to know when
-		    // any logged changes are made to the database
-		    // Not getting this right for JCC is probably O.K., this
-		    // will probably be a problem for ODBC and XA
-		    // The problem is that JDBC doesn't provide this information
-		    // so we would have to expand the JDBC API or call a
-		    // builtin method to check(expensive)
-		    // For now we will assume that every execute immediate
-		    // does an update (that is the most conservative thing)
-		    if (database.RDBUPDRM_sent == false) {
-			writeRDBUPDRM();
-		    }
-
-		    // we need to set update count in SQLCARD
-		    checkWarning(null, database.getDefaultStatement().getStatement(),
-				 null, updateCount, true, true);
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
-		}
-		break;
+			if (checkSecurityCodepoint)
+				verifyInOrderACCSEC_SECCHK(codePoint,session.getRequiredSecurityCodepoint());
 
-	    case CodePoint.EXCSQLSET:
-		try {
-		    if (parseEXCSQLSET())
-			// all went well.
-			writeSQLCARDs(null,0);
-		} catch (SQLWarning w) {
-		    writeSQLCARD(w, CodePoint.SVRCOD_WARNING, 0, 0);
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
-		}
-		break;
+			switch(codePoint)
+			{
+				case CodePoint.CNTQRY:
+					try{
+						stmt = parseCNTQRY();
+						if (stmt != null)
+						{
+							writeQRYDTA(stmt);
+							if (stmt.rsIsClosed())
+							{
+								writeENDQRYRM(CodePoint.SVRCOD_WARNING);
+								writeNullSQLCARDobject();
+							}
+							// Send any warnings if JCC can handle them
+							checkWarning(null, null, stmt.getResultSet(), 0, false, sendWarningsOnCNTQRY);
+						}
+					}
+					catch(SQLException e)
+					{
+						// if we got a SQLException we need to clean up and
+						// close the result set Beetle 4758
+						cleanUpAndCloseResultSet(stmt, e, writerMark);
+					}
+					break;
+				case CodePoint.EXCSQLIMM:
+					try {
+						updateCount = parseEXCSQLIMM();
+						// RESOLVE: checking updateCount is not sufficient
+						// since it will be 0 for creates, we need to know when
+						// any logged changes are made to the database
+						// Not getting this right for JCC is probably O.K., this
+						// will probably be a problem for ODBC and XA
+						// The problem is that JDBC doesn't provide this information
+						// so we would have to expand the JDBC API or call a
+						// builtin method to check(expensive)
+						// For now we will assume that every execute immediate
+						// does an update (that is the most conservative thing)
+						if (database.RDBUPDRM_sent == false)
+						{
+							writeRDBUPDRM();
+						}
+
+						// we need to set update count in SQLCARD
+						checkWarning(null, database.getDefaultStatement().getStatement(),
+							null, updateCount, true, true);
+					} catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
+
+				case CodePoint.EXCSQLSET:
+					try {
+						if (parseEXCSQLSET())
+						// all went well.
+							writeSQLCARDs(null,0);
+					}
+					catch (SQLWarning w)
+					{
+						writeSQLCARD(w, CodePoint.SVRCOD_WARNING, 0, 0);
+					}
+					catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
 					
-	    case CodePoint.PRPSQLSTT:
-		int sqldaType;
-		PRPSQLSTTfailed = false;
-		try {
-		    database.getConnection().clearWarnings();
-		    sqldaType = parsePRPSQLSTT();
-		    if (sqldaType > 0)		// do write SQLDARD
-			writeSQLDARD(database.getCurrentStatement(),
-				     (sqldaType ==  CodePoint.TYPSQLDA_LIGHT_OUTPUT),
-				     database.getConnection().getWarnings());
-		    else
-			checkWarning(database.getConnection(), null, null, 0, true, true);
-
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    writeSQLCARDs(e, 0, true);
-		    PRPSQLSTTfailed = true;
-		    errorInChain(e);
-		}
-		break;
-	    case CodePoint.OPNQRY:
-		PreparedStatement ps = null;
-		try {
-		    if (PRPSQLSTTfailed) {
-			// read the command objects
-			// for ps with parameter
-			// Skip objects/parameters
-			skipRemainder(true);
-
-			// If we failed to prepare, then we fail
-			// to open, which  means OPNQFLRM.
-			writeOPNQFLRM(null);
-			break;
-		    }
-		    Pkgnamcsn pkgnamcsn = parseOPNQRY();
-		    if (pkgnamcsn != null) {
-			stmt = database.getDRDAStatement(pkgnamcsn);
-			ps = stmt.getPreparedStatement();
-			ps.clearWarnings();
-			if (pendingStatementTimeout >= 0) {
-			    ps.setQueryTimeout(pendingStatementTimeout);
-			    pendingStatementTimeout = -1;
-			}
-			stmt.execute();
-			writeOPNQRYRM(false, stmt);
-			checkWarning(null, ps, null, 0, false, true);
+				case CodePoint.PRPSQLSTT:
+					int sqldaType;
+					PRPSQLSTTfailed = false;
+					try {
+						database.getConnection().clearWarnings();
+						sqldaType = parsePRPSQLSTT();
+						if (sqldaType > 0)		// do write SQLDARD
+							writeSQLDARD(database.getCurrentStatement(),
+										 (sqldaType ==  CodePoint.TYPSQLDA_LIGHT_OUTPUT),
+										 database.getConnection().getWarnings());
+						else
+							checkWarning(database.getConnection(), null, null, 0, true, true);
+
+					} catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						writeSQLCARDs(e, 0, true);
+						PRPSQLSTTfailed = true;
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.OPNQRY:
+					PreparedStatement ps = null;
+					try {
+						if (PRPSQLSTTfailed) {
+							// read the command objects
+							// for ps with parameter
+							// Skip objects/parameters
+							skipRemainder(true);
+
+							// If we failed to prepare, then we fail
+							// to open, which  means OPNQFLRM.
+							writeOPNQFLRM(null);
+							break;
+						}
+						Pkgnamcsn pkgnamcsn = parseOPNQRY();
+						if (pkgnamcsn != null)
+						{
+							stmt = database.getDRDAStatement(pkgnamcsn);
+							ps = stmt.getPreparedStatement();
+							ps.clearWarnings();
+                            if (pendingStatementTimeout >= 0) {
+                                ps.setQueryTimeout(pendingStatementTimeout);
+                                pendingStatementTimeout = -1;
+                            }
+							stmt.execute();
+							writeOPNQRYRM(false, stmt);
+							checkWarning(null, ps, null, 0, false, true);
+
+							writeQRYDSC(stmt, false);
+
+							stmt.rsSuspend();
+
+							if (stmt.getQryprctyp() == CodePoint.LMTBLKPRC) {
+								// The DRDA spec allows us to send
+								// QRYDTA here if there are no LOB
+								// columns.
+								DRDAResultSet drdars =
+									stmt.getCurrentDrdaResultSet();
+								try {
+									if (drdars != null &&
+										!drdars.hasLobColumns()) {
+										writeQRYDTA(stmt);
+									}
+								} catch (SQLException sqle) {
+									cleanUpAndCloseResultSet(stmt, sqle,
+															 writerMark);
+								}
+							}
+						}
+					}
+					catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						// The fix for DERBY-1196 removed code 
+						// here to close the prepared statement 
+						// if OPNQRY failed.
+							writeOPNQFLRM(e);
+					}
+					break;
+				case CodePoint.RDBCMM:
+					try
+					{
+						if (SanityManager.DEBUG)
+							trace("Received commit");
+						if (!database.getConnection().getAutoCommit())
+						{
+							database.getConnection().clearWarnings();
+							database.commit();
+							writeENDUOWRM(COMMIT);
+							checkWarning(database.getConnection(), null, null, 0, true, true);
+						}
+						// we only want to write one of these per transaction
+						// so set to false in preparation for next command
+						database.RDBUPDRM_sent = false;
+					}
+					catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						// Even in case of error, we have to write the ENDUOWRM.
+						writeENDUOWRM(COMMIT);
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.RDBRLLBCK:
+					try
+					{
+						if (SanityManager.DEBUG)
+							trace("Received rollback");
+						database.getConnection().clearWarnings();
+						database.rollback();
+						writeENDUOWRM(ROLLBACK);
+						checkWarning(database.getConnection(), null, null, 0, true, true);
+						// we only want to write one of these per transaction
+						// so set to false in preparation for next command
+						database.RDBUPDRM_sent = false;
+					}
+					catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						// Even in case of error, we have to write the ENDUOWRM.
+						writeENDUOWRM(ROLLBACK);
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.CLSQRY:
+					try{
+						stmt = parseCLSQRY();
+						stmt.rsClose();
+						writeSQLCARDs(null, 0);
+					}
+					catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.EXCSAT:
+					parseEXCSAT();
+					writeEXCSATRD();
+					break;
+				case CodePoint.ACCSEC:
+					int securityCheckCode = parseACCSEC();
+					writeACCSECRD(securityCheckCode); 
+					checkSecurityCodepoint = true;
+					break;
+				case CodePoint.SECCHK:
+					if(parseDRDAConnection())
+						// security all checked and connection ok
+						checkSecurityCodepoint = false;
+					break;
+				/* since we don't support sqlj, we won't get bind commands from jcc, we
+				 * might get it from ccc; just skip them.
+				 */
+				case CodePoint.BGNBND:
+					reader.skipBytes();
+					writeSQLCARDs(null, 0);
+					break;
+				case CodePoint.BNDSQLSTT:
+					reader.skipBytes();
+					parseSQLSTTDss();
+					writeSQLCARDs(null, 0);
+					break;
+				case CodePoint.SQLSTTVRB:
+					// optional
+					reader.skipBytes();
+					break;
+				case CodePoint.ENDBND:
+					reader.skipBytes();
+					writeSQLCARDs(null, 0);
+					break;
+				case CodePoint.DSCSQLSTT:
+					if (PRPSQLSTTfailed) {
+						reader.skipBytes();
+						writeSQLCARDs(null, 0);
+						break;
+					}
+					try {
+						boolean rtnOutput = parseDSCSQLSTT();
+						writeSQLDARD(database.getCurrentStatement(), rtnOutput,
+									 null);
+						
+					} catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						server.consoleExceptionPrint(e);
+						try {
+							writeSQLDARD(database.getCurrentStatement(), true, e);
+						} catch (SQLException e2) {	// should not get here since doing nothing with ps
+							agentError("Why am I getting another SQLException?");
+						}
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.EXCSQLSTT:
+					if (PRPSQLSTTfailed) {
+						// Skip parameters too if they are chained Beetle 4867
+						skipRemainder(true);
+						writeSQLCARDs(null, 0);
+						break;
+					}
+					try {
+						parseEXCSQLSTT();
+
+						DRDAStatement curStmt = database.getCurrentStatement();
+						if (curStmt != null)
+							curStmt.rsSuspend();
+					} catch (SQLException e)
+					{
+						writer.clearDSSesBackToMark(writerMark);
+						if (SanityManager.DEBUG) 
+						{
+							server.consoleExceptionPrint(e);
+						}
+						writeSQLCARDs(e, 0);
+						errorInChain(e);
+					}
+					break;
+				case CodePoint.SYNCCTL:
+					if (xaProto == null)
+						xaProto = new DRDAXAProtocol(this);
+					xaProto.parseSYNCCTL();
+					break;
+				default:
+					codePointNotSupported(codePoint);
+			}
 
-			writeQRYDSC(stmt, false);
+			// Set the correct chaining bits for whatever
+			// reply DSS(es) we just wrote.  If we've reached
+			// the end of the chain, this method will send
+			// the DSS(es) across.
+			finalizeChain();
 
-			stmt.rsSuspend();
+		}
+		while (reader.isChainedWithSameID() || reader.isChainedWithDiffID());
+	}
 
-			if (stmt.getQryprctyp() == CodePoint.LMTBLKPRC) {
-			    // The DRDA spec allows us to send
-			    // QRYDTA here if there are no LOB
-			    // columns.
-			    DRDAResultSet drdars =
-				stmt.getCurrentDrdaResultSet();
-			    try {
-				if (drdars != null &&
-				    !drdars.hasLobColumns()) {
-				    writeQRYDTA(stmt);
-				}
-			    } catch (SQLException sqle) {
-				cleanUpAndCloseResultSet(stmt, sqle,
-							 writerMark);
-			    }
-			}
-		    }
-		}
-		catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    // The fix for DERBY-1196 removed code 
-		    // here to close the prepared statement 
-		    // if OPNQRY failed.
-		    writeOPNQFLRM(e);
+	/**
+	 * If there's a severe error in the DDM chain, and if the header indicates
+	 * "terminate chain on error", we stop processing further commands in the chain
+	 * nor do we send any reply for them.  In accordance to this, a SQLERRRM message 
+	 * indicating the severe error must have been sent! (otherwise application requestor,
+	 * such as JCC, would not terminate the receiving of chain replies.)
+	 *
+	 * Each DRDA command is processed independently. DRDA defines no interdependencies
+	 * across chained commands. A command is processed the same when received within
+	 * a set of chained commands or received separately.  The chaining was originally
+	 * defined as a way to save network costs.
+	 *
+ 	 * @param e		the SQLException raised
+	 * @exception	DRDAProtocolException
+	 */
+	private void errorInChain(SQLException e) throws DRDAProtocolException
+	{
+		if (reader.terminateChainOnErr() && (getExceptionSeverity(e) > CodePoint.SVRCOD_ERROR))
+		{
+			if (SanityManager.DEBUG)  trace("terminating the chain on error...");
+			skipRemainder(false);
 		}
-		break;
-	    case CodePoint.RDBCMM:
-		try {
-		    if (SanityManager.DEBUG)
-			trace("Received commit");
-		    if (!database.getConnection().getAutoCommit()) {
-			database.getConnection().clearWarnings();
-			database.commit();
-			writeENDUOWRM(COMMIT);
-			checkWarning(database.getConnection(), null, null, 0, true, true);
-		    }
-		    // we only want to write one of these per transaction
-		    // so set to false in preparation for next command
-		    database.RDBUPDRM_sent = false;
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    // Even in case of error, we have to write the ENDUOWRM.
-		    writeENDUOWRM(COMMIT);
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
+	}
+
+	/**
+	 * Exchange server attributes with application requester
+	 *
+	 * @exception DRDAProtocolException
+	 */
+	private void exchangeServerAttributes()
+		throws  DRDAProtocolException
+	{
+		int codePoint;
+		correlationID = reader.readDssHeader();
+		if (SanityManager.DEBUG) {
+		  if (correlationID == 0)
+		  {
+		    SanityManager.THROWASSERT(
+					      "Unexpected value for correlationId = " + correlationID);
+		  }
 		}
-		break;
-	    case CodePoint.RDBRLLBCK:
-		try {
-		    if (SanityManager.DEBUG)
-			trace("Received rollback");
-		    database.getConnection().clearWarnings();
-		    database.rollback();
-		    writeENDUOWRM(ROLLBACK);
-		    checkWarning(database.getConnection(), null, null, 0, true, true);
-		    // we only want to write one of these per transaction
-		    // so set to false in preparation for next command
-		    database.RDBUPDRM_sent = false;
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    // Even in case of error, we have to write the ENDUOWRM.
-		    writeENDUOWRM(ROLLBACK);
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
-		}
-		break;
-	    case CodePoint.CLSQRY:
-		try{
-		    stmt = parseCLSQRY();
-		    stmt.rsClose();
-		    writeSQLCARDs(null, 0);
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
+
+		codePoint = reader.readLengthAndCodePoint();
+
+		// The first code point in the exchange of attributes must be EXCSAT
+		if (codePoint != CodePoint.EXCSAT)
+		{
+			//Throw PRCCNVRM 
+			throw
+			    new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_PRCCNVRM,
+										  this, codePoint,
+										  CodePoint.PRCCNVCD_EXCSAT_FIRST_AFTER_CONN);
 		}
-		break;
-	    case CodePoint.EXCSAT:
+
 		parseEXCSAT();
 		writeEXCSATRD();
-		break;
-	    case CodePoint.ACCSEC:
-		int securityCheckCode = parseACCSEC();
-		writeACCSECRD(securityCheckCode); 
-		checkSecurityCodepoint = true;
-		break;
-	    case CodePoint.SECCHK:
-		if(parseDRDAConnection())
-		    // security all checked and connection ok
-		    checkSecurityCodepoint = false;
-		break;
-		/* since we don't support sqlj, we won't get bind commands from jcc, we
-		 * might get it from ccc; just skip them.
-		 */
-	    case CodePoint.BGNBND:
-		reader.skipBytes();
-		writeSQLCARDs(null, 0);
-		break;
-	    case CodePoint.BNDSQLSTT:
-		reader.skipBytes();
-		parseSQLSTTDss();
-		writeSQLCARDs(null, 0);
-		break;
-	    case CodePoint.SQLSTTVRB:
-		// optional
-		reader.skipBytes();
-		break;
-	    case CodePoint.ENDBND:
-		reader.skipBytes();
-		writeSQLCARDs(null, 0);
-		break;
-	    case CodePoint.DSCSQLSTT:
-		if (PRPSQLSTTfailed) {
-		    reader.skipBytes();
-		    writeSQLCARDs(null, 0);
-		    break;
-		}
-		try {
-		    boolean rtnOutput = parseDSCSQLSTT();
-		    writeSQLDARD(database.getCurrentStatement(), rtnOutput,
-				 null);
-						
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    server.consoleExceptionPrint(e);
-		    try {
-			writeSQLDARD(database.getCurrentStatement(), true, e);
-		    } catch (SQLException e2) {	// should not get here since doing nothing with ps
-			agentError("Why am I getting another SQLException?");
-		    }
-		    errorInChain(e);
-		}
-		break;
-	    case CodePoint.EXCSQLSTT:
-		if (PRPSQLSTTfailed) {
-		    // Skip parameters too if they are chained Beetle 4867
-		    skipRemainder(true);
-		    writeSQLCARDs(null, 0);
-		    break;
-		}
-		try {
-		    parseEXCSQLSTT();
+		finalizeChain();
+		session.setState(session.ATTEXC);
+	}
+	
 
-		    DRDAStatement curStmt = database.getCurrentStatement();
-		    if (curStmt != null)
-			curStmt.rsSuspend();
-		} catch (SQLException e) {
-		    writer.clearDSSesBackToMark(writerMark);
-		    if (SanityManager.DEBUG)  {
-			server.consoleExceptionPrint(e);
-		    }
-		    writeSQLCARDs(e, 0);
-		    errorInChain(e);
-		}
-		break;
-	    case CodePoint.SYNCCTL:
-		if (xaProto == null)
-		    xaProto = new DRDAXAProtocol(this);
-		xaProto.parseSYNCCTL();
-		break;
-	    default:
-		codePointNotSupported(codePoint);
-	    }
-
-	    // Set the correct chaining bits for whatever
-	    // reply DSS(es) we just wrote.  If we've reached
-	    // the end of the chain, this method will send
-	    // the DSS(es) across.
-	    finalizeChain();
+	private boolean parseDRDAConnection() throws DRDAProtocolException
+	{
+		int codePoint;
+		boolean sessionOK = true;
 
-	}
-	while (reader.isChainedWithSameID() || reader.isChainedWithDiffID());
-    }
 
-    /**
-     * If there's a severe error in the DDM chain, and if the header indicates
-     * "terminate chain on error", we stop processing further commands in the chain
-     * nor do we send any reply for them.  In accordance to this, a SQLERRRM message 
-     * indicating the severe error must have been sent! (otherwise application requestor,
-     * such as JCC, would not terminate the receiving of chain replies.)
-     *
-     * Each DRDA command is processed independently. DRDA defines no interdependencies
-     * across chained commands. A command is processed the same when received within
-     * a set of chained commands or received separately.  The chaining was originally
-     * defined as a way to save network costs.
-     *
-     * @param e		the SQLException raised
-     * @exception	DRDAProtocolException
-     */
-    private void errorInChain(SQLException e) throws DRDAProtocolException {
-	if (reader.terminateChainOnErr() && (getExceptionSeverity(e) > CodePoint.SVRCOD_ERROR)) {
-	    if (SanityManager.DEBUG)  trace("terminating the chain on error...");
-	    skipRemainder(false);
-	}
-    }
+		int securityCheckCode = parseSECCHK();
+		if (SanityManager.DEBUG)
+			trace("*** SECCHKRM securityCheckCode is: "+securityCheckCode);
+		writeSECCHKRM(securityCheckCode);
+		//at this point if the security check failed, we're done, the session failed
+		if (securityCheckCode != 0)
+		{
+			return false;
+		}
 
-    /**
-     * Exchange server attributes with application requester
-     *
-     * @exception DRDAProtocolException
-     */
-    private void exchangeServerAttributes()
-	throws  DRDAProtocolException {
-	int codePoint;
-	correlationID = reader.readDssHeader();
-	if (SanityManager.DEBUG) {
-	    if (correlationID == 0) {
-		SanityManager.THROWASSERT(
-					  "Unexpected value for correlationId = " + correlationID);
-	    }
-	}
-
-	codePoint = reader.readLengthAndCodePoint();
-
-	// The first code point in the exchange of attributes must be EXCSAT
-	if (codePoint != CodePoint.EXCSAT) {
-	    //Throw PRCCNVRM 
-	    throw
-		new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_PRCCNVRM,
-					  this, codePoint,
-					  CodePoint.PRCCNVCD_EXCSAT_FIRST_AFTER_CONN);
-	}
-
-	parseEXCSAT();
-	writeEXCSATRD();
-	finalizeChain();
-	session.setState(session.ATTEXC);
-    }
-	
+		correlationID = reader.readDssHeader();
+		codePoint = reader.readLengthAndCodePoint();
+		verifyRequiredObject(codePoint,CodePoint.ACCRDB);
+		int svrcod = parseACCRDB();
 
-    private boolean parseDRDAConnection() throws DRDAProtocolException {
-	int codePoint;
-	boolean sessionOK = true;
-
-
-	int securityCheckCode = parseSECCHK();
-	if (SanityManager.DEBUG)
-	    trace("*** SECCHKRM securityCheckCode is: "+securityCheckCode);
-	writeSECCHKRM(securityCheckCode);
-	//at this point if the security check failed, we're done, the session failed
-	if (securityCheckCode != 0) {
-	    return false;
-	}
-
-	correlationID = reader.readDssHeader();
-	codePoint = reader.readLengthAndCodePoint();
-	verifyRequiredObject(codePoint,CodePoint.ACCRDB);
-	int svrcod = parseACCRDB();
-
-	//If network server gets a null connection form InternalDriver, reply with
-	//RDBAFLRM and SQLCARD with null SQLException 
-	if(database.getConnection() == null && databaseAccessException == null){
-	    writeRDBfailure(CodePoint.RDBAFLRM);
-	    return false;
-	}		
+		//If network server gets a null connection form InternalDriver, reply with
+		//RDBAFLRM and SQLCARD with null SQLException 
+		if(database.getConnection() == null && databaseAccessException == null){
+			writeRDBfailure(CodePoint.RDBAFLRM);
+			return false;
+		}		
 		
-	//if earlier we couldn't access the database
-	if (databaseAccessException != null) {
-
-	    //if the Database was not found we will try DS
-	    int failureType = getRdbAccessErrorCodePoint();
-	    if (failureType == CodePoint.RDBNFNRM 
-		|| failureType == CodePoint.RDBATHRM) {
-		writeRDBfailure(failureType);
-	    } else {
-		writeRDBfailure(CodePoint.RDBAFLRM);
-	    }
-	    return false;
-	} else if (database.accessCount > 1 ) { // already in conversation with database 
-	    writeRDBfailure(CodePoint.RDBACCRM);
-	    return false;
-	}
-	else // everything is fine 
-	    writeACCRDBRM(svrcod);
-
-	// compare this application requester with previously stored
-	// application requesters and if we have already seen this one
-	// use stored application requester 
-	session.appRequester = server.getAppRequester(appRequester);
-	return sessionOK;
-    }
+		//if earlier we couldn't access the database
+		if (databaseAccessException != null)
+		{
+
+			//if the Database was not found we will try DS
+			int failureType = getRdbAccessErrorCodePoint();
+			if (failureType == CodePoint.RDBNFNRM 
+				|| failureType == CodePoint.RDBATHRM)
+			{
+				writeRDBfailure(failureType);
+			}
+			else
+			{
+				writeRDBfailure(CodePoint.RDBAFLRM);
+			}
+			return false;
+		}
+		else if (database.accessCount > 1 )	// already in conversation with database
+		{
+			writeRDBfailure(CodePoint.RDBACCRM);
+			return false;
+		}
+		else // everything is fine 
+			writeACCRDBRM(svrcod);
+
+		// compare this application requester with previously stored
+		// application requesters and if we have already seen this one
+		// use stored application requester 
+		session.appRequester = server.getAppRequester(appRequester);
+		return sessionOK;
+	}
 
-    /**
-     * Write RDB Failure
-     *
-     * Instance Variables
-     * 	SVRCOD - Severity Code - required
-     *	RDBNAM - Relational Database name - required
-     *  SRVDGN - Server Diagnostics - optional (not sent for now)
-     *
-     * @param	codePoint	codepoint of failure
-     */
-    private void writeRDBfailure(int codePoint) throws DRDAProtocolException {
-	writer.createDssReply();
-	writer.startDdm(codePoint);
-	writer.writeScalar2Bytes(CodePoint.SVRCOD, CodePoint.SVRCOD_ERROR);
-	writeRDBNAM(database.dbName);
+	/**
+	 * Write RDB Failure
+	 *
+	 * Instance Variables
+	 * 	SVRCOD - Severity Code - required
+	 *	RDBNAM - Relational Database name - required
+	 *  SRVDGN - Server Diagnostics - optional (not sent for now)
+ 	 *
+	 * @param	codePoint	codepoint of failure
+	 */
+	private void writeRDBfailure(int codePoint) throws DRDAProtocolException
+	{
+		writer.createDssReply();
+		writer.startDdm(codePoint);
+		writer.writeScalar2Bytes(CodePoint.SVRCOD, CodePoint.SVRCOD_ERROR);
+		writeRDBNAM(database.dbName);
     	writer.endDdmAndDss();
     	
     	switch(codePoint){
-	case CodePoint.RDBAFLRM:
-	    //RDBAFLRM requires TYPDEFNAM and TYPDEFOVR
-	    writer.createDssObject();
-	    writer.writeScalarString(CodePoint.TYPDEFNAM,
-				     CodePoint.TYPDEFNAM_QTDSQLASC);
-	    writeTYPDEFOVR();
-	    writer.endDss();
-	case CodePoint.RDBNFNRM:
-	case CodePoint.RDBATHRM:
-	    writeSQLCARD(databaseAccessException,CodePoint.SVRCOD_ERROR,0,0);
-	case CodePoint.RDBACCRM:
-	    //Ignore anything that was chained to the ACCRDB.
-	    skipRemainder(false);
-
-	    // Finalize chain state for whatever we wrote in
-	    // response to ACCRDB.
-	    finalizeChain();
-	    break;
+    		case CodePoint.RDBAFLRM:
+    			//RDBAFLRM requires TYPDEFNAM and TYPDEFOVR
+    			writer.createDssObject();
+    			writer.writeScalarString(CodePoint.TYPDEFNAM,
+    									 CodePoint.TYPDEFNAM_QTDSQLASC);
+    			writeTYPDEFOVR();
+    			writer.endDss();
+    		case CodePoint.RDBNFNRM:
+    		case CodePoint.RDBATHRM:
+    			writeSQLCARD(databaseAccessException,CodePoint.SVRCOD_ERROR,0,0);
+    		case CodePoint.RDBACCRM:
+    			//Ignore anything that was chained to the ACCRDB.
+    			skipRemainder(false);
+
+    			// Finalize chain state for whatever we wrote in
+    			// response to ACCRDB.
+    			finalizeChain();
+    			break;
     	}
     	
-    }
+	}
 
-    /* Check the database access exception and return the appropriate
-       error codepoint.
-       RDBNFNRM - Database not found
-       RDBATHRM - Not Authorized
-       RDBAFLRM - Access failure
-       @return RDB Access codepoint 
+	/* Check the database access exception and return the appropriate
+	   error codepoint.
+	   RDBNFNRM - Database not found
+	   RDBATHRM - Not Authorized
+	   RDBAFLRM - Access failure
+	   @return RDB Access codepoint 
 	           
-    */
+	*/
 
-    private int getRdbAccessErrorCodePoint() {
-	String sqlState = databaseAccessException.getSQLState();
-	if (sqlState.regionMatches(0,SQLState.DATABASE_NOT_FOUND,0,5) |
-	    sqlState.regionMatches(0,SQLState.NO_SUCH_DATABASE,0,5))
-	    return CodePoint.RDBNFNRM;
-	else
-	    if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5) ||
-		sqlState.regionMatches(0,SQLState.AUTH_INVALID_USER_NAME,0,5))
-		return CodePoint.RDBATHRM;
-	    else
-		return CodePoint.RDBAFLRM;
-    }
+	private int getRdbAccessErrorCodePoint()
+	{
+		String sqlState = databaseAccessException.getSQLState();
+		if (sqlState.regionMatches(0,SQLState.DATABASE_NOT_FOUND,0,5) |
+			sqlState.regionMatches(0,SQLState.NO_SUCH_DATABASE,0,5))
+			return CodePoint.RDBNFNRM;
+		else
+			if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5) ||
+				sqlState.regionMatches(0,SQLState.AUTH_INVALID_USER_NAME,0,5))
+				return CodePoint.RDBATHRM;
+		else
+				return CodePoint.RDBAFLRM;
+	}
 
 
-    /**
-     * Verify userId and password
-     *
-     * Username and password is verified by making a connection to the
-     * database
-     *
-     * @return security check code, 0 is O.K.
-     * @exception DRDAProtocolException
-     */
-    private int verifyUserIdPassword() throws DRDAProtocolException {
-	databaseAccessException = null;
-	int retSecChkCode = 0;
+	/**
+	 * Verify userId and password
+	 *
+	 * Username and password is verified by making a connection to the
+	 * database
+	 *
+	 * @return security check code, 0 is O.K.
+	 * @exception DRDAProtocolException
+	 */
+	private int verifyUserIdPassword() throws DRDAProtocolException
+	{
+		databaseAccessException = null;
+		int retSecChkCode = 0;
 
 
-	String realName = database.dbName; //first strip off properties
-	int endOfName = realName.indexOf(';');
-	if (endOfName != -1)
-	    realName = realName.substring(0, endOfName);
-	retSecChkCode = getConnFromDatabaseName();
-	return retSecChkCode;
-    }
+		String realName = database.dbName; //first strip off properties
+		int endOfName = realName.indexOf(';');
+		if (endOfName != -1)
+			realName = realName.substring(0, endOfName);
+		retSecChkCode = getConnFromDatabaseName();
+		return retSecChkCode;
+	}
 
-    /**
-     * Get connection from a database name
-     *
-     * Username and password is verified by making a connection to the
-     * database
-     *
-     * @return security check code, 0 is O.K.
-     * @exception DRDAProtocolException
-     */
-    private int getConnFromDatabaseName() throws DRDAProtocolException {
-	Properties p = new Properties();
-	databaseAccessException = null;
-	//if we haven't got the correlation token yet, use session number for drdaID
-	if (session.drdaID == null)
-	    session.drdaID = leftBrace + session.connNum + rightBrace;
-	p.put(Attribute.DRDAID_ATTR, session.drdaID);
-	try {
-	    database.makeConnection(p);
-	} catch (SQLException se) {
-	    String sqlState = se.getSQLState();
-	    // need to set the security check code based on the reason the connection     
-	    // was denied, Cloudscape doesn't say whether the userid or password caused
-	    // the problem, so we will just return userid invalid
-	    databaseAccessException = se;
-	    for (; se != null; se = se.getNextException()) {
-		if (SanityManager.DEBUG)
-		    trace(se.getMessage());
-		println2Log(database.dbName, session.drdaID, se.getMessage());
-	    }
+	/**
+	 * Get connection from a database name
+	 *
+	 * Username and password is verified by making a connection to the
+	 * database
+	 *
+	 * @return security check code, 0 is O.K.
+	 * @exception DRDAProtocolException
+	 */
+	private int getConnFromDatabaseName() throws DRDAProtocolException
+	{
+		Properties p = new Properties();
+		databaseAccessException = null;
+		//if we haven't got the correlation token yet, use session number for drdaID
+		if (session.drdaID == null)
+			session.drdaID = leftBrace + session.connNum + rightBrace;
+		p.put(Attribute.DRDAID_ATTR, session.drdaID);
+	 	try {
+			database.makeConnection(p);
+	  	} catch (SQLException se) {
+			String sqlState = se.getSQLState();
+			// need to set the security check code based on the reason the connection     
+			// was denied, Cloudscape doesn't say whether the userid or password caused
+			// the problem, so we will just return userid invalid
+			databaseAccessException = se;
+			for (; se != null; se = se.getNextException())
+			{
+				if (SanityManager.DEBUG)
+					trace(se.getMessage());
+	 			println2Log(database.dbName, session.drdaID, se.getMessage());
+			}
 
-	    if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5))
-		return CodePoint.SECCHKCD_USERIDINVALID;
+			if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5))
+				return CodePoint.SECCHKCD_USERIDINVALID;
 
-	    return 0;
+			return 0;
 			
-	} catch (Exception e) {
-	    // If cloudscape has shut down for some reason,
-	    // we will send  an agent error and then try to 
-	    // get the driver loaded again.  We have to get
-	    // rid of the client first in case they are holding
-	    // the DriverManager lock.
-	    println2Log(database.dbName, session.drdaID, 
-			"Driver not loaded"
-			+ e.getMessage());
-	    try {
-		agentError("Driver not loaded");
-	    } catch (DRDAProtocolException dpe) {
-		// Retry starting the server before rethrowing 
-		// the protocol exception.  Then hopfully all
-		// will be well when they try again.
-		try {
-		    server.startNetworkServer();
-		} catch (Exception re) {
-		    println2Log(database.dbName, session.drdaID, "Failed attempt to reload driver " +re.getMessage()  );
 		}
-		throw dpe;
-	    }
-	}
+		catch (Exception e)
+		{
+			// If cloudscape has shut down for some reason,
+			// we will send  an agent error and then try to 
+			// get the driver loaded again.  We have to get
+			// rid of the client first in case they are holding
+			// the DriverManager lock.
+			println2Log(database.dbName, session.drdaID, 
+						"Driver not loaded"
+						+ e.getMessage());
+				try {
+					agentError("Driver not loaded");
+				}
+				catch (DRDAProtocolException dpe)
+				{
+					// Retry starting the server before rethrowing 
+					// the protocol exception.  Then hopfully all
+					// will be well when they try again.
+					try {
+						server.startNetworkServer();
+					} catch (Exception re) {
+						println2Log(database.dbName, session.drdaID, "Failed attempt to reload driver " +re.getMessage()  );
+					}
+					throw dpe;
+				}
+		}
 		
 	
-	// Everything worked so log connection to the database.
-	if (getLogConnections())
-	    println2Log(database.dbName, session.drdaID,
-			"Apache Derby Network Server connected to database " +
-			database.dbName);
-	return 0;
-    }
+		// Everything worked so log connection to the database.
+		if (getLogConnections())
+	 		println2Log(database.dbName, session.drdaID,
+				"Apache Derby Network Server connected to database " +
+						database.dbName);
+		return 0;
+	}
 
 
-    /**
-     * Parses EXCSAT (Exchange Server Attributes)
-     * Instance variables
-     *	EXTNAM(External Name)	- optional
-     *  MGRLVLLS(Manager Levels) - optional
-     *	SPVNAM(Supervisor Name) - optional
-     *  SRVCLSNM(Server Class Name) - optional
-     *  SRVNAM(Server Name) - optional, ignorable
-     *  SRVRLSLV(Server Product Release Level) - optional, ignorable
-     *
-     * @exception DRDAProtocolException
-     */
-    private void parseEXCSAT() throws DRDAProtocolException {
-	int codePoint;
-	String strVal;
-
-	// There are three kinds of EXCSAT's we might get.
-	// 1) Initial Exchange attributes.
-	//    For this we need to initialize the apprequester.
-	//    Session state is set to ATTEXC and then the AR must 
-	//    follow up with ACCSEC and SECCHK to get the connection.
-	//  2) Send of EXCSAT as ping or mangager level adjustment. 
-	//     (see parseEXCSAT2())
-	//     For this we just ignore the EXCSAT objects that
-	//     are already set.
-	//  3) Send of EXCSAT for connection reset. (see parseEXCSAT2())
-	//     This is treated just like ping and will be followed up 
-	//     by an ACCSEC request if in fact it is a connection reset.
-
-	// If we have already exchanged attributes once just 
-	// process any new manager levels and return (case 2 and 3 above)
-	if (appRequester != null) {
-	    parseEXCSAT2();
-	    return;
-	}
-
-	// set up a new Application Requester to store information about the
-	// application requester for this session
-
-	appRequester = new AppRequester();
-
-	reader.markCollection();
-
-	codePoint = reader.getCodePoint();
-	while (codePoint != -1) {
-	    switch (codePoint) {
-		// optional
-	    case CodePoint.EXTNAM:
-		appRequester.extnam = reader.readString();
-		if (SanityManager.DEBUG)
-		    trace("extName = " + appRequester.extnam);
-		if (appRequester.extnam.length() > CodePoint.MAX_NAME)
-		    tooBig(CodePoint.EXTNAM);
-		break;
-		// optional
-	    case CodePoint.MGRLVLLS:
-		parseMGRLVLLS(1);
-		break;
-		// optional 
-	    case CodePoint.SPVNAM:
-		appRequester.spvnam = reader.readString();
-		// This is specified as a null parameter so length should
-		// be zero
-		if (appRequester.spvnam != null)
-		    badObjectLength(CodePoint.SPVNAM);
-		break;
-		// optional
-	    case CodePoint.SRVNAM:
-		appRequester.srvnam = reader.readString();
-		if (SanityManager.DEBUG)
-		    trace("serverName = " +  appRequester.srvnam);
-		if (appRequester.srvnam.length() > CodePoint.MAX_NAME)
-		    tooBig(CodePoint.SRVNAM);
-		break;
-		// optional
-	    case CodePoint.SRVRLSLV:
-		appRequester.srvrlslv = reader.readString();
-		if (SanityManager.DEBUG)
-		    trace("serverlslv = " + appRequester.srvrlslv);
-		if (appRequester.srvrlslv.length() > CodePoint.MAX_NAME)
-		    tooBig(CodePoint.SRVRLSLV);
-		break;
-		// optional
-	    case CodePoint.SRVCLSNM:
-		appRequester.srvclsnm = reader.readString();
-		if (SanityManager.DEBUG)
-		    trace("serverClassName = " + appRequester.srvclsnm);
-		if (appRequester.srvclsnm.length() > CodePoint.MAX_NAME)
-		    tooBig(CodePoint.SRVCLSNM);
-		break;
-	    default:
-		invalidCodePoint(codePoint);
-	    }
-	    codePoint = reader.getCodePoint();
+	/**
+	 * Parses EXCSAT (Exchange Server Attributes)
+	 * Instance variables
+	 *	EXTNAM(External Name)	- optional
+	 *  MGRLVLLS(Manager Levels) - optional
+	 *	SPVNAM(Supervisor Name) - optional
+	 *  SRVCLSNM(Server Class Name) - optional
+	 *  SRVNAM(Server Name) - optional, ignorable
+	 *  SRVRLSLV(Server Product Release Level) - optional, ignorable
+	 *
+	 * @exception DRDAProtocolException
+	 */
+	private void parseEXCSAT() throws DRDAProtocolException
+	{
+		int codePoint;
+		String strVal;
+
+		// There are three kinds of EXCSAT's we might get.
+		// 1) Initial Exchange attributes.
+		//    For this we need to initialize the apprequester.
+		//    Session state is set to ATTEXC and then the AR must 
+		//    follow up with ACCSEC and SECCHK to get the connection.
+		//  2) Send of EXCSAT as ping or mangager level adjustment. 
+		//     (see parseEXCSAT2())
+		//     For this we just ignore the EXCSAT objects that
+		//     are already set.
+		//  3) Send of EXCSAT for connection reset. (see parseEXCSAT2())
+		//     This is treated just like ping and will be followed up 
+		//     by an ACCSEC request if in fact it is a connection reset.
+
+		// If we have already exchanged attributes once just 
+		// process any new manager levels and return (case 2 and 3 above)
+		if (appRequester != null)
+		{
+			parseEXCSAT2();
+			return;
+		}
+
+		// set up a new Application Requester to store information about the
+		// application requester for this session
+
+		appRequester = new AppRequester();
+
+		reader.markCollection();
+
+		codePoint = reader.getCodePoint();
+		while (codePoint != -1)
+		{
+			switch (codePoint)
+			{
+				// optional
+				case CodePoint.EXTNAM:
+					appRequester.extnam = reader.readString();
+					if (SanityManager.DEBUG)
+						trace("extName = " + appRequester.extnam);
+					if (appRequester.extnam.length() > CodePoint.MAX_NAME)
+						tooBig(CodePoint.EXTNAM);
+					break;
+				// optional
+				case CodePoint.MGRLVLLS:
+					parseMGRLVLLS(1);
+					break;
+				// optional 
+				case CodePoint.SPVNAM:
+					appRequester.spvnam = reader.readString();
+					// This is specified as a null parameter so length should
+					// be zero
+					if (appRequester.spvnam != null)
+						badObjectLength(CodePoint.SPVNAM);
+					break;
+				// optional
+				case CodePoint.SRVNAM:
+					appRequester.srvnam = reader.readString();
+					if (SanityManager.DEBUG)
+						trace("serverName = " +  appRequester.srvnam);
+					if (appRequester.srvnam.length() > CodePoint.MAX_NAME)
+						tooBig(CodePoint.SRVNAM);
+					break;
+				// optional
+				case CodePoint.SRVRLSLV:
+					appRequester.srvrlslv = reader.readString();
+					if (SanityManager.DEBUG)
+						trace("serverlslv = " + appRequester.srvrlslv);
+					if (appRequester.srvrlslv.length() > CodePoint.MAX_NAME)
+						tooBig(CodePoint.SRVRLSLV);
+					break;
+				// optional
+				case CodePoint.SRVCLSNM:
+					appRequester.srvclsnm = reader.readString();
+					if (SanityManager.DEBUG)
+						trace("serverClassName = " + appRequester.srvclsnm);
+					if (appRequester.srvclsnm.length() > CodePoint.MAX_NAME)
+						tooBig(CodePoint.SRVCLSNM);
+					break;
+				default:
+					invalidCodePoint(codePoint);
+			}
+			codePoint = reader.getCodePoint();
+		}
 	}
-    }
 
-    /**
-     * Parses EXCSAT2 (Exchange Server Attributes)
-     * Instance variables
-     *	EXTNAM(External Name)	- optional
-     *  MGRLVLLS(Manager Levels) - optional
-     *	SPVNAM(Supervisor Name) - optional
-     *  SRVCLSNM(Server Class Name) - optional
-     *  SRVNAM(Server Name) - optional, ignorable
-     *  SRVRLSLV(Server Product Release Level) - optional, ignorable
-     *
-     * @exception DRDAProtocolException
-     * 
-     * This parses a second occurrence of an EXCSAT command
-     * The target must ignore the values for extnam, srvclsnm, srvnam and srvrlslv.
-     * I am also going to ignore spvnam since it should be null anyway.
-     * Only new managers can be added.
-     */
-    private void parseEXCSAT2() throws DRDAProtocolException {
-	int codePoint;
-	reader.markCollection();
-
-	codePoint = reader.getCodePoint();
-	while (codePoint != -1) {
-	    switch (codePoint) {
-		// optional
-	    case CodePoint.EXTNAM:
-	    case CodePoint.SRVNAM:
-	    case CodePoint.SRVRLSLV:
-	    case CodePoint.SRVCLSNM:
-	    case CodePoint.SPVNAM:
-		reader.skipBytes();
-		break;
-		// optional
-	    case CodePoint.MGRLVLLS:
-		parseMGRLVLLS(2);
-		break;
-	    default:
-		invalidCodePoint(codePoint);
-	    }
-	    codePoint = reader.getCodePoint();
+	/**
+	 * Parses EXCSAT2 (Exchange Server Attributes)
+	 * Instance variables
+	 *	EXTNAM(External Name)	- optional
+	 *  MGRLVLLS(Manager Levels) - optional
+	 *	SPVNAM(Supervisor Name) - optional
+	 *  SRVCLSNM(Server Class Name) - optional
+	 *  SRVNAM(Server Name) - optional, ignorable
+	 *  SRVRLSLV(Server Product Release Level) - optional, ignorable
+	 *
+	 * @exception DRDAProtocolException
+	 * 
+	 * This parses a second occurrence of an EXCSAT command
+	 * The target must ignore the values for extnam, srvclsnm, srvnam and srvrlslv.
+	 * I am also going to ignore spvnam since it should be null anyway.
+	 * Only new managers can be added.
+	 */
+	private void parseEXCSAT2() throws DRDAProtocolException
+	{
+		int codePoint;
+		reader.markCollection();
+
+		codePoint = reader.getCodePoint();
+		while (codePoint != -1)
+		{
+			switch (codePoint)
+			{
+				// optional
+				case CodePoint.EXTNAM:
+				case CodePoint.SRVNAM:
+				case CodePoint.SRVRLSLV:
+				case CodePoint.SRVCLSNM:
+				case CodePoint.SPVNAM:
+					reader.skipBytes();
+					break;
+				// optional
+				case CodePoint.MGRLVLLS:
+					parseMGRLVLLS(2);
+					break;
+				default:
+					invalidCodePoint(codePoint);
+			}
+			codePoint = reader.getCodePoint();
+		}
 	}
-    }
 
-    /**
-     *	Parse manager levels
-     *  Instance variables
-     *		MGRLVL - repeatable, required
-     *		  CODEPOINT
-     *			CCSIDMGR - CCSID Manager
-     *			CMNAPPC - LU 6.2 Conversational Communications Manager 
-     *			CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager
-     *			CMNTCPIP - TCP/IP Communication Manager 
-     *			DICTIONARY - Dictionary
-     *			RDB - Relational Database 
-     *			RSYNCMGR - Resynchronization Manager 
-     *			SECMGR - Security Manager
-     *			SQLAM - SQL Application Manager
-     *			SUPERVISOR - Supervisor
-     *			SYNCPTMGR - Sync Point Manager 
-     *		  VALUE
-     *
-     *	On the second appearance of this codepoint, it can only add managers
-     *
-     * @param time	1 for first time this is seen, 2 for subsequent ones
-     * @exception DRDAProtocolException
-     * 
-     */
-    private void parseMGRLVLLS(int time) throws DRDAProtocolException {
-	int manager, managerLevel;
-	int currentLevel;
-	// set up vectors to keep track of manager information
-	unknownManagers = new Vector();
-	knownManagers = new Vector();
-	errorManagers = new Vector();
-	errorManagersLevel = new Vector();
-	if (SanityManager.DEBUG)
-	    trace("Manager Levels");
-
-	while (reader.moreDdmData()) {
-	    manager = reader.readNetworkShort();
-	    managerLevel = reader.readNetworkShort();
-	    if (CodePoint.isKnownManager(manager)) {
-		knownManagers.addElement(new Integer(manager));
-		//if the manager level hasn't been set, set it
-		currentLevel = appRequester.getManagerLevel(manager);
-		if (currentLevel == appRequester.MGR_LEVEL_UNKNOWN)
-		    appRequester.setManagerLevel(manager, managerLevel);
-		else {
-		    //if the level is still the same we'll ignore it
-		    if (currentLevel != managerLevel) {
-			//keep a list of conflicting managers
-			errorManagers.addElement(new Integer(manager));
-			errorManagersLevel.addElement(new Integer (managerLevel));
-		    }
-		}
-
-	    }
-	    else
-		unknownManagers.addElement(new Integer(manager));
-	    if (SanityManager.DEBUG)
-		trace("Manager = " + java.lang.Integer.toHexString(manager) + 
-		      " ManagerLevel " + managerLevel);
-	}
-	sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM);
-	// did we have any errors
-	if (errorManagers.size() > 0) {
-	    Object [] oa = new Object[errorManagers.size()*2];
-	    int j = 0;
-	    for (int i = 0; i < errorManagers.size(); i++) {
-		oa[j++] = errorManagers.elementAt(i);
-		oa[j++] = errorManagersLevel.elementAt(i);
-	    }
-	    throw new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_MGRLVLRM,
-					    this, 0,
-					    0, oa);
+	/**
+	 *	Parse manager levels
+	 *  Instance variables
+	 *		MGRLVL - repeatable, required
+	 *		  CODEPOINT
+	 *			CCSIDMGR - CCSID Manager
+	 *			CMNAPPC - LU 6.2 Conversational Communications Manager 
+	 *			CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager
+	 *			CMNTCPIP - TCP/IP Communication Manager 
+	 *			DICTIONARY - Dictionary
+	 *			RDB - Relational Database 
+	 *			RSYNCMGR - Resynchronization Manager 
+	 *			SECMGR - Security Manager
+	 *			SQLAM - SQL Application Manager
+	 *			SUPERVISOR - Supervisor
+	 *			SYNCPTMGR - Sync Point Manager 
+	 *		  VALUE
+	 *
+	 *	On the second appearance of this codepoint, it can only add managers
+	 *
+	 * @param time	1 for first time this is seen, 2 for subsequent ones
+	 * @exception DRDAProtocolException
+	 * 
+	 */
+	private void parseMGRLVLLS(int time) throws DRDAProtocolException
+	{
+		int manager, managerLevel;
+		int currentLevel;
+		// set up vectors to keep track of manager information
+		unknownManagers = new Vector();
+		knownManagers = new Vector();
+		errorManagers = new Vector();
+		errorManagersLevel = new Vector();
+		if (SanityManager.DEBUG)
+			trace("Manager Levels");
+
+		while (reader.moreDdmData())
+		{
+			manager = reader.readNetworkShort();
+			managerLevel = reader.readNetworkShort();
+			if (CodePoint.isKnownManager(manager))
+			{
+				knownManagers.addElement(new Integer(manager));
+				//if the manager level hasn't been set, set it
+				currentLevel = appRequester.getManagerLevel(manager);
+				if (currentLevel == appRequester.MGR_LEVEL_UNKNOWN)
+			    	appRequester.setManagerLevel(manager, managerLevel);
+				else
+				{
+					//if the level is still the same we'll ignore it
+					if (currentLevel != managerLevel)
+					{
+						//keep a list of conflicting managers
+						errorManagers.addElement(new Integer(manager));
+						errorManagersLevel.addElement(new Integer (managerLevel));
+					}
+				}
+
+			}
+			else
+				unknownManagers.addElement(new Integer(manager));
+			if (SanityManager.DEBUG)
+			   trace("Manager = " + java.lang.Integer.toHexString(manager) + 
+					  " ManagerLevel " + managerLevel);
+		}
+		sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM);
+		// did we have any errors
+		if (errorManagers.size() > 0)
+		{
+			Object [] oa = new Object[errorManagers.size()*2];
+			int j = 0;
+			for (int i = 0; i < errorManagers.size(); i++)
+			{
+				oa[j++] = errorManagers.elementAt(i);
+				oa[j++] = errorManagersLevel.elementAt(i);
+			}
+			throw new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_MGRLVLRM,
+										  this, 0,
+										  0, oa);
+		}
 	}
-    }
-    /**
-     * Write reply to EXCSAT command
-     * Instance Variables
-     *	EXTNAM - External Name (optional)
-     *  MGRLVLLS - Manager Level List (optional)
-     *  SRVCLSNM - Server Class Name (optional) - used by JCC
-     *  SRVNAM - Server Name (optional)
-     *  SRVRLSLV - Server Product Release Level (optional)
-     *
-     * @exception DRDAProtocolException
-     */
-    private void writeEXCSATRD() throws DRDAProtocolException {
-	writer.createDssReply();
-	writer.startDdm(CodePoint.EXCSATRD);
-	writer.writeScalarString(CodePoint.EXTNAM, server.att_extnam);
-	//only reply with manager levels if we got sent some
-	if (knownManagers != null && knownManagers.size() > 0)
-	    writeMGRLEVELS();
-	writer.writeScalarString(CodePoint.SRVCLSNM, server.att_srvclsnm);
-	writer.writeScalarString(CodePoint.SRVNAM, server.ATT_SRVNAM);
-	writer.writeScalarString(CodePoint.SRVRLSLV, server.att_srvrlslv);
+	/**
+	 * Write reply to EXCSAT command
+	 * Instance Variables
+	 *	EXTNAM - External Name (optional)
+	 *  MGRLVLLS - Manager Level List (optional)
+	 *  SRVCLSNM - Server Class Name (optional) - used by JCC
+	 *  SRVNAM - Server Name (optional)
+	 *  SRVRLSLV - Server Product Release Level (optional)
+	 *
+	 * @exception DRDAProtocolException
+	 */
+	private void writeEXCSATRD() throws DRDAProtocolException
+	{
+		writer.createDssReply();
+		writer.startDdm(CodePoint.EXCSATRD);
+		writer.writeScalarString(CodePoint.EXTNAM, server.att_extnam);
+		//only reply with manager levels if we got sent some
+		if (knownManagers != null && knownManagers.size() > 0)
+			writeMGRLEVELS();
+		writer.writeScalarString(CodePoint.SRVCLSNM, server.att_srvclsnm);
+		writer.writeScalarString(CodePoint.SRVNAM, server.ATT_SRVNAM);
+		writer.writeScalarString(CodePoint.SRVRLSLV, server.att_srvrlslv);
     	writer.endDdmAndDss();
-    }
-    /**
-     * Write manager levels
-     * The target server must not provide information for any target
-     * managers unless the source explicitly requests it.
-     * For each manager class, if the target server's support level
+	}
+	/**
+	 * Write manager levels
+	 * The target server must not provide information for any target
+	 * managers unless the source explicitly requests it.
+	 * For each manager class, if the target server's support level
      * is greater than or equal to the source server's level, then the source
      * server's level is returned for that class if the target server can operate
      * at the source's level; otherwise a level 0 is returned.  If the target
@@ -1403,3533 +1504,3777 @@
      * The manager levels the source server specifies or the target server
      * returns must be compatible with the manager-level dependencies of the specified
      * manangers.  Incompatible manager levels cannot be specified.
-     *  Instance variables
-     *		MGRLVL - repeatable, required
-     *		  CODEPOINT
-     *			CCSIDMGR - CCSID Manager
-     *			CMNAPPC - LU 6.2 Conversational Communications Manager 
-     *			CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager
-     *			CMNTCPIP - TCP/IP Communication Manager   
-     *			DICTIONARY - Dictionary 
-     *			RDB - Relational Database 
-     *			RSYNCMGR - Resynchronization Manager   
-     *			SECMGR - Security Manager
-     *			SQLAM - SQL Application Manager 
-     *			SUPERVISOR - Supervisor 
-     *			SYNCPTMGR - Sync Point Manager 
-     *			XAMGR - XA manager 
-     *		  VALUE
-     */
-    private void writeMGRLEVELS() throws DRDAProtocolException {
-	int manager;
-	int appLevel;
-	int serverLevel;
-	writer.startDdm(CodePoint.MGRLVLLS);
-	for (int i = 0; i < knownManagers.size(); i++) {
-	    manager = ((Integer)knownManagers.elementAt(i)).intValue();
-	    appLevel = appRequester.getManagerLevel(manager);
-	    serverLevel = server.getManagerLevel(manager);
-	    if (serverLevel >= appLevel) {
-		//Note appLevel has already been set to 0 if we can't support
-		//the original app Level
-		writer.writeCodePoint4Bytes(manager, appLevel);
-	    } else {
-		writer.writeCodePoint4Bytes(manager, serverLevel);
-		// reset application manager level to server level
-		appRequester.setManagerLevel(manager, serverLevel);
-	    }
-	}
-	// write 0 for all unknown managers
-	for (int i = 0; i < unknownManagers.size(); i++) {
-	    manager = ((Integer)unknownManagers.elementAt(i)).intValue();
-	    writer.writeCodePoint4Bytes(manager, 0);
+	 *  Instance variables
+	 *		MGRLVL - repeatable, required
+	 *		  CODEPOINT
+	 *			CCSIDMGR - CCSID Manager
+	 *			CMNAPPC - LU 6.2 Conversational Communications Manager 
+	 *			CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager
+	 *			CMNTCPIP - TCP/IP Communication Manager   
+	 *			DICTIONARY - Dictionary 
+	 *			RDB - Relational Database 
+	 *			RSYNCMGR - Resynchronization Manager   
+	 *			SECMGR - Security Manager
+	 *			SQLAM - SQL Application Manager 
+	 *			SUPERVISOR - Supervisor 
+	 *			SYNCPTMGR - Sync Point Manager 
+	 *			XAMGR - XA manager 
+	 *		  VALUE
+	 */
+	private void writeMGRLEVELS() throws DRDAProtocolException
+	{
+		int manager;
+		int appLevel;
+		int serverLevel;
+		writer.startDdm(CodePoint.MGRLVLLS);
+		for (int i = 0; i < knownManagers.size(); i++)
+		{
+			manager = ((Integer)knownManagers.elementAt(i)).intValue();
+			appLevel = appRequester.getManagerLevel(manager);
+			serverLevel = server.getManagerLevel(manager);
+			if (serverLevel >= appLevel)
+			{
+				//Note appLevel has already been set to 0 if we can't support
+				//the original app Level
+				writer.writeCodePoint4Bytes(manager, appLevel);
+			}
+			else
+			{
+				writer.writeCodePoint4Bytes(manager, serverLevel);
+				// reset application manager level to server level
+				appRequester.setManagerLevel(manager, serverLevel);
+			}
+		}
+		// write 0 for all unknown managers
+		for (int i = 0; i < unknownManagers.size(); i++)
+		{
+			manager = ((Integer)unknownManagers.elementAt(i)).intValue();
+			writer.writeCodePoint4Bytes(manager, 0);
+		}
+		writer.endDdm();
 	}
-	writer.endDdm();
-    }
-    /**
-     *  Parse Access Security
-     *
-     *	If the target server supports the SECMEC requested by the application requester
-     *	then a single value is returned and it is identical to the SECMEC value
-     *	in the ACCSEC command.  If the target server does not support the SECMEC
-     *	requested, then one or more values are returned and the application requester
-     *  must choose one of these values for the security mechanism.
-     *  We currently support
-     *		- user id and password (default for JCC)
-     *		- encrypted user id and password
-     *
+	/**
+	 *  Parse Access Security
+	 *
+	 *	If the target server supports the SECMEC requested by the application requester
+	 *	then a single value is returned and it is identical to the SECMEC value
+	 *	in the ACCSEC command.  If the target server does not support the SECMEC
+	 *	requested, then one or more values are returned and the application requester
+	 *  must choose one of these values for the security mechanism.
+	 *  We currently support
+	 *		- user id and password (default for JCC)
+	 *		- encrypted user id and password
+	 *
      *  Instance variables
-     *    SECMGRNM  - security manager name - optional
-     *	  SECMEC 	- security mechanism - required
-     *	  RDBNAM	- relational database name - optional
-     * 	  SECTKN	- security token - optional, (required if sec mech. needs it)
-     *
-     *  @return security check code - 0 if everything O.K.
-     */
-    private int parseACCSEC() throws  DRDAProtocolException {
-	int securityCheckCode = 0;
-	int securityMechanism = 0;
-	byte [] publicKeyIn = null;
-
-	reader.markCollection();
-	int codePoint = reader.getCodePoint();
-	while (codePoint != -1) {
-	    switch(codePoint) {
-		//optional
-	    case CodePoint.SECMGRNM:
-		// this is defined to be 0 length
-		if (reader.getDdmLength() != 0)
-		    badObjectLength(CodePoint.SECMGRNM);
-		break;
-		//required
-	    case CodePoint.SECMEC:
-		checkLength(CodePoint.SECMEC, 2);
-		securityMechanism = reader.readNetworkShort();
-		if (SanityManager.DEBUG)
-		    trace("Security mechanism = " + securityMechanism);
+	 *    SECMGRNM  - security manager name - optional
+	 *	  SECMEC 	- security mechanism - required
+	 *	  RDBNAM	- relational database name - optional
+	 * 	  SECTKN	- security token - optional, (required if sec mech. needs it)
+	 *
+	 *  @return security check code - 0 if everything O.K.
+	 */
+	private int parseACCSEC() throws  DRDAProtocolException
+	{
+		int securityCheckCode = 0;
+		int securityMechanism = 0;
+		byte [] publicKeyIn = null;
+
+		reader.markCollection();
+		int codePoint = reader.getCodePoint();
+		while (codePoint != -1)
+		{
+			switch(codePoint)
+			{
+				//optional
+				case CodePoint.SECMGRNM:
+					// this is defined to be 0 length
+					if (reader.getDdmLength() != 0)
+						badObjectLength(CodePoint.SECMGRNM);
+					break;
+				//required
+				case CodePoint.SECMEC:
+					checkLength(CodePoint.SECMEC, 2);
+					securityMechanism = reader.readNetworkShort();
+					if (SanityManager.DEBUG)
+						trace("Security mechanism = " + securityMechanism);
                     
-		// if Property.DRDA_PROP_SECURITYMECHANISM has been set, then
-		// network server only accepts connections which use that
-		// security mechanism. No other types of connections 
-		// are accepted.
-		// Make check to see if this property has been set.
-		// if set, and if the client requested security mechanism 
-		// is not the same, then return a security check code 
-		// that the server does not support/allow this security 
-		// mechanism
-		if ( (server.getSecurityMechanism() != 
-		      NetworkServerControlImpl.INVALID_OR_NOTSET_SECURITYMECHANISM)
-		     && securityMechanism != server.getSecurityMechanism())
-		    securityCheckCode = CodePoint.SECCHKCD_NOTSUPPORTED;
-		else {
-		    // for plain text userid,password USRIDPWD, and USRIDONL
-		    // no need of decryptionManager
-		    if (securityMechanism != CodePoint.SECMEC_USRIDPWD &&

[... 11306 lines stripped ...]


Mime
View raw message