jtopenlite.com.ibm.jtopenlite.command.CommandConnection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400-jdk9 Show documentation
Show all versions of jt400-jdk9 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpenLite
//
// Filename: CommandConnection.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 2011-2012 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.jtopenlite.command;
import com.ibm.jtopenlite.*;
//import com.ibm.jtopenlite.base.experimental.*;
import java.io.*;
import java.net.*;
import javax.net.ssl.SSLSocketFactory;
/**
* Represents a TCP/IP socket connection to the System i Remote Command host server
* (QSYSWRK/QZRCSRVS prestart jobs). This connection can be used to call programs
* and execute CL commands.
* See {@link com.ibm.jtopenlite.samples.CallCommand} for sample program that uses CommandConnection.
**/
public class CommandConnection extends HostServerConnection
{
/**
* The default TCP/IP port the Remote Command host server listens on.
* If your system has been configured to use a different port, use
* the {@link PortMapper PortMapper} class to determine the port.
*
**/
public static final int DEFAULT_COMMAND_SERVER_PORT = 8475;
public static final int DEFAULT_SSL_COMMAND_SERVER_PORT = 9475;
private int ccsid_;
private int datastreamLevel_;
private String NLV_ ;
private CommandConnection(SystemInfo info, Socket socket, HostInputStream in, HostOutputStream out, int ccsid, int datastreamLevel, String user, String jobName, String NLV)
{
super(info, user, jobName, socket, in, out);
ccsid_ = ccsid;
datastreamLevel_ = datastreamLevel;
NLV_ = NLV;
}
protected void sendEndJobRequest() throws IOException
{
out_.writeInt(20); // Length is 40 if server ID is E004.
out_.writeShort(0); // Header ID.
out_.writeShort(0xE008); // Server ID.
out_.writeInt(0); // CS instance.
out_.writeInt(0); // Correlation ID.
out_.writeShort(0); // Template length.
out_.writeShort(0x1004); // ReqRep ID for remote command server.
out_.flush();
}
/**
* Get the NLV used by the connection
* @return NLV used by the connection
*/
public String getNLV() {
return NLV_;
}
/**
* Get the CCSID used by the connection
* @return CCSID used by the connection
*/
public int getCcsid() {
return ccsid_;
}
/**
* Connects to the Remote Command host server on the default port after first connecting
* to the Signon host server and authenticating the specified user.
**/
public static CommandConnection getConnection(String system, String user, String password) throws IOException
{
return getConnection(false, system, user, password);
}
/**
* Connects to the Remote Command host server on the default port after first connecting
* to the Signon host server and authenticating the specified user.
**/
public static CommandConnection getConnection(final boolean isSSL, String system, String user, String password) throws IOException
{
SignonConnection conn = SignonConnection.getConnection(isSSL, system, user, password);
try
{
return getConnection(isSSL, conn.getInfo(), user, password);
}
finally
{
conn.close();
}
}
/**
* Connects to the Remote Command host server on the default port using the specified system information and user.
**/
public static CommandConnection getConnection(SystemInfo info, String user, String password) throws IOException
{
return getConnection(false, info, user, password);
}
/**
* Connects to the Remote Command host server on the default port using the specified system information and user.
**/
public static CommandConnection getConnection(final boolean isSSL, SystemInfo info, String user, String password) throws IOException
{
return getConnection(isSSL, info, user, password, isSSL ? DEFAULT_SSL_COMMAND_SERVER_PORT :DEFAULT_COMMAND_SERVER_PORT, false);
}
/**
* Connects to the Remote Command host server on the specified port using the specified system information and user.
**/
public static CommandConnection getConnection(SystemInfo info, String user, String password, int commandPort, boolean compress) throws IOException
{
return getConnection(false, info, user, password, commandPort, compress);
}
/**
* Connects to the Remote Command host server on the specified port using the specified system information and user.
**/
public static CommandConnection getConnection(final boolean isSSL, SystemInfo info, String user, String password, int commandPort, boolean compress) throws IOException
{
if (commandPort < 0 || commandPort > 65535)
{
throw new IOException("Bad command port: "+commandPort);
}
CommandConnection conn = null;
Socket commandServer = isSSL? SSLSocketFactory.getDefault().createSocket(info.getSystem(), commandPort) : new Socket(info.getSystem(), commandPort);
InputStream in = commandServer.getInputStream();
OutputStream out = commandServer.getOutputStream();
try
{
if (compress)
{
throw new IOException("Experimental compression streams not enabled.");
// in = new CompressionInputStream(in);
// out = new CompressionOutputStream(new BufferedOutputStream(out));
}
// Exchange random seeds.
HostOutputStream dout = new HostOutputStream(compress ? out : new BufferedOutputStream(out));
HostInputStream din = new HostInputStream(new BufferedInputStream(in));
String jobName = connect(info, dout, din, 0xE008, user, password);
String NLV = Conv.getDefaultNLV();
sendExchangeAttributesRequest(dout, NLV);
dout.flush();
int length = din.readInt();
if (length < 20)
{
throw DataStreamException.badLength("commandExchangeAttributes", length);
}
din.skipBytes(16);
int rc = din.readShort();
// We ignore the same return codes that JTOPEN ignores
if (rc != 0x0100 && // Limited user.
rc != 0x0104 && // Invalid CCSID.
rc != 0x0105 && // Invalid NLV, default to primary NLV:
rc != 0x0106 && // NLV not installed, default to primary NLV:
// The NLV may not be supported or it may not be installed on the system.
rc != 0x0107 && // Error retrieving product information. Can't validate NLV.
rc != 0x0108 && // Error trying to add NLV library to system library list:
// One possible reason for failure is the user may not be authorized to CHGSYSLIBL command.
rc != 0 )
{
throw DataStreamException.badReturnCode("commandExchangeAttributes", rc);
}
int ccsid = din.readInt();
byte[] nlvBytes = new byte[4];
nlvBytes[0] = (byte) din.readByte();
nlvBytes[1] = (byte) din.readByte();
nlvBytes[2] = (byte) din.readByte();
nlvBytes[3] = (byte) din.readByte();
NLV = Conv.ebcdicByteArrayToString(nlvBytes, 0, 4);
// Server version
din.skipBytes(4);
int datastreamLevel = din.readShort();
din.skipBytes(length-36);
din.end();
conn = new CommandConnection(info, commandServer, din, dout, ccsid, datastreamLevel, user, jobName, NLV);
return conn;
}
finally
{
if (conn == null)
{
in.close();
out.close();
commandServer.close();
}
}
}
/**
* Calls the specified program using the specified parameter data and returns the result.
**/
public CommandResult call(String pgmLibrary, String pgmName, Parameter[] parms) throws IOException
{
if (isClosed()) throw new IOException("Connection closed");
sendCallProgramRequest(out_, pgmLibrary, pgmName, parms, datastreamLevel_);
out_.flush();
int length = in_.readInt();
if (length < 20)
{
throw DataStreamException.badLength("commandCallProgram", length);
}
in_.skipBytes(16);
int rc = in_.readShort();
final boolean success = rc == 0;
Message[] messages = null;
if (rc == 0)
{
in_.skipBytes(2);
for (int i=0; i 0)
{
int byteLength = in_.readInt();
in_.skipBytes(2);
int outputLength = in_.readInt();
int usage = in_.readShort();
byte[] outputData = new byte[byteLength-12];
in_.readFully(outputData);
parms[i].setOutputData(outputData);
}
}
messages = new Message[0];
}
else
{
messages = getMessages(length);
// throw DataStreamException.badReturnCode("commandCallProgram", rc);
}
in_.end();
return new CommandResult(success, messages, rc);
}
/**
* Calls the specified program and returns the result.
**/
public CommandResult call(Program pgm) throws IOException
{
if (isClosed()) throw new IOException("Connection closed");
pgm.newCall();
sendCallProgramRequest(out_, pgm, datastreamLevel_);
out_.flush();
int length = in_.readInt();
if (length < 20)
{
throw DataStreamException.badLength("commandCallProgram", length);
}
in_.skipBytes(16);
int rc = in_.readShort();
final boolean success = rc == 0;
Message[] messages = null;
if (rc == 0)
{
in_.skipBytes(2);
final int numParms = pgm.getNumberOfParameters();
for (int i=0; i 0)
{
int byteLength = in_.readInt();
in_.skipBytes(2);
int outputLength = in_.readInt();
int usage = in_.readShort();
int parmLength = byteLength-12;
byte[] buf = pgm.getTempDataBuffer();
if (buf == null || buf.length < parmLength) buf = new byte[parmLength];
in_.readFully(buf, 0, parmLength);
pgm.setParameterOutputData(i, buf, parmLength);
}
}
messages = new Message[0];
}
else
{
messages = getMessages(length);
// throw DataStreamException.badReturnCode("commandCallProgram", rc);
}
in_.end();
return new CommandResult(success, messages, rc);
}
private static void sendCallProgramRequest(HostOutputStream out, Program pgm, int datastreamLevel) throws IOException
{
int length = 43;
final int numParms = pgm.getNumberOfParameters();
for (int i=0; i= 10;
final int messageOption = newerServer ? 4 : (datastreamLevel < 7 ? 0 : 2); // Always return all messages when possible.
out.writeByte(messageOption);
out.writeShort(numParms); // Number of parameters.
for (int i=0; i outputLength ? inputLength : outputLength;
out.writeInt(maxLength); // Either the input length or output length, whichever is larger.
switch (pgm.getParameterType(i))
{
case Parameter.TYPE_NULL:
if (datastreamLevel < 6)
{
// Nulls not allowed.
out.writeShort(1); // Treat as input.
}
else
{
out.writeShort(255);
}
break;
case Parameter.TYPE_INPUT:
out.writeShort(11);
byte[] inputBuf = pgm.getParameterInputData(i);
out.write(inputBuf, 0, inputLength);
break;
case Parameter.TYPE_OUTPUT:
out.writeShort(12);
break;
case Parameter.TYPE_INPUT_OUTPUT:
out.writeShort(13);
inputBuf = pgm.getParameterInputData(i);
out.write(inputBuf, 0, inputLength);
break;
}
}
}
private static void sendCallProgramRequest(HostOutputStream out, String pgmLibrary, String pgmName, Parameter[] parms, int datastreamLevel) throws IOException
{
int length = 43;
for (int i=0; i= 10;
final int messageOption = newerServer ? 4 : (datastreamLevel < 7 ? 0 : 2); // Always return all messages when possible.
out.writeByte(messageOption);
out.writeShort(parms.length); // Number of parameters.
for (int i=0; i buffer.length) {
buffer = new char[messageID.length];
}
String messageIDString = Conv.ebcdicByteArrayToString(messageID, buffer);
// String messageTextString = new String(messageText, "Cp037");
if (messageText.length > buffer.length) {
buffer = new char[messageText.length];
}
String messageTextString = Conv.ebcdicByteArrayToString(messageText, buffer);
messages[i] = new Message(messageIDString, messageTextString);
curLength += 40 + messageTypeLength-2 + messageIDLength + messageFileNameLength + messageFileLibraryNameLength + messageTextLength + messageSubstitutionTextLength + messageHelpLength;
}
else if (messageCP == 0x1102)
{
byte[] messageID = new byte[7];
in_.readFully(messageID);
int messageType = in_.readShort();
int severity = in_.readShort();
byte[] fileName = new byte[10];
in_.readFully(fileName);
byte[] libraryName = new byte[10];
in_.readFully(libraryName);
int substitutionDataLength = in_.readShort();
int textLength = in_.readShort();
byte[] substitutionData = new byte[substitutionDataLength];
in_.readFully(substitutionData);
byte[] text = new byte[textLength];
in_.readFully(text);
curLength += 35 + substitutionDataLength + textLength;
// String messageIDString = new String(messageID, "Cp037");
if (messageID.length > buffer.length) {
buffer = new char[messageID.length];
}
String messageIDString = Conv.ebcdicByteArrayToString(messageID, buffer);
// String messageTextString = new String(messageText, "Cp037");
if (text.length > buffer.length) {
buffer = new char[text.length];
}
String messageTextString = Conv.ebcdicByteArrayToString(text, buffer);
messages[i] = new Message(messageIDString, messageTextString);
}
int remaining = messageLength-(curLength-oldLength);
in_.skipBytes(remaining);
}
in_.skipBytes(length-curLength);
return messages;
}
private static void sendRunCommandRequest(HostOutputStream out, String cmd, int datastreamLevel) throws IOException
{
final boolean newerServer = datastreamLevel >= 10;
final byte[] commandBytes = newerServer ? Conv.stringToUnicodeByteArray(cmd) : Conv.stringToEBCDICByteArray37(cmd);
out.writeInt(newerServer ? 31 + commandBytes.length : 27 + commandBytes.length); // Length.
out.writeShort(0); // Header ID.
out.writeShort(0xE008); // Server ID.
out.writeInt(0); // CS instance.
out.writeInt(0); // Correlation ID.
out.writeShort(1); // Template length.
out.writeShort(0x1002); // ReqRep ID.
final int messageOption = newerServer ? 4 : (datastreamLevel < 7 ? 0 : 2); // Always return all messages when possible.
out.writeByte(messageOption);
if (newerServer)
{
out.writeInt(10+commandBytes.length); // Command LL.
out.writeShort(0x1104); // Command CP.
out.writeInt(1200); // Command CCSID.
out.write(commandBytes);
}
else
{
out.writeInt(6+commandBytes.length); // Command LL.
out.writeShort(0x1101); // Command CP.
out.write(commandBytes);
}
}
private static void sendExchangeAttributesRequest(HostOutputStream out, String NLV) throws IOException
{
out.writeInt(34); // Length.
out.writeShort(0); // Header ID.
out.writeShort(0xE008); // Server ID.
out.writeInt(0); // CS instance.
out.writeInt(0); // Correlation ID.
out.writeShort(14); // Template length.
out.writeShort(0x1001); // ReqRep ID.
out.writeInt(1200); // CCSID.
// out.write("2924".getBytes("Cp037")); // NLV.
byte[] NLVbytes = Conv.stringToEBCDICByteArray37(NLV);
out.write(NLVbytes);
out.writeInt(1); // Client version.
out.writeShort(0); // Client datastream level.
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy