Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.j2ssh.connection » [javadoc | source]
    1   /*
    2    *  SSHTools - Java SSH2 API
    3    *
    4    *  Copyright (C) 2002-2003 Lee David Painter and Contributors.
    5    *
    6    *  Contributions made by:
    7    *
    8    *  Brett Smith
    9    *  Richard Pernavas
   10    *  Erwin Bolwidt
   11    *
   12    *  This program is free software; you can redistribute it and/or
   13    *  modify it under the terms of the GNU General Public License
   14    *  as published by the Free Software Foundation; either version 2
   15    *  of the License, or (at your option) any later version.
   16    *
   17    *  This program is distributed in the hope that it will be useful,
   18    *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   19    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20    *  GNU General Public License for more details.
   21    *
   22    *  You should have received a copy of the GNU General Public License
   23    *  along with this program; if not, write to the Free Software
   24    *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   25    */
   26   package com.sshtools.j2ssh.connection;
   27   
   28   import com.sshtools.j2ssh.io.IOStreamConnector;
   29   import com.sshtools.j2ssh.transport.MessageNotAvailableException;
   30   import com.sshtools.j2ssh.transport.MessageStoreEOFException;
   31   import com.sshtools.j2ssh.transport.SshMessageStore;
   32   
   33   import org.apache.commons.logging.Log;
   34   import org.apache.commons.logging.LogFactory;
   35   
   36   import java.io.IOException;
   37   import java.io.InputStream;
   38   import java.io.OutputStream;
   39   
   40   
   41   /**
   42    *
   43    *
   44    * @author $author$
   45    * @version $Revision: 1.16 $
   46    */
   47   public abstract class IOChannel extends Channel {
   48       private static Log log = LogFactory.getLog(IOChannel.class);
   49   
   50       /**  */
   51       private SshMessageStore incoming = new SshMessageStore();
   52   
   53       /**  */
   54       protected ChannelInputStream in;
   55   
   56       /**  */
   57       protected ChannelOutputStream out;
   58   
   59       /**  */
   60       protected InputStream boundInputStream = null;
   61   
   62       /**  */
   63       protected OutputStream boundOutputStream = null;
   64   
   65       //protected IOChannel boundIOChannel = null;
   66   
   67       /**  */
   68       protected IOStreamConnector ios = null;
   69   
   70       /**
   71        *
   72        *
   73        * @param connection
   74        * @param localChannelId
   75        * @param senderChannelId
   76        * @param initialWindowSize
   77        * @param maximumPacketSize
   78        *
   79        * @throws IOException
   80        */
   81       protected void init(ConnectionProtocol connection, long localChannelId,
   82           long senderChannelId, long initialWindowSize, long maximumPacketSize)
   83           throws IOException {
   84           this.in = new ChannelInputStream(incoming); //ChannelInputStream.createStandard(incoming);
   85           this.out = new ChannelOutputStream(this);
   86           super.init(connection, localChannelId, senderChannelId,
   87               initialWindowSize, maximumPacketSize);
   88       }
   89   
   90       /**
   91        *
   92        *
   93        * @throws IOException
   94        */
   95       protected void open() throws IOException {
   96           super.open();
   97   
   98           // If were bound send any outstanding messages sitting around
   99           if (boundOutputStream != null) {
  100               sendOutstandingMessages();
  101           }
  102   
  103           // Start the bound inputstream
  104           if ((boundInputStream != null) && (ios == null)) {
  105               ios.setCloseInput(false);
  106               ios.setCloseOutput(false);
  107               ios.connect(boundInputStream, out);
  108           }
  109       }
  110   
  111       /**
  112        *
  113        *
  114        * @return
  115        */
  116       public ChannelInputStream getInputStream() {
  117           return in;
  118       }
  119   
  120       /**
  121        *
  122        *
  123        * @return
  124        */
  125       public ChannelOutputStream getOutputStream() {
  126           return out;
  127       }
  128   
  129       /**
  130        *
  131        *
  132        * @param msg
  133        *
  134        * @throws IOException
  135        */
  136       protected void onChannelData(SshMsgChannelData msg)
  137           throws IOException {
  138           // Synchronize on the message store to ensure that another thread
  139           // does not try to read its data. This will make sure that the incoming
  140           // messages are not being flushed to an outputstream after a bind
  141           synchronized (incoming) {
  142               if (boundOutputStream != null) {
  143                   try {
  144                       boundOutputStream.write(msg.getChannelData());
  145                   } catch (IOException ex) {
  146                       log.info(
  147                           "Could not route data to the bound OutputStream; Closing channel.");
  148                       log.info(ex.getMessage());
  149                       close();
  150                   }
  151               } else {
  152                   incoming.addMessage(msg);
  153               }
  154           }
  155       }
  156   
  157       /**
  158        *
  159        *
  160        * @throws IOException
  161        */
  162       public void setLocalEOF() throws IOException {
  163           super.setLocalEOF();
  164   
  165           if (!out.isClosed()) {
  166               out.close();
  167           }
  168       }
  169   
  170       /**
  171        *
  172        *
  173        * @throws IOException
  174        */
  175       protected void onChannelEOF() throws IOException {
  176           if (!in.isClosed()) {
  177               in.close();
  178           }
  179       }
  180   
  181       /**
  182        *
  183        *
  184        * @throws IOException
  185        */
  186       protected void onChannelClose() throws IOException {
  187           // Close the input/output streams
  188           if (!in.isClosed()) {
  189               in.close();
  190           }
  191   
  192           if (!out.isClosed()) {
  193               out.close();
  194           }
  195   
  196           // Close the bound channel
  197   
  198           /* if(boundIOChannel!=null && !boundIOChannel.isClosed())
  199                boundIOChannel.close();*/
  200   
  201           // Close the IOStream connector if were bound
  202           if (ios != null) {
  203               ios.close();
  204           }
  205       }
  206   
  207       /**
  208        *
  209        *
  210        * @param msg
  211        *
  212        * @throws IOException
  213        */
  214       protected void onChannelExtData(SshMsgChannelExtendedData msg)
  215           throws IOException {
  216           // This class will not deal with extended data
  217           // incoming.addMessage(msg);
  218       }
  219   
  220       /*public void bindIOChannel(IOChannel boundIOChannel) throws IOException {
  221          this.boundIOChannel = boundIOChannel;
  222           // If the bound channel is open then bind the outputstreams
  223           if (boundIOChannel.getState().getValue() == ChannelState.CHANNEL_OPEN) {
  224        throw new IOException("You cannot bind to an open channel");
  225           }
  226           // Create an event listener so we can listen
  227           boundIOChannel.addEventListener(new ChannelEventListener() {
  228        public void onChannelOpen(Channel channel) {
  229            try {
  230              bindOutputStream(IOChannel.this.boundIOChannel.getOutputStream());
  231              IOChannel.this.boundIOChannel.bindOutputStream(getOutputStream());
  232            }
  233            catch (IOException ex) {
  234              log.info("Failed to bind the channel");
  235            }
  236        }
  237        public void onChannelEOF(Channel channel) {
  238          try {
  239              //setLocalEOF();
  240              close();
  241          }
  242          catch (IOException ex) {
  243            log.info("Failed to set the channel to EOF");
  244          }
  245        }
  246        public void onChannelClose(Channel channel)  {
  247          try {
  248            if(!isClosed())
  249              close();
  250          }
  251          catch (IOException ex) {
  252            log.info("Failed to close the channel");
  253          }
  254        }
  255        public void onDataReceived(Channel channel, byte[] data) {
  256        }
  257        public void onDataSent(Channel channel, byte[] data) {
  258        }
  259           });
  260        }*/
  261       public void bindOutputStream(OutputStream boundOutputStream)
  262           throws IOException {
  263           // Synchronize on the incoming message store to ensure that no other
  264           // messages are added whilst we transfer to a bound state
  265           synchronized (incoming) {
  266               this.boundOutputStream = boundOutputStream;
  267   
  268               if (state.getValue() == ChannelState.CHANNEL_OPEN) {
  269                   sendOutstandingMessages();
  270               }
  271           }
  272       }
  273   
  274       /**
  275        *
  276        *
  277        * @param boundInputStream
  278        *
  279        * @throws IOException
  280        */
  281       public void bindInputStream(InputStream boundInputStream)
  282           throws IOException {
  283           this.boundInputStream = boundInputStream;
  284           this.ios = new IOStreamConnector();
  285   
  286           if (state.getValue() == ChannelState.CHANNEL_OPEN) {
  287               ios.setCloseInput(false);
  288               ios.setCloseOutput(false);
  289               ios.connect(boundInputStream, out);
  290           }
  291       }
  292   
  293       private void sendOutstandingMessages() throws IOException {
  294           if ((boundInputStream != null) && (boundOutputStream != null) &&
  295                   incoming.hasMessages()) {
  296               while (true) {
  297                   try {
  298                       // Peek into the message store and look for the next message
  299                       SshMsgChannelData msg = (SshMsgChannelData) incoming.peekMessage(SshMsgChannelData.SSH_MSG_CHANNEL_DATA);
  300   
  301                       // Remove the message so we dont process again
  302                       incoming.removeMessage(msg);
  303   
  304                       // Write the message out to the bound OutputStream
  305                       try {
  306                           boundOutputStream.write(msg.getChannelData());
  307                       } catch (IOException ex1) {
  308                           //log.info("Could not write outstanding messages to the bound OutputStream: "  +ex1.getMessage());
  309                           close();
  310                       }
  311                   } catch (MessageStoreEOFException ex) {
  312                       break;
  313                   } catch (MessageNotAvailableException ex) {
  314                       break;
  315                   } catch (InterruptedException ex) {
  316                       throw new IOException("The thread was interrupted");
  317                   }
  318               }
  319           }
  320       }
  321   }

Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.j2ssh.connection » [javadoc | source]