gt:     requestId = nextRequestId();
context: /*
   *  SSHTools - Java SSH2 API
   *
   *  Copyright (C) 2002 Lee David Painter.
   *
   *  This program is free software; you can redistribute it and/or
   *  modify it under the terms of the GNU Library General Public License
   *  as published by the Free Software Foundation; either version 2 of
   *  the License, or (at your option) any later version.
   *
   *  You may also distribute it and/or modify it under the terms of the
   *  Apache style J2SSH Software License. A copy of which should have
   *  been provided with the distribution.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  License document supplied with your distribution for more details.
   *
   */
  
  package com.sshtools.j2ssh.sftp;
  
  import java.io.IOException;
  import java.util.List;
  import java.util.StringTokenizer;
  import java.util.Vector;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import com.sshtools.j2ssh.connection.ChannelState;
  import com.sshtools.j2ssh.io.UnsignedInteger32;
  import com.sshtools.j2ssh.io.UnsignedInteger64;
  import com.sshtools.j2ssh.subsystem.SubsystemChannel;
  import com.sshtools.j2ssh.subsystem.SubsystemMessage;
  import com.sshtools.j2ssh.transport.MessageNotAvailableException;
  import com.sshtools.j2ssh.transport.MessageStoreEOFException;
  
  /**
   *
   *
   * @author $author$
   * @version $Revision: 1.2 $
   */
  public class SftpSubsystemClient
      extends SubsystemChannel {
    /**  */
    public static final int OPEN_READ = SshFxpOpen.FXF_READ;
  
    /**  */
    public static final int OPEN_WRITE = SshFxpOpen.FXF_WRITE;
  
    /**  */
    public static final int OPEN_APPEND = SshFxpOpen.FXF_APPEND;
  
    /**  */
    public static final int OPEN_CREATE = SshFxpOpen.FXF_CREAT;
  
    /**  */
    public static final int OPEN_TRUNCATE = SshFxpOpen.FXF_TRUNC;
  
    /**  */
    public static final int OPEN_EXCLUSIVE = SshFxpOpen.FXF_EXCL;
  
    /**  */
    public static final int VERSION_1 = 1;
  
    /**  */
    public static final int VERSION_2 = 2;
  
    /**  */
    public static final int VERSION_3 = 3;
  
    /**  */
    public static final int VERSION_4 = 4;
  
    /* Private variables */
    private static Log log = LogFactory.getLog(SftpSubsystemClient.class);
    private List handles = new Vector();
    private UnsignedInteger32 nextRequestId = new UnsignedInteger32(1);
    private int version = VERSION_3;
    private SftpMessageStore messageStore;
  
    /**
     * Creates a new SftpSubsystemClient object.
     */
    public SftpSubsystemClient() {
      // We will use our own message store implementation
      super("sftp", new SftpMessageStore());
      messageStore = (SftpMessageStore)super.messageStore;
      registerMessages();
    }
  
    /**
     *
     *
     * @return
     */
    public String getName() {
      return "sftp";
    }
  
    /**
     *
     *
     * @return
     */
    protected long availableWindowSpace() {
      return getRemoteWindow().getWindowSpace();
    }
  
    /**
     *
     *
     * @return
     */
    protected long maximumPacketSize() {
      return getRemotePacketSize();
    }
  
    /**
     *
     *
     * @param handle
     *
     * @throws IOException
     */
    protected synchronized void closeHandle(byte[] handle) throws IOException {
      if (!isValidHandle(handle)) {
        throw new IOException("The handle is invalid!");
      }
  
      // We will remove the handle first so that even if an excpetion occurs
      // the file as far as were concerned is closed
      handles.remove(handle);
  
      UnsignedInteger32 requestId = nextRequestId();
      SshFxpClose msg = new SshFxpClose(requestId, handle);
      sendMessage(msg);
      getOKRequestStatus(requestId);
    }
  
    /**
     *
     *
     * @param file
     *
     * @throws IOException
     */
    public void closeFile(SftpFile file) throws IOException {
      closeHandle(file.getHandle());
    }
  
    /**
     *
     *
     * @param handle
     *
     * @return
     */
    protected boolean isValidHandle(byte[] handle) {
      return handles.contains(handle);
    }
  
    /**
     *
     *
     * @param file
     * @param children
     *
     * @return
     *
     * @throws IOException
     */
    public synchronized int listChildren(SftpFile file, List children) throws
        IOException {
      if (file.isDirectory()) {
        if (!isValidHandle(file.getHandle())) {
          file = openDirectory(file.getAbsolutePath());
  
          if (!isValidHandle(file.getHandle())) {
            throw new IOException("Failed to open directory");
          }
        }
      }
      else {
        throw new IOException("Cannot list children for this file object");
      }
  
      UnsignedInteger32 requestId = nextRequestId();
      SshFxpReadDir msg = new SshFxpReadDir(requestId, file.getHandle());
      sendMessage(msg);
  
      try {
        SubsystemMessage reply = messageStore.getMessage(requestId);
  
        if (reply instanceof SshFxpName) {
          SshFxpName names = (SshFxpName) reply;
          SftpFile[] files = names.getFiles();
          SftpFile f;
  
          for (int i = 0; i < files.length; i++) {
            f = new SftpFile(file.getAbsolutePath() + "/"
                             + files[i].getFilename(), files[i].getAttributes());
            f.setSFTPSubsystem(this);
  
            children.add(f);
          }
  
          return files.length;
        }
        else if (reply instanceof SshFxpStatus) {
          SshFxpStatus status = (SshFxpStatus) reply;
  
          if (status.getErrorCode().intValue() == SshFxpStatus.STATUS_FX_EOF) {
            return -1;
          }
          else {
            throw new IOException(status.getErrorMessage());
          }
        }
        else {
          throw new IOException("Unexpected server response "
                                + reply.getMessageName());
        }
      }
      catch (InterruptedException ex) {
        throw new IOException("The thread was interrupted");
      }
    }
  
    /**
     *
     *
     * @param path
     *
     * @throws IOException
     */
    public synchronized void makeDirectory(String path) throws IOException {
      UnsignedInteger32 requestId = nextRequestId();
      SshFxpMkdir msg = new SshFxpMkdir(requestId, path, new FileAttributes());
      sendMessage(msg);
      getOKRequestStatus(requestId);
    }
  
    /**
     *
     *
     * @param path
     *
     * @throws IOException
     */
    public void recurseMakeDirectory(String path) throws IOException {
      SftpFile file;
  
      if (path.trim().length() > 0) {
        try {
          file = openDirectory(path);
          file.close();
        }
        catch (IOException ioe) {
          StringTokenizer tokenizer = new StringTokenizer(path, "/", true);
          String dir = "";
  
          while (tokenizer.hasMoreElements()) {
            dir += tokenizer.nextElement();
  
            try {
              file = openDirectory(dir);
              file.close();
            }
            catch (IOException ioe2) {
              log.info("Creating " + dir);
              makeDirectory(dir);
            }
          }
        }
      }
    }
  
    /**
     *
     *
     * @return
     *
     * @throws IOException
     */
    /*protected boolean onStart() throws IOException {
      return initialize();
    }*/
  
    /**
     *
     *
     * @param path
     *
     * @return
     *
     * @throws IOException
     */
    public synchronized SftpFile openDirectory(String path) throws IOException {
      String absolutePath = getAbsolutePath(path);
      UnsignedInteger32 requestId = nextRequestId();
      SubsystemMessage msg = new SshFxpOpenDir(requestId, absolutePath);
      sendMessage(msg);
  
      byte[] handle = getHandleResponse(requestId);
  