Home | History | Annotate | Download | only in ssh2
      1 /*
      2  * Copyright (c) 2011 David Kocher. All rights reserved.
      3  * Please refer to the LICENSE.txt for licensing details.
      4  */
      5 package ch.ethz.ssh2;
      6 
      7 import java.io.BufferedInputStream;
      8 import java.io.BufferedOutputStream;
      9 import java.io.IOException;
     10 import java.io.OutputStream;
     11 
     12 /**
     13  * @version $Id:$
     14  */
     15 public class SCPInputStream extends BufferedInputStream
     16 {
     17 	private Session session;
     18 
     19 	/**
     20 	 * Bytes remaining to be read from the stream
     21 	 */
     22 	private long remaining;
     23 
     24 	public SCPInputStream(SCPClient client, Session session) throws IOException
     25 	{
     26 		super(session.getStdout());
     27 
     28 		this.session = session;
     29 
     30 		OutputStream os = new BufferedOutputStream(session.getStdin(), 512);
     31 
     32 		os.write(0x0);
     33 		os.flush();
     34 
     35 		final SCPClient.LenNamePair lnp;
     36 
     37 		while (true)
     38 		{
     39 			int c = session.getStdout().read();
     40 			if (c < 0)
     41 			{
     42 				throw new IOException("Remote scp terminated unexpectedly.");
     43 			}
     44 
     45 			String line = client.receiveLine(session.getStdout());
     46 
     47 			if (c == 'T')
     48 			{
     49 				/* Ignore modification times */
     50 				continue;
     51 			}
     52 
     53 			if ((c == 1) || (c == 2))
     54 			{
     55 				throw new IOException("Remote SCP error: " + line);
     56 			}
     57 
     58 			if (c == 'C')
     59 			{
     60 				lnp = client.parseCLine(line);
     61 				break;
     62 
     63 			}
     64 			throw new IOException("Remote SCP error: " + ((char) c) + line);
     65 		}
     66 
     67 		os.write(0x0);
     68 		os.flush();
     69 
     70 		this.remaining = lnp.length;
     71 	}
     72 
     73 	@Override
     74 	public int read() throws IOException
     75 	{
     76 		if (!(remaining > 0))
     77 		{
     78 			return -1;
     79 		}
     80 
     81 		int read = super.read();
     82 		if (read < 0)
     83 		{
     84 			throw new IOException("Remote scp terminated connection unexpectedly");
     85 		}
     86 
     87 		remaining -= read;
     88 
     89 		return read;
     90 	}
     91 
     92 	@Override
     93 	public int read(byte b[], int off, int len) throws IOException
     94 	{
     95 		if (!(remaining > 0))
     96 		{
     97 			return -1;
     98 		}
     99 
    100 		int trans = (int) remaining;
    101 		if (remaining > len)
    102 		{
    103 			trans = len;
    104 		}
    105 
    106 		int read = super.read(b, off, trans);
    107 		if (read < 0)
    108 		{
    109 			throw new IOException("Remote scp terminated connection unexpectedly");
    110 		}
    111 
    112 		remaining -= read;
    113 
    114 		return read;
    115 	}
    116 
    117 	@Override
    118 	public void close() throws IOException
    119 	{
    120 		try
    121 		{
    122 			session.getStdin().write(0x0);
    123 			session.getStdin().flush();
    124 		}
    125 		finally
    126 		{
    127 			if (session != null)
    128 			{
    129 				session.close();
    130 			}
    131 		}
    132 	}
    133 }
    134