This file is indexed.

/usr/lib/x86_64-linux-gnu/perl5/5.24/Net/SSH2/Channel.pm is in libnet-ssh2-perl 0.63-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
package Net::SSH2::Channel;

use strict;
use warnings;
use Carp;

# methods

sub shell {
    $_[0]->process('shell')
}

sub exec {
    $_[0]->process(exec => $_[1])
}

sub subsystem {
    $_[0]->process(subsystem => $_[1])
}

sub error {
    shift->session->error(@_)
}

sub blocking {
    shift->session->blocking(@_)
}

sub setenv {
    my ($self, %env) = @_;
    my $rc = 1;
    while (my ($k, $v) = each %env) {
        $self->_setenv($k, $v)
            or undef $rc;
    }
    $rc
}

sub read1 {
    my $self = shift;
    my $buffer;
    my $rc = $self->read($buffer, @_);
    return (defined $rc ? $buffer : undef);
}

sub read2 {
    my ($self, $max_size) = @_;
    $max_size = 32678 unless defined $max_size;
    my $ssh2 = $self->session;
    my $old_blocking = $ssh2->blocking;
    my $timeout = $ssh2->timeout;
    my $delay = (($timeout and $timeout < 2000) ? 0.0005 * $timeout : 1);
    my $deadline;
    $deadline = time + 1 + 0.001 * $timeout if $timeout;
    $ssh2->blocking(0);
    while (1) {
        my @out;
        my $bytes;
        my $fail;
        my $zero;
        for (0, 1) {
            my $rc = $self->read($out[$_], $max_size, $_);
            if (defined $rc) {
                $rc or $zero++;
                $bytes += $rc;
                $deadline = time + 1 + 0.001 * $timeout if $timeout;
            }
            else {
                $out[$_] = '';
                if ($ssh2->error != Net::SSH2::LIBSSH2_ERROR_EAGAIN()) {
                    $fail++;
                    last;
                }
            }
        }
        if ($bytes) {
            $ssh2->blocking($old_blocking);
            return (wantarray ? @out : $out[0])
        }
        my $eof = $self->eof;
        if ($fail or $eof) {
            $ssh2->_set_error if $eof;
            $ssh2->blocking($old_blocking);
            return;
        }
        unless ($zero) {
            return unless $old_blocking;
            if ($deadline and time > $deadline) {
                $ssh2->_set_error(Net::SSH2::LIBSSH2_ERROR_TIMEOUT(), "Time out waiting for data");
                return;
            }
            return if $deadline and time > $deadline;
            my $sock = $ssh2->sock;
            my $fn = fileno($sock);
            my ($rbm, $wbm) = ('', '');
            my $bd = $ssh2->block_directions;
            vec($rbm, $fn, 1) = 1 if $bd & Net::SSH2::LIBSSH2_SESSION_BLOCK_INBOUND();
            vec($wbm, $fn, 1) = 1 if $bd & Net::SSH2::LIBSSH2_SESSION_BLOCK_OUTBOUND();
            select $rbm, $wbm, undef, $delay;
        }
    }
}

sub readline {
    my ($self, $ext, $eol) = @_;
    return if $self->eof;
    $ext ||= 0;
    $eol = $/ unless @_ >= 3;
    if (wantarray or not defined $eol) {
        my $data = '';
        my $buffer;
        while (1) {
            my $bytes = $self->read($buffer, 32768, $ext);
            last unless defined $bytes;
            if (!$bytes and $self->eof) {
                $self->session->_set_error(Net::SSH2::LIBSSH2_ERROR_NONE());
                last;
            }
            $data .= $buffer;
        }
        defined $eol and return split /(?<=\Q$eol\E)/s, $data;
        wantarray and not length $data and return ();
        return $data;
    }
    else {
        my $c;
        my $data = '';
        while (1) {
            $c = $self->getc($ext);
            last unless defined $c;
            $data .= $c;
            if ( (!length($c) and $self->eof) or
                 $data =~ /\Q$eol\E\z/) {
                $self->session->_set_error(Net::SSH2::LIBSSH2_ERROR_NONE());
                last;
            }
        }
        return (length $data ? $data : undef);
    }
}

sub wait_closed {
    my $self = shift;
    if ($self->wait_eof) {
        $self->flush('all');
        return $self->_wait_closed;
    }
    undef;
}

sub exit_status {
    my $self = shift;
    return unless $self->wait_closed;
    return $self->_exit_status;
}

sub exit_signal {
    my $self = shift;
    return unless $self->wait_closed;
    return $self->_exit_signal;
}

