001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.j2ssh.subsystem;
027:
028: import com.sshtools.j2ssh.connection.*;
029: import com.sshtools.j2ssh.io.*;
030: import com.sshtools.j2ssh.transport.*;
031:
032: import org.apache.commons.logging.*;
033:
034: import java.io.*;
035:
036: public abstract class SubsystemChannel extends Channel {
037: private static Log log = LogFactory.getLog(SubsystemChannel.class);
038: Integer exitCode = null;
039: String name;
040: protected SubsystemMessageStore messageStore;
041: DynamicBuffer buffer = new DynamicBuffer();
042: int nextMessageLength = -1;
043:
044: public SubsystemChannel(String name) {
045: this .name = name;
046: this .messageStore = new SubsystemMessageStore();
047: }
048:
049: public SubsystemChannel(String name,
050: SubsystemMessageStore messageStore) {
051: this .name = name;
052: this .messageStore = messageStore;
053: }
054:
055: public String getChannelType() {
056: return "session";
057: }
058:
059: protected void sendMessage(SubsystemMessage msg)
060: throws InvalidMessageException, IOException {
061: if (log.isDebugEnabled()) {
062: log.debug("Sending " + msg.getMessageName()
063: + " subsystem message");
064: }
065:
066: byte[] msgdata = msg.toByteArray();
067:
068: // Write the message length
069: sendChannelData(ByteArrayWriter.encodeInt(msgdata.length));
070:
071: // Write the message data
072: sendChannelData(msgdata);
073: }
074:
075: protected void onChannelRequest(String requestType,
076: boolean wantReply, byte[] requestData)
077: throws java.io.IOException {
078: log.debug("Channel Request received: " + requestType);
079:
080: if (requestType.equals("exit-status")) {
081: exitCode = new Integer((int) ByteArrayReader.readInt(
082: requestData, 0));
083: log.debug("Exit code of " + exitCode.toString()
084: + " received");
085: } else if (requestType.equals("exit-signal")) {
086: ByteArrayReader bar = new ByteArrayReader(requestData);
087: String signal = bar.readString();
088: boolean coredump = bar.read() != 0;
089: String message = bar.readString();
090: String language = bar.readString();
091: log.debug("Exit signal " + signal + " received");
092: log.debug("Signal message: " + message);
093: log.debug("Core dumped: " + String.valueOf(coredump));
094:
095: /*if (signalListener != null) {
096: signalListener.onExitSignal(signal, coredump, message);
097: }*/
098: } else if (requestType.equals("xon-xoff")) {
099: /*if (requestData.length >= 1) {
100: localFlowControl = (requestData[0] != 0);
101: }*/
102: } else if (requestType.equals("signal")) {
103: String signal = ByteArrayReader.readString(requestData, 0);
104: log.debug("Signal " + signal + " received");
105:
106: /*if (signalListener != null) {
107: signalListener.onSignal(signal);
108: }*/
109: } else {
110: if (wantReply) {
111: connection.sendChannelRequestFailure(this );
112: }
113: }
114: }
115:
116: protected void onChannelExtData(SshMsgChannelExtendedData msg)
117: throws java.io.IOException {
118: }
119:
120: protected void onChannelData(SshMsgChannelData msg)
121: throws java.io.IOException {
122: // Write the data to a temporary buffer that may also contain data
123: // that has not been processed
124: buffer.getOutputStream().write(msg.getChannelData());
125:
126: int read;
127: byte[] tmp = new byte[4];
128: byte[] msgdata;
129:
130: // Now process any outstanding messages
131: while (buffer.getInputStream().available() > 4) {
132: if (nextMessageLength == -1) {
133: read = 0;
134:
135: while ((read += buffer.getInputStream().read(tmp)) < 4) {
136: ;
137: }
138:
139: nextMessageLength = (int) ByteArrayReader.readInt(tmp,
140: 0);
141: }
142:
143: if (buffer.getInputStream().available() >= nextMessageLength) {
144: msgdata = new byte[nextMessageLength];
145: buffer.getInputStream().read(msgdata);
146: messageStore.addMessage(msgdata);
147: nextMessageLength = -1;
148: } else {
149: break;
150: }
151: }
152: }
153:
154: protected void onChannelEOF() throws java.io.IOException {
155: }
156:
157: protected void onChannelClose() throws java.io.IOException {
158: if (messageStore != null)
159: messageStore.close();
160: }
161:
162: public byte[] getChannelOpenData() {
163: return null;
164: }
165:
166: protected void onChannelOpen() throws java.io.IOException {
167: }
168:
169: public boolean startSubsystem() throws IOException {
170: log.info("Starting " + name + " subsystem");
171:
172: ByteArrayWriter baw = new ByteArrayWriter();
173: baw.writeString(name);
174:
175: return connection.sendChannelRequest(this , "subsystem", true,
176: baw.toByteArray());
177: }
178:
179: public byte[] getChannelConfirmationData() {
180: return null;
181: }
182: }
|