Source Code Cross Referenced for NetworkServerControlImpl.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » drda » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.drda 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.drda.NetworkServerControlImpl
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.drda;
0023:
0024:        import java.io.ByteArrayInputStream;
0025:        import java.io.ByteArrayOutputStream;
0026:        import java.io.DataOutputStream;
0027:        import java.io.FilterOutputStream;
0028:        import java.io.IOException;
0029:        import java.io.InputStream;
0030:        import java.io.OutputStream;
0031:        import java.io.PrintStream;
0032:        import java.io.PrintWriter;
0033:        import java.net.InetAddress;
0034:        import java.net.ServerSocket;
0035:        import java.net.Socket;
0036:        import java.net.UnknownHostException;
0037:        import java.security.AccessController;
0038:        import java.security.PrivilegedActionException;
0039:        import java.security.PrivilegedExceptionAction;
0040:        import java.sql.Connection;
0041:        import java.sql.Driver;
0042:        import java.sql.DriverManager;
0043:        import java.sql.SQLException;
0044:        import java.sql.SQLWarning;
0045:        import java.util.ArrayList;
0046:        import java.util.Enumeration;
0047:        import java.util.Hashtable;
0048:        import java.util.Properties;
0049:        import java.util.StringTokenizer;
0050:        import java.util.Vector;
0051:
0052:        import org.apache.derby.drda.NetworkServerControl;
0053:        import org.apache.derby.iapi.error.StandardException;
0054:        import org.apache.derby.iapi.jdbc.DRDAServerStarter;
0055:        import org.apache.derby.iapi.reference.Attribute;
0056:        import org.apache.derby.iapi.reference.DRDAConstants;
0057:        import org.apache.derby.iapi.reference.Property;
0058:        import org.apache.derby.iapi.reference.SQLState;
0059:        import org.apache.derby.iapi.services.i18n.MessageService;
0060:        import org.apache.derby.iapi.services.info.JVMInfo;
0061:        import org.apache.derby.iapi.services.info.ProductGenusNames;
0062:        import org.apache.derby.iapi.services.info.ProductVersionHolder;
0063:        import org.apache.derby.iapi.services.monitor.Monitor;
0064:        import org.apache.derby.iapi.services.property.PropertyUtil;
0065:        import org.apache.derby.iapi.services.sanity.SanityManager;
0066:        import org.apache.derby.iapi.tools.i18n.LocalizedOutput;
0067:        import org.apache.derby.iapi.tools.i18n.LocalizedResource;
0068:        import org.apache.derby.iapi.util.CheapDateFormatter;
0069:        import org.apache.derby.iapi.util.StringUtil;
0070:        import org.apache.derby.impl.jdbc.EmbedSQLException;
0071:
0072:        /** 
0073:        
0074:         NetworkServerControlImpl does all the work for NetworkServerControl
0075:         @see NetworkServerControl for description
0076:
0077:         */
0078:        public final class NetworkServerControlImpl {
0079:            private final static int NO_USAGE_MSGS = 12;
0080:            private final static String[] COMMANDS = { "start", "shutdown",
0081:                    "trace", "tracedirectory", "ping", "logconnections",
0082:                    "sysinfo", "runtimeinfo", "maxthreads", "timeslice" };
0083:            // number of required arguments for each command
0084:            private final static int[] COMMAND_ARGS = { 0, 0, 1, 1, 0, 1, 0, 0,
0085:                    1, 1 };
0086:            private final static int COMMAND_START = 0;
0087:            private final static int COMMAND_SHUTDOWN = 1;
0088:            private final static int COMMAND_TRACE = 2;
0089:            private final static int COMMAND_TRACEDIRECTORY = 3;
0090:            private final static int COMMAND_TESTCONNECTION = 4;
0091:            private final static int COMMAND_LOGCONNECTIONS = 5;
0092:            private final static int COMMAND_SYSINFO = 6;
0093:            private final static int COMMAND_RUNTIME_INFO = 7;
0094:            private final static int COMMAND_MAXTHREADS = 8;
0095:            private final static int COMMAND_TIMESLICE = 9;
0096:            private final static int COMMAND_PROPERTIES = 10;
0097:            private final static int COMMAND_UNKNOWN = -1;
0098:            private final static String[] DASHARGS = { "p", "d", "u", "ld",
0099:                    "ea", "ep", "b", "h", "s" };
0100:            private final static int DASHARG_PORT = 0;
0101:            private final static int DASHARG_DATABASE = 1;
0102:            private final static int DASHARG_USER = 2;
0103:            private final static int DASHARG_LOADSYSIBM = 3;
0104:            private final static int DASHARG_ENCALG = 4;
0105:            private final static int DASHARG_ENCPRV = 5;
0106:            private final static int DASHARG_BOOTPASSWORD = 6;
0107:            private final static int DASHARG_HOST = 7;
0108:            private final static int DASHARG_SESSION = 8;
0109:
0110:            // command protocol version - you need to increase this number each time
0111:            // the command protocol changes 
0112:            private final static int PROTOCOL_VERSION = 1;
0113:            private final static String COMMAND_HEADER = "CMD:";
0114:            private final static String REPLY_HEADER = "RPY:";
0115:            private final static int REPLY_HEADER_LENGTH = REPLY_HEADER
0116:                    .length();
0117:            private final static int OK = 0;
0118:            private final static int WARNING = 1;
0119:            private final static int ERROR = 2;
0120:            private final static int SQLERROR = 3;
0121:            private final static int SQLWARNING = 4;
0122:
0123:            private final static String DRDA_PROP_MESSAGES = "org.apache.derby.loc.drda.messages";
0124:            private final static String DRDA_PROP_DEBUG = "derby.drda.debug";
0125:            private final static String CLOUDSCAPE_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
0126:
0127:            public final static String UNEXPECTED_ERR = "Unexpected exception";
0128:
0129:            private final static int MIN_MAXTHREADS = -1;
0130:            private final static int MIN_TIMESLICE = -1;
0131:            private final static int USE_DEFAULT = -1;
0132:            private final static int DEFAULT_MAXTHREADS = 0; //for now create whenever needed
0133:            private final static int DEFAULT_TIMESLICE = 0; //for now never yield
0134:
0135:            private final static String DEFAULT_HOST = "localhost";
0136:            private final static String DRDA_MSG_PREFIX = "DRDA_";
0137:            private final static String DEFAULT_LOCALE = "en";
0138:            private final static String DEFAULT_LOCALE_COUNTRY = "US";
0139:
0140:            // Check up to 10 seconds to see if shutdown occurred
0141:            private final static int SHUTDOWN_CHECK_ATTEMPTS = 20;
0142:            private final static int SHUTDOWN_CHECK_INTERVAL = 500;
0143:
0144:            // maximum reply size
0145:            private final static int MAXREPLY = 32767;
0146:
0147:            // Application Server Attributes.
0148:            protected static String att_srvclsnm;
0149:            protected final static String ATT_SRVNAM = "NetworkServerControl";
0150:
0151:            protected static String att_extnam;
0152:            protected static String att_srvrlslv;
0153:            protected static String prdId;
0154:            protected static byte[] prdIdBytes_;
0155:
0156:            private static String buildNumber;
0157:            private static String versionString;
0158:            // we will use single or mixed, not double byte to reduce traffic on the
0159:            // wire, this is in keeping with JCC
0160:            // Note we specify UTF8 for the single byte encoding even though it can
0161:            // be multi-byte.
0162:            protected final static int CCSIDSBC = 1208; //use UTF8
0163:            protected final static int CCSIDMBC = 1208; //use UTF8
0164:            protected final static String DEFAULT_ENCODING = "UTF8"; // use UTF8 for writing
0165:            protected final static int DEFAULT_CCSID = 1208;
0166:            protected final static byte SPACE_CHAR = 32;
0167:
0168:            // Application Server manager levels - this needs to be in sync
0169:            // with CodePoint.MGR_CODEPOINTS
0170:            protected final static int[] MGR_LEVELS = { 7, // AGENT
0171:                    4, // CCSID Manager
0172:                    0, // CNMAPPC not implemented
0173:                    0, // CMNSYNCPT not implemented
0174:                    5, // CMNTCPIP
0175:                    0, // DICTIONARY
0176:                    7, // RDB
0177:                    0, // RSYNCMGR
0178:                    7, // SECMGR
0179:                    7, // SQLAM
0180:                    0, // SUPERVISOR
0181:                    0, // SYNCPTMGR
0182:                    7 // XAMGR
0183:            };
0184:
0185:            protected PrintWriter logWriter; // console
0186:            protected PrintWriter cloudscapeLogWriter; // derby.log
0187:            private static Driver cloudscapeDriver;
0188:
0189:            // error types
0190:            private final static int ERRTYPE_SEVERE = 1;
0191:            private final static int ERRTYPE_USER = 2;
0192:            private final static int ERRTYPE_INFO = 3;
0193:            private final static int ERRTYPE_UNKNOWN = -1;
0194:
0195:            // command argument information
0196:            private Vector commandArgs = new Vector();
0197:            private String databaseArg;
0198:            private String userArg;
0199:            private String passwordArg;
0200:            private String bootPasswordArg;
0201:            private String encAlgArg;
0202:            private String encPrvArg;
0203:            private String hostArg = DEFAULT_HOST;
0204:            private InetAddress hostAddress;
0205:            private int sessionArg;
0206:
0207:            // Used to debug memory in SanityManager.DEBUG mode
0208:            private memCheck mc;
0209:
0210:            // reply buffer
0211:            private byte[] replyBuffer;
0212:            private int replyBufferCount; //length of reply
0213:            private int replyBufferPos; //current position in reply
0214:
0215:            //
0216:            // server configuration
0217:            //
0218:            // static values - set at start can't be changed once server has started
0219:            private int portNumber = NetworkServerControl.DEFAULT_PORTNUMBER; // port server listens to
0220:
0221:            // configurable values
0222:            private String traceDirectory; // directory to place trace files in
0223:            private Object traceDirectorySync = new Object();// object to use for syncing
0224:            private boolean traceAll; // trace all sessions
0225:            private Object traceAllSync = new Object(); // object to use for syncing reading
0226:            // and changing trace all
0227:            private Object serverStartSync = new Object(); // for syncing start of server.
0228:            private boolean logConnections; // log connects
0229:            private Object logConnectionsSync = new Object(); // object to use for syncing 
0230:            // logConnections value
0231:            private int minThreads; // default minimum number of connection threads
0232:            private int maxThreads; // default maximum number of connection threads
0233:            private Object threadsSync = new Object(); // object to use for syncing reading
0234:            // and changing default min and max threads
0235:            private int timeSlice; // default time slice of a session to a thread
0236:            private Object timeSliceSync = new Object();// object to use for syncing reading
0237:            // and changing timeSlice
0238:
0239:            private boolean keepAlive = true; // keepAlive value for client socket 
0240:            private int minPoolSize; //minimum pool size for pooled connections
0241:            private int maxPoolSize; //maximum pool size for pooled connections
0242:            private Object poolSync = new Object(); // object to use for syning reading
0243:
0244:            protected boolean debugOutput = false;
0245:            private boolean cleanupOnStart = false; // Should we clean up when starting the server?
0246:            private boolean restartFlag = false;
0247:
0248:            protected final static int INVALID_OR_NOTSET_SECURITYMECHANISM = -1;
0249:            // variable to store value set to derby.drda.securityMechanism
0250:            // default value is -1 which indicates that this property isnt set or
0251:            // the value is invalid
0252:            private int allowOnlySecurityMechanism = INVALID_OR_NOTSET_SECURITYMECHANISM;
0253:            //
0254:            // variables for a client command session
0255:            //
0256:            private Socket clientSocket = null;
0257:            private InputStream clientIs = null;
0258:            private OutputStream clientOs = null;
0259:            private ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
0260:            private DataOutputStream commandOs = new DataOutputStream(
0261:                    byteArrayOs);
0262:
0263:            private Object shutdownSync = new Object();
0264:            private boolean shutdown;
0265:            private int connNum; // number of connections since server started
0266:            private ServerSocket serverSocket;
0267:            private NetworkServerControlImpl serverInstance;
0268:            private LocalizedResource langUtil;
0269:            public String clientLocale;
0270:            ArrayList localAddresses; // list of local addresses for checking admin
0271:            // commands. 
0272:
0273:            // open sessions
0274:            private Hashtable sessionTable = new Hashtable();
0275:
0276:            // current session
0277:            private Session currentSession;
0278:            // DRDAConnThreads
0279:            private Vector threadList = new Vector();
0280:
0281:            // queue of sessions waiting for a free thread - the queue is managed
0282:            // in a simple first come, first serve manner - no priorities
0283:            private Vector runQueue = new Vector();
0284:
0285:            // number of DRDAConnThreads waiting for something to do
0286:            private int freeThreads;
0287:
0288:            // known application requesters
0289:            private Hashtable appRequesterTable = new Hashtable();
0290:
0291:            // accessed by inner classes for privileged action
0292:            private String propertyFileName;
0293:            private Runnable acceptClients;
0294:
0295:            // if the server is started from the command line, it should shutdown the
0296:            // databases it has booted.
0297:            private boolean shutdownDatabasesOnShutdown = false;
0298:
0299:            /**
0300:             * Can EUSRIDPWD security mechanism be used with 
0301:             * the current JVM
0302:             */
0303:            private static boolean SUPPORTS_EUSRIDPWD = false;
0304:
0305:            /*
0306:             * DRDA Specification for the EUSRIDPWD security mechanism
0307:             * requires DH algorithm support with a 32-byte prime to be
0308:             * used. Not all JCE implementations have support for this.
0309:             * Hence here we need to find out if EUSRIDPWD can be used
0310:             * with the current JVM.
0311:             */
0312:            static {
0313:                try {
0314:                    // The DecryptionManager class will instantiate objects of the required 
0315:                    // security algorithms that are needed for EUSRIDPWD
0316:                    // An exception will be thrown if support is not available
0317:                    // in the JCE implementation in the JVM in which the server
0318:                    // is started.
0319:                    new DecryptionManager();
0320:                    SUPPORTS_EUSRIDPWD = true;
0321:                } catch (Exception e) {
0322:                    // if an exception is thrown, ignore exception.
0323:                    // set SUPPORTS_EUSRIDPWD to false indicating that the server 
0324:                    // does not have support for EUSRIDPWD security mechanism
0325:                    SUPPORTS_EUSRIDPWD = false;
0326:                }
0327:            }
0328:
0329:            // constructor
0330:            public NetworkServerControlImpl() throws Exception {
0331:                init();
0332:                getPropertyInfo();
0333:            }
0334:
0335:            /**
0336:             * Internal constructor for NetworkServerControl API. 
0337:             * @param address - InetAddress to listen on, May not be null.  Throws NPE if null
0338:             * @param portNumber - portNumber to listen on, -1 use propert or default.
0339:             * @throws Exception on error
0340:             * @see NetworkServerControl
0341:             */
0342:            public NetworkServerControlImpl(InetAddress address, int portNumber)
0343:                    throws Exception {
0344:                init();
0345:                getPropertyInfo();
0346:                this .hostAddress = address;
0347:                this .portNumber = (portNumber <= 0) ? this .portNumber
0348:                        : portNumber;
0349:                this .hostArg = address.getHostAddress();
0350:            }
0351:
0352:            private void init() throws Exception {
0353:
0354:                // adjust the application in accordance with derby.ui.locale and derby.ui.codeset
0355:                langUtil = new LocalizedResource(null, null, DRDA_PROP_MESSAGES);
0356:
0357:                serverInstance = this ;
0358:
0359:                //set Server attributes to be used in EXCSAT
0360:                ProductVersionHolder myPVH = getNetProductVersionHolder();
0361:                att_extnam = ATT_SRVNAM + " "
0362:                        + java.lang.Thread.currentThread().getName();
0363:
0364:                att_srvclsnm = myPVH.getProductName();
0365:                versionString = myPVH.getVersionBuildString(true);
0366:
0367:                String majorStr = String.valueOf(myPVH.getMajorVersion());
0368:                String minorStr = String.valueOf(myPVH.getMinorVersion());
0369:                // Maintenance version. Server protocol version.
0370:                // Only changed if client needs to recognize a new server version.
0371:                String drdaMaintStr = String.valueOf(myPVH
0372:                        .getDrdaMaintVersion());
0373:
0374:                // PRDID format as JCC expects it: CSSMMmx
0375:                // MM = major version
0376:                // mm = minor version
0377:                // x = drda MaintenanceVersion
0378:
0379:                prdId = DRDAConstants.DERBY_DRDA_SERVER_ID;
0380:                if (majorStr.length() == 1)
0381:                    prdId += "0";
0382:                prdId += majorStr;
0383:
0384:                if (minorStr.length() == 1)
0385:                    prdId += "0";
0386:
0387:                prdId += minorStr;
0388:
0389:                prdId += drdaMaintStr;
0390:                att_srvrlslv = prdId + "/" + myPVH.getVersionBuildString(true);
0391:                // Precompute this to save some cycles
0392:                prdIdBytes_ = prdId.getBytes(DEFAULT_ENCODING);
0393:
0394:                if (SanityManager.DEBUG) {
0395:                    if (majorStr.length() > 2 || minorStr.length() > 2
0396:                            || drdaMaintStr.length() > 1)
0397:                        SanityManager
0398:                                .THROWASSERT("version values out of expected range  for PRDID");
0399:                }
0400:
0401:                buildNumber = myPVH.getBuildNumber();
0402:            }
0403:
0404:            private PrintWriter makePrintWriter(OutputStream out) {
0405:                if (out != null)
0406:                    return new PrintWriter(out, true /* flush the buffer at the end of each line */);
0407:                else
0408:                    return null;
0409:            }
0410:
0411:            protected static Driver getDriver() {
0412:                return cloudscapeDriver;
0413:            }
0414:
0415:            /********************************************************************************
0416:             * Implementation of NetworkServerControl API
0417:             * The server commands throw exceptions for errors, so that users can handle
0418:             * them themselves in addition to having the errors written to the console
0419:             * and possibly derby.log.  To turn off logging the errors to the console,
0420:             * set the output writer to null.
0421:             ********************************************************************************/
0422:
0423:            /**
0424:             * Set the output stream for console messages
0425:             * If this is set to null, no messages will be written to the console
0426:             *
0427:             * @param outWriter	output stream for console messages
0428:             */
0429:            public void setLogWriter(PrintWriter outWriter) {
0430:                // wrap the user-set outWriter with, autoflush to true.
0431:                // this will ensure that messages to console will be 
0432:                // written out to the outWriter on a println.
0433:                // DERBY-1466
0434:                if (outWriter != null)
0435:                    logWriter = new PrintWriter(outWriter, true);
0436:                else
0437:                    logWriter = outWriter;
0438:            }
0439:
0440:            /**
0441:             * Write an error message to console output stream
0442:             * and throw an exception for this error
0443:             *
0444:             * @param msg	error message
0445:             * @exception Exception
0446:             */
0447:            public void consoleError(String msg) throws Exception {
0448:                consoleMessage(msg);
0449:                throw new Exception(msg);
0450:            }
0451:
0452:            /**
0453:             * Write an exception to console output stream,
0454:             * but only if debugOutput is true.
0455:             *
0456:             * @param e	exception 
0457:             */
0458:            public void consoleExceptionPrint(Exception e) {
0459:                if (debugOutput == true)
0460:                    consoleExceptionPrintTrace(e);
0461:
0462:                return;
0463:            }
0464:
0465:            /**
0466:             * Write an exception (with trace) to console
0467:             * output stream.
0468:             *
0469:             * @param e	exception 
0470:             */
0471:            public void consoleExceptionPrintTrace(Throwable e) {
0472:                consoleMessage(e.getMessage());
0473:                if (logWriter != null) {
0474:                    synchronized (logWriter) {
0475:                        e.printStackTrace(logWriter);
0476:                    }
0477:                } else {
0478:                    e.printStackTrace();
0479:                }
0480:
0481:                if (cloudscapeLogWriter != null) {
0482:                    synchronized (cloudscapeLogWriter) {
0483:                        e.printStackTrace(cloudscapeLogWriter);
0484:                    }
0485:                }
0486:            }
0487:
0488:            /**
0489:             * Write a message to console output stream
0490:             *
0491:             * @param msg	message
0492:             */
0493:            public void consoleMessage(String msg) {
0494:                // print to console if we have one
0495:                if (logWriter != null) {
0496:                    synchronized (logWriter) {
0497:                        logWriter.println(msg);
0498:                    }
0499:                }
0500:                // always print to derby.log
0501:                if (cloudscapeLogWriter != null)
0502:                    synchronized (cloudscapeLogWriter) {
0503:                        Monitor.logMessage(msg);
0504:                    }
0505:            }
0506:
0507:            /**
0508:             * Start a network server.  Launches a separate thread with 
0509:             * DRDAServerStarter.  Want to use Monitor.startModule,
0510:             * so it can all get shutdown when cloudscape shuts down, but 
0511:             * can't get it working right now.
0512:             *
0513:             * @param consoleWriter   PrintWriter to which server console will be 
0514:             *                        output. Null will disable console output.
0515:             *
0516:             *		   
0517:             * @exception Exception	throws an exception if an error occurs
0518:             */
0519:            public void start(PrintWriter consoleWriter) throws Exception {
0520:                DRDAServerStarter starter = new DRDAServerStarter();
0521:                starter.setStartInfo(hostAddress, portNumber, consoleWriter);
0522:                startNetworkServer();
0523:                starter.boot(false, null);
0524:            }
0525:
0526:            /**
0527:             * Start a network server
0528:             *
0529:             * @param consoleWriter   PrintWriter to which server console will be 
0530:             *                        output. Null will disable console output.
0531:             *
0532:             *		   
0533:             * @exception Exception	throws an exception if an error occurs
0534:             */
0535:            public void blockingStart(PrintWriter consoleWriter)
0536:                    throws Exception {
0537:                startNetworkServer();
0538:                setLogWriter(consoleWriter);
0539:                cloudscapeLogWriter = Monitor.getStream().getPrintWriter();
0540:                if (SanityManager.DEBUG && debugOutput) {
0541:                    memCheck.showmem();
0542:                    mc = new memCheck(200000);
0543:                    mc.start();
0544:                }
0545:                // Open a server socket listener      
0546:                try {
0547:                    serverSocket = (ServerSocket) AccessController
0548:                            .doPrivileged(new PrivilegedExceptionAction() {
0549:                                public Object run() throws IOException,
0550:                                        UnknownHostException {
0551:                                    if (hostAddress == null)
0552:                                        hostAddress = InetAddress
0553:                                                .getByName(hostArg);
0554:                                    // Make a list of valid
0555:                                    // InetAddresses for NetworkServerControl
0556:                                    // admin commands.
0557:                                    buildLocalAddressList(hostAddress);
0558:                                    return new ServerSocket(portNumber, 0,
0559:                                            hostAddress);
0560:                                }
0561:                            });
0562:                } catch (PrivilegedActionException e) {
0563:                    Exception e1 = e.getException();
0564:                    if (e1 instanceof  IOException)
0565:                        consolePropertyMessage("DRDA_ListenPort.S",
0566:                                new String[] { Integer.toString(portNumber),
0567:                                        hostArg });
0568:                    if (e1 instanceof  UnknownHostException) {
0569:                        consolePropertyMessage("DRDA_UnknownHost.S", hostArg);
0570:                    } else
0571:                        throw e1;
0572:                } catch (Exception e) {
0573:                    // If we find other (unexpected) errors, we ultimately exit--so make
0574:                    // sure we print the error message before doing so (Beetle 5033).
0575:                    throwUnexpectedException(e);
0576:                }
0577:
0578:                consolePropertyMessage("DRDA_Ready.I", new String[] {
0579:                        Integer.toString(portNumber), att_srvclsnm,
0580:                        versionString, getFormattedTimestamp() });
0581:
0582:                // We accept clients on a separate thread so we don't run into a problem
0583:                // blocking on the accept when trying to process a shutdown
0584:                acceptClients = (Runnable) new ClientThread(this , serverSocket);
0585:                Thread clientThread = (Thread) AccessController
0586:                        .doPrivileged(new PrivilegedExceptionAction() {
0587:                            public Object run() throws Exception {
0588:                                return new Thread(acceptClients);
0589:                            }
0590:                        });
0591:                clientThread.start();
0592:
0593:                // wait until we are told to shutdown or someone sends an InterruptedException
0594:                synchronized (shutdownSync) {
0595:                    try {
0596:                        shutdownSync.wait();
0597:                    } catch (InterruptedException e) {
0598:                        shutdown = true;
0599:                    }
0600:                }
0601:
0602:                // Need to interrupt the memcheck thread if it is sleeping.
0603:                if (mc != null)
0604:                    mc.interrupt();
0605:
0606:                //interrupt client thread
0607:                clientThread.interrupt();
0608:
0609:                // Close out the sessions
0610:                synchronized (sessionTable) {
0611:                    for (Enumeration e = sessionTable.elements(); e
0612:                            .hasMoreElements();) {
0613:                        Session session = (Session) e.nextElement();
0614:                        session.close();
0615:                    }
0616:                }
0617:
0618:                synchronized (threadList) {
0619:                    //interupt any connection threads still active
0620:                    for (int i = 0; i < threadList.size(); i++) {
0621:                        ((DRDAConnThread) threadList.get(i)).close();
0622:                        ((DRDAConnThread) threadList.get(i)).interrupt();
0623:                    }
0624:                    threadList.clear();
0625:                }
0626:
0627:                // close the listener socket
0628:                try {
0629:                    serverSocket.close();
0630:                } catch (IOException e) {
0631:                    consolePropertyMessage("DRDA_ListenerClose.S");
0632:                }
0633:
0634:                // Wake up those waiting on sessions, so
0635:                // they can close down
0636:                synchronized (runQueue) {
0637:                    runQueue.notifyAll();
0638:                }
0639:
0640:                if (shutdownDatabasesOnShutdown) {
0641:
0642:                    // Shutdown Cloudscape
0643:                    try {
0644:                        if (cloudscapeDriver != null)
0645:                            cloudscapeDriver.connect(
0646:                                    "jdbc:derby:;shutdown=true",
0647:                                    (Properties) null);
0648:                    } catch (SQLException sqle) {
0649:                        // If we can't shutdown cloudscape. Perhaps authentication is
0650:                        // set to true or some other reason. We will just print a
0651:                        // message to the console and proceed.
0652:                        String expectedState = StandardException
0653:                                .getSQLStateFromIdentifier(SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);
0654:                        if (!expectedState.equals(sqle.getSQLState())) {
0655:                            consolePropertyMessage("DRDA_ShutdownWarning.I",
0656:                                    sqle.getMessage());
0657:                        }
0658:                    }
0659:                }
0660:
0661:                consolePropertyMessage("DRDA_ShutdownSuccess.I", new String[] {
0662:                        att_srvclsnm, versionString, getFormattedTimestamp() });
0663:
0664:            }
0665:
0666:            /** 
0667:             * Load Cloudscape and save driver for future use.
0668:             * We can't call Driver Manager when the client connects, 
0669:             * because they might be holding the DriverManager lock.
0670:             *
0671:             * 
0672:             */
0673:
0674:            protected void startNetworkServer() throws Exception {
0675:
0676:                // we start the cloudscape server here.
0677:                boolean restartCheck = this .restartFlag;
0678:                synchronized (serverStartSync) {
0679:
0680:                    if (restartCheck == this .restartFlag) {
0681:                        // then we can go ahead and restart the server (odds
0682:                        // that some else has just done so are very slim (but not
0683:                        // impossible--however, even if it does happen, things
0684:                        // should still work correctly, just not as efficiently...))
0685:
0686:                        try {
0687:
0688:                            if (cleanupOnStart) {
0689:                                // we're restarting the server (probably after a shutdown
0690:                                // exception), so we need to clean up first.
0691:
0692:                                // Close and remove sessions on runQueue.
0693:                                synchronized (runQueue) {
0694:                                    for (int i = 0; i < runQueue.size(); i++) {
0695:                                        Session s = (Session) runQueue.get(i);
0696:                                        s.close();
0697:                                        removeFromSessionTable(s.getConnNum());
0698:                                    }
0699:                                    runQueue.clear();
0700:                                }
0701:
0702:                                // DERBY-1326: There could be active threads that
0703:                                // contain old/invalid sessions. These sessions won't
0704:                                // be cleaned up until there is some activity on
0705:                                // them. We could optimize this by going through
0706:                                // sessionTable and closing the sessions' socket
0707:                                // streams.
0708:
0709:                                // Unload driver, then restart the server.
0710:                                cloudscapeDriver = null; // so it gets collected.
0711:                                System.gc();
0712:                            }
0713:
0714:                            // start the server.
0715:                            Class.forName(CLOUDSCAPE_DRIVER).newInstance();
0716:                            cloudscapeDriver = DriverManager
0717:                                    .getDriver(Attribute.PROTOCOL);
0718:
0719:                        } catch (Exception e) {
0720:                            consolePropertyMessage("DRDA_LoadException.S", e
0721:                                    .getMessage());
0722:                        }
0723:                        cleanupOnStart = true;
0724:                        this .restartFlag = !this .restartFlag;
0725:                    }
0726:                    // else, multiple threads hit this synchronize block at the same
0727:                    // time, but one of them already executed it--so all others just
0728:                    // return and do nothing (no need to restart the server multiple
0729:                    // times in a row).
0730:                }
0731:            }
0732:
0733:            /**
0734:             * Shutdown a network server
0735:             *
0736:             * @exception Exception	throws an exception if an error occurs
0737:             */
0738:            public void shutdown() throws Exception {
0739:                setUpSocket();
0740:                writeCommandHeader(COMMAND_SHUTDOWN);
0741:                send();
0742:                readResult();
0743:                // Wait up to 10 seconds for things to really shut down
0744:                // need a quiet ping so temporarily disable the logwriter
0745:                PrintWriter savWriter = logWriter;
0746:                // DERBY-1571: If logWriter is null, stack traces are printed to
0747:                // System.err. Set logWriter to a silent stream to suppress stack
0748:                // traces too.
0749:                FilterOutputStream silentStream = new FilterOutputStream(null) {
0750:                    public void write(int b) {
0751:                    }
0752:
0753:                    public void flush() {
0754:                    }
0755:
0756:                    public void close() {
0757:                    }
0758:                };
0759:                setLogWriter(new PrintWriter(silentStream));
0760:                int ntry;
0761:                for (ntry = 0; ntry < SHUTDOWN_CHECK_ATTEMPTS; ntry++) {
0762:                    Thread.sleep(SHUTDOWN_CHECK_INTERVAL);
0763:                    try {
0764:                        ping();
0765:                    } catch (Exception e) {
0766:                        // as soon as we can't ping return
0767:                        if (ntry == SHUTDOWN_CHECK_ATTEMPTS)
0768:                            consolePropertyMessage("DRDA_ShutdownError.S",
0769:                                    new String[] {
0770:                                            Integer.toString(portNumber),
0771:                                            hostArg });
0772:                        break;
0773:                    }
0774:                }
0775:                logWriter = savWriter;
0776:                return;
0777:            }
0778:
0779:            /*
0780:             Shutdown the server directly (If you have the original object)
0781:             No Network communication needed.
0782:             */
0783:            public void directShutdown() {
0784:                shutdown = true;
0785:                synchronized (shutdownSync) {
0786:                    // wake up the server thread
0787:                    shutdownSync.notifyAll();
0788:                }
0789:
0790:            }
0791:
0792:            /**
0793:             */
0794:            public boolean isServerStarted() throws Exception {
0795:                try {
0796:                    ping();
0797:                } catch (Exception e) {
0798:                    return false;
0799:                }
0800:                return true;
0801:            }
0802:
0803:            public void ping() throws Exception {
0804:                // database no longer used, but don't change the protocol 
0805:                // in case we add
0806:                // authorization  later.
0807:                String database = null; // no longer used but don't change the protocol
0808:                String user = null;
0809:                String password = null;
0810:
0811:                setUpSocket();
0812:                writeCommandHeader(COMMAND_TESTCONNECTION);
0813:                writeLDString(database);
0814:                writeLDString(user);
0815:                writeLDString(password);
0816:                send();
0817:                readResult();
0818:
0819:            }
0820:
0821:            /**
0822:             * Turn tracing on or off for all sessions
0823:             *
0824:             * @param on			true to turn tracing on, false to turn tracing off
0825:             *
0826:             * @exception Exception	throws an exception if an error occurs
0827:             */
0828:            public void trace(boolean on) throws Exception {
0829:                trace(0, on);
0830:            }
0831:
0832:            /**
0833:             * Turn tracing on or off for one session or all sessions
0834:             *
0835:             * @param connNum	the connNum of the session, 0 if all sessions
0836:             * @param on			true to turn tracing on, false to turn tracing off
0837:             *
0838:             * @exception Exception	throws an exception if an error occurs
0839:             */
0840:            public void trace(int connNum, boolean on) throws Exception {
0841:                setUpSocket();
0842:                writeCommandHeader(COMMAND_TRACE);
0843:                commandOs.writeInt(connNum);
0844:                writeByte(on ? 1 : 0);
0845:                send();
0846:                readResult();
0847:                consoleTraceMessage(connNum, on);
0848:            }
0849:
0850:            /**
0851:             * Print trace change message to console
0852:             *
0853:             * @param on			true to print tracing on, false to print tracing off
0854:             *
0855:             * @exception Exception	throws an exception if an error occurs
0856:             */
0857:            private void consoleTraceMessage(int connNum, boolean on)
0858:                    throws Exception {
0859:                if (connNum == 0)
0860:                    consolePropertyMessage("DRDA_TraceChangeAll.I",
0861:                            on ? "DRDA_ON.I" : "DRDA_OFF.I");
0862:                else {
0863:                    String[] args = new String[2];
0864:                    args[0] = on ? "DRDA_ON.I" : "DRDA_OFF.I";
0865:                    args[1] = new Integer(connNum).toString();
0866:                    consolePropertyMessage("DRDA_TraceChangeOne.I", args);
0867:                }
0868:            }
0869:
0870:            /**
0871:             * Turn logging connections on or off. When logging is turned on a message is
0872:             * written to derby.log each time a connection is made.
0873:             *
0874:             * @param on			true to turn on, false to turn  off
0875:             *
0876:             * @exception Exception	throws an exception if an error occurs
0877:             */
0878:            public void logConnections(boolean on) throws Exception {
0879:                setUpSocket();
0880:                writeCommandHeader(COMMAND_LOGCONNECTIONS);
0881:                writeByte(on ? 1 : 0);
0882:                send();
0883:                readResult();
0884:            }
0885:
0886:            /**
0887:             *@see NetworkServerControl#setTraceDirectory
0888:             */
0889:            public void sendSetTraceDirectory(String traceDirectory)
0890:                    throws Exception {
0891:                setUpSocket();
0892:                writeCommandHeader(COMMAND_TRACEDIRECTORY);
0893:                writeLDString(traceDirectory);
0894:                send();
0895:                readResult();
0896:            }
0897:
0898:            /**
0899:             *@see NetworkServerControl#getSysinfo
0900:             */
0901:            public String sysinfo() throws Exception {
0902:                setUpSocket();
0903:                writeCommandHeader(COMMAND_SYSINFO);
0904:                send();
0905:                return readStringReply("DRDA_SysInfoError.S");
0906:            }
0907:
0908:            /**
0909:             *@see NetworkServerControl#getRuntimeInfo
0910:             */
0911:            public String runtimeInfo() throws Exception {
0912:                setUpSocket();
0913:                writeCommandHeader(COMMAND_RUNTIME_INFO);
0914:                send();
0915:                return readStringReply("DRDA_RuntimeInfoError.S");
0916:            }
0917:
0918:            /**
0919:             * Display usage information
0920:             *
0921:             */
0922:            public void usage() {
0923:                try {
0924:                    for (int i = 1; i <= NO_USAGE_MSGS; i++)
0925:                        consolePropertyMessage("DRDA_Usage" + i + ".I");
0926:                } catch (Exception e) {
0927:                } // ignore exceptions - there shouldn't be any
0928:            }
0929:
0930:            /**
0931:             * Connect to  network server and set connection maxthread parameter
0932:             *
0933:             * @param max		maximum number of connections, if 0, connections 
0934:             *						created when no free connection available
0935:             *						if -1, use default
0936:             *
0937:             * @exception Exception	throws an exception if an error occurs
0938:             */
0939:            public void netSetMaxThreads(int max) throws Exception {
0940:                setUpSocket();
0941:                writeCommandHeader(COMMAND_MAXTHREADS);
0942:                commandOs.writeInt(max);
0943:                send();
0944:                readResult();
0945:                int newval = readInt();
0946:                consolePropertyMessage("DRDA_MaxThreadsChange.I", new Integer(
0947:                        newval).toString());
0948:            }
0949:
0950:            /**
0951:             * Set network server connection timeslice parameter
0952:             *
0953:             * @param timeslice	amount of time given to each session before yielding to 
0954:             *						another session, if 0, never yield. if -1, use default.
0955:             *
0956:             * @exception Exception	throws an exception if an error occurs
0957:             */
0958:            public void netSetTimeSlice(int timeslice) throws Exception {
0959:                setUpSocket();
0960:                writeCommandHeader(COMMAND_TIMESLICE);
0961:                commandOs.writeInt(timeslice);
0962:                send();
0963:                readResult();
0964:                int newval = readInt();
0965:                consolePropertyMessage("DRDA_TimeSliceChange.I", new Integer(
0966:                        newval).toString());
0967:            }
0968:
0969:            /**
0970:             * Get current properties
0971:             *
0972:             * @return Properties object containing properties
0973:             * @exception Exception	throws an exception if an error occurs
0974:             */
0975:            public Properties getCurrentProperties() throws Exception {
0976:                setUpSocket();
0977:                writeCommandHeader(COMMAND_PROPERTIES);
0978:                send();
0979:                byte[] val = readBytesReply("DRDA_PropertyError.S");
0980:                Properties p = new Properties();
0981:                try {
0982:                    ByteArrayInputStream bs = new ByteArrayInputStream(val);
0983:                    p.load(bs);
0984:                } catch (IOException io) {
0985:                    consolePropertyMessage("DRDA_IOException.S", io
0986:                            .getMessage());
0987:                }
0988:                return p;
0989:            }
0990:
0991:            /**
0992:             * Set a thread name to be something that is both meaningful and unique (primarily
0993:             * for debugging purposes).
0994:             *
0995:             * The received thread's name is set to a new string of the form
0996:             *  [newName + "_n"], where 'n' is a unique thread id originally generated
0997:             *  by the jvm Thread constructor.  If the default name of the thread has
0998:             *  been changed before getting here, then nothing is done.
0999:             *
1000:             * @param thrd An instance of a Thread object that still has its default
1001:             *  thread name (as generated by the jvm Thread constructor).  This should
1002:             *  always be of the form "Thread-N", where N is a unique thread id
1003:             *  generated by the jvm.  Ex. "Thread-0", "Thread-1", etc.
1004:             *
1005:             **/
1006:            public static void setUniqueThreadName(Thread thrd, String newName) {
1007:
1008:                // First, pull off the unique thread id already found in thrd's default name;
1009:                // we do so by searching for the '-' character, and then counting everything
1010:                // after it as a N.
1011:                if (thrd.getName().indexOf("Thread-") == -1) {
1012:                    // default name has been changed; don't do anything.
1013:                    return;
1014:                } else {
1015:                    String oldName = thrd.getName();
1016:                    thrd.setName(newName
1017:                            + "_"
1018:                            + oldName.substring(oldName.indexOf("-") + 1,
1019:                                    oldName.length()));
1020:                } // end else.
1021:
1022:                return;
1023:
1024:            }
1025:
1026:            /*******************************************************************************/
1027:            /*        Protected methods                                                    */
1028:            /*******************************************************************************/
1029:            /**
1030:             * Remove session from session table
1031:             *
1032:             * @param sessionid 	id of session to be removed
1033:             */
1034:            protected void removeFromSessionTable(int sessionid) {
1035:                sessionTable.remove(new Integer(sessionid));
1036:            }
1037:
1038:            /**
1039:             * 	processCommands reads and processes NetworkServerControlImpl commands sent
1040:             * 	to the network server over the socket.  The protocol used is
1041:             * 		4 bytes 	- String CMD:
1042:             * 		2 bytes		- Protocol version
1043:             *		1 byte		- length of locale (0 for default)
1044:             *			n bytes - locale
1045:             *		1 byte		- length of codeset (0 for default)
1046:             *			n bytes - codeset
1047:             * 		1 byte		- command
1048:             * 		n bytes		- parameters for the command
1049:             * 	The server returns
1050:             *		4 bytes		- String RPY:
1051:             *	for most commands
1052:             *		1 byte		- command result, 0 - OK, 1 - warning, 2 - error
1053:             *	 if warning or error
1054:             *		1 bytes		- length of message key
1055:             *		n bytes		- message key
1056:             *		1 byte		- number of parameters to message
1057:             *		{2 bytes		- length of parameter
1058:             *		n bytes		- parameter} for each parameter
1059:             *  for sysinfo
1060:             *		1 byte		- command result, 0 - OK, 1 - warning, 2 - error
1061:             *   if OK 
1062:             *		2 bytes		- length of sysinfo
1063:             *		n bytes		- sysinfo
1064:             *		
1065:             * 		
1066:             * 	Note, the 3rd byte of the command must not be 'D0' to distinquish it 
1067:             *	from DSS structures.
1068:             * 	The protocol for the parameters for each command follows:
1069:             *
1070:             * 	Command: trace <connection id> {on | off}
1071:             * 	Protocol:
1072:             * 		4 bytes		- connection id - connection id of 0 means all sessions
1073:             * 		1 byte		- 0 off, 1 on
1074:             * 
1075:             * 	Command: logConnections {on | off}
1076:             * 	Protocol:
1077:             * 		1 byte		- 0 off, 1 on
1078:             * 
1079:             * 	Command: shutdown
1080:             * 	No parameters
1081:             * 
1082:             * 	Command: sysinfo
1083:             * 	No parameters
1084:             * 
1085:             * 	Command: dbstart
1086:             * 	Protocol:
1087:             * 		2 bytes		- length of database name
1088:             * 		n bytes		- database name
1089:             * 		2 bytes		- length of boot password
1090:             * 		n bytes		- boot password 
1091:             * 		2 bytes		- length of encryption algorithm
1092:             * 		n bytes		- encryption algorithm
1093:             * 		2 bytes		- length of encryption provider
1094:             * 		n bytes		- encryption provider
1095:             * 		2 bytes		- length of user name
1096:             * 		n bytes		- user name
1097:             * 		2 bytes		- length of password
1098:             * 		n bytes		- password
1099:             *
1100:             * 	Command: dbshutdown
1101:             * 	Protocol:
1102:             * 		2 bytes		- length of database name
1103:             * 		n bytes		- database name
1104:             * 		2 bytes		- length of user name
1105:             * 		n bytes		- user name
1106:             * 		2 bytes		- length of password
1107:             * 		n bytes		- password
1108:             *
1109:             * 	Command: connpool
1110:             * 	Protocol:
1111:             * 		2 bytes		- length of database name, if 0, default for all databases
1112:             *						is set
1113:             * 		n bytes		- database name
1114:             *		2 bytes		- minimum number of connections, if 0, connection pool not used
1115:             *						if value is -1 use default
1116:             *		2 bytes		- maximum number of connections, if 0, connections are created
1117:             *						as needed, if value is -1 use default
1118:             *
1119:             * 	Command: maxthreads
1120:             * 	Protocol:
1121:             *		2 bytes		- maximum number of threads
1122:             *
1123:             * 	Command: timeslice 
1124:             * 	Protocol:
1125:             *		4 bytes		- timeslice value
1126:             *
1127:             * 	Command: tracedirectory
1128:             * 	Protocol:
1129:             * 		2 bytes		- length of directory name
1130:             * 		n bytes		- directory name
1131:             *
1132:             *	Command: test connection
1133:             * 	Protocol:
1134:             * 		2 bytes		- length of database name if 0, just the connection
1135:             *						to the network server is tested and user name and 
1136:             *						password aren't sent
1137:             * 		n bytes		- database name
1138:             * 		2 bytes		- length of user name (optional)
1139:             * 		n bytes		- user name
1140:             * 		2 bytes		- length of password  (optional)
1141:             * 		n bytes		- password
1142:             *
1143:             *	The calling routine is synchronized so that multiple threads don't clobber each
1144:             * 	other. This means that configuration commands will be serialized.
1145:             * 	This shouldn't be a problem since they should be fairly rare.
1146:             * 		
1147:             * @param reader	input reader for command
1148:             * @param writer output writer for command
1149:             * @param session	session information
1150:             *
1151:             * @exception Throwable	throws an exception if an error occurs
1152:             */
1153:            protected synchronized void processCommands(DDMReader reader,
1154:                    DDMWriter writer, Session session) throws Throwable {
1155:                try {
1156:                    String protocolStr = reader.readCmdString(4);
1157:                    String locale = DEFAULT_LOCALE;
1158:                    String codeset = null;
1159:                    // get the version
1160:                    int version = reader.readNetworkShort();
1161:                    if (version <= 0 || version > PROTOCOL_VERSION)
1162:                        throw new Throwable(langUtil.getTextMessage(
1163:                                "DRDA_UnknownProtocol.S", new Integer(version)
1164:                                        .toString()));
1165:                    int localeLen = reader.readByte();
1166:                    if (localeLen > 0) {
1167:                        currentSession = session;
1168:                        locale = reader.readCmdString(localeLen);
1169:                        session.langUtil = new LocalizedResource(codeset,
1170:                                locale, DRDA_PROP_MESSAGES);
1171:                    }
1172:                    String notLocalMessage = null;
1173:                    // for now codesetLen is always 0
1174:                    int codesetLen = reader.readByte();
1175:                    int command = reader.readByte();
1176:                    if (command != COMMAND_TESTCONNECTION) {
1177:                        try {
1178:                            checkAddressIsLocal(session.clientSocket
1179:                                    .getInetAddress());
1180:                        } catch (Exception e) {
1181:                            notLocalMessage = e.getMessage();
1182:                        }
1183:                    }
1184:                    if (notLocalMessage != null) {
1185:                        sendMessage(writer, ERROR, notLocalMessage);
1186:                        session.langUtil = null;
1187:                        currentSession = null;
1188:                        return;
1189:                    }
1190:
1191:                    switch (command) {
1192:                    case COMMAND_SHUTDOWN:
1193:                        sendOK(writer);
1194:                        directShutdown();
1195:                        break;
1196:                    case COMMAND_TRACE:
1197:                        sessionArg = reader.readNetworkInt();
1198:                        boolean on = (reader.readByte() == 1);
1199:                        if (setTrace(on)) {
1200:                            sendOK(writer);
1201:                        } else {
1202:                            sendMessage(writer, ERROR, localizeMessage(
1203:                                    "DRDA_SessionNotFound.U",
1204:                                    (session.langUtil == null) ? langUtil
1205:                                            : session.langUtil,
1206:                                    new String[] { new Integer(sessionArg)
1207:                                            .toString() }));
1208:                        }
1209:                        break;
1210:                    case COMMAND_TRACEDIRECTORY:
1211:                        setTraceDirectory(reader.readCmdString());
1212:                        sendOK(writer);
1213:                        consolePropertyMessage("DRDA_TraceDirectoryChange.I",
1214:                                traceDirectory);
1215:                        break;
1216:                    case COMMAND_TESTCONNECTION:
1217:                        databaseArg = reader.readCmdString();
1218:                        userArg = reader.readCmdString();
1219:                        passwordArg = reader.readCmdString();
1220:                        if (databaseArg != null)
1221:                            connectToDatabase(writer, databaseArg, userArg,
1222:                                    passwordArg);
1223:                        else
1224:                            sendOK(writer);
1225:                        break;
1226:                    case COMMAND_LOGCONNECTIONS:
1227:                        boolean log = (reader.readByte() == 1);
1228:                        setLogConnections(log);
1229:                        sendOK(writer);
1230:                        consolePropertyMessage("DRDA_LogConnectionsChange.I",
1231:                                (log ? "DRDA_ON.I" : "DRDA_OFF.I"));
1232:                        break;
1233:                    case COMMAND_SYSINFO:
1234:                        sendSysInfo(writer);
1235:                        break;
1236:                    case COMMAND_PROPERTIES:
1237:                        sendPropInfo(writer);
1238:                        break;
1239:                    case COMMAND_RUNTIME_INFO:
1240:                        sendRuntimeInfo(writer);
1241:                        break;
1242:                    case COMMAND_MAXTHREADS:
1243:                        int max = reader.readNetworkInt();
1244:                        try {
1245:                            setMaxThreads(max);
1246:                        } catch (Exception e) {
1247:                            sendMessage(writer, ERROR, e.getMessage());
1248:                            return;
1249:                        }
1250:                        int newval = getMaxThreads();
1251:                        sendOKInt(writer, newval);
1252:                        consolePropertyMessage("DRDA_MaxThreadsChange.I",
1253:                                new Integer(newval).toString());
1254:                        break;
1255:                    case COMMAND_TIMESLICE:
1256:                        int timeslice = reader.readNetworkInt();
1257:                        try {
1258:                            setTimeSlice(timeslice);
1259:                        } catch (Exception e) {
1260:                            sendMessage(writer, ERROR, e.getMessage());
1261:                            return;
1262:                        }
1263:                        newval = getTimeSlice();
1264:                        sendOKInt(writer, newval);
1265:                        consolePropertyMessage("DRDA_TimeSliceChange.I",
1266:                                new Integer(newval).toString());
1267:                        break;
1268:                    }
1269:                } catch (DRDAProtocolException e) {
1270:                    //we need to handle this since we aren't in DRDA land here
1271:                    consoleExceptionPrintTrace(e);
1272:
1273:                } catch (Exception e) {
1274:                    consoleExceptionPrintTrace(e);
1275:                } finally {
1276:                    session.langUtil = null;
1277:                    currentSession = null;
1278:                }
1279:            }
1280:
1281:            /**
1282:             * Get the next session for the thread to work on
1283:             * Called from DRDAConnThread after session completes or timeslice
1284:             * exceeded.   
1285:             *
1286:             * If there is a waiting session, pick it up and put currentSession 
1287:             * at the back of the queue if there is one.
1288:             * @param currentSession	session thread is currently working on
1289:             *
1290:             * @return  next session to work on, could be same as current session
1291:             */
1292:            protected Session getNextSession(Session currentSession) {
1293:                Session retval = null;
1294:                if (shutdown == true)
1295:                    return retval;
1296:                synchronized (runQueue) {
1297:                    try {
1298:                        // nobody waiting - go on with current session
1299:                        if (runQueue.size() == 0) {
1300:                            // no current session - wait for some work
1301:                            if (currentSession == null) {
1302:                                while (runQueue.size() == 0) {
1303:                                    // This thread has nothing to do now so 
1304:                                    // we will add it to freeThreads
1305:                                    freeThreads++;
1306:                                    runQueue.wait();
1307:                                    if (shutdown == true)
1308:                                        return null;
1309:                                    freeThreads--;
1310:                                }
1311:                            } else
1312:                                return currentSession;
1313:                        }
1314:                        retval = (Session) runQueue.elementAt(0);
1315:                        runQueue.removeElementAt(0);
1316:                        if (currentSession != null)
1317:                            runQueueAdd(currentSession);
1318:                    } catch (InterruptedException e) {
1319:                        // If for whatever reason (ex. database shutdown) a waiting thread is
1320:                        // interrupted while in this method, that thread is going to be
1321:                        // closed down, so we need to decrement the number of threads
1322:                        // that will be available for use.
1323:                        freeThreads--;
1324:                    }
1325:                }
1326:                return retval;
1327:            }
1328:
1329:            /**
1330:             * Get the stored application requester or store if we haven't seen it yet
1331:             *
1332:             * @param appRequester Application Requester to look for
1333:             *
1334:             * @return  stored application requester
1335:             */
1336:            protected AppRequester getAppRequester(AppRequester appRequester) {
1337:                AppRequester s = null;
1338:
1339:                if (SanityManager.DEBUG) {
1340:                    if (appRequester == null)
1341:                        SanityManager
1342:                                .THROWASSERT("null appRequester in getAppRequester");
1343:                }
1344:
1345:                if (!appRequesterTable.isEmpty())
1346:                    s = (AppRequester) appRequesterTable
1347:                            .get(appRequester.prdid);
1348:
1349:                if (s == null) {
1350:                    appRequesterTable.put(appRequester.prdid, appRequester);
1351:                    return appRequester;
1352:                } else {
1353:                    //compare just in case there are some differences
1354:                    //if they are different use the one we just read in
1355:                    if (s.equals(appRequester))
1356:                        return s;
1357:                    else
1358:                        return appRequester;
1359:                }
1360:            }
1361:
1362:            /**
1363:             * Get the server manager level for a given manager
1364:             *
1365:             * @param manager codepoint for manager
1366:             * @return manager level
1367:             */
1368:            protected int getManagerLevel(int manager) {
1369:                int mindex = CodePoint.getManagerIndex(manager);
1370:                if (SanityManager.DEBUG) {
1371:                    if (mindex == CodePoint.UNKNOWN_MANAGER)
1372:                        SanityManager.THROWASSERT("manager out of bounds");
1373:                }
1374:                return MGR_LEVELS[mindex];
1375:            }
1376:
1377:            /**
1378:             * Check whether a CCSID code page is supported
1379:             *
1380:             * @param ccsid	CCSID to check
1381:             * @return true if supported; false otherwise
1382:             */
1383:            protected boolean supportsCCSID(int ccsid) {
1384:                try {
1385:                    CharacterEncodings.getJavaEncoding(ccsid);
1386:                } catch (Exception e) {
1387:                    return false;
1388:                }
1389:                return true;
1390:            }
1391:
1392:            /**
1393:             * Put property message on console
1394:             *
1395:             * @param msgProp		message property key
1396:             *
1397:             * @throws Exception if an error occurs
1398:             */
1399:            protected void consolePropertyMessage(String msgProp)
1400:                    throws Exception {
1401:                consolePropertyMessageWork(msgProp, null);
1402:            }
1403:
1404:            /**
1405:             * Put property message on console
1406:             *
1407:             * @param msgProp		message property key
1408:             * @param arg			argument for message
1409:             *
1410:             * @throws Exception if an error occurs
1411:             */
1412:            protected void consolePropertyMessage(String msgProp, String arg)
1413:                    throws Exception {
1414:                consolePropertyMessageWork(msgProp, new String[] { arg });
1415:            }
1416:
1417:            /**
1418:             * Put property message on console
1419:             *
1420:             * @param msgProp		message property key
1421:             * @param args			argument array for message
1422:             *
1423:             * @throws Exception if an error occurs
1424:             */
1425:            protected void consolePropertyMessage(String msgProp, String[] args)
1426:                    throws Exception {
1427:                consolePropertyMessageWork(msgProp, args);
1428:            }
1429:
1430:            /**
1431:             * Is this the command protocol
1432:             * 
1433:             * @param  val
1434:             */
1435:            protected static boolean isCmd(String val) {
1436:                if (val.equals(COMMAND_HEADER))
1437:                    return true;
1438:                else
1439:                    return false;
1440:            }
1441:
1442:            /*******************************************************************************/
1443:            /*        Private methods                                                      */
1444:            /*******************************************************************************/
1445:            /**
1446:             * Write Command reply
1447:             *
1448:             * @param writer	writer to use 
1449:             *
1450:             * @throws Exception if a problem occurs sending OK
1451:             */
1452:            private void writeCommandReplyHeader(DDMWriter writer)
1453:                    throws Exception {
1454:                writer.setCMDProtocol();
1455:                writer.writeString(REPLY_HEADER);
1456:            }
1457:
1458:            /**
1459:             * Send OK from server to client after processing a command
1460:             *
1461:             * @param writer	writer to use for sending OK
1462:             *
1463:             * @throws Exception if a problem occurs sending OK
1464:             */
1465:            private void sendOK(DDMWriter writer) throws Exception {
1466:                writeCommandReplyHeader(writer);
1467:                writer.writeByte(OK);
1468:                writer.flush();
1469:            }
1470:
1471:            /**
1472:             * Send OK and int value
1473:             *
1474:             * @param writer writer to use for sending
1475:             * @param val 	int val to send
1476:             * 
1477:             * @throws Exception if a problem occurs
1478:             */
1479:            private void sendOKInt(DDMWriter writer, int val) throws Exception {
1480:                writeCommandReplyHeader(writer);
1481:                writer.writeByte(OK);
1482:                writer.writeNetworkInt(val);
1483:                writer.flush();
1484:            }
1485:
1486:            /**
1487:             * Send Error or Warning from server to client after processing a command
1488:             *
1489:             * @param writer	writer to use for sending message
1490:             * @param messageType	1 for Warning, 2 for Error 3 for SQLError
1491:             * @param message 	message 
1492:             *
1493:             * @throws Exception if a problem occurs sending message
1494:             */
1495:            private void sendMessage(DDMWriter writer, int messageType,
1496:                    String message) throws Exception {
1497:                writeCommandReplyHeader(writer);
1498:                writer.writeByte(messageType);
1499:                writer.writeLDString(message);
1500:                writer.flush();
1501:            }
1502:
1503:            /**
1504:             * Send SQL Exception from server to client after processing a command
1505:             *
1506:             * @param writer	writer to use for sending message
1507:             * @param se		Cloudscape exception
1508:             * @param type		type of exception, SQLERROR or SQLWARNING
1509:             *
1510:             * @throws Exception if a problem occurs sending message
1511:             */
1512:            private void sendSQLMessage(DDMWriter writer, SQLException se,
1513:                    int type) throws Exception {
1514:                StringBuffer locMsg = new StringBuffer();
1515:                //localize message if necessary
1516:                while (se != null) {
1517:                    if (currentSession != null
1518:                            && currentSession.langUtil != null
1519:                            && se instanceof  EmbedSQLException) {
1520:                        locMsg.append(se.getSQLState()
1521:                                + ":"
1522:                                + MessageService
1523:                                        .getLocalizedMessage(
1524:                                                currentSession.langUtil
1525:                                                        .getLocale(),
1526:                                                ((EmbedSQLException) se)
1527:                                                        .getMessageId(),
1528:                                                ((EmbedSQLException) se)
1529:                                                        .getArguments()));
1530:                    } else
1531:                        locMsg.append(se.getSQLState() + ":" + se.getMessage());
1532:                    se = se.getNextException();
1533:                    if (se != null)
1534:                        locMsg.append("\n");
1535:                }
1536:                sendMessage(writer, type, locMsg.toString());
1537:            }
1538:
1539:            /**
1540:             * Send SysInfo information from server to client
1541:             *
1542:             * @param writer 	writer to use for sending sysinfo
1543:             *
1544:             * @throws Exception if a problem occurs sending value
1545:             */
1546:            private void sendSysInfo(DDMWriter writer) throws Exception {
1547:                StringBuffer sysinfo = new StringBuffer();
1548:                sysinfo.append(getNetSysInfo());
1549:                sysinfo.append(getCLSSysInfo());
1550:                try {
1551:                    writeCommandReplyHeader(writer);
1552:                    writer.writeByte(0); //O.K.
1553:                    writer.writeLDString(sysinfo.toString());
1554:                } catch (DRDAProtocolException e) {
1555:                    consolePropertyMessage("DRDA_SysInfoWriteError.S", e
1556:                            .getMessage());
1557:                }
1558:                writer.flush();
1559:            }
1560:
1561:            /**
1562:             * Send RuntimeInfo information from server to client
1563:             *
1564:             * @param writer 	writer to use for sending sysinfo
1565:             *
1566:             * @throws Exception if a problem occurs sending value
1567:             */
1568:            private void sendRuntimeInfo(DDMWriter writer) throws Exception {
1569:                try {
1570:                    writeCommandReplyHeader(writer);
1571:                    writer.writeByte(0); //O.K.
1572:                    writer.writeLDString(getRuntimeInfo());
1573:                } catch (DRDAProtocolException e) {
1574:                    consolePropertyMessage("DRDA_SysInfoWriteError.S", e
1575:                            .getMessage());
1576:                }
1577:                writer.flush();
1578:            }
1579:
1580:            /**
1581:             * Send property information from server to client
1582:             *
1583:             * @param writer 	writer to use for sending sysinfo
1584:             *
1585:             * @throws Exception if a problem occurs sending value
1586:             */
1587:            private void sendPropInfo(DDMWriter writer) throws Exception {
1588:                try {
1589:                    ByteArrayOutputStream out = new ByteArrayOutputStream();
1590:                    Properties p = getPropertyValues();
1591:                    p.store(out, "NetworkServerControl properties");
1592:                    try {
1593:                        writeCommandReplyHeader(writer);
1594:                        writer.writeByte(0); //O.K.
1595:                        writer.writeLDBytes(out.toByteArray());
1596:                    } catch (DRDAProtocolException e) {
1597:                        consolePropertyMessage("DRDA_PropInfoWriteError.S", e
1598:                                .getMessage());
1599:                    }
1600:                    writer.flush();
1601:                } catch (Exception e) {
1602:                    consoleExceptionPrintTrace(e);
1603:                }
1604:            }
1605:
1606:            /**
1607:             * Get Net Server information
1608:             *
1609:             * @return system information for the Network Server
1610:             */
1611:            private String getNetSysInfo() {
1612:                StringBuffer sysinfo = new StringBuffer();
1613:                LocalizedResource localLangUtil = langUtil;
1614:                if (currentSession != null && currentSession.langUtil != null)
1615:                    localLangUtil = currentSession.langUtil;
1616:                sysinfo.append(localLangUtil
1617:                        .getTextMessage("DRDA_SysInfoBanner.I")
1618:                        + "\n");
1619:                sysinfo.append(localLangUtil
1620:                        .getTextMessage("DRDA_SysInfoVersion.I")
1621:                        + " " + att_srvrlslv);
1622:                sysinfo.append("  ");
1623:                sysinfo.append(localLangUtil
1624:                        .getTextMessage("DRDA_SysInfoBuild.I")
1625:                        + " " + buildNumber);
1626:                sysinfo.append("  ");
1627:                sysinfo.append(localLangUtil
1628:                        .getTextMessage("DRDA_SysInfoDrdaPRDID.I")
1629:                        + " " + prdId);
1630:                if (SanityManager.DEBUG) {
1631:                    sysinfo.append("  ** SANE BUILD **");
1632:                }
1633:                sysinfo.append("\n");
1634:                // add property information
1635:                Properties p = getPropertyValues();
1636:                ByteArrayOutputStream bos = new ByteArrayOutputStream();
1637:                PrintStream ps = new PrintStream(bos);
1638:                p.list(ps);
1639:                sysinfo.append(bos.toString());
1640:                return sysinfo.toString();
1641:            }
1642:
1643:            /**
1644:             * @see NetworkServerControl#getRuntimeInfo
1645:             */
1646:            private String getRuntimeInfo() {
1647:                return buildRuntimeInfo(langUtil);
1648:            }
1649:
1650:            /**
1651:             * Get Cloudscape information
1652:             *
1653:             * @return system information for Cloudscape
1654:             *
1655:             * @throws IOException if a problem occurs encoding string
1656:             */
1657:            private String getCLSSysInfo() throws IOException {
1658:                ByteArrayOutputStream bos = new ByteArrayOutputStream();
1659:                LocalizedResource localLangUtil = langUtil;
1660:                if (currentSession != null && currentSession.langUtil != null)
1661:                    localLangUtil = currentSession.langUtil;
1662:                LocalizedOutput aw = localLangUtil.getNewOutput(bos);
1663:                org.apache.derby.impl.tools.sysinfo.Main.getMainInfo(aw, false);
1664:                return bos.toString();
1665:            }
1666:
1667:            /**
1668:             * Execute the command given on the command line
1669:             *
1670:             * @param args	array of arguments indicating command to be executed
1671:             *
1672:             * @exception Exception	throws an exception if an error occurs
1673:             * see class comments for more information
1674:             */
1675:            public void executeWork(String args[]) throws Exception {
1676:                // For convenience just use NetworkServerControlImpls log writer for user messages
1677:                logWriter = makePrintWriter(System.out);
1678:
1679:                int command = 0;
1680:                if (args.length > 0)
1681:                    command = findCommand(args);
1682:                else {
1683:                    consolePropertyMessage("DRDA_NoArgs.U");
1684:                }
1685:
1686:                // if we didn't have a valid command just return - error already generated
1687:                if (command == COMMAND_UNKNOWN)
1688:                    return;
1689:
1690:                // check that we have the right number of required arguments
1691:                if (commandArgs.size() != COMMAND_ARGS[command])
1692:                    consolePropertyMessage("DRDA_InvalidNoArgs.U",
1693:                            COMMANDS[command]);
1694:                int min;
1695:                int max;
1696:
1697:                switch (command) {
1698:                case COMMAND_START:
1699:                    // the server was started from the command line, shutdown the
1700:                    // databases when the server is shutdown
1701:                    shutdownDatabasesOnShutdown = true;
1702:                    blockingStart(makePrintWriter(System.out));
1703:                    break;
1704:                case COMMAND_SHUTDOWN:
1705:                    shutdown();
1706:                    consolePropertyMessage("DRDA_ShutdownSuccess.I",
1707:                            new String[] { att_srvclsnm, versionString,
1708:                                    getFormattedTimestamp() });
1709:                    break;
1710:                case COMMAND_TRACE: {
1711:                    boolean on = isOn((String) commandArgs.elementAt(0));
1712:                    trace(sessionArg, on);
1713:                    consoleTraceMessage(sessionArg, on);
1714:                    break;
1715:                }
1716:                case COMMAND_TRACEDIRECTORY:
1717:                    setTraceDirectory((String) commandArgs.elementAt(0));
1718:                    consolePropertyMessage("DRDA_TraceDirectoryChange.I",
1719:                            traceDirectory);
1720:                    break;
1721:                case COMMAND_TESTCONNECTION:
1722:                    ping();
1723:                    consolePropertyMessage("DRDA_ConnectionTested.I",
1724:                            new String[] { hostArg,
1725:                                    (new Integer(portNumber)).toString() });
1726:                    break;
1727:                case COMMAND_LOGCONNECTIONS: {
1728:                    boolean on = isOn((String) commandArgs.elementAt(0));
1729:                    logConnections(on);
1730:                    consolePropertyMessage("DRDA_LogConnectionsChange.I",
1731:                            on ? "DRDA_ON.I" : "DRDA_OFF.I");
1732:                    break;
1733:                }
1734:                case COMMAND_SYSINFO: {
1735:                    String info = sysinfo();
1736:                    consoleMessage(info);
1737:                    break;
1738:                }
1739:                case COMMAND_MAXTHREADS:
1740:                    max = 0;
1741:                    try {
1742:                        max = Integer.parseInt((String) commandArgs
1743:                                .elementAt(0));
1744:                    } catch (NumberFormatException e) {
1745:                        consolePropertyMessage("DRDA_InvalidValue.U",
1746:                                new String[] {
1747:                                        (String) commandArgs.elementAt(0),
1748:                                        "maxthreads" });
1749:                    }
1750:                    if (max < MIN_MAXTHREADS)
1751:                        consolePropertyMessage("DRDA_InvalidValue.U",
1752:                                new String[] { new Integer(max).toString(),
1753:                                        "maxthreads" });
1754:                    netSetMaxThreads(max);
1755:
1756:                    break;
1757:                case COMMAND_RUNTIME_INFO:
1758:                    String reply = runtimeInfo();
1759:                    consoleMessage(reply);
1760:                    break;
1761:                case COMMAND_TIMESLICE:
1762:                    int timeslice = 0;
1763:                    String timeSliceArg = (String) commandArgs.elementAt(0);
1764:                    try {
1765:                        timeslice = Integer.parseInt(timeSliceArg);
1766:                    } catch (NumberFormatException e) {
1767:                        consolePropertyMessage("DRDA_InvalidValue.U",
1768:                                new String[] {
1769:                                        (String) commandArgs.elementAt(0),
1770:                                        "timeslice" });
1771:                    }
1772:                    if (timeslice < MIN_TIMESLICE)
1773:                        consolePropertyMessage("DRDA_InvalidValue.U",
1774:                                new String[] {
1775:                                        new Integer(timeslice).toString(),
1776:                                        "timeslice" });
1777:                    netSetTimeSlice(timeslice);
1778:
1779:                    break;
1780:                default:
1781:                    //shouldn't get here
1782:                    if (SanityManager.DEBUG)
1783:                        SanityManager.THROWASSERT("Invalid command in switch:"
1784:                                + command);
1785:                }
1786:            }
1787:
1788:            /**
1789:             * Add session to the run queue
1790:             *
1791:             * @param clientSession	session needing work
1792:             */
1793:            private void runQueueAdd(Session clientSession) {
1794:                synchronized (runQueue) {
1795:                    runQueue.addElement(clientSession);
1796:                    runQueue.notify();
1797:                }
1798:            }
1799:
1800:            /**
1801:             * Go through the arguments and find the command and save the dash arguments
1802:             *	and arguments to the command.  Only one command is allowed in the argument
1803:             *	list.
1804:             *
1805:             * @param args	arguments to search
1806:             *
1807:             * @return  command
1808:             */
1809:            private int findCommand(String[] args) throws Exception {
1810:                try {
1811:                    // process the dashArgs and pull out the command args 
1812:                    int i = 0;
1813:                    int newpos = 0;
1814:                    while (i < args.length) {
1815:                        if (args[i].startsWith("-")) {
1816:                            newpos = processDashArg(i, args);
1817:                            if (newpos == i)
1818:                                commandArgs.addElement(args[i++]);
1819:                            else
1820:                                i = newpos;
1821:                        } else
1822:                            commandArgs.addElement(args[i++]);
1823:                    }
1824:
1825:                    // look up command
1826:                    if (commandArgs.size() > 0) {
1827:                        for (i = 0; i < COMMANDS.length; i++) {
1828:                            if (StringUtil.SQLEqualsIgnoreCase(COMMANDS[i],
1829:                                    (String) commandArgs.firstElement())) {
1830:                                commandArgs.removeElementAt(0);
1831:                                return i;
1832:                            }
1833:                        }
1834:                    }
1835:                    // didn't find command
1836:                    consolePropertyMessage("DRDA_UnknownCommand.U",
1837:                            (String) commandArgs.firstElement());
1838:                } catch (Exception e) {
1839:                    if (e.getMessage().equals(
1840:                            NetworkServerControlImpl.UNEXPECTED_ERR))
1841:                        throw e;
1842:                    //Ignore expected exceptions, they will have been
1843:                    //handled by the consolePropertyMessage routine
1844:                }
1845:                return COMMAND_UNKNOWN;
1846:            }
1847:
1848:            /**
1849:             * Get the dash argument. Optional arguments are formated as -x value.
1850:             *
1851:             * @param pos	starting point
1852:             * @param args	arguments to search
1853:             *
1854:             * @return  command
1855:             *
1856:             * @exception Exception	thrown if an error occurs
1857:             */
1858:            private int processDashArg(int pos, String[] args) throws Exception {
1859:                //check for a negative number
1860:                char c = args[pos].charAt(1);
1861:                if (c >= '0' && c <= '9')
1862:                    return pos;
1863:                int dashArg = -1;
1864:                for (int i = 0; i < DASHARGS.length; i++) {
1865:                    if (DASHARGS[i].equals(args[pos].substring(1))) {
1866:                        dashArg = i;
1867:                        pos++;
1868:                        break;
1869:                    }
1870:                }
1871:                if (dashArg == -1)
1872:                    consolePropertyMessage("DRDA_UnknownArgument.U", args[pos]);
1873:                switch (dashArg) {
1874:                case DASHARG_PORT:
1875:                    if (pos < args.length) {
1876:                        try {
1877:                            portNumber = Integer.parseInt(args[pos]);
1878:                        } catch (NumberFormatException e) {
1879:                            consolePropertyMessage("DRDA_InvalidValue.U",
1880:                                    new String[] { args[pos],
1881:                                            "DRDA_PortNumber.I" });
1882:                        }
1883:                    } else
1884:                        consolePropertyMessage("DRDA_MissingValue.U",
1885:                                "DRDA_PortNumber.I");
1886:                    break;
1887:                case DASHARG_HOST:
1888:                    if (pos < args.length) {
1889:                        hostArg = args[pos];
1890:                    } else
1891:                        consolePropertyMessage("DRDA_MissingValue.U",
1892:                                "DRDA_Host.I");
1893:                    break;
1894:                case DASHARG_DATABASE:
1895:                    if (pos < args.length)
1896:                        databaseArg = args[pos];
1897:                    else
1898:                        consolePropertyMessage("DRDA_MissingValue.U",
1899:                                "DRDA_DatabaseDirectory.I");
1900:                    break;
1901:                case DASHARG_USER:
1902:                    if (pos < args.length) {
1903:                        userArg = args[pos++];
1904:                        if (pos < args.length)
1905:                            passwordArg = args[pos];
1906:                        else
1907:                            consolePropertyMessage("DRDA_MissingValue.U",
1908:                                    "DRDA_Password.I");
1909:                    } else
1910:                        consolePropertyMessage("DRDA_MissingValue.U",
1911:                                "DRDA_User.I");
1912:                    break;
1913:                case DASHARG_ENCALG:
1914:                    if (pos < args.length)
1915:                        encAlgArg = args[pos];
1916:                    else
1917:                        consolePropertyMessage("DRDA_MissingValue.U",
1918:                                "DRDA_EncryptionAlgorithm.I");
1919:                    break;
1920:                case DASHARG_ENCPRV:
1921:                    if (pos < args.length)
1922:                        encPrvArg = args[pos];
1923:                    else
1924:                        consolePropertyMessage("DRDA_MissingValue.U",
1925:                                "DRDA_EncryptionProvider.I");
1926:                    break;
1927:                case DASHARG_LOADSYSIBM:
1928:                    break;
1929:                case DASHARG_SESSION:
1930:                    if (pos < args.length)
1931:                        try {
1932:                            sessionArg = Integer.parseInt(args[pos]);
1933:                        } catch (NumberFormatException e) {
1934:                            consolePropertyMessage(
1935:                                    "DRDA_InvalidValue.U",
1936:                                    new String[] { args[pos], "DRDA_Session.I" });
1937:                        }
1938:                    else
1939:                        consolePropertyMessage("DRDA_MissingValue.U",
1940:                                "DRDA_Session.I");
1941:                    break;
1942:                default:
1943:                    //shouldn't get here
1944:                }
1945:                return pos + 1;
1946:            }
1947:
1948:            /**
1949:             * Is string "on" or "off"
1950:             *
1951:             * @param arg	string to check
1952:             *
1953:             * @return  true if string is "on", false if string is "off"
1954:             *
1955:             * @exception Exception	thrown if string is not one of "on" or "off"
1956:             */
1957:            private boolean isOn(String arg) throws Exception {
1958:                if (StringUtil.SQLEqualsIgnoreCase(arg, "on"))
1959:                    return true;
1960:                else if (!StringUtil.SQLEqualsIgnoreCase(arg, "off"))
1961:                    consolePropertyMessage("DRDA_OnOffValue.U", arg);
1962:                return false;
1963:            }
1964:
1965:            /**
1966:             * Set up client socket to send a command to the network server
1967:             *
1968:             * @exception Exception	thrown if exception encountered
1969:             */
1970:            private void setUpSocket() throws Exception {
1971:
1972:                try {
1973:                    clientSocket = (Socket) AccessController
1974:                            .doPrivileged(new PrivilegedExceptionAction() {
1975:
1976:                                public Object run()
1977:                                        throws UnknownHostException,
1978:                                        IOException {
1979:                                    if (hostAddress == null)
1980:                                        hostAddress = InetAddress
1981:                                                .getByName(hostArg);
1982:
1983:                                    // JDK131 can't connect with a client
1984:                                    // socket with 0.0.0.0 (all addresses) so we will
1985:                                    // getLocalHost() which will suffice.
1986:                                    InetAddress connectAddress;
1987:                                    if (JVMInfo.JDK_ID <= JVMInfo.J2SE_13
1988:                                            && hostAddress.getHostAddress()
1989:                                                    .equals("0.0.0.0"))
1990:                                        connectAddress = InetAddress
1991:                                                .getLocalHost();
1992:                                    else
1993:                                        connectAddress = hostAddress;
1994:
1995:                                    return new Socket(connectAddress,
1996:                                            portNumber);
1997:                                }
1998:                            });
1999:                } catch (PrivilegedActionException pae) {
2000:                    Exception e1 = pae.getException();
2001:                    if (e1 instanceof  UnknownHostException) {
2002:                        consolePropertyMessage("DRDA_UnknownHost.S", hostArg);
2003:                    } else if (e1 instanceof  IOException) {
2004:                        consolePropertyMessage("DRDA_NoIO.S", new String[] {
2005:                                hostArg, (new Integer(portNumber)).toString() });
2006:                    }
2007:                } catch (Exception e) {
2008:                    // If we find other (unexpected) errors, we ultimately exit--so make
2009:                    // sure we print the error message before doing so (Beetle 5033).
2010:                    throwUnexpectedException(e);
2011:                }
2012:
2013:                try {
2014:                    clientIs = clientSocket.getInputStream();
2015:                    clientOs = clientSocket.getOutputStream();
2016:                } catch (IOException e) {
2017:                    consolePropertyMessage("DRDA_NoInputStream.I");
2018:                    throw e;
2019:                }
2020:            }
2021:
2022:            private void checkAddressIsLocal(InetAddress inetAddr)
2023:                    throws UnknownHostException, Exception {
2024:                for (int i = 0; i < localAddresses.size(); i++) {
2025:                    if (inetAddr.equals((InetAddress) localAddresses.get(i))) {
2026:                        return;
2027:                    }
2028:                }
2029:                consolePropertyMessage("DRDA_NeedLocalHost.S", new String[] {
2030:                        inetAddr.getHostName(),
2031:                        serverSocket.getInetAddress().getHostName() });
2032:
2033:            }
2034:
2035:            /**
2036:             * Build local address list to allow admin commands.
2037:             *
2038:             * @param bindAddr Address on which server was started
2039:             * 
2040:             * Note: Some systems may not support localhost.
2041:             * In that case a console message will print for the localhost entries,
2042:             * but the server will continue to start.
2043:             **/
2044:            private void buildLocalAddressList(InetAddress bindAddr) {
2045:                localAddresses = new ArrayList(3);
2046:                localAddresses.add(bindAddr);
2047:                try {
2048:                    localAddresses.add(InetAddress.getLocalHost());
2049:                    localAddresses.add(InetAddress.getByName("localhost"));
2050:                } catch (UnknownHostException uhe) {
2051:                    try {
2052:                        consolePropertyMessage("DRDA_UnknownHostWarning.I", uhe
2053:                                .getMessage());
2054:                    } catch (Exception e) { // just a warning shouldn't actually throw an exception
2055:                    }
2056:                }
2057:            }
2058:
2059:            /**
2060:             * Routines for writing commands for NetworkServerControlImpl being used as a client
2061:             * to a server
2062:             */
2063:
2064:            /**
2065:             * Write command header consisting of command header string and protocol
2066:             * version and command
2067:             *
2068:             * @param command	command to be written
2069:             *
2070:             * @exception Exception	throws an exception if an error occurs
2071:             */
2072:            private void writeCommandHeader(int command) throws Exception {
2073:                try {
2074:                    writeString(COMMAND_HEADER);
2075:                    commandOs
2076:                            .writeByte((byte) ((PROTOCOL_VERSION & 0xf0) >> 8));
2077:                    commandOs.writeByte((byte) (PROTOCOL_VERSION & 0x0f));
2078:
2079:                    if (clientLocale != null && clientLocale != DEFAULT_LOCALE) {
2080:                        commandOs.writeByte(clientLocale.length());
2081:                        commandOs.writeBytes(clientLocale);
2082:                    } else
2083:                        commandOs.writeByte((byte) 0);
2084:                    commandOs.writeByte((byte) 0);
2085:                    commandOs.writeByte((byte) command);
2086:                } catch (IOException e) {
2087:                    clientSocketError(e);
2088:                }
2089:            }
2090:
2091:            /**
2092:             * Write length delimited string string
2093:             *
2094:             * @param msg	string to be written
2095:             *
2096:             * @exception Exception	throws an exception if an error occurs
2097:             */
2098:            private void writeLDString(String msg) throws Exception {
2099:                try {
2100:                    if (msg == null) {
2101:                        commandOs.writeShort(0);
2102:                    } else {
2103:                        commandOs.writeShort(msg.length());
2104:                        writeString(msg);
2105:                    }
2106:                } catch (IOException e) {
2107:                    clientSocketError(e);
2108:                }
2109:            }
2110:
2111:            /** Write string
2112:             *
2113:             * @param msg String to write
2114:             */
2115:
2116:            protected void writeString(String msg) throws Exception {
2117:                byte[] msgBytes = msg.getBytes(DEFAULT_ENCODING);
2118:                commandOs.write(msgBytes, 0, msgBytes.length);
2119:            }
2120:
2121:            /**
2122:             * Write short
2123:             *
2124:             * @param value	value to be written
2125:             *
2126:             * @exception Exception	throws an exception if an error occurs
2127:             */
2128:            private void writeShort(int value) throws Exception {
2129:                try {
2130:                    commandOs.writeByte((byte) ((value & 0xf0) >> 8));
2131:                    commandOs.writeByte((byte) (value & 0x0f));
2132:                } catch (IOException e) {
2133:                    clientSocketError(e);
2134:                }
2135:            }
2136:
2137:            /**
2138:             * Write byte
2139:             *
2140:             * @param value	value to be written
2141:             *
2142:             * @exception Exception	throws an exception if an error occurs
2143:             */
2144:            private void writeByte(int value) throws Exception {
2145:                try {
2146:                    commandOs.writeByte((byte) (value & 0x0f));
2147:                } catch (IOException e) {
2148:                    clientSocketError(e);
2149:                }
2150:            }
2151:
2152:            /**
2153:             * Send client message to server
2154:             *
2155:             *
2156:             * @exception Exception	throws an exception if an error occurs
2157:             */
2158:            private void send() throws Exception {
2159:                try {
2160:                    byteArrayOs.writeTo(clientOs);
2161:                    commandOs.flush();
2162:                    byteArrayOs.reset(); //discard anything currently in the byte array
2163:                } catch (IOException e) {
2164:                    clientSocketError(e);
2165:                }
2166:            }
2167:
2168:            /**
2169:             * Stream error writing to client socket
2170:             */
2171:            private void clientSocketError(IOException e) throws IOException {
2172:                try {
2173:                    consolePropertyMessage("DRDA_ClientSocketError.S", e
2174:                            .getMessage());
2175:                } catch (Exception ce) {
2176:                } // catch the exception consolePropertyMessage will
2177:                // throw since we also want to print a stack trace
2178:                consoleExceptionPrintTrace(e);
2179:                throw e;
2180:            }
2181:
2182:            /**
2183:             * Read result from sending client message to server
2184:             *
2185:             * @exception Exception	throws an exception if an error occurs
2186:             */
2187:            private void readResult() throws Exception {
2188:                fillReplyBuffer();
2189:                readCommandReplyHeader();
2190:                if (replyBufferPos >= replyBufferCount)
2191:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2192:                int messageType = replyBuffer[replyBufferPos++] & 0xFF;
2193:                if (messageType == OK) // O.K.
2194:                    return;
2195:                // get error and display and throw exception
2196:                String message = readLDString();
2197:                if (messageType == SQLERROR)
2198:                    wrapSQLError(message);
2199:                else if (messageType == SQLWARNING)
2200:                    wrapSQLWarning(message);
2201:                else
2202:                    consolePropertyMessage(message);
2203:            }
2204:
2205:            /**
2206:             * Ensure the reply buffer is at large enought to hold all the data;
2207:             * don't just rely on OS level defaults
2208:             *
2209:             *
2210:             * @param minimumBytesNeeded	size of buffer required	
2211:             * @exception Exception throws an exception if a problem reading the reply
2212:             */
2213:            private void ensureDataInBuffer(int minimumBytesNeeded)
2214:                    throws Exception {
2215:                // make sure the buffer is large enough
2216:                while ((replyBufferCount - replyBufferPos) < minimumBytesNeeded) {
2217:                    try {
2218:                        int bytesRead = clientIs.read(replyBuffer,
2219:                                replyBufferCount, replyBuffer.length
2220:                                        - replyBufferCount);
2221:                        replyBufferCount += bytesRead;
2222:
2223:                    } catch (IOException e) {
2224:                        clientSocketError(e);
2225:                    }
2226:                }
2227:            }
2228:
2229:            /**
2230:             * Fill the reply buffer with the reply allocates a reply buffer if one doesn't
2231:             * exist
2232:             *
2233:             *
2234:             * @exception Exception throws an exception if a problem reading the reply
2235:             */
2236:            private void fillReplyBuffer() throws Exception {
2237:                if (replyBuffer == null)
2238:                    replyBuffer = new byte[MAXREPLY];
2239:                try {
2240:                    replyBufferCount = clientIs.read(replyBuffer);
2241:                } catch (IOException e) {
2242:                    clientSocketError(e);
2243:                }
2244:                if (replyBufferCount == -1)
2245:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2246:                replyBufferPos = 0;
2247:            }
2248:
2249:            /**
2250:             * Read the command reply header from the server
2251:             *
2252:             * @exception Exception throws an exception if an error occurs
2253:             */
2254:            private void readCommandReplyHeader() throws Exception {
2255:                ensureDataInBuffer(REPLY_HEADER_LENGTH);
2256:                if (replyBufferCount < REPLY_HEADER_LENGTH) {
2257:                    consolePropertyMessage("DRDA_InvalidReplyHeader1.S",
2258:                            Integer.toString(replyBufferCount));
2259:                }
2260:                String header = new String(replyBuffer, 0, REPLY_HEADER_LENGTH,
2261:                        DEFAULT_ENCODING);
2262:                if (!header.equals(REPLY_HEADER)) {
2263:                    consolePropertyMessage("DRDA_InvalidReplyHeader2.S", header);
2264:                }
2265:                replyBufferPos += REPLY_HEADER_LENGTH;
2266:            }
2267:
2268:            /**
2269:             * Read short from buffer
2270:             * @exception Exception	throws an exception if an error occurs
2271:             */
2272:            private int readShort() throws Exception {
2273:                ensureDataInBuffer(2);
2274:                if (replyBufferPos + 2 > replyBufferCount)
2275:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2276:                return ((replyBuffer[replyBufferPos++] & 0xff) << 8)
2277:                        + (replyBuffer[replyBufferPos++] & 0xff);
2278:            }
2279:
2280:            /**
2281:             * Read int from buffer
2282:             * @exception Exception	throws an exception if an error occurs
2283:             */
2284:            private int readInt() throws Exception {
2285:                ensureDataInBuffer(4);
2286:                if (replyBufferPos + 4 > replyBufferCount)
2287:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2288:                return ((replyBuffer[replyBufferPos++] & 0xff) << 24)
2289:                        + ((replyBuffer[replyBufferPos++] & 0xff) << 16)
2290:                        + ((replyBuffer[replyBufferPos++] & 0xff) << 8)
2291:                        + (replyBuffer[replyBufferPos++] & 0xff);
2292:            }
2293:
2294:            /**
2295:             * Read String reply
2296:             *
2297:             * @param msgKey	error message key
2298:             * @return string value or null 
2299:             * @exception Exception throws an error if problems reading reply
2300:             */
2301:            private String readStringReply(String msgKey) throws Exception {
2302:                fillReplyBuffer();
2303:                readCommandReplyHeader();
2304:                if (replyBuffer[replyBufferPos++] == 0) // O.K.
2305:                    return readLDString();
2306:                else
2307:                    consolePropertyMessage(msgKey);
2308:                return null;
2309:
2310:            }
2311:
2312:            /**
2313:             * Read length delimited string from a buffer
2314:             *
2315:             * @return string value from buffer
2316:             * @exception Exception throws an error if problems reading reply
2317:             */
2318:            private String readLDString() throws Exception {
2319:                int strlen = readShort();
2320:                ensureDataInBuffer(strlen);
2321:                if (replyBufferPos + strlen > replyBufferCount)
2322:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2323:                String retval = new String(replyBuffer, replyBufferPos, strlen,
2324:                        DEFAULT_ENCODING);
2325:                replyBufferPos += strlen;
2326:                return retval;
2327:            }
2328:
2329:            /**
2330:             * Read Bytes reply
2331:             *
2332:             * @param msgKey	error message key
2333:             * @return string value or null 
2334:             * @exception Exception throws an error if problems reading reply
2335:             */
2336:            private byte[] readBytesReply(String msgKey) throws Exception {
2337:                fillReplyBuffer();
2338:                readCommandReplyHeader();
2339:                if (replyBuffer[replyBufferPos++] == 0) // O.K.
2340:                    return readLDBytes();
2341:                else
2342:                    consolePropertyMessage(msgKey);
2343:                return null;
2344:
2345:            }
2346:
2347:            /**
2348:             * Read length delimited bytes from a buffer
2349:             *
2350:             * @return byte array from buffer
2351:             * @exception Exception throws an error if problems reading reply
2352:             */
2353:            private byte[] readLDBytes() throws Exception {
2354:                int len = readShort();
2355:                ensureDataInBuffer(len);
2356:                if (replyBufferPos + len > replyBufferCount)
2357:                    consolePropertyMessage("DRDA_InvalidReplyTooShort.S");
2358:                byte[] retval = new byte[len];
2359:                for (int i = 0; i < len; i++)
2360:                    retval[i] = replyBuffer[replyBufferPos++];
2361:                return retval;
2362:            }
2363:
2364:            /**
2365:             * Initialize fields from system properties
2366:             *
2367:             */
2368:            private void getPropertyInfo() throws Exception {
2369:                //set values according to properties
2370:
2371:                String directory = PropertyUtil
2372:                        .getSystemProperty(Property.SYSTEM_HOME_PROPERTY);
2373:                String propval = PropertyUtil
2374:                        .getSystemProperty(Property.DRDA_PROP_LOGCONNECTIONS);
2375:                if (propval != null
2376:                        && StringUtil.SQLEqualsIgnoreCase(propval, "true"))
2377:                    setLogConnections(true);
2378:                propval = PropertyUtil
2379:                        .getSystemProperty(Property.DRDA_PROP_TRACEALL);
2380:                if (propval != null
2381:                        && StringUtil.SQLEqualsIgnoreCase(propval, "true"))
2382:                    setTraceAll(true);
2383:
2384:                //If the derby.system.home property has been set, it is the default. 
2385:                //Otherwise, the default is the current directory. 
2386:                //If derby.system.home is not set, directory will be null and trace files will get
2387:                //created in current directory.
2388:                propval = PropertyUtil.getSystemProperty(
2389:                        Property.DRDA_PROP_TRACEDIRECTORY, directory);
2390:                if (propval != null) {
2391:                    if (propval.equals(""))
2392:                        propval = directory;
2393:                    setTraceDirectory(propval);
2394:                }
2395:
2396:                //DERBY-375 If a system property is specified without any value, getProperty returns 
2397:                //an empty string. Use default values in such cases.
2398:                propval = PropertyUtil
2399:                        .getSystemProperty(Property.DRDA_PROP_MINTHREADS);
2400:                if (propval != null) {
2401:                    if (propval.equals(""))
2402:                        propval = "0";
2403:                    setMinThreads(getIntPropVal(Property.DRDA_PROP_MINTHREADS,
2404:                            propval));
2405:                }
2406:
2407:                propval = PropertyUtil
2408:                        .getSystemProperty(Property.DRDA_PROP_MAXTHREADS);
2409:                if (propval != null) {
2410:                    if (propval.equals(""))
2411:                        propval = "0";
2412:                    setMaxThreads(getIntPropVal(Property.DRDA_PROP_MAXTHREADS,
2413:                            propval));
2414:                }
2415:
2416:                propval = PropertyUtil
2417:                        .getSystemProperty(Property.DRDA_PROP_TIMESLICE);
2418:                if (propval != null) {
2419:                    if (propval.equals(""))
2420:                        propval = "0";
2421:                    setTimeSlice(getIntPropVal(Property.DRDA_PROP_TIMESLICE,
2422:                            propval));
2423:                }
2424:
2425:                propval = PropertyUtil
2426:                        .getSystemProperty(Property.DRDA_PROP_PORTNUMBER);
2427:                if (propval != null) {
2428:                    if (propval.equals(""))
2429:                        propval = String
2430:                                .valueOf(NetworkServerControl.DEFAULT_PORTNUMBER);
2431:                    portNumber = getIntPropVal(Property.DRDA_PROP_PORTNUMBER,
2432:                            propval);
2433:                }
2434:
2435:                propval = PropertyUtil
2436:                        .getSystemProperty(Property.DRDA_PROP_KEEPALIVE);
2437:                if (propval != null
2438:                        && StringUtil.SQLEqualsIgnoreCase(propval, "false"))
2439:                    keepAlive = false;
2440:
2441:                propval = PropertyUtil
2442:                        .getSystemProperty(Property.DRDA_PROP_HOSTNAME);
2443:                if (propval != null) {
2444:                    if (propval.equals(""))
2445:                        hostArg = DEFAULT_HOST;
2446:                    else
2447:                        hostArg = propval;
2448:                }
2449:                propval = PropertyUtil
2450:                        .getSystemProperty(NetworkServerControlImpl.DRDA_PROP_DEBUG);
2451:                if (propval != null
2452:                        && StringUtil.SQLEqualsIgnoreCase(propval, "true"))
2453:                    debugOutput = true;
2454:
2455:                propval = PropertyUtil
2456:                        .getSystemProperty(Property.DRDA_PROP_SECURITYMECHANISM);
2457:                if (propval != null) {
2458:                    setSecurityMechanism(propval);
2459:                }
2460:
2461:            }
2462:
2463:            /**
2464:             * Retrieve the SECMEC integer value from the
2465:             * user friendly security mechanism name
2466:             * @param s  security mechanism name
2467:             * @return integer value , return the SECMEC value for 
2468:             * the security mechanism as defined by DRDA spec
2469:             * or INVALID_OR_NOTSET_SECURITYMECHANISM if 's'
2470:             * passed is invalid  or not supported security 
2471:             * mechanism
2472:             */
2473:            private int getSecMecValue(String s) {
2474:                int secmec = INVALID_OR_NOTSET_SECURITYMECHANISM;
2475:
2476:                if (StringUtil.SQLEqualsIgnoreCase(s, "USER_ONLY_SECURITY"))
2477:                    secmec = CodePoint.SECMEC_USRIDONL;
2478:                else if (StringUtil.SQLEqualsIgnoreCase(s,
2479:                        "CLEAR_TEXT_PASSWORD_SECURITY"))
2480:                    secmec = CodePoint.SECMEC_USRIDPWD;
2481:                else if (StringUtil.SQLEqualsIgnoreCase(s,
2482:                        "ENCRYPTED_USER_AND_PASSWORD_SECURITY"))
2483:                    secmec = CodePoint.SECMEC_EUSRIDPWD;
2484:                else if (StringUtil.SQLEqualsIgnoreCase(s,
2485:                        "STRONG_PASSWORD_SUBSTITUTE_SECURITY"))
2486:                    secmec = CodePoint.SECMEC_USRSSBPWD;
2487:
2488:                return secmec;
2489:            }
2490:
2491:            /**
2492:             * Retrieve the string name for the integer
2493:             * secmec value
2494:             * @param secmecVal   secmec value
2495:             * @return String - return the string name corresponding 
2496:             * to the secmec value if recognized else returns null
2497:             */
2498:            private String getStringValueForSecMec(int secmecVal) {
2499:                switch (secmecVal) {
2500:                case CodePoint.SECMEC_USRIDONL:
2501:                    return "USER_ONLY_SECURITY";
2502:
2503:                case CodePoint.SECMEC_USRIDPWD:
2504:                    return "CLEAR_TEXT_PASSWORD_SECURITY";
2505:
2506:                case CodePoint.SECMEC_EUSRIDPWD:
2507:                    return "ENCRYPTED_USER_AND_PASSWORD_SECURITY";
2508:
2509:                case CodePoint.SECMEC_USRSSBPWD:
2510:                    return "STRONG_PASSWORD_SUBSTITUTE_SECURITY";
2511:                }
2512:                return null;
2513:            }
2514:
2515:            /**
2516:             * This method returns whether EUSRIDPWD security mechanism
2517:             * is supported or not. See class static block for more
2518:             * info.
2519:             * @return true if EUSRIDPWD is supported, false otherwise
2520:             */
2521:            boolean supportsEUSRIDPWD() {
2522:                return SUPPORTS_EUSRIDPWD;
2523:            }
2524:
2525:            /**
2526:             * Get integer property values
2527:             *
2528:             * @param propName 	property name
2529:             * @param propVal	string property value
2530:             * @return integer value
2531:             *
2532:             * @exception Exception if not a valid integer
2533:             */
2534:            private int getIntPropVal(String propName, String propVal)
2535:                    throws Exception {
2536:                int val = 0;
2537:                try {
2538:                    val = (new Integer(propVal)).intValue();
2539:                } catch (Exception e) {
2540:                    consolePropertyMessage("DRDA_InvalidPropVal.S",
2541:                            new String[] { propName, propVal });
2542:                }
2543:                return val;
2544:            }
2545:
2546:            /**
2547:             * Handle console error message
2548:             * 	- display on console and if it is a user error, display usage
2549:             *  - if user error or severe error, throw exception with message key and message
2550:             *
2551:             * @param messageKey	message key
2552:             * @param args			arguments to message
2553:             *
2554:             * @throws Exception if an error occurs
2555:             */
2556:            private void consolePropertyMessageWork(String messageKey,
2557:                    String[] args) throws Exception {
2558:                String locMsg = null;
2559:
2560:                int type = getMessageType(messageKey);
2561:
2562:                if (type == ERRTYPE_UNKNOWN)
2563:                    locMsg = messageKey;
2564:                else
2565:                    locMsg = localizeMessage(messageKey, langUtil, args);
2566:
2567:                //display on the console
2568:                consoleMessage(locMsg);
2569:
2570:                //if it is a user error display usage
2571:                if (type == ERRTYPE_USER)
2572:                    usage();
2573:
2574:                //we may want to use a different locale for throwing the exception
2575:                //since this can be sent to a browser with a different locale
2576:                if (currentSession != null && currentSession.langUtil != null
2577:                        && type != ERRTYPE_UNKNOWN)
2578:                    locMsg = localizeMessage(messageKey,
2579:                            currentSession.langUtil, args);
2580:
2581:                // throw an exception for severe and user errors
2582:                if (type == ERRTYPE_SEVERE || type == ERRTYPE_USER) {
2583:                    if (messageKey.equals("DRDA_SQLException.S"))
2584:                        throwSQLException(args[0]);
2585:                    else if (messageKey.equals("DRDA_SQLWarning.I"))
2586:                        throwSQLWarning(args[0]);
2587:                    else
2588:                        throw new Exception(messageKey + ":" + locMsg);
2589:                }
2590:
2591:                // throw an exception with just the message if the error type is
2592:                // unknown
2593:                if (type == ERRTYPE_UNKNOWN)
2594:                    throw new Exception(locMsg);
2595:
2596:                return;
2597:
2598:            }
2599:
2600:            /**
2601:             * Throw a SQL Exception which was sent over by a server
2602:             * Format of the msg is SQLSTATE:localized message\nSQLSTATE:next localized message
2603:             *
2604:             * @param msg		msg containing SQL Exception
2605:             *
2606:             * @throws SQLException
2607:             */
2608:            private void throwSQLException(String msg) throws SQLException {
2609:                SQLException se = null;
2610:                SQLException ne;
2611:                SQLException ce = null;
2612:                StringBuffer strbuf = new StringBuffer();
2613:                StringTokenizer tokenizer = new StringTokenizer(msg, "\n");
2614:                String sqlstate = null;
2615:                String str;
2616:                while (tokenizer.hasMoreTokens()) {
2617:                    str = tokenizer.nextToken();
2618:                    //start of the next message
2619:                    if (str.charAt(5) == ':') {
2620:                        if (strbuf.length() > 0) {
2621:                            if (se == null) {
2622:                                se = new SQLException(strbuf.toString(),
2623:                                        sqlstate);
2624:                                ce = se;
2625:                            } else {
2626:                                ne = new SQLException(strbuf.toString(),
2627:                                        sqlstate);
2628:                                ce.setNextException(ne);
2629:                                ce = ne;
2630:                            }
2631:                            strbuf = new StringBuffer();
2632:                        }
2633:                        strbuf.append(str.substring(6));
2634:                        sqlstate = str.substring(0, 5);
2635:                    } else
2636:                        strbuf.append(str);
2637:                }
2638:                if (strbuf.length() > 0) {
2639:                    if (se == null) {
2640:                        se = new SQLException(strbuf.toString(), sqlstate);
2641:                        ce = se;
2642:                    } else {
2643:                        ne = new SQLException(strbuf.toString(), sqlstate);
2644:                        ce.setNextException(ne);
2645:                        ce = ne;
2646:                    }
2647:                }
2648:                throw se;
2649:            }
2650:
2651:            /**
2652:             * Throw a SQL Warning which was sent over by a server
2653:             * Format of the msg is SQLSTATE:localized message\nSQLSTATE:next localized message
2654:             *
2655:             * @param msg		msg containing SQL Warning
2656:             *
2657:             * @throws SQLWarning
2658:             */
2659:            private void throwSQLWarning(String msg) throws SQLWarning {
2660:                SQLWarning se = null;
2661:                SQLWarning ne;
2662:                SQLWarning ce = null;
2663:                StringBuffer strbuf = new StringBuffer();
2664:                StringTokenizer tokenizer = new StringTokenizer(msg, "\n");
2665:                String sqlstate = null;
2666:                String str;
2667:                while (tokenizer.hasMoreTokens()) {
2668:                    str = tokenizer.nextToken();
2669:                    //start of the next message
2670:                    if (str.charAt(5) == ':') {
2671:                        if (strbuf.length() > 0) {
2672:                            if (se == null) {
2673:                                se = new SQLWarning(strbuf.toString(), sqlstate);
2674:                                ce = se;
2675:                            } else {
2676:                                ne = new SQLWarning(strbuf.toString(), sqlstate);
2677:                                ce.setNextException(ne);
2678:                                ce = ne;
2679:                            }
2680:                            strbuf = new StringBuffer();
2681:                        }
2682:                        strbuf.append(str.substring(6));
2683:                        sqlstate = str.substring(0, 5);
2684:                    } else
2685:                        strbuf.append(str);
2686:                }
2687:                if (strbuf.length() > 0) {
2688:                    if (se == null) {
2689:                        se = new SQLWarning(strbuf.toString(), sqlstate);
2690:                        ce = se;
2691:                    } else {
2692:                        ne = new SQLWarning(strbuf.toString(), sqlstate);
2693:                        ce.setNextException(ne);
2694:                        ce = ne;
2695:                    }
2696:                }
2697:                throw se;
2698:            }
2699:
2700:            /**
2701:             * Print a trace for the (unexpected) exception received, then
2702:             * throw a generic exception indicating that 1) an unexpected
2703:             * exception was thrown, and 2) we've already printed the trace
2704:             * (so don't do it again).
2705:             * 
2706:             * @param e An unexpected exception.
2707:             * @throws Exception with message UNEXPECTED_ERR.
2708:             */
2709:            private void throwUnexpectedException(Exception e) throws Exception {
2710:
2711:                consoleExceptionPrintTrace(e);
2712:                throw new Exception(UNEXPECTED_ERR);
2713:
2714:            }
2715:
2716:            /**
2717:             * Localize a message given a particular AppUI 
2718:             *
2719:             * @param msgProp	message key
2720:             * @param localLangUtil LocalizedResource to use to localize message
2721:             * @param args		arguments to message
2722:             *
2723:             */
2724:            private String localizeMessage(String msgProp,
2725:                    LocalizedResource localLangUtil, String[] args) {
2726:                String locMsg = null;
2727:                //check if the argument is a property
2728:                if (args != null) {
2729:                    String[] argMsg = new String[args.length];
2730:                    for (int i = 0; i < args.length; i++) {
2731:                        if (isMsgProperty(args[i]))
2732:                            argMsg[i] = localLangUtil.getTextMessage(args[i]);
2733:                        else
2734:                            argMsg[i] = args[i];
2735:                    }
2736:                    switch (args.length) {
2737:                    case 1:
2738:                        locMsg = localLangUtil.getTextMessage(msgProp,
2739:                                argMsg[0]);
2740:                        break;
2741:                    case 2:
2742:                        locMsg = localLangUtil.getTextMessage(msgProp,
2743:                                argMsg[0], argMsg[1]);
2744:                        break;
2745:                    case 3:
2746:                        locMsg = localLangUtil.getTextMessage(msgProp,
2747:                                argMsg[0], argMsg[1], argMsg[2]);
2748:                        break;
2749:                    case 4:
2750:                        locMsg = localLangUtil.getTextMessage(msgProp,
2751:                                argMsg[0], argMsg[1], argMsg[2], argMsg[3]);
2752:                        break;
2753:                    default:
2754:                        //shouldn't get here
2755:                    }
2756:                } else
2757:                    locMsg = localLangUtil.getTextMessage(msgProp);
2758:                return locMsg;
2759:            }
2760:
2761:            /**
2762:             * Determine type of message
2763:             *
2764:             * @param msg		message 
2765:             *
2766:             * @return message type
2767:             */
2768:            private int getMessageType(String msg) {
2769:                //all property messages should start with DRDA_
2770:                if (!msg.startsWith(DRDA_MSG_PREFIX))
2771:                    return ERRTYPE_UNKNOWN;
2772:                int startpos = msg.indexOf('.') + 1;
2773:                if (startpos >= msg.length())
2774:                    return ERRTYPE_UNKNOWN;
2775:                if (msg.length() > (startpos + 1))
2776:                    return ERRTYPE_UNKNOWN;
2777:                char type = msg.charAt(startpos);
2778:                if (type == 'S')
2779:                    return ERRTYPE_SEVERE;
2780:                if (type == 'U')
2781:                    return ERRTYPE_USER;
2782:                if (type == 'I')
2783:                    return ERRTYPE_INFO;
2784:                return ERRTYPE_UNKNOWN;
2785:            }
2786:
2787:            /**
2788:             * Determine whether string is a property key or not
2789:             * 	property keys start with DRDA_MSG_PREFIX
2790:             *
2791:             * @param msg		message 
2792:             *
2793:             * @return true if it is a property key; false otherwise
2794:             */
2795:            private boolean isMsgProperty(String msg) {
2796:                if (msg.startsWith(DRDA_MSG_PREFIX))
2797:                    return true;
2798:                else
2799:                    return false;
2800:            }
2801:
2802:            /**
2803:             * Get the current value of logging connections
2804:             *
2805:             * @return true if logging connections is on; false otherwise
2806:             */
2807:            public boolean getLogConnections() {
2808:                synchronized (logConnectionsSync) {
2809:                    return logConnections;
2810:                }
2811:            }
2812:
2813:            /**
2814:             * Set the current value of logging connections
2815:             *
2816:             * @param value	true to turn logging connections on; false to turn it off
2817:             */
2818:            private void setLogConnections(boolean value) {
2819:                synchronized (logConnectionsSync) {
2820:                    logConnections = value;
2821:                }
2822:                // update the value in all the threads
2823:                synchronized (threadList) {
2824:                    for (Enumeration e = threadList.elements(); e
2825:                            .hasMoreElements();) {
2826:                        DRDAConnThread thread = (DRDAConnThread) e
2827:                                .nextElement();
2828:                        thread.setLogConnections(value);
2829:                    }
2830:                }
2831:            }
2832:
2833:            /**
2834:             * Set the security mechanism for derby.drda.securityMechanism
2835:             * If this property is set, server will only allow connections
2836:             * from client with this security mechanism.
2837:             * This method will map the user friendly string representing 
2838:             * the security mechanism to the corresponding drda secmec value
2839:             * @param s security mechanism string value
2840:             * @throws Exception if  value to set is invalid
2841:             * @see Property#DRDA_PROP_SECURITYMECHANISM 
2842:             */
2843:            private void setSecurityMechanism(String s) throws Exception {
2844:                allowOnlySecurityMechanism = getSecMecValue(s);
2845:
2846:                // if server vm cannot support EUSRIDPWD, then do not allow 
2847:                // derby.drda.securityMechanism to be set to EUSRIDPWD security
2848:                // mechanism
2849:                if ((allowOnlySecurityMechanism == INVALID_OR_NOTSET_SECURITYMECHANISM)
2850:                        || (allowOnlySecurityMechanism == CodePoint.SECMEC_EUSRIDPWD && !SUPPORTS_EUSRIDPWD))
2851:                    consolePropertyMessage("DRDA_InvalidValue.U", new String[] {
2852:                            s, Property.DRDA_PROP_SECURITYMECHANISM });
2853:            }
2854:
2855:            /**
2856:             * get the security mechanism (secmec value) that the server
2857:             * will accept connections from.
2858:             * @return the securitymechanism value. It is value that 
2859:             * the derby.drda.securityMechanism was set to, if it is not set, then
2860:             * it is equal to INVALID_OR_NOTSET_SECURITYMECHANISM
2861:             * @see Property#DRDA_PROP_SECURITYMECHANISM 
2862:             */
2863:            protected int getSecurityMechanism() {
2864:                return allowOnlySecurityMechanism;
2865:            }
2866:
2867:            /**
2868:             * Set the trace on/off for all sessions, or one session, depending on
2869:             * whether we got -s argument.
2870:             *
2871:             * @param on	true to turn trace on; false to turn it off
2872:             * @return true if set false if an error occurred
2873:             */
2874:            private boolean setTrace(boolean on) {
2875:                if (sessionArg == 0) {
2876:                    setTraceAll(on);
2877:                    synchronized (sessionTable) {
2878:                        for (Enumeration e = sessionTable.elements(); e
2879:                                .hasMoreElements();) {
2880:                            Session session = (Session) e.nextElement();
2881:                            if (on)
2882:                                session.setTraceOn(traceDirectory);
2883:                            else
2884:                                session.setTraceOff();
2885:                        }
2886:                    }
2887:                } else {
2888:                    Session session = (Session) sessionTable.get(new Integer(
2889:                            sessionArg));
2890:                    if (session != null) {
2891:                        if (on)
2892:                            session.setTraceOn(traceDirectory);
2893:                        else
2894:                            session.setTraceOff();
2895:                    } else
2896:                        return false;
2897:                }
2898:                return true;
2899:            }
2900:
2901:            /**
2902:             * Get the current value of the time slice
2903:             *
2904:             * @return time slice value
2905:             */
2906:            protected int getTimeSlice() {
2907:                return timeSlice;
2908:            }
2909:
2910:            /**
2911:             * Set the current value of  time slice
2912:             *
2913:             * @param value time slice value
2914:             * @exception Exception if value is < 0
2915:             */
2916:            private void setTimeSlice(int value) throws Exception {
2917:                if (value < MIN_TIMESLICE)
2918:                    consolePropertyMessage("DRDA_InvalidValue.U", new String[] {
2919:                            new Integer(value).toString(), "timeslice" });
2920:                if (value == USE_DEFAULT)
2921:                    value = DEFAULT_TIMESLICE;
2922:                synchronized (timeSliceSync) {
2923:                    timeSlice = value;
2924:                }
2925:            }
2926:
2927:            /** 
2928:             * Get the current value of keepAlive to configure how long the server
2929:             * should keep the socket alive for a disconnected client
2930:             */
2931:            protected boolean getKeepAlive() {
2932:                return keepAlive;
2933:            }
2934:
2935:            /**
2936:             * Get the current value of minimum number of threads to create at start
2937:             *
2938:             * @return value of minimum number of threads
2939:             */
2940:            private int getMinThreads() {
2941:                synchronized (threadsSync) {
2942:                    return minThreads;
2943:                }
2944:            }
2945:
2946:            /**
2947:             * Set the current value of minimum number of threads to create at start
2948:             *
2949:             * @param value	 value of minimum number of threads
2950:             */
2951:            private void setMinThreads(int value) {
2952:                synchronized (threadsSync) {
2953:                    minThreads = value;
2954:                }
2955:            }
2956:
2957:            /**
2958:             * Get the current value of maximum number of threads to create 
2959:             *
2960:             * @return value of maximum number of threads
2961:             */
2962:            private int getMaxThreads() {
2963:                synchronized (threadsSync) {
2964:                    return maxThreads;
2965:                }
2966:            }
2967:
2968:            /**
2969:             * Set the current value of maximum number of threads to create 
2970:             *
2971:             * @param value	value of maximum number of threads
2972:             * @exception Exception if value is less than 0
2973:             */
2974:            private void setMaxThreads(int value) throws Exception {
2975:                if (value < MIN_MAXTHREADS)
2976:                    consolePropertyMessage("DRDA_InvalidValue.U", new String[] {
2977:                            new Integer(value).toString(), "maxthreads" });
2978:                if (value == USE_DEFAULT)
2979:                    value = DEFAULT_MAXTHREADS;
2980:                synchronized (threadsSync) {
2981:                    maxThreads = value;
2982:                }
2983:            }
2984:
2985:            /**
2986:             * Get the current value of whether to trace all the sessions
2987:             *
2988:             * @return true if tracing is on for all sessions; false otherwise
2989:             */
2990:            protected boolean getTraceAll() {
2991:                synchronized (traceAllSync) {
2992:                    return traceAll;
2993:                }
2994:            }
2995:
2996:            /**
2997:             * Set the current value of whether to trace all the sessions
2998:             *
2999:             * @param value	true if tracing is on for all sessions; false otherwise
3000:             */
3001:            private void setTraceAll(boolean value) {
3002:                synchronized (traceAllSync) {
3003:                    traceAll = value;
3004:                }
3005:            }
3006:
3007:            /**
3008:             * Get the current value of trace directory
3009:             *
3010:             * @return trace directory
3011:             */
3012:            protected String getTraceDirectory() {
3013:                synchronized (traceDirectorySync) {
3014:                    return traceDirectory;
3015:                }
3016:            }
3017:
3018:            /**
3019:             * Set the current value of trace directory
3020:             *
3021:             * @param value	trace directory
3022:             */
3023:            private void setTraceDirectory(String value) {
3024:                synchronized (traceDirectorySync) {
3025:                    traceDirectory = value;
3026:                }
3027:            }
3028:
3029:            /**
3030:             * Connect to a database to test whether a connection can be made
3031:             *
3032:             * @param writer	connection to send message to
3033:             * @param database 	database directory to connect to
3034:             * @param user		user to use
3035:             * @param password	password to use
3036:             */
3037:            private void connectToDatabase(DDMWriter writer, String database,
3038:                    String user, String password) throws Exception {
3039:                Properties p = new Properties();
3040:                if (user != null)
3041:                    p.put("user", user);
3042:                if (password != null)
3043:                    p.put("password", password);
3044:                try {
3045:                    Class.forName(CLOUDSCAPE_DRIVER);
3046:                } catch (Exception e) {
3047:                    sendMessage(writer, ERROR, e.getMessage());
3048:                    return;
3049:                }
3050:                try {
3051:                    //Note, we add database to the url so that we can allow additional
3052:                    //url attributes
3053:                    Connection conn = DriverManager.getConnection(
3054:                            Attribute.PROTOCOL + database, p);
3055:                    // send warnings
3056:                    SQLWarning warn = conn.getWarnings();
3057:                    if (warn != null)
3058:                        sendSQLMessage(writer, warn, SQLWARNING);
3059:                    else
3060:                        sendOK(writer);
3061:                    conn.close();
3062:                    return;
3063:                } catch (SQLException se) {
3064:                    sendSQLMessage(writer, se, SQLERROR);
3065:                }
3066:            }
3067:
3068:            /**
3069:             * Boot database 
3070:             *
3071:             * @param writer	connection to send message to
3072:             * @param database 	database directory to connect to
3073:             * @param bootPassword	boot password
3074:             * @param encPrv	encryption provider
3075:             * @param encAlg	encryption algorithm
3076:             * @param user		user to use
3077:             * @param password	password to use
3078:             */
3079:            private void startDatabase(DDMWriter writer, String database,
3080:                    String bootPassword, String encPrv, String encAlg,
3081:                    String user, String password) throws Exception {
3082:                Properties p = new Properties();
3083:                if (bootPassword != null)
3084:                    p.put(Attribute.BOOT_PASSWORD, bootPassword);
3085:                if (encPrv != null)
3086:                    p.put(Attribute.CRYPTO_PROVIDER, encPrv);
3087:                if (encAlg != null)
3088:                    p.put(Attribute.CRYPTO_ALGORITHM, encAlg);
3089:                if (user != null)
3090:                    p.put(Attribute.USERNAME_ATTR, user);
3091:                if (password != null)
3092:                    p.put(Attribute.PASSWORD_ATTR, password);
3093:                try {
3094:                    Class.forName(CLOUDSCAPE_DRIVER);
3095:                } catch (Exception e) {
3096:                    sendMessage(writer, ERROR, e.getMessage());
3097:                    return;
3098:                }
3099:                try {
3100:                    //Note, we add database to the url so that we can allow additional
3101:                    //url attributes
3102:                    Connection conn = DriverManager.getConnection(
3103:                            Attribute.PROTOCOL + database, p);
3104:                    SQLWarning warn = conn.getWarnings();
3105:                    if (warn != null)
3106:                        sendSQLMessage(writer, warn, SQLWARNING);
3107:                    else
3108:                        sendOK(writer);
3109:                    conn.close();
3110:                } catch (SQLException se) {
3111:                    sendSQLMessage(writer, se, SQLERROR);
3112:                } catch (Exception e) {
3113:                    sendMessage(writer, ERROR, e.getMessage());
3114:                }
3115:            }
3116:
3117:            /**
3118:             * Shutdown a database 
3119:             *
3120:             * @param writer	connection to send message to
3121:             * @param database 	database directory to shutdown to
3122:             * @param user		user to use
3123:             * @param password	password to use
3124:             */
3125:            private void shutdownDatabase(DDMWriter writer, String database,
3126:                    String user, String password) throws Exception {
3127:
3128:                StringBuffer url = new StringBuffer(Attribute.PROTOCOL
3129:                        + database);
3130:                if (user != null)
3131:                    url.append(";user=" + user);
3132:                if (password != null)
3133:                    url.append(";password=" + password);
3134:                url.append(";shutdown=true");
3135:                try {
3136:                    Class.forName(CLOUDSCAPE_DRIVER);
3137:                } catch (Exception e) {
3138:                    sendMessage(writer, ERROR, e.getMessage());
3139:                    return;
3140:                }
3141:                try {
3142:                    Connection conn = DriverManager.getConnection(url
3143:                            .toString());
3144:                    SQLWarning warn = conn.getWarnings();
3145:                    if (warn != null)
3146:                        sendSQLMessage(writer, warn, SQLWARNING);
3147:                    else
3148:                        sendOK(writer);
3149:                    conn.close();
3150:                } catch (SQLException se) {
3151:                    //ignore shutdown error
3152:                    String expectedState = StandardException
3153:                            .getSQLStateFromIdentifier(SQLState.SHUTDOWN_DATABASE);
3154:                    if (!expectedState.equals(se.getSQLState())) {
3155:                        sendSQLMessage(writer, se, SQLERROR);
3156:                        return;
3157:                    }
3158:                    sendOK(writer);
3159:                }
3160:            }
3161:
3162:            /**
3163:             * Wrap SQL Error - display to console and raise exception
3164:             *
3165:             * @param messageKey	Cloudscape SQL Exception message id
3166:             *
3167:             * @exception Exception raises exception for message
3168:             */
3169:            private void wrapSQLError(String messageKey) throws Exception {
3170:                consolePropertyMessage("DRDA_SQLException.S", messageKey);
3171:            }
3172:
3173:            /**
3174:             * Wrap SQL Warning - display to console and raise exception
3175:             *
3176:             * @param messageKey	Cloudscape SQL Exception message id
3177:             *
3178:             * @exception Exception raises exception for message
3179:             */
3180:            private void wrapSQLWarning(String messageKey) throws Exception {
3181:                consolePropertyMessage("DRDA_SQLWarning.I", messageKey);
3182:            }
3183:
3184:            private Properties getPropertyValues() {
3185:                Properties retval = new Properties();
3186:                retval.put(Property.DRDA_PROP_PORTNUMBER, new Integer(
3187:                        portNumber).toString());
3188:                retval.put(Property.DRDA_PROP_HOSTNAME, hostArg);
3189:                retval.put(Property.DRDA_PROP_KEEPALIVE, new Boolean(keepAlive)
3190:                        .toString());
3191:
3192:                String tracedir = getTraceDirectory();
3193:                if (tracedir != null)
3194:                    retval.put(Property.DRDA_PROP_TRACEDIRECTORY, tracedir);
3195:                retval.put(Property.DRDA_PROP_TRACEALL, new Boolean(
3196:                        getTraceAll()).toString());
3197:                retval.put(Property.DRDA_PROP_MINTHREADS, new Integer(
3198:                        getMinThreads()).toString());
3199:                retval.put(Property.DRDA_PROP_MAXTHREADS, new Integer(
3200:                        getMaxThreads()).toString());
3201:                retval.put(Property.DRDA_PROP_TIMESLICE, new Integer(
3202:                        getTimeSlice()).toString());
3203:
3204:                retval.put(Property.DRDA_PROP_TIMESLICE, new Integer(
3205:                        getTimeSlice()).toString());
3206:                retval.put(Property.DRDA_PROP_LOGCONNECTIONS, new Boolean(
3207:                        getLogConnections()).toString());
3208:                String startDRDA = PropertyUtil
3209:                        .getSystemProperty(Property.START_DRDA);
3210:                //DERBY-375 If a system property is specified without any value, getProperty returns 
3211:                //an empty string. Use default values in such cases.
3212:                if (startDRDA != null && startDRDA.equals(""))
3213:                    startDRDA = "false";
3214:
3215:                retval.put(Property.START_DRDA, (startDRDA == null) ? "false"
3216:                        : startDRDA);
3217:
3218:                // if Property.DRDA_PROP_SECURITYMECHANISM has been set on server
3219:                // then put it in retval else the default behavior is as though 
3220:                // it is not set
3221:                if (getSecurityMechanism() != INVALID_OR_NOTSET_SECURITYMECHANISM)
3222:                    retval.put(Property.DRDA_PROP_SECURITYMECHANISM,
3223:                            getStringValueForSecMec(getSecurityMechanism()));
3224:
3225:                //get the trace value for each session if tracing for all is not set
3226:                if (!getTraceAll()) {
3227:                    synchronized (sessionTable) {
3228:                        for (Enumeration e = sessionTable.elements(); e
3229:                                .hasMoreElements();) {
3230:                            Session session = (Session) e.nextElement();
3231:                            if (session.isTraceOn())
3232:                                retval.put(Property.DRDA_PROP_TRACE + "."
3233:                                        + session.getConnNum(), "true");
3234:                        }
3235:                    }
3236:                }
3237:                return retval;
3238:            }
3239:
3240:            /**
3241:             * Add a session - for use by <code>ClientThread</code>. Put the session
3242:             * into the session table and the run queue. Start a new
3243:             * <code>DRDAConnThread</code> if there are more sessions waiting than
3244:             * there are free threads, and the maximum number of threads is not
3245:             * exceeded.
3246:             *
3247:             * <p><code>addSession()</code> should only be called from one thread at a
3248:             * time.
3249:             *
3250:             * @param clientSocket the socket to read from and write to
3251:             */
3252:            void addSession(Socket clientSocket) throws Exception {
3253:
3254:                int connectionNumber = ++connNum;
3255:
3256:                if (getLogConnections()) {
3257:                    consolePropertyMessage("DRDA_ConnNumber.I", Integer
3258:                            .toString(connectionNumber));
3259:                }
3260:
3261:                // Note that we always re-fetch the tracing configuration because it
3262:                // may have changed (there are administrative commands which allow
3263:                // dynamic tracing reconfiguration).
3264:                Session session = new Session(connectionNumber, clientSocket,
3265:                        getTraceDirectory(), getTraceAll());
3266:
3267:                sessionTable.put(new Integer(connectionNumber), session);
3268:
3269:                // Check whether there are enough free threads to service all the
3270:                // threads in the run queue in addition to the newly added session.
3271:                boolean enoughThreads;
3272:                synchronized (runQueue) {
3273:                    enoughThreads = (runQueue.size() < freeThreads);
3274:                }
3275:                // No need to hold the synchronization on runQueue any longer than
3276:                // this. Since no other threads can make runQueue grow, and no other
3277:                // threads will reduce the number of free threads without removing
3278:                // sessions from runQueue, (runQueue.size() < freeThreads) cannot go
3279:                // from true to false until addSession() returns.
3280:
3281:                DRDAConnThread thread = null;
3282:
3283:                // try to start a new thread if we don't have enough free threads
3284:                if (!enoughThreads) {
3285:                    // Synchronize on threadsSync to ensure that the value of
3286:                    // maxThreads doesn't change until the new thread is added to
3287:                    // threadList.
3288:                    synchronized (threadsSync) {
3289:                        // only start a new thread if we have no maximum number of
3290:                        // threads or the maximum number of threads is not exceeded
3291:                        if ((maxThreads == 0)
3292:                                || (threadList.size() < maxThreads)) {
3293:                            thread = new DRDAConnThread(session, this ,
3294:                                    getTimeSlice(), getLogConnections());
3295:                            threadList.add(thread);
3296:                            thread.start();
3297:                        }
3298:                    }
3299:                }
3300:
3301:                // add the session to the run queue if we didn't start a new thread
3302:                if (thread == null) {
3303:                    runQueueAdd(session);
3304:                }
3305:            }
3306:
3307:            /**
3308:             * Remove a thread from the thread list. Should be called when a
3309:             * <code>DRDAConnThread</code> has been closed.
3310:             *
3311:             * @param thread the closed thread
3312:             */
3313:            void removeThread(DRDAConnThread thread) {
3314:                threadList.remove(thread);
3315:            }
3316:
3317:            protected Object getShutdownSync() {
3318:                return shutdownSync;
3319:            }
3320:
3321:            protected boolean getShutdown() {
3322:                return shutdown;
3323:            }
3324:
3325:            public String buildRuntimeInfo(LocalizedResource locallangUtil) {
3326:
3327:                String s = locallangUtil
3328:                        .getTextMessage("DRDA_RuntimeInfoBanner.I")
3329:                        + "\n";
3330:                int sessionCount = 0;
3331:                s += locallangUtil
3332:                        .getTextMessage("DRDA_RuntimeInfoSessionBanner.I")
3333:                        + "\n";
3334:                for (int i = 0; i < threadList.size(); i++) {
3335:                    String sessionInfo = ((DRDAConnThread) threadList.get(i))
3336:                            .buildRuntimeInfo("", locallangUtil);
3337:                    if (!sessionInfo.equals("")) {
3338:                        sessionCount++;
3339:                        s += sessionInfo + "\n";
3340:                    }
3341:                }
3342:                int waitingSessions = 0;
3343:                for (int i = 0; i < runQueue.size(); i++) {
3344:                    s += ((Session) runQueue.get(i)).buildRuntimeInfo("",
3345:                            locallangUtil);
3346:                    waitingSessions++;
3347:                }
3348:                s += "-------------------------------------------------------------\n";
3349:                s += locallangUtil
3350:                        .getTextMessage("DRDA_RuntimeInfoNumThreads.I")
3351:                        + threadList.size() + "\n";
3352:                s += locallangUtil
3353:                        .getTextMessage("DRDA_RuntimeInfoNumActiveSessions.I")
3354:                        + sessionCount + "\n";
3355:                s += locallangUtil
3356:                        .getTextMessage("DRDA_RuntimeInfoNumWaitingSessions.I")
3357:                        + +waitingSessions + "\n\n";
3358:
3359:                Runtime rt = Runtime.getRuntime();
3360:                rt.gc();
3361:                long totalmem = rt.totalMemory();
3362:                long freemem = rt.freeMemory();
3363:                s += locallangUtil
3364:                        .getTextMessage("DRDA_RuntimeInfoTotalMemory.I")
3365:                        + +totalmem + "\t";
3366:                s += locallangUtil
3367:                        .getTextMessage("DRDA_RuntimeInfoFreeMemory.I")
3368:                        + +freemem + "\n\n";
3369:
3370:                return s;
3371:            }
3372:
3373:            protected void setClientLocale(String locale) {
3374:                clientLocale = locale;
3375:            }
3376:
3377:            /**
3378:             * Retrieve product version information
3379:             * We need to make sure that this method gets the stream and passes it to 
3380:             * ProductVersionHolder, because it lives in the Network Server jar
3381:             * and won't be readily available to ProductVersionHolder when running
3382:             * under security manager.
3383:             */
3384:            private ProductVersionHolder getNetProductVersionHolder()
3385:                    throws Exception {
3386:                ProductVersionHolder myPVH = null;
3387:                try {
3388:                    myPVH = (ProductVersionHolder) AccessController
3389:                            .doPrivileged(new PrivilegedExceptionAction() {
3390:
3391:                                public Object run()
3392:                                        throws UnknownHostException,
3393:                                        IOException {
3394:                                    InputStream versionStream = getClass()
3395:                                            .getResourceAsStream(
3396:                                                    ProductGenusNames.NET_INFO);
3397:
3398:                                    return ProductVersionHolder
3399:                                            .getProductVersionHolderFromMyEnv(versionStream);
3400:                                }
3401:                            });
3402:
3403:                } catch (PrivilegedActionException e) {
3404:                    Exception e1 = e.getException();
3405:                    consolePropertyMessage("DRDA_ProductVersionReadError.S", e1
3406:                            .getMessage());
3407:                }
3408:                return myPVH;
3409:            }
3410:
3411:            /**
3412:             * This method returns a timestamp to be used in the messages. 
3413:             * CheapDateFormatter class, which uses GMT, is used to format timestamps. 
3414:             * This is to keep the formatting consistent with Derby boot message since
3415:             * network server messages and the boot message get written to derby.log.   
3416:             * 
3417:             * @return current timestamp formatted in GMT
3418:             */
3419:            private String getFormattedTimestamp() {
3420:                long currentTime = System.currentTimeMillis();
3421:                return CheapDateFormatter.formatDate(currentTime);
3422:            }
3423:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.