my %signal_number;
sub exit_signal_number {
    my $self = shift;
    my $signal = $self->exit_signal;
    return unless defined $signal;
    return 0 unless $signal;
    unless (%signal_number) {
        require Config;
        my @names = split /\s+/, $Config::Config{sig_name};
        @signal_number{@names} = 0..$#names;
    }
    $signal =~ s/\@\.[^\.]+\.config\.guess$//;
    my $number = $signal_number{$signal};
    $number = 255 unless defined $number;
    return $number;
}

# tie interface

sub PRINT {
    my $self = shift;
    my $sep = defined($,) ? $, : '';
    $self->write(join $sep, @_)
}

sub PRINTF {
    my $self = shift;
    my $template = shift;
    $self->write(sprintf $template, @_);
}

sub WRITE {
    my ($self, $buf, $len, $offset) = @_;
    $self->write(substr($buf, $offset || 0, $len))
}

sub READLINE { shift->readline(0, $/) }

sub READ {
    my ($self, undef, $len, $offset) = @_;
    my $bytes = $self->read(my($buffer), $len);
    substr($_[1], $offset || 0) = $buffer
        if defined $bytes;
    return $bytes;
}

sub BINMODE { 1 }

sub CLOSE {
    my $self = shift;
    my $ob = $self->blocking;
    $self->blocking(1);
    my $rc = undef;
    if ($self->close and
        $self->wait_closed) {
        my $status = $self->exit_status;
        my $signal = $self->exit_signal_number;
        $self->session->_set_error;
        $? = ($status << 8) | $signal;
        $rc = 1 if $? == 0;
    }
    $self->blocking($ob);
    $rc;
}

sub EOF {
    my $self = shift;
    $self->eof;
}

*GETC = \&getc;

1;
__END__

=head1 NAME

Net::SSH2::Channel - SSH2 channel object

=head1 SYNOPSIS

  my $chan = $ssh2->channel()
    or $ssh2->die_with_error;

  $chan->exec("ls -ld /usr/local/libssh2*")
    or $ssh2->die_with_error;

  $chan->send_eof;

  while (<$chan>) {
    print "line read: $_";
  }

  print "exit status: " . $chan->exit_status . "\n";

=head1 DESCRIPTION

A channel object is created by the L<Net::SSH2> C<channel> method.  As well
as being an object, it is also a tied filehandle.

=head2 setenv ( key, value ... )

Sets remote environment variables. Note that most servers do not allow
environment variables to be freely set.

Pass in a list of keys and values with the values to set.

It returns a true value if all the given environment variables were
correctly set.

=head2 blocking ( flag )

Enable or disable blocking.

Note that this is currently implemented in libssh2 by setting a
per-session flag. It's equivalent to L<Net::SSH2::blocking>.

=head2 eof

Returns true if the remote server sent an EOF.

=head2 send_eof

Sends an EOF to the remote side.

After an EOF has been sent, no more data may be
sent to the remote process C<STDIN> channel.

Note that if a PTY was requested for the channel, the EOF may be
ignored by the remote server. See L</pty>.

=head2 close

Close the channel (happens automatically on object destruction).

=head2 wait_closed

Wait for a remote close event.

In order to avoid a bug in libssh2 this method discards any unread
data queued in the channel.

=head2 exit_status

Returns the channel's program exit status.

This method blocks until the remote side closes the channel.

=head2 pty ( terminal [, modes [, width [, height ]]] )

Request a terminal on a channel.

C<terminal> is the type of emulation (e.g. vt102, ansi,
etc...). C<modes> are the terminal mode modifiers.

If provided, C<width> and C<height> are the width and height in
characters (defaults to 80x24); if negative their absolute values
specify width and height in pixels.

=head2 pty_size ( width, height )

Request a terminal size change on a channel. C<width> and C<height> are the
width and height in characters; if negative their absolute values specify
width and height in pixels.

=head2 ext_data ( mode )

Set extended data handling mode:

=over 4

=item normal (default)

Keep data in separate channels; C<STDERR> is read separately.

=item ignore

Ignore all extended data.

=item merge

Merge into the regular channel.

=back

=head2 process ( request, message )

Start a process on the channel.  See also L<shell>, L<exec>, L<subsystem>.

Note that only one invocation of C<process> or any of the shortcuts
C<shell>, C<exec> or C<subsystem> is allowed per channel. In order to
run several commands, shells or/and subsystems, a new C<Channel>
instance must be used for every one.

Alternatively, it is also possible to launch a remote shell (using
L<shell>) and simulate the user interaction printing commands to its
C<stdin> stream and reading data back from its C<stdout> and
C<stderr>. But this approach should be avoided if possible; talking to
a shell is difficult and, in general, unreliable.

=head2 shell

Start a shell on the remote host (calls C<process("shell")>).

=head2 exec ( command )

Execute the command on the remote host (calls C<process("exec", command)>).

Note that the given command is parsed by the remote shell; it should
be properly quoted, specially when passing data from untrusted sources.

=head2 subsystem ( name )

Run subsystem on the remote host (calls C<process("subsystem", name)>).

=head2 read ( buffer, max_size [, ext ] )

Attempts to read up to C<max_size> bytes from the channel into C<buffer>. If
C<ext> is true, reads from the extended data channel (C<STDERR>).

The method returns as soon as some data is available, even if the
given size has not been reached.

Returns number of bytes read or C<undef> on failure. Note that 0 is a
valid return code.

=head2 read2 ( [max_size] )

Attempts to read from both the ordinary (stdout) and the extended
(stderr) channel streams.

Returns two scalars with the data read both from stdout and stderr. It
returns as soon as some data is available and any of the returned
values may be an empty string.

When some error happens it returns the empty list.

Example:

  my ($out, $err) = ('', '');
  while (!$channel->eof) {
      if (my ($o, $e) = $channel->read2) {
          $out .= $o;
          $err .= $e;
      }
      else {
          $ssh2->die_with_error;
      }
  }
  print "STDOUT:\n$out\nSTDERR:\n$err\n";

=head2 readline ( [ext [, eol ] ] )

Reads the next line from the selected stream (C<ext> defaults to 0:
stdout).

C<$/> is used as the end of line marker when C<eol> is C<undef>.

In list context reads and returns all the remaining lines until some
read error happens or the remote side sends an eof.

Note that this method is only safe when the complementary stream
(e.g. C<!ext>) is guaranteed to not generate data or when L</ext_data>
has been used to discard or merge it; otherwise it may hang. This is a
limitation of libssh2 that hopefully would be removed in a future
release, in the meantime you are advised to use L<read2> instead.

=head2 getc( [ext] )

Reads and returns the next character from the selected stream.

Returns C<undef> on error.

Note that due to some libssh2 quirks, the return value can be the
empty string which may indicate an EOF condition (but not
always!). See L</eof>.

=head2 write ( buffer )

Send the data in C<buffer> through the channel. Returns number of
bytes written, undef on failure.

In versions of this module prior to 0.57, when working in non-blocking
mode, the would-block condition was signaled by returning
C<LIBSSH2_ERROR_EAGAIN> (a negative number) while leaving the session
error status unset. From version 0.59, C<undef> is returned and the
session error status is set to C<LIBSSH2_ERROR_EAGAIN> as for any
other error.

In non-blocking mode, if C<write> fails with a C<LIBSSH2_ERROR_EAGAIN>
error, no other operation must be invoked over any object in the same
SSH session besides L</sock> and L<blocking_directions>.

Once the socket becomes ready again, the exact same former C<write>
call, with exactly the same arguments must be invoked.

Failing to do that would result in a corrupted SSH session. This is a
limitation in libssh2.

=head2 flush ( [ ext ] )

Flushes the channel; if C<ext> is present and set, flushes extended
data channel. Returns number of bytes flushed, C<undef> on error.

=head2 exit_signal

Returns the name of exit signal from the remote command.

In list context returns also the error message and a language tag,
though as of libssh2 1.7.0, those values are always undef.

This method blocks until the remote side closes the channel.

=head2 exit_signal_number

Converts the signal name to a signal number using the local mapping
(which may be different to the remote one if the operating systems
differ).

=head2 window_read

Returns the number of bytes which the remote end may send without
overflowing the window limit.

In list context it also returns the number of bytes that are
immediately available for read and the size of the initial window.

=head2 window_write

Returns the number of bytes which may be safely written to the channel
without blocking at the SSH level. In list context it also returns the
size of the initial window.

Note that this method doesn't take into account the TCP connection
being used under the hood. Getting a positive integer back from this
method does not guarantee that such number of bytes could be written
to the channel without blocking the TCP connection.

=head2 receive_window_adjust (adjustment [, force])

Adjust the channel receive window by the given C<adjustment> bytes.

If the amount to be adjusted is less than C<LIBSSH2_CHANNEL_MINADJUST>
and force is false the adjustment amount will be queued for a later
packet.

On success returns the new size of the receive window. On failure it
returns C<undef>.

=head1 SEE ALSO

L<Net::SSH2>.

=cut