~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NSch/NSch/Channel.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2006-2010 ymnk, JCraft,Inc. All rights reserved.
 
3
 
 
4
Redistribution and use in source and binary forms, with or without
 
5
modification, are permitted provided that the following conditions are met:
 
6
 
 
7
  1. Redistributions of source code must retain the above copyright notice,
 
8
     this list of conditions and the following disclaimer.
 
9
 
 
10
  2. Redistributions in binary form must reproduce the above copyright 
 
11
     notice, this list of conditions and the following disclaimer in 
 
12
     the documentation and/or other materials provided with the distribution.
 
13
 
 
14
  3. The names of the authors may not be used to endorse or promote products
 
15
     derived from this software without specific prior written permission.
 
16
 
 
17
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 
18
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 
19
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 
20
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 
23
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
24
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
25
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
26
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
This code is based on jsch (http://www.jcraft.com/jsch).
 
29
All credit should go to the authors of jsch.
 
30
*/
 
31
 
 
32
using System;
 
33
using System.Collections;
 
34
using System.IO;
 
35
using NSch;
 
36
using Sharpen;
 
37
 
 
38
namespace NSch
 
39
{
 
40
        public abstract class Channel : Runnable
 
41
        {
 
42
                internal const int SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91;
 
43
 
 
44
                internal const int SSH_MSG_CHANNEL_OPEN_FAILURE = 92;
 
45
 
 
46
                internal const int SSH_MSG_CHANNEL_WINDOW_ADJUST = 93;
 
47
 
 
48
                internal const int SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1;
 
49
 
 
50
                internal const int SSH_OPEN_CONNECT_FAILED = 2;
 
51
 
 
52
                internal const int SSH_OPEN_UNKNOWN_CHANNEL_TYPE = 3;
 
53
 
 
54
                internal const int SSH_OPEN_RESOURCE_SHORTAGE = 4;
 
55
 
 
56
                internal static int index = 0;
 
57
 
 
58
                private static ArrayList pool = new ArrayList();
 
59
 
 
60
                internal static NSch.Channel GetChannel(string type)
 
61
                {
 
62
                        if (type.Equals("session"))
 
63
                        {
 
64
                                return new ChannelSession();
 
65
                        }
 
66
                        if (type.Equals("shell"))
 
67
                        {
 
68
                                return new ChannelShell();
 
69
                        }
 
70
                        if (type.Equals("exec"))
 
71
                        {
 
72
                                return new ChannelExec();
 
73
                        }
 
74
                        if (type.Equals("x11"))
 
75
                        {
 
76
                                return new ChannelX11();
 
77
                        }
 
78
                        if (type.Equals("auth-agent@openssh.com"))
 
79
                        {
 
80
                                return new ChannelAgentForwarding();
 
81
                        }
 
82
                        if (type.Equals("direct-tcpip"))
 
83
                        {
 
84
                                return new ChannelDirectTCPIP();
 
85
                        }
 
86
                        if (type.Equals("forwarded-tcpip"))
 
87
                        {
 
88
                                return new ChannelForwardedTCPIP();
 
89
                        }
 
90
                        if (type.Equals("sftp"))
 
91
                        {
 
92
                                return new ChannelSftp();
 
93
                        }
 
94
                        if (type.Equals("subsystem"))
 
95
                        {
 
96
                                return new ChannelSubsystem();
 
97
                        }
 
98
                        return null;
 
99
                }
 
100
 
 
101
                internal static NSch.Channel GetChannel(int id, Session session)
 
102
                {
 
103
                        lock (pool)
 
104
                        {
 
105
                                for (int i = 0; i < pool.Count; i++)
 
106
                                {
 
107
                                        NSch.Channel c = (NSch.Channel)(pool[i]);
 
108
                                        if (c.id == id && c.session == session)
 
109
                                        {
 
110
                                                return c;
 
111
                                        }
 
112
                                }
 
113
                        }
 
114
                        return null;
 
115
                }
 
116
 
 
117
                internal static void Del(NSch.Channel c)
 
118
                {
 
119
                        lock (pool)
 
120
                        {
 
121
                                pool.RemoveElement(c);
 
122
                        }
 
123
                }
 
124
 
 
125
                internal int id;
 
126
 
 
127
                internal int recipient = -1;
 
128
 
 
129
                internal byte[] type = Util.Str2byte("foo");
 
130
 
 
131
                internal int lwsize_max = unchecked((int)(0x100000));
 
132
 
 
133
                internal int lwsize;
 
134
 
 
135
                internal int lmpsize = unchecked((int)(0x4000));
 
136
 
 
137
                internal long rwsize = 0;
 
138
 
 
139
                internal int rmpsize = 0;
 
140
 
 
141
                internal IO io = null;
 
142
 
 
143
                internal Sharpen.Thread thread = null;
 
144
 
 
145
                internal bool eof_local = false;
 
146
 
 
147
                internal bool eof_remote = false;
 
148
 
 
149
                internal bool close = false;
 
150
 
 
151
                internal bool connected = false;
 
152
 
 
153
                internal int exitstatus = -1;
 
154
 
 
155
                internal int reply = 0;
 
156
 
 
157
                internal int connectTimeout = 0;
 
158
 
 
159
                private Session session;
 
160
 
 
161
                internal int notifyme = 0;
 
162
 
 
163
                public Channel()
 
164
                {
 
165
                        lwsize = lwsize_max;
 
166
                        //int lwsize_max=0x20000;  // 32*1024*4
 
167
                        // local initial window size
 
168
                        // local maximum packet size
 
169
                        //int lmpsize=0x8000;     // local maximum packet size
 
170
                        // remote initial window size
 
171
                        // remote maximum packet size
 
172
                        lock (pool)
 
173
                        {
 
174
                                id = index++;
 
175
                                pool.Add(this);
 
176
                        }
 
177
                }
 
178
 
 
179
                internal virtual void SetRecipient(int foo)
 
180
                {
 
181
                        this.recipient = foo;
 
182
                }
 
183
 
 
184
                internal virtual int GetRecipient()
 
185
                {
 
186
                        return recipient;
 
187
                }
 
188
 
 
189
                /// <exception cref="NSch.JSchException"></exception>
 
190
                internal virtual void Init()
 
191
                {
 
192
                }
 
193
 
 
194
                /// <exception cref="NSch.JSchException"></exception>
 
195
                public virtual void Connect()
 
196
                {
 
197
                        Connect(0);
 
198
                }
 
199
 
 
200
                /// <exception cref="NSch.JSchException"></exception>
 
201
                public virtual void Connect(int connectTimeout)
 
202
                {
 
203
                        Session _session = GetSession();
 
204
                        if (!_session.IsConnected())
 
205
                        {
 
206
                                throw new JSchException("session is down");
 
207
                        }
 
208
                        this.connectTimeout = connectTimeout;
 
209
                        try
 
210
                        {
 
211
                                Buffer buf = new Buffer(100);
 
212
                                Packet packet = new Packet(buf);
 
213
                                // send
 
214
                                // byte   SSH_MSG_CHANNEL_OPEN(90)
 
215
                                // string channel type         //
 
216
                                // uint32 sender channel       // 0
 
217
                                // uint32 initial window size  // 0x100000(65536)
 
218
                                // uint32 maxmum packet size   // 0x4000(16384)
 
219
                                packet.Reset();
 
220
                                buf.PutByte(unchecked((byte)90));
 
221
                                buf.PutString(this.type);
 
222
                                buf.PutInt(this.id);
 
223
                                buf.PutInt(this.lwsize);
 
224
                                buf.PutInt(this.lmpsize);
 
225
                                _session.Write(packet);
 
226
                                int retry = 1000;
 
227
                                long start = Runtime.CurrentTimeMillis();
 
228
                                long timeout = connectTimeout;
 
229
                                while (this.GetRecipient() == -1 && _session.IsConnected() && retry > 0)
 
230
                                {
 
231
                                        if (timeout > 0L)
 
232
                                        {
 
233
                                                if ((Runtime.CurrentTimeMillis() - start) > timeout)
 
234
                                                {
 
235
                                                        retry = 0;
 
236
                                                        continue;
 
237
                                                }
 
238
                                        }
 
239
                                        try
 
240
                                        {
 
241
                                                Sharpen.Thread.Sleep(50);
 
242
                                        }
 
243
                                        catch (Exception)
 
244
                                        {
 
245
                                        }
 
246
                                        retry--;
 
247
                                }
 
248
                                if (!_session.IsConnected())
 
249
                                {
 
250
                                        throw new JSchException("session is down");
 
251
                                }
 
252
                                if (retry == 0)
 
253
                                {
 
254
                                        throw new JSchException("channel is not opened.");
 
255
                                }
 
256
                                if (this.IsClosed())
 
257
                                {
 
258
                                        throw new JSchException("channel is not opened.");
 
259
                                }
 
260
                                connected = true;
 
261
                                Start();
 
262
                        }
 
263
                        catch (Exception e)
 
264
                        {
 
265
                                connected = false;
 
266
                                Disconnect();
 
267
                                if (e is JSchException)
 
268
                                {
 
269
                                        throw (JSchException)e;
 
270
                                }
 
271
                                throw new JSchException(e.ToString(), e);
 
272
                        }
 
273
                }
 
274
 
 
275
                public virtual void SetXForwarding(bool foo)
 
276
                {
 
277
                }
 
278
 
 
279
                /// <exception cref="NSch.JSchException"></exception>
 
280
                public virtual void Start()
 
281
                {
 
282
                }
 
283
 
 
284
                public virtual bool IsEOF()
 
285
                {
 
286
                        return eof_remote;
 
287
                }
 
288
 
 
289
                internal virtual void GetData(Buffer buf)
 
290
                {
 
291
                        SetRecipient(buf.GetInt());
 
292
                        SetRemoteWindowSize(buf.GetUInt());
 
293
                        SetRemotePacketSize(buf.GetInt());
 
294
                }
 
295
 
 
296
                public virtual void SetInputStream(InputStream @in)
 
297
                {
 
298
                        io.SetInputStream(@in, false);
 
299
                }
 
300
 
 
301
                public virtual void SetInputStream(InputStream @in, bool dontclose)
 
302
                {
 
303
                        io.SetInputStream(@in, dontclose);
 
304
                }
 
305
 
 
306
                public virtual void SetOutputStream(OutputStream @out)
 
307
                {
 
308
                        io.SetOutputStream(@out, false);
 
309
                }
 
310
 
 
311
                public virtual void SetOutputStream(OutputStream @out, bool dontclose)
 
312
                {
 
313
                        io.SetOutputStream(@out, dontclose);
 
314
                }
 
315
 
 
316
                public virtual void SetExtOutputStream(OutputStream @out)
 
317
                {
 
318
                        io.SetExtOutputStream(@out, false);
 
319
                }
 
320
 
 
321
                public virtual void SetExtOutputStream(OutputStream @out, bool dontclose)
 
322
                {
 
323
                        io.SetExtOutputStream(@out, dontclose);
 
324
                }
 
325
 
 
326
                /// <exception cref="System.IO.IOException"></exception>
 
327
                public virtual InputStream GetInputStream()
 
328
                {
 
329
                        PipedInputStream @in = new Channel.MyPipedInputStream(this, 32 * 1024);
 
330
                        // this value should be customizable.
 
331
                        io.SetOutputStream(new Channel.PassiveOutputStream(this, @in), false);
 
332
                        return @in;
 
333
                }
 
334
 
 
335
                /// <exception cref="System.IO.IOException"></exception>
 
336
                public virtual InputStream GetExtInputStream()
 
337
                {
 
338
                        PipedInputStream @in = new Channel.MyPipedInputStream(this, 32 * 1024);
 
339
                        // this value should be customizable.
 
340
                        io.SetExtOutputStream(new Channel.PassiveOutputStream(this, @in), false);
 
341
                        return @in;
 
342
                }
 
343
 
 
344
                /// <exception cref="System.IO.IOException"></exception>
 
345
                public virtual OutputStream GetOutputStream()
 
346
                {
 
347
                        NSch.Channel channel = this;
 
348
                        OutputStream @out = new _OutputStream_268(this, channel);
 
349
                        // close should be finished silently.
 
350
                        return @out;
 
351
                }
 
352
 
 
353
                private sealed class _OutputStream_268 : OutputStream
 
354
                {
 
355
                        public _OutputStream_268(Channel _enclosing, NSch.Channel channel)
 
356
                        {
 
357
                                this._enclosing = _enclosing;
 
358
                                this.channel = channel;
 
359
                                this.dataLen = 0;
 
360
                                this.buffer = null;
 
361
                                this.packet = null;
 
362
                                this.closed = false;
 
363
                                this.b = new byte[1];
 
364
                        }
 
365
 
 
366
                        private int dataLen;
 
367
 
 
368
                        private Buffer buffer;
 
369
 
 
370
                        private Packet packet;
 
371
 
 
372
                        private bool closed;
 
373
 
 
374
                        /// <exception cref="System.IO.IOException"></exception>
 
375
                        private void Init()
 
376
                        {
 
377
                                lock (this)
 
378
                                {
 
379
                                        this.buffer = new Buffer(this._enclosing.rmpsize);
 
380
                                        this.packet = new Packet(this.buffer);
 
381
                                        byte[] _buf = this.buffer.buffer;
 
382
                                        if (_buf.Length - (14 + 0) - 32 - 20 <= 0)
 
383
                                        {
 
384
                                                this.buffer = null;
 
385
                                                this.packet = null;
 
386
                                                throw new IOException("failed to initialize the channel.");
 
387
                                        }
 
388
                                }
 
389
                        }
 
390
 
 
391
                        internal byte[] b;
 
392
 
 
393
                        /// <exception cref="System.IO.IOException"></exception>
 
394
                        public override void Write(int w)
 
395
                        {
 
396
                                this.b[0] = unchecked((byte)w);
 
397
                                this.Write(this.b, 0, 1);
 
398
                        }
 
399
 
 
400
                        /// <exception cref="System.IO.IOException"></exception>
 
401
                        public override void Write(byte[] buf, int s, int l)
 
402
                        {
 
403
                                if (this.packet == null)
 
404
                                {
 
405
                                        this.Init();
 
406
                                }
 
407
                                if (this.closed)
 
408
                                {
 
409
                                        throw new IOException("Already closed");
 
410
                                }
 
411
                                byte[] _buf = this.buffer.buffer;
 
412
                                int _bufl = _buf.Length;
 
413
                                while (l > 0)
 
414
                                {
 
415
                                        int _l = l;
 
416
                                        if (l > _bufl - (14 + this.dataLen) - 32 - 20)
 
417
                                        {
 
418
                                                _l = _bufl - (14 + this.dataLen) - 32 - 20;
 
419
                                        }
 
420
                                        if (_l <= 0)
 
421
                                        {
 
422
                                                this.Flush();
 
423
                                                continue;
 
424
                                        }
 
425
                                        System.Array.Copy(buf, s, _buf, 14 + this.dataLen, _l);
 
426
                                        this.dataLen += _l;
 
427
                                        s += _l;
 
428
                                        l -= _l;
 
429
                                }
 
430
                        }
 
431
 
 
432
                        /// <exception cref="System.IO.IOException"></exception>
 
433
                        public override void Flush()
 
434
                        {
 
435
                                if (this.closed)
 
436
                                {
 
437
                                        throw new IOException("Already closed");
 
438
                                }
 
439
                                if (this.dataLen == 0)
 
440
                                {
 
441
                                        return;
 
442
                                }
 
443
                                this.packet.Reset();
 
444
                                this.buffer.PutByte(unchecked((byte)Session.SSH_MSG_CHANNEL_DATA));
 
445
                                this.buffer.PutInt(this._enclosing.recipient);
 
446
                                this.buffer.PutInt(this.dataLen);
 
447
                                this.buffer.Skip(this.dataLen);
 
448
                                try
 
449
                                {
 
450
                                        int foo = this.dataLen;
 
451
                                        this.dataLen = 0;
 
452
                                        this._enclosing.GetSession().Write(this.packet, channel, foo);
 
453
                                }
 
454
                                catch (Exception e)
 
455
                                {
 
456
                                        this.Close();
 
457
                                        throw new IOException(e.ToString());
 
458
                                }
 
459
                        }
 
460
 
 
461
                        /// <exception cref="System.IO.IOException"></exception>
 
462
                        public override void Close()
 
463
                        {
 
464
                                if (this.packet == null)
 
465
                                {
 
466
                                        try
 
467
                                        {
 
468
                                                this.Init();
 
469
                                        }
 
470
                                        catch (IOException)
 
471
                                        {
 
472
                                                return;
 
473
                                        }
 
474
                                }
 
475
                                if (this.closed)
 
476
                                {
 
477
                                        return;
 
478
                                }
 
479
                                if (this.dataLen > 0)
 
480
                                {
 
481
                                        this.Flush();
 
482
                                }
 
483
                                channel.Eof();
 
484
                                this.closed = true;
 
485
                        }
 
486
 
 
487
                        private readonly Channel _enclosing;
 
488
 
 
489
                        private readonly NSch.Channel channel;
 
490
                }
 
491
 
 
492
                internal class MyPipedInputStream : PipedInputStream
 
493
                {
 
494
                        /// <exception cref="System.IO.IOException"></exception>
 
495
                        public MyPipedInputStream(Channel _enclosing) : base()
 
496
                        {
 
497
                                this._enclosing = _enclosing;
 
498
                        }
 
499
 
 
500
                        /// <exception cref="System.IO.IOException"></exception>
 
501
                        public MyPipedInputStream(Channel _enclosing, int size) : base()
 
502
                        {
 
503
                                this._enclosing = _enclosing;
 
504
                                this.buffer = new byte[size];
 
505
                        }
 
506
 
 
507
                        /// <exception cref="System.IO.IOException"></exception>
 
508
                        public MyPipedInputStream(Channel _enclosing, PipedOutputStream @out) : base(@out
 
509
                                )
 
510
                        {
 
511
                                this._enclosing = _enclosing;
 
512
                        }
 
513
 
 
514
                        /// <exception cref="System.IO.IOException"></exception>
 
515
                        public MyPipedInputStream(Channel _enclosing, PipedOutputStream @out, int size) : 
 
516
                                base(@out)
 
517
                        {
 
518
                                this._enclosing = _enclosing;
 
519
                                this.buffer = new byte[size];
 
520
                        }
 
521
 
 
522
                        private readonly Channel _enclosing;
 
523
                }
 
524
 
 
525
                internal virtual void SetLocalWindowSizeMax(int foo)
 
526
                {
 
527
                        this.lwsize_max = foo;
 
528
                }
 
529
 
 
530
                internal virtual void SetLocalWindowSize(int foo)
 
531
                {
 
532
                        this.lwsize = foo;
 
533
                }
 
534
 
 
535
                internal virtual void SetLocalPacketSize(int foo)
 
536
                {
 
537
                        this.lmpsize = foo;
 
538
                }
 
539
 
 
540
                internal virtual void SetRemoteWindowSize(long foo)
 
541
                {
 
542
                        lock (this)
 
543
                        {
 
544
                                this.rwsize = foo;
 
545
                        }
 
546
                }
 
547
 
 
548
                internal virtual void AddRemoteWindowSize(int foo)
 
549
                {
 
550
                        lock (this)
 
551
                        {
 
552
                                this.rwsize += foo;
 
553
                                if (notifyme > 0)
 
554
                                {
 
555
                                        Sharpen.Runtime.NotifyAll(this);
 
556
                                }
 
557
                        }
 
558
                }
 
559
 
 
560
                internal virtual void SetRemotePacketSize(int foo)
 
561
                {
 
562
                        this.rmpsize = foo;
 
563
                }
 
564
 
 
565
                public virtual void Run()
 
566
                {
 
567
                }
 
568
 
 
569
                /// <exception cref="System.IO.IOException"></exception>
 
570
                internal virtual void Write(byte[] foo)
 
571
                {
 
572
                        Write(foo, 0, foo.Length);
 
573
                }
 
574
 
 
575
                /// <exception cref="System.IO.IOException"></exception>
 
576
                internal virtual void Write(byte[] foo, int s, int l)
 
577
                {
 
578
                        try
 
579
                        {
 
580
                                io.Put(foo, s, l);
 
581
                        }
 
582
                        catch (ArgumentNullException)
 
583
                        {
 
584
                        }
 
585
                }
 
586
 
 
587
                /// <exception cref="System.IO.IOException"></exception>
 
588
                internal virtual void Write_ext(byte[] foo, int s, int l)
 
589
                {
 
590
                        try
 
591
                        {
 
592
                                io.Put_ext(foo, s, l);
 
593
                        }
 
594
                        catch (ArgumentNullException)
 
595
                        {
 
596
                        }
 
597
                }
 
598
 
 
599
                internal virtual void Eof_remote()
 
600
                {
 
601
                        eof_remote = true;
 
602
                        try
 
603
                        {
 
604
                                io.Out_close();
 
605
                        }
 
606
                        catch (ArgumentNullException)
 
607
                        {
 
608
                        }
 
609
                }
 
610
 
 
611
                internal virtual void Eof()
 
612
                {
 
613
                        if (eof_local)
 
614
                        {
 
615
                                return;
 
616
                        }
 
617
                        eof_local = true;
 
618
                        try
 
619
                        {
 
620
                                Buffer buf = new Buffer(100);
 
621
                                Packet packet = new Packet(buf);
 
622
                                packet.Reset();
 
623
                                buf.PutByte(unchecked((byte)Session.SSH_MSG_CHANNEL_EOF));
 
624
                                buf.PutInt(GetRecipient());
 
625
                                lock (this)
 
626
                                {
 
627
                                        if (!close)
 
628
                                        {
 
629
                                                GetSession().Write(packet);
 
630
                                        }
 
631
                                }
 
632
                        }
 
633
                        catch (Exception)
 
634
                        {
 
635
                        }
 
636
                }
 
637
 
 
638
                //System.err.println("Channel.eof");
 
639
                //e.printStackTrace();
 
640
                internal virtual void Close()
 
641
                {
 
642
                        if (close)
 
643
                        {
 
644
                                return;
 
645
                        }
 
646
                        close = true;
 
647
                        eof_local = eof_remote = true;
 
648
                        try
 
649
                        {
 
650
                                Buffer buf = new Buffer(100);
 
651
                                Packet packet = new Packet(buf);
 
652
                                packet.Reset();
 
653
                                buf.PutByte(unchecked((byte)Session.SSH_MSG_CHANNEL_CLOSE));
 
654
                                buf.PutInt(GetRecipient());
 
655
                                lock (this)
 
656
                                {
 
657
                                        GetSession().Write(packet);
 
658
                                }
 
659
                        }
 
660
                        catch (Exception)
 
661
                        {
 
662
                        }
 
663
                }
 
664
 
 
665
                //e.printStackTrace();
 
666
                public virtual bool IsClosed()
 
667
                {
 
668
                        return close;
 
669
                }
 
670
 
 
671
                internal static void Disconnect(Session session)
 
672
                {
 
673
                        Channel[] channels = null;
 
674
                        int count = 0;
 
675
                        lock (pool)
 
676
                        {
 
677
                                channels = new Channel[pool.Count];
 
678
                                for (int i = 0; i < pool.Count; i++)
 
679
                                {
 
680
                                        try
 
681
                                        {
 
682
                                                Channel c = ((Channel)(pool[i]));
 
683
                                                if (c.session == session)
 
684
                                                {
 
685
                                                        channels[count++] = c;
 
686
                                                }
 
687
                                        }
 
688
                                        catch (Exception)
 
689
                                        {
 
690
                                        }
 
691
                                }
 
692
                        }
 
693
                        for (int i_1 = 0; i_1 < count; i_1++)
 
694
                        {
 
695
                                channels[i_1].Disconnect();
 
696
                        }
 
697
                }
 
698
 
 
699
                public virtual void Disconnect()
 
700
                {
 
701
                        //System.err.println(this+":disconnect "+io+" "+connected);
 
702
                        //Thread.dumpStack();
 
703
                        try
 
704
                        {
 
705
                                lock (this)
 
706
                                {
 
707
                                        if (!connected)
 
708
                                        {
 
709
                                                return;
 
710
                                        }
 
711
                                        connected = false;
 
712
                                }
 
713
                                Close();
 
714
                                eof_remote = eof_local = true;
 
715
                                thread = null;
 
716
                                try
 
717
                                {
 
718
                                        if (io != null)
 
719
                                        {
 
720
                                                io.Close();
 
721
                                        }
 
722
                                }
 
723
                                catch (Exception)
 
724
                                {
 
725
                                }
 
726
                        }
 
727
                        finally
 
728
                        {
 
729
                                //e.printStackTrace();
 
730
                                // io=null;
 
731
                                Channel.Del(this);
 
732
                        }
 
733
                }
 
734
 
 
735
                public virtual bool IsConnected()
 
736
                {
 
737
                        Session _session = this.session;
 
738
                        if (_session != null)
 
739
                        {
 
740
                                return _session.IsConnected() && connected;
 
741
                        }
 
742
                        return false;
 
743
                }
 
744
 
 
745
                /// <exception cref="System.Exception"></exception>
 
746
                public virtual void SendSignal(string signal)
 
747
                {
 
748
                        RequestSignal request = new RequestSignal();
 
749
                        request.SetSignal(signal);
 
750
                        request.DoRequest(GetSession(), this);
 
751
                }
 
752
 
 
753
                internal class PassiveInputStream : Channel.MyPipedInputStream
 
754
                {
 
755
                        internal PipedOutputStream @out;
 
756
 
 
757
                        /// <exception cref="System.IO.IOException"></exception>
 
758
                        public PassiveInputStream(Channel _enclosing, PipedOutputStream @out, int size) : 
 
759
                                base(_enclosing)
 
760
                        {
 
761
                                this._enclosing = _enclosing;
 
762
                                //  public String toString(){
 
763
                                //      return "Channel: type="+new String(type)+",id="+id+",recipient="+recipient+",window_size="+window_size+",packet_size="+packet_size;
 
764
                                //  }
 
765
                                this.@out = @out;
 
766
                        }
 
767
 
 
768
                        /// <exception cref="System.IO.IOException"></exception>
 
769
                        public PassiveInputStream(Channel _enclosing, PipedOutputStream @out) : base(_enclosing
 
770
                                )
 
771
                        {
 
772
                                this._enclosing = _enclosing;
 
773
                                this.@out = @out;
 
774
                        }
 
775
 
 
776
                        /// <exception cref="System.IO.IOException"></exception>
 
777
                        public override void Close()
 
778
                        {
 
779
                                if (this.@out != null)
 
780
                                {
 
781
                                        this.@out.Close();
 
782
                                }
 
783
                                this.@out = null;
 
784
                        }
 
785
 
 
786
                        private readonly Channel _enclosing;
 
787
                }
 
788
 
 
789
                internal class PassiveOutputStream : PipedOutputStream
 
790
                {
 
791
                        /// <exception cref="System.IO.IOException"></exception>
 
792
                        public PassiveOutputStream(Channel _enclosing, PipedInputStream @in) : base(@in)
 
793
                        {
 
794
                                this._enclosing = _enclosing;
 
795
                        }
 
796
 
 
797
                        private readonly Channel _enclosing;
 
798
                }
 
799
 
 
800
                internal virtual void SetExitStatus(int status)
 
801
                {
 
802
                        exitstatus = status;
 
803
                }
 
804
 
 
805
                public virtual int GetExitStatus()
 
806
                {
 
807
                        return exitstatus;
 
808
                }
 
809
 
 
810
                internal virtual void SetSession(Session session)
 
811
                {
 
812
                        this.session = session;
 
813
                }
 
814
 
 
815
                /// <exception cref="NSch.JSchException"></exception>
 
816
                public virtual Session GetSession()
 
817
                {
 
818
                        Session _session = session;
 
819
                        if (_session == null)
 
820
                        {
 
821
                                throw new JSchException("session is not available");
 
822
                        }
 
823
                        return _session;
 
824
                }
 
825
 
 
826
                public virtual int GetId()
 
827
                {
 
828
                        return id;
 
829
                }
 
830
 
 
831
                /// <exception cref="System.Exception"></exception>
 
832
                protected internal virtual void SendOpenConfirmation()
 
833
                {
 
834
                        Buffer buf = new Buffer(100);
 
835
                        Packet packet = new Packet(buf);
 
836
                        packet.Reset();
 
837
                        buf.PutByte(unchecked((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION));
 
838
                        buf.PutInt(GetRecipient());
 
839
                        buf.PutInt(id);
 
840
                        buf.PutInt(lwsize);
 
841
                        buf.PutInt(lmpsize);
 
842
                        GetSession().Write(packet);
 
843
                }
 
844
 
 
845
                protected internal virtual void SendOpenFailure(int reasoncode)
 
846
                {
 
847
                        try
 
848
                        {
 
849
                                Buffer buf = new Buffer(100);
 
850
                                Packet packet = new Packet(buf);
 
851
                                packet.Reset();
 
852
                                buf.PutByte(unchecked((byte)SSH_MSG_CHANNEL_OPEN_FAILURE));
 
853
                                buf.PutInt(GetRecipient());
 
854
                                buf.PutInt(reasoncode);
 
855
                                buf.PutString(Util.Str2byte("open failed"));
 
856
                                buf.PutString(Util.empty);
 
857
                                GetSession().Write(packet);
 
858
                        }
 
859
                        catch (Exception)
 
860
                        {
 
861
                        }
 
862
                }
 
863
        }
 
864
}