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 SCPInputStream(SCPClient client, Session session)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 read()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 read(byte b[], int off, int len)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 close()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