1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ 2 /** 3 * This program will demonstrate the file transfer from remote to local 4 * $ CLASSPATH=.:../build javac ScpFrom.java 5 * $ CLASSPATH=.:../build java ScpFrom user@remotehost:file1 file2 6 * You will be asked passwd. 7 * If everything works fine, a file 'file1' on 'remotehost' will copied to 8 * local 'file1'. 9 * 10 */ 11 import com.jcraft.jsch.*; 12 import java.awt.*; 13 import javax.swing.*; 14 import java.io.*; 15 16 public class ScpFrom{ main(String[] arg)17 public static void main(String[] arg){ 18 if(arg.length!=2){ 19 System.err.println("usage: java ScpFrom user@remotehost:file1 file2"); 20 System.exit(-1); 21 } 22 23 FileOutputStream fos=null; 24 try{ 25 26 String user=arg[0].substring(0, arg[0].indexOf('@')); 27 arg[0]=arg[0].substring(arg[0].indexOf('@')+1); 28 String host=arg[0].substring(0, arg[0].indexOf(':')); 29 String rfile=arg[0].substring(arg[0].indexOf(':')+1); 30 String lfile=arg[1]; 31 32 String prefix=null; 33 if(new File(lfile).isDirectory()){ 34 prefix=lfile+File.separator; 35 } 36 37 JSch jsch=new JSch(); 38 Session session=jsch.getSession(user, host, 22); 39 40 // username and password will be given via UserInfo interface. 41 UserInfo ui=new MyUserInfo(); 42 session.setUserInfo(ui); 43 session.connect(); 44 45 // exec 'scp -f rfile' remotely 46 rfile=rfile.replace("'", "'\"'\"'"); 47 rfile="'"+rfile+"'"; 48 String command="scp -f "+rfile; 49 Channel channel=session.openChannel("exec"); 50 ((ChannelExec)channel).setCommand(command); 51 52 // get I/O streams for remote scp 53 OutputStream out=channel.getOutputStream(); 54 InputStream in=channel.getInputStream(); 55 56 channel.connect(); 57 58 byte[] buf=new byte[1024]; 59 60 // send '\0' 61 buf[0]=0; out.write(buf, 0, 1); out.flush(); 62 63 while(true){ 64 int c=checkAck(in); 65 if(c!='C'){ 66 break; 67 } 68 69 // read '0644 ' 70 in.read(buf, 0, 5); 71 72 long filesize=0L; 73 while(true){ 74 if(in.read(buf, 0, 1)<0){ 75 // error 76 break; 77 } 78 if(buf[0]==' ')break; 79 filesize=filesize*10L+(long)(buf[0]-'0'); 80 } 81 82 String file=null; 83 for(int i=0;;i++){ 84 in.read(buf, i, 1); 85 if(buf[i]==(byte)0x0a){ 86 file=new String(buf, 0, i); 87 break; 88 } 89 } 90 91 //System.out.println("filesize="+filesize+", file="+file); 92 93 // send '\0' 94 buf[0]=0; out.write(buf, 0, 1); out.flush(); 95 96 // read a content of lfile 97 fos=new FileOutputStream(prefix==null ? lfile : prefix+file); 98 int foo; 99 while(true){ 100 if(buf.length<filesize) foo=buf.length; 101 else foo=(int)filesize; 102 foo=in.read(buf, 0, foo); 103 if(foo<0){ 104 // error 105 break; 106 } 107 fos.write(buf, 0, foo); 108 filesize-=foo; 109 if(filesize==0L) break; 110 } 111 fos.close(); 112 fos=null; 113 114 if(checkAck(in)!=0){ 115 System.exit(0); 116 } 117 118 // send '\0' 119 buf[0]=0; out.write(buf, 0, 1); out.flush(); 120 } 121 122 session.disconnect(); 123 124 System.exit(0); 125 } 126 catch(Exception e){ 127 System.out.println(e); 128 try{if(fos!=null)fos.close();}catch(Exception ee){} 129 } 130 } 131 checkAck(InputStream in)132 static int checkAck(InputStream in) throws IOException{ 133 int b=in.read(); 134 // b may be 0 for success, 135 // 1 for error, 136 // 2 for fatal error, 137 // -1 138 if(b==0) return b; 139 if(b==-1) return b; 140 141 if(b==1 || b==2){ 142 StringBuffer sb=new StringBuffer(); 143 int c; 144 do { 145 c=in.read(); 146 sb.append((char)c); 147 } 148 while(c!='\n'); 149 if(b==1){ // error 150 System.out.print(sb.toString()); 151 } 152 if(b==2){ // fatal error 153 System.out.print(sb.toString()); 154 } 155 } 156 return b; 157 } 158 159 public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{ getPassword()160 public String getPassword(){ return passwd; } promptYesNo(String str)161 public boolean promptYesNo(String str){ 162 Object[] options={ "yes", "no" }; 163 int foo=JOptionPane.showOptionDialog(null, 164 str, 165 "Warning", 166 JOptionPane.DEFAULT_OPTION, 167 JOptionPane.WARNING_MESSAGE, 168 null, options, options[0]); 169 return foo==0; 170 } 171 172 String passwd; 173 JTextField passwordField=(JTextField)new JPasswordField(20); 174 getPassphrase()175 public String getPassphrase(){ return null; } promptPassphrase(String message)176 public boolean promptPassphrase(String message){ return true; } promptPassword(String message)177 public boolean promptPassword(String message){ 178 Object[] ob={passwordField}; 179 int result= 180 JOptionPane.showConfirmDialog(null, ob, message, 181 JOptionPane.OK_CANCEL_OPTION); 182 if(result==JOptionPane.OK_OPTION){ 183 passwd=passwordField.getText(); 184 return true; 185 } 186 else{ return false; } 187 } showMessage(String message)188 public void showMessage(String message){ 189 JOptionPane.showMessageDialog(null, message); 190 } 191 final GridBagConstraints gbc = 192 new GridBagConstraints(0,0,1,1,1,1, 193 GridBagConstraints.NORTHWEST, 194 GridBagConstraints.NONE, 195 new Insets(0,0,0,0),0,0); 196 private Container panel; promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo)197 public String[] promptKeyboardInteractive(String destination, 198 String name, 199 String instruction, 200 String[] prompt, 201 boolean[] echo){ 202 panel = new JPanel(); 203 panel.setLayout(new GridBagLayout()); 204 205 gbc.weightx = 1.0; 206 gbc.gridwidth = GridBagConstraints.REMAINDER; 207 gbc.gridx = 0; 208 panel.add(new JLabel(instruction), gbc); 209 gbc.gridy++; 210 211 gbc.gridwidth = GridBagConstraints.RELATIVE; 212 213 JTextField[] texts=new JTextField[prompt.length]; 214 for(int i=0; i<prompt.length; i++){ 215 gbc.fill = GridBagConstraints.NONE; 216 gbc.gridx = 0; 217 gbc.weightx = 1; 218 panel.add(new JLabel(prompt[i]),gbc); 219 220 gbc.gridx = 1; 221 gbc.fill = GridBagConstraints.HORIZONTAL; 222 gbc.weighty = 1; 223 if(echo[i]){ 224 texts[i]=new JTextField(20); 225 } 226 else{ 227 texts[i]=new JPasswordField(20); 228 } 229 panel.add(texts[i], gbc); 230 gbc.gridy++; 231 } 232 233 if(JOptionPane.showConfirmDialog(null, panel, 234 destination+": "+name, 235 JOptionPane.OK_CANCEL_OPTION, 236 JOptionPane.QUESTION_MESSAGE) 237 ==JOptionPane.OK_OPTION){ 238 String[] response=new String[prompt.length]; 239 for(int i=0; i<prompt.length; i++){ 240 response[i]=texts[i].getText(); 241 } 242 return response; 243 } 244 else{ 245 return null; // cancel 246 } 247 } 248 } 249 } 250