00001 using System;
00002 using System.Net;
00003 using System.IO;
00004 using Tamir.Streams;
00005 using System.Runtime.CompilerServices;
00006 using Tamir.SharpSsh.java.lang;
00007 using Str = Tamir.SharpSsh.java.String;
00008
00009 namespace Tamir.SharpSsh.jsch
00010 {
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 public abstract class Channel : Tamir.SharpSsh.java.lang.Runnable
00042 {
00043 internal static int index=0;
00044 private static java.util.Vector pool=new java.util.Vector();
00045 internal static Channel getChannel(String type)
00046 {
00047 if(type.Equals("session"))
00048 {
00049 return new ChannelSession();
00050 }
00051 if(type.Equals("shell"))
00052 {
00053 return new ChannelShell();
00054 }
00055 if(type.Equals("exec"))
00056 {
00057 return new ChannelExec();
00058 }
00059 if(type.Equals("x11"))
00060 {
00061 return new ChannelX11();
00062 }
00063 if(type.Equals("direct-tcpip"))
00064 {
00065 return new ChannelDirectTCPIP();
00066 }
00067 if(type.Equals("forwarded-tcpip"))
00068 {
00069 return new ChannelForwardedTCPIP();
00070 }
00071 if(type.Equals("sftp"))
00072 {
00073 return new ChannelSftp();
00074 }
00075 if(type.Equals("subsystem"))
00076 {
00077 return new ChannelSubsystem();
00078 }
00079 return null;
00080 }
00081 internal static Channel getChannel(int id, Session session)
00082 {
00083 lock(pool)
00084 {
00085 for(int i=0; i<pool.size(); i++)
00086 {
00087 Channel c=(Channel)(pool.elementAt(i));
00088 if(c.id==id && c.session==session) return c;
00089 }
00090 }
00091 return null;
00092 }
00093 internal static void del(Channel c)
00094 {
00095 lock(pool)
00096 {
00097 pool.removeElement(c);
00098 }
00099 }
00100
00101 internal int id;
00102 internal int recipient=-1;
00103 internal byte[] type=new Str("foo").getBytes();
00104 internal int lwsize_max=0x100000;
00105 internal int lwsize=0x100000;
00106 internal int lmpsize=0x4000;
00107
00108 internal int rwsize=0;
00109 internal int rmpsize=0;
00110
00111 internal IO io=null;
00112 internal Thread thread=null;
00113
00114 internal bool eof_local=false;
00115 internal bool _eof_remote=false;
00116
00117 internal bool _close=false;
00118 internal bool connected=false;
00119
00120 internal int exitstatus=-1;
00121
00122 internal int reply=0;
00123
00124 internal Session session;
00125
00126 internal Channel()
00127 {
00128 lock(pool)
00129 {
00130 id=index++;
00131 pool.addElement(this);
00132 }
00133 }
00134 internal virtual void setRecipient(int foo)
00135 {
00136 this.recipient=foo;
00137 }
00138 internal virtual int getRecipient()
00139 {
00140 return recipient;
00141 }
00142
00143 public virtual void init()
00144 {
00145 }
00146
00147 public virtual void connect()
00148 {
00149 if(!session.isConnected())
00150 {
00151 throw new JSchException("session is down");
00152 }
00153 try
00154 {
00155 Buffer buf=new Buffer(100);
00156 Packet packet=new Packet(buf);
00157
00158
00159
00160
00161
00162
00163 packet.reset();
00164 buf.putByte((byte)90);
00165 buf.putString(this.type);
00166 buf.putInt(this.id);
00167 buf.putInt(this.lwsize);
00168 buf.putInt(this.lmpsize);
00169 session.write(packet);
00170
00171 int retry=1000;
00172 while(this.getRecipient()==-1 &&
00173 session.isConnected() &&
00174 retry>0)
00175 {
00176 try{Thread.sleep(50);}
00177 catch(Exception ee){}
00178 retry--;
00179 }
00180 if(!session.isConnected())
00181 {
00182 throw new JSchException("session is down");
00183 }
00184 if(retry==0)
00185 {
00186 throw new JSchException("channel is not opened.");
00187 }
00188 connected=true;
00189 start();
00190 }
00191 catch(Exception e)
00192 {
00193 connected=false;
00194 if(e is JSchException) throw (JSchException)e;
00195 }
00196 }
00197
00198 public virtual void setXForwarding(bool foo)
00199 {
00200 }
00201
00202 public virtual void start(){}
00203
00204 public bool isEOF() {return _eof_remote;}
00205
00206 internal virtual void getData(Buffer buf)
00207 {
00208 setRecipient(buf.getInt());
00209 setRemoteWindowSize(buf.getInt());
00210 setRemotePacketSize(buf.getInt());
00211 }
00212
00213 public virtual void setInputStream(Stream In)
00214 {
00215 io.setInputStream(In, false);
00216 }
00217 public virtual void setInputStream(Stream In, bool dontclose)
00218 {
00219 io.setInputStream(In, dontclose);
00220 }
00221 public virtual void setOutputStream(Stream Out)
00222 {
00223 io.setOutputStream(Out, false);
00224 }
00225 public virtual void setOutputStream(Stream Out, bool dontclose)
00226 {
00227 io.setOutputStream(Out, dontclose);
00228 }
00229 public virtual void setExtOutputStream(Stream Out)
00230 {
00231 io.setExtOutputStream(Out, false);
00232 }
00233 public virtual void setExtOutputStream(Stream Out, bool dontclose)
00234 {
00235 io.setExtOutputStream(Out, dontclose);
00236 }
00237 public virtual java.io.InputStream getInputStream()
00238 {
00239 PipedInputStream In=
00240 new MyPipedInputStream(
00241 32*1024
00242 );
00243 io.setOutputStream(new PassiveOutputStream(In), false);
00244 return In;
00245 }
00246 public virtual java.io.InputStream getExtInputStream()
00247 {
00248 PipedInputStream In=
00249 new MyPipedInputStream(
00250 32*1024
00251 );
00252 io.setExtOutputStream(new PassiveOutputStream(In), false);
00253 return In;
00254 }
00255 public virtual Stream getOutputStream()
00256 {
00257 PipedOutputStream Out=new PipedOutputStream();
00258 io.setInputStream(new PassiveInputStream(Out
00259 , 32*1024
00260 ), false);
00261
00262 return Out;
00263 }
00264 internal class MyPipedInputStream : PipedInputStream
00265 {
00266 internal MyPipedInputStream():base() { ; }
00267 internal MyPipedInputStream(int size) :base()
00268 {
00269 buffer=new byte[size];
00270 }
00271 internal MyPipedInputStream(PipedOutputStream Out):base(Out) { }
00272 internal MyPipedInputStream(PipedOutputStream Out, int size):base(Out)
00273 {
00274 buffer=new byte[size];
00275 }
00276 }
00277 internal virtual void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
00278 internal virtual void setLocalWindowSize(int foo){ this.lwsize=foo; }
00279 internal virtual void setLocalPacketSize(int foo){ this.lmpsize=foo; }
00280 [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.Synchronized)]
00281 internal virtual void setRemoteWindowSize(int foo){ this.rwsize=foo; }
00282 [System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.Synchronized)]
00283 internal virtual void addRemoteWindowSize(int foo){ this.rwsize+=foo; }
00284 internal virtual void setRemotePacketSize(int foo){ this.rmpsize=foo; }
00285
00286 public virtual void run()
00287 {
00288 }
00289
00290 internal virtual void write(byte[] foo)
00291 {
00292 write(foo, 0, foo.Length);
00293 }
00294 internal virtual void write(byte[] foo, int s, int l)
00295 {
00296 try
00297 {
00298
00299 io.put(foo, s, l);
00300 }
00301 catch(NullReferenceException e){}
00302 }
00303 internal virtual void write_ext(byte[] foo, int s, int l)
00304 {
00305 try
00306 {
00307
00308 io.put_ext(foo, s, l);
00309 }
00310 catch(NullReferenceException e){}
00311 }
00312
00313 internal virtual void eof_remote()
00314 {
00315 _eof_remote=true;
00316 try
00317 {
00318 if(io.outs!=null)
00319 {
00320 io.outs.Close();
00321 io.outs=null;
00322 }
00323 }
00324 catch(NullReferenceException e){}
00325 catch(IOException e){}
00326 }
00327
00328 internal virtual void eof()
00329 {
00330
00331
00332 if(_close)return;
00333 if(eof_local)return;
00334 eof_local=true;
00335
00336 try
00337 {
00338 Buffer buf=new Buffer(100);
00339 Packet packet=new Packet(buf);
00340 packet.reset();
00341 buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
00342 buf.putInt(getRecipient());
00343 session.write(packet);
00344 }
00345 catch(Exception e)
00346 {
00347
00348
00349 }
00350
00351
00352
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 internal virtual void close()
00392 {
00393
00394 if(_close)return;
00395 _close=true;
00396 try
00397 {
00398 Buffer buf=new Buffer(100);
00399 Packet packet=new Packet(buf);
00400 packet.reset();
00401 buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
00402 buf.putInt(getRecipient());
00403 session.write(packet);
00404 }
00405 catch(Exception e)
00406 {
00407
00408 }
00409 }
00410 public virtual bool isClosed()
00411 {
00412 return _close;
00413 }
00414 internal static void disconnect(Session session)
00415 {
00416 Channel[] channels=null;
00417 int count=0;
00418 lock(pool)
00419 {
00420 channels=new Channel[pool.size()];
00421 for(int i=0; i<pool.size(); i++)
00422 {
00423 try
00424 {
00425 Channel c=((Channel)(pool.elementAt(i)));
00426 if(c.session==session)
00427 {
00428 channels[count++]=c;
00429 }
00430 }
00431 catch(Exception e)
00432 {
00433 }
00434 }
00435 }
00436 for(int i=0; i<count; i++)
00437 {
00438 channels[i].disconnect();
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 public virtual void disconnect()
00451 {
00452
00453 if(!connected)
00454 {
00455 return;
00456 }
00457 connected=false;
00458
00459 close();
00460
00461 _eof_remote=eof_local=true;
00462
00463 thread=null;
00464
00465 try
00466 {
00467 if(io!=null)
00468 {
00469 io.close();
00470 }
00471 }
00472 catch(Exception e)
00473 {
00474
00475 }
00476 io=null;
00477 Channel.del(this);
00478 }
00479
00480 public virtual bool isConnected()
00481 {
00482 if(this.session!=null)
00483 {
00484 return session.isConnected() && connected;
00485 }
00486 return false;
00487 }
00488
00489 public virtual void sendSignal(String foo)
00490 {
00491 RequestSignal request=new RequestSignal();
00492 request.setSignal(foo);
00493 request.request(session, this);
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 internal class PassiveInputStream : MyPipedInputStream
00509 {
00510 internal PipedOutputStream Out;
00511 internal PassiveInputStream(PipedOutputStream Out, int size) :base(Out, size)
00512 {
00513 this.Out=Out;
00514 }
00515 internal PassiveInputStream(PipedOutputStream Out):base(Out)
00516 {
00517 this.Out=Out;
00518 }
00519 public override void close()
00520 {
00521 if(Out!=null)
00522 {
00523 this.Out.close();
00524 }
00525 Out=null;
00526 }
00527 }
00528 internal class PassiveOutputStream : PipedOutputStream
00529 {
00530 internal PassiveOutputStream(PipedInputStream In) :base(In)
00531 {
00532 }
00533 }
00534
00535 internal virtual void setExitStatus(int foo){ exitstatus=foo; }
00536 public virtual int getExitStatus(){ return exitstatus; }
00537
00538 internal virtual void setSession(Session session)
00539 {
00540 this.session=session;
00541 }
00542 public virtual Session getSession(){ return session; }
00543 public virtual int getId(){ return id; }
00544
00545
00546 }
00547 }