summaryrefslogtreecommitdiff
path: root/modules/ssh/channel.scm
blob: 361c14f5aa0b91df5b9866dc68993b7e1cc68882 (about) (plain)
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
;;; channel.scm -- API for SSH channel manipulation.

;; Copyright (C) 2013, 2014, 2015, 2016 Artyom V. Poptsov <poptsov.artyom@gmail.com>
;;
;; This file is a part of Guile-SSH.
;;
;; Guile-SSH is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;;
;; Guile-SSH is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Guile-SSH.  If not, see
;; <http://www.gnu.org/licenses/>.


;;; Commentary:

;; This module contains API that is used for working with SSH
;; channels.
;;
;; These procedures are exported:
;;
;;   channel?
;;   make-channel
;;   channel-open-session
;;   channel-request-env
;;   channel-request-exec
;;   channel-request-pty
;;   channel-request-shell
;;   channel-open-forward
;;   channel-cancel-forward
;;   channel-set-pty-size!
;;   channel-set-stream!
;;   channel-stream
;;   channel-session
;;   channel-open?
;;   channel-send-eof
;;   channel-eof?


;;; Code:

(define-module (ssh channel)
  #:use-module (ssh log)
  #:use-module (ssh session)
  #:export (channel
            channel?
            make-channel
            channel-open-session
            channel-request-env
            channel-request-exec
            channel-request-pty
            channel-request-shell
            channel-open-forward
            channel-listen-forward
            channel-accept-forward
            channel-cancel-forward
            channel-request-send-exit-status
            channel-set-pty-size!
            channel-stream-set!
            channel-set-stream!         ; deprecated
            channel-stream
            channel-get-stream          ; deprecated
            channel-session
            channel-get-session         ; deprecated
            channel-get-exit-status
            channel-open?
            channel-send-eof
            channel-eof?))

(define* (make-channel session #:optional (mode OPEN_BOTH))
  (cond
    ((string-contains mode OPEN_BOTH)
     (%make-channel session (logior RDNG WRTNG)))
    ((string-contains mode OPEN_READ)
     (%make-channel session RDNG))
    ((string-contains mode OPEN_WRITE)
     (%make-channel session WRTNG))
    (else
     (throw 'guile-ssh-error "Wrong mode" mode))))


(define (channel-session channel)
  "Get the session to which belongs the CHANNEL.  Throw 'guile-ssh-error' on
an error.  Return the session."
  (%gssh-channel-session channel))

(define (channel-get-session channel)
  (issue-deprecation-warning "'channel-get-session' is deprecated.  "
                             "Use 'channel-session' instead.")
  (%gssh-channel-session channel))

(define (channel-stream channel)
  "Get current stream name from a CHANNEL.  Throw 'guile-ssh-error' on error.
Return one of the following symbols: stdout, stderr."
  (%gssh-channel-stream channel))

(define (channel-get-stream channel)
  (issue-deprecation-warning "'channel-get-stream' is deprecated.  "
                             "Use 'channel-stream' instead.")
  (%gssh-channel-stream channel))

(define (channel-stream-set! channel stream)
  "Set stream STREAM for channel CHANNEL.  STREAM must be one of the following
symbols: stdout (default), stderr.  Return value is undefined."
  (%gssh-channel-stream-set! channel stream))

(define (channel-set-stream! channel stream)
  (issue-deprecation-warning "'channel-get-stream' is deprecated.  "
                             "Use 'channel-stream' instead.")
  (%gssh-channel-stream-set! channel stream))


(define* (channel-open-forward channel
                               #:key (source-host "localhost") local-port
                               remote-host (remote-port local-port))
  "Open a TCP/IP forwarding channel.  Connect to a REMOTE-HOST and REMOTE-PORT,
and use SOURCE-HOST and LOCAL-PORT as origination of connections.

If the SOURCE-HOST is not set, then \"localhost\" is used.  If REMOTE-PORT is
not set, then it will be set to LOCAL-PORT value.

Please note that the procedure does not bind the LOCAL-PORT and does not
automatically forward the content of a socket to the channel."
  (%channel-open-forward channel
                         remote-host remote-port
                         source-host local-port))

(define* (channel-listen-forward session #:key (address #f) (port 0))
  "Send the \"tcpip-forward\" global request using SESSION to ask the server
to begin listening for inbound connections on the specified ADDRESS and PORT.
If ADDRESS is not specified (or set to #f) then the server binds all addresses
on all protocol families supported by the server.  When 0 is passed as a PORT
then server allocates the next unprivileged port.

The procedure returns two values: the first value is the result of the
operation (either 'ok', 'again' or 'error'), and the second value is the bound
port number (if PORT was set to 0)."
  (%channel-listen-forward session address port))

(define* (channel-accept-forward session #:optional (timeout 0))
  "Accept an incoming TCP/IP forwarding channel and get information about
incoming connection.  Return two values: the first value is the incoming
channel, and the second value is a port number on which the connection was
issued."
  (%channel-accept-forward session timeout))

(define (channel-send-eof channel)
  "Send an end of file (EOF) on the CHANNEL.  This action doesn't close the
channel; you may still read from it but not write.  Throw 'guile-ssh-error' on
an error.  Return value is undefined."
  (%channel-send-eof channel))

;;;


(load-extension "libguile-ssh" "init_channel")

;;; channel.scm ends here.