00001 using System;
00002 using System.IO;
00003 using System.Collections;
00004 using System.Windows.Forms;
00005
00006
00007
00008
00009
00010
00011
00012 namespace Tamir.SharpSsh.jsch.examples
00013 {
00022 public class Sftp
00023 {
00024 public static void Main(String[] arg)
00025 {
00026 try
00027 {
00028 JSch jsch=new JSch();
00029
00030 InputForm inForm = new InputForm();
00031 inForm.Text = "Enter username@hostname";
00032 inForm.textBox1.Text = Environment.UserName+"@localhost";
00033
00034 if (!inForm.PromptForInput())
00035 {
00036 Console.WriteLine("Cancelled");
00037 return;
00038 }
00039 String host = inForm.textBox1.Text;
00040 String user=host.Substring(0, host.IndexOf('@'));
00041 host=host.Substring(host.IndexOf('@')+1);
00042
00043 Session session=jsch.getSession(user, host, 22);
00044
00045
00046 UserInfo ui=new MyUserInfo();
00047 session.setUserInfo(ui);
00048
00049 session.connect();
00050
00051 Channel channel=session.openChannel("sftp");
00052 channel.connect();
00053 ChannelSftp c=(ChannelSftp)channel;
00054
00055 Stream ins=Console.OpenStandardInput();
00056 TextWriter outs=Console.Out;
00057
00058 ArrayList cmds=new ArrayList();
00059 byte[] buf=new byte[1024];
00060 int i;
00061 String str;
00062 int level=0;
00063
00064 while(true)
00065 {
00066 outs.Write("sftp> ");
00067 cmds.Clear();
00068 i=ins.Read(buf, 0, 1024);
00069 if(i<=0)break;
00070
00071 i--;
00072 if(i>0 && buf[i-1]==0x0d)i--;
00073
00074
00075 int s=0;
00076 for(int ii=0; ii<i; ii++)
00077 {
00078 if(buf[ii]==' ')
00079 {
00080 if(ii-s>0){ cmds.Add(Util.getString(buf, s, ii-s)); }
00081 while(ii<i){if(buf[ii]!=' ')break; ii++;}
00082 s=ii;
00083 }
00084 }
00085 if(s<i){ cmds.Add(Util.getString(buf, s, i-s)); }
00086 if(cmds.Count==0)continue;
00087
00088 String cmd=(String)cmds[0];
00089 if(cmd.Equals("quit"))
00090 {
00091 c.quit();
00092 break;
00093 }
00094 if(cmd.Equals("exit"))
00095 {
00096 c.exit();
00097 break;
00098 }
00099 if(cmd.Equals("rekey"))
00100 {
00101 session.rekey();
00102 continue;
00103 }
00104 if(cmd.Equals("compression"))
00105 {
00106 if(cmds.Count<2)
00107 {
00108 outs.WriteLine("compression level: "+level);
00109 continue;
00110 }
00111 try
00112 {
00113 level=int.Parse((String)cmds[1]);
00114 Hashtable config=new Hashtable();
00115 if(level==0)
00116 {
00117 config.Add("compression.s2c", "none");
00118 config.Add("compression.c2s", "none");
00119 }
00120 else
00121 {
00122 config.Add("compression.s2c", "zlib,none");
00123 config.Add("compression.c2s", "zlib,none");
00124 }
00125 session.setConfig(config);
00126 }
00127 catch{}
00128 continue;
00129 }
00130 if(cmd.Equals("cd") || cmd.Equals("lcd"))
00131 {
00132 if(cmds.Count<2) continue;
00133 String path=(String)cmds[1];
00134 try
00135 {
00136 if(cmd.Equals("cd")) c.cd(path);
00137 else c.lcd(path);
00138 }
00139 catch(SftpException e)
00140 {
00141 Console.WriteLine(e.message);
00142 }
00143 continue;
00144 }
00145 if(cmd.Equals("rm") || cmd.Equals("rmdir") || cmd.Equals("mkdir"))
00146 {
00147 if(cmds.Count<2) continue;
00148 String path=(String)cmds[1];
00149 try
00150 {
00151 if(cmd.Equals("rm")) c.rm(path);
00152 else if(cmd.Equals("rmdir")) c.rmdir(path);
00153 else c.mkdir(path);
00154 }
00155 catch(SftpException e)
00156 {
00157 Console.WriteLine(e.message);
00158 }
00159 continue;
00160 }
00161 if(cmd.Equals("chgrp") || cmd.Equals("chown") || cmd.Equals("chmod"))
00162 {
00163 if(cmds.Count!=3) continue;
00164 String path=(String)cmds[2];
00165 int foo=0;
00166 if(cmd.Equals("chmod"))
00167 {
00168 byte[] bar=Util.getBytes((String)cmds[1]);
00169 int k;
00170 for(int j=0; j<bar.Length; j++)
00171 {
00172 k=bar[j];
00173 if(k<'0'||k>'7'){foo=-1; break;}
00174 foo<<=3;
00175 foo|=(k-'0');
00176 }
00177 if(foo==-1)continue;
00178 }
00179 else
00180 {
00181 try{foo=int.Parse((String)cmds[1]);}
00182 catch{}
00183 }
00184 try
00185 {
00186 if(cmd.Equals("chgrp")){ c.chgrp(foo, path); }
00187 else if(cmd.Equals("chown")){ c.chown(foo, path); }
00188 else if(cmd.Equals("chmod")){ c.chmod(foo, path); }
00189 }
00190 catch(SftpException e)
00191 {
00192 Console.WriteLine(e.message);
00193 }
00194 continue;
00195 }
00196 if(cmd.Equals("pwd") || cmd.Equals("lpwd"))
00197 {
00198 str=(cmd.Equals("pwd")?"Remote":"Local");
00199 str+=" working directory: ";
00200 if(cmd.Equals("pwd")) str+=c.pwd();
00201 else str+=c.lpwd();
00202 outs.WriteLine(str);
00203 continue;
00204 }
00205 if(cmd.Equals("ls") || cmd.Equals("dir"))
00206 {
00207 String path=".";
00208 if(cmds.Count==2) path=(String)cmds[1];
00209 try
00210 {
00211 ArrayList vv=c.ls(path);
00212 if(vv!=null)
00213 {
00214 for(int ii=0; ii<vv.Count; ii++)
00215 {
00216 object obj = vv[ii];
00217 if(obj is ChannelSftp.LsEntry)
00218 outs.WriteLine(vv[ii]);
00219 }
00220 }
00221 }
00222 catch(SftpException e)
00223 {
00224 Console.WriteLine(e.message);
00225 }
00226 continue;
00227 }
00228 if(cmd.Equals("lls") || cmd.Equals("ldir"))
00229 {
00230 String path=".";
00231 if(cmds.Count==2) path=(String)cmds[1];
00232 try
00233 {
00234
00235 if(!File.Exists(path))
00236 {
00237 outs.WriteLine(path+": No such file or directory");
00238 continue;
00239 }
00240 if(Directory.Exists(path))
00241 {
00242 String[] list=Directory.GetDirectories(path);
00243 for(int ii=0; ii<list.Length; ii++)
00244 {
00245 outs.WriteLine(list[ii]);
00246 }
00247 continue;
00248 }
00249 outs.WriteLine(path);
00250 }
00251 catch(Exception e)
00252 {
00253 Console.WriteLine(e);
00254 }
00255 continue;
00256 }
00257 if(cmd.Equals("get") ||
00258 cmd.Equals("get-resume") || cmd.Equals("get-append") ||
00259 cmd.Equals("put") ||
00260 cmd.Equals("put-resume") || cmd.Equals("put-append")
00261 )
00262 {
00263 if(cmds.Count!=2 && cmds.Count!=3) continue;
00264 String p1=(String)cmds[1];
00265
00266 String p2=".";
00267 if(cmds.Count==3)p2=(String)cmds[2];
00268 try
00269 {
00270 SftpProgressMonitor monitor=new MyProgressMonitor();
00271 if(cmd.StartsWith("get"))
00272 {
00273 int mode=ChannelSftp.OVERWRITE;
00274 if(cmd.Equals("get-resume")){ mode=ChannelSftp.RESUME; }
00275 else if(cmd.Equals("get-append")){ mode=ChannelSftp.APPEND; }
00276 c.get(p1, p2, monitor, mode);
00277 }
00278 else
00279 {
00280 int mode=ChannelSftp.OVERWRITE;
00281 if(cmd.Equals("put-resume")){ mode=ChannelSftp.RESUME; }
00282 else if(cmd.Equals("put-append")){ mode=ChannelSftp.APPEND; }
00283 c.put(p1, p2, monitor, mode);
00284 }
00285 }
00286 catch(SftpException e)
00287 {
00288 Console.WriteLine(e.message);
00289 }
00290 continue;
00291 }
00292 if(cmd.Equals("ln") || cmd.Equals("symlink") || cmd.Equals("rename"))
00293 {
00294 if(cmds.Count!=3) continue;
00295 String p1=(String)cmds[1];
00296 String p2=(String)cmds[2];
00297 try
00298 {
00299 if(cmd.Equals("rename")) c.rename(p1, p2);
00300 else c.symlink(p1, p2);
00301 }
00302 catch(SftpException e)
00303 {
00304 Console.WriteLine(e.message);
00305 }
00306 continue;
00307 }
00308 if(cmd.Equals("stat") || cmd.Equals("lstat"))
00309 {
00310 if(cmds.Count!=2) continue;
00311 String p1=(String)cmds[1];
00312 SftpATTRS attrs=null;
00313 try
00314 {
00315 if(cmd.Equals("stat")) attrs=c.stat(p1);
00316 else attrs=c.lstat(p1);
00317 }
00318 catch(SftpException e)
00319 {
00320 Console.WriteLine(e.message);
00321 }
00322 if(attrs!=null)
00323 {
00324 outs.WriteLine(attrs);
00325 }
00326 else
00327 {
00328 }
00329 continue;
00330 }
00331 if(cmd.Equals("version"))
00332 {
00333 outs.WriteLine("SFTP protocol version "+c.version());
00334 continue;
00335 }
00336 if(cmd.Equals("help") || cmd.Equals("?"))
00337 {
00338 outs.WriteLine(help);
00339 continue;
00340 }
00341 outs.WriteLine("unimplemented command: "+cmd);
00342 }
00343 session.disconnect();
00344 }
00345 catch(Exception e)
00346 {
00347 Console.WriteLine(e);
00348 }
00349 }
00350
00351 public class MyUserInfo : UserInfo
00352 {
00353 public String getPassword(){ return passwd; }
00354 public bool promptYesNo(String str)
00355 {
00356 DialogResult returnVal = MessageBox.Show(
00357 str,
00358 "SharpSSH",
00359 MessageBoxButtons.YesNo,
00360 MessageBoxIcon.Warning);
00361 return (returnVal==DialogResult.Yes);
00362 }
00363
00364 String passwd;
00365 InputForm passwordField=new InputForm();
00366
00367 public String getPassphrase(){ return null; }
00368 public bool promptPassphrase(String message){ return true; }
00369 public bool promptPassword(String message)
00370 {
00371 InputForm inForm = new InputForm();
00372 inForm.Text = message;
00373 inForm.PasswordField = true;
00374
00375 if ( inForm.PromptForInput() )
00376 {
00377 passwd=inForm.getText();
00378 return true;
00379 }
00380 else{ return false; }
00381 }
00382 public void showMessage(String message)
00383 {
00384 MessageBox.Show(
00385 message,
00386 "SharpSSH",
00387 MessageBoxButtons.OK,
00388 MessageBoxIcon.Asterisk);
00389 }
00390 }
00391
00392 public class MyProgressMonitor : SftpProgressMonitor
00393 {
00394 private ConsoleProgressBar bar;
00395 private long c = 0;
00396 private long max = 0;
00397 private long percent=-1;
00398 int elapsed=-1;
00399
00400 System.Timers.Timer timer;
00401
00402 public override void init(int op, String src, String dest, long max)
00403 {
00404 bar = new ConsoleProgressBar();
00405 this.max=max;
00406 elapsed=0;
00407 timer=new System.Timers.Timer(1000);
00408 timer.Start();
00409 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
00410 }
00411 public override bool count(long c)
00412 {
00413 this.c += c;
00414 if(percent>=this.c*100/max){ return true; }
00415 percent=this.c*100/max;
00416
00417 string note = ("Transfering... [Elapsed time: "+elapsed+"]");
00418
00419 bar.Update((int)this.c, (int)max, note);
00420 return true;
00421 }
00422 public override void end()
00423 {
00424 timer.Stop();
00425 timer.Dispose();
00426 string note = ("Done in "+elapsed+" seconds!");
00427 bar.Update((int)this.c, (int)max, note);
00428 bar=null;
00429 }
00430
00431 private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
00432 {
00433 this.elapsed++;
00434 }
00435 }
00436
00437 private static String help =
00438 " Available commands:\n"+
00439 " * means unimplemented command.\n"+
00440 "cd path Change remote directory to 'path'\n"+
00441 "lcd path Change local directory to 'path'\n"+
00442 "chgrp grp path Change group of file 'path' to 'grp'\n"+
00443 "chmod mode path Change permissions of file 'path' to 'mode'\n"+
00444 "chown own path Change owner of file 'path' to 'own'\n"+
00445 "help Display this help text\n"+
00446 "get remote-path [local-path] Download file\n"+
00447 "get-resume remote-path [local-path] Resume to download file.\n"+
00448 "get-append remote-path [local-path] Append remote file to local file\n"+
00449 "*lls [ls-options [path]] Display local directory listing\n"+
00450 "ln oldpath newpath Symlink remote file\n"+
00451 "*lmkdir path Create local directory\n"+
00452 "lpwd Print local working directory\n"+
00453 "ls [path] Display remote directory listing\n"+
00454 "*lumask umask Set local umask to 'umask'\n"+
00455 "mkdir path Create remote directory\n"+
00456 "put local-path [remote-path] Upload file\n"+
00457 "put-resume local-path [remote-path] Resume to upload file\n"+
00458 "put-append local-path [remote-path] Append local file to remote file.\n"+
00459 "pwd Display remote working directory\n"+
00460 "stat path Display info about path\n"+
00461 "exit Quit sftp\n"+
00462 "quit Quit sftp\n"+
00463 "rename oldpath newpath Rename remote file\n"+
00464 "rmdir path Remove remote directory\n"+
00465 "rm path Delete remote file\n"+
00466 "symlink oldpath newpath Symlink remote file\n"+
00467 "rekey Key re-exchanging\n"+
00468 "compression level Packet compression will be enabled\n"+
00469 "version Show SFTP version\n"+
00470 "? Synonym for help";
00471 }
00472
00473 }