SCP on paramiko

import paramiko

class SCPClient(paramiko.SSHClient):
  def read_response(self, stdout):
    c = ord(stdout.read(1))
    if c == 0:
      return
    if c == -1:
      raise paramiko.SSHException("Remote scp terminated unexpectedly")
    if c != 1 and c != 2:
      raise paramiko.SSHException("Remote scp sent illegal error code")
    if c == 2:
      raise paramiko.SSHException("Remote scp terminated with error(%s)")
    
    err = stdout.readline()
    raise paramiko.SSHException("Remote scp terminated with error(%s)" % err)
    
  def send(self, localpath=None, remotepath=None, preserve=False, mode="0644"):
    if localpath is None:
      raise Exception("localpath must be specified")
    if remotepath is None:
      raise Exception("remotepath must be specified")
    if not os.path.exists(localpath):
      raise Exception("%s doesn't exist" % localpath)
    rdname = os.path.dirname(remotepath)
    rbname = os.path.basename(remotepath)
    if not rbname:
      rbname = os.path.basename(localpath)
    fsize = os.path.getsize(localpath)
    st = os.stat(localpath)
      
    cmd = "scp -t %s" % (remotepath)
    stdin, stdout, stderr = self.exec_command(cmd)
    
    if preserve:
      mtime = st.st_mtime
      atime = st.st_atime
      tline = "T%d %ld %d %ld\n" % (
        long(mtime), 
        long(mtime*1000000), # not sure
        long(atime), 
        long(atime*1000000)) # not sure
      stdin.write(tline)
    cline = "C%s %d %s\n" % (mode, fsize, rbname)
    stdin.write(cline)
    stdin.flush()
    
    self.read_response(stdout)
    
    fh = open(localpath, "rb")
    while True:
      s = fh.read(4096)
      if not s:
        break
      stdin.write(s)
      stdin.flush()
    fh.close()
    
    stdin.write("\0")
    stdin.flush()
    
    self.read_response(stdout)
    
    stdin.write("E\n")
    stdin.close()

# use it like:
client = SCPClient()
client.connect(host, username="user1", password="password1")
client.send(localpath="/home/foo/foo.txt", remotepath="/home/bar/bar.txt")

I've just ported it from SSH2 implementation of Java, Ganymed. And this experimental code can only send file, not receive -:)

Read OpenSSH/scp.c for more details!

Wondering how you can get remote stderr on error occuring...