libssh 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -9
- data/.rubocop_todo.yml +0 -7
- data/CHANGELOG.md +9 -0
- data/Rakefile +9 -1
- data/example/exec.rb +18 -6
- data/ext/libssh_ruby/channel.c +110 -12
- data/ext/libssh_ruby/error.c +13 -1
- data/ext/libssh_ruby/key.c +13 -5
- data/ext/libssh_ruby/libssh_ruby.c +29 -15
- data/ext/libssh_ruby/scp.c +12 -13
- data/ext/libssh_ruby/session.c +58 -13
- data/lib/libssh/key.rb +4 -0
- data/lib/libssh/version.rb +2 -1
- data/lib/sshkit/backends/libssh.rb +58 -13
- data/libssh.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 639bee53286516a176e3e46c5646a93593405f3e
|
4
|
+
data.tar.gz: e934c062774b730c8a35a4b69ea075f9389af9d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e1596553a20bb479ebb3878fc1a2dbb968bbf9eb3fb3a4c6308ec85ce2e34ddd52770584b85764a8fde72260fb4ddec5da926923ae4a5da1e137d91fe1147b2
|
7
|
+
data.tar.gz: 4ba23660ed50cb0193df4bdac73134138fcb2dfe6bef6c84c00c4b883d81db8bc2ccd2f6b8ac3bb37e9281efb33b22a0bfde564b33b8ef7ce792063d0eb9cf31
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.rubocop.yml
CHANGED
@@ -3,20 +3,19 @@ inherit_from: .rubocop_todo.yml
|
|
3
3
|
AllCops:
|
4
4
|
DisplayCopNames: true
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Metrics/LineLength:
|
13
|
-
Enabled: false
|
14
|
-
Metrics/MethodLength:
|
6
|
+
Style/Documentation:
|
7
|
+
Exclude:
|
8
|
+
- 'lib/libssh/key.rb' # Documented in ext
|
9
|
+
- 'spec/**'
|
10
|
+
|
11
|
+
Metrics:
|
15
12
|
Enabled: false
|
16
13
|
|
17
14
|
Style/GlobalVars:
|
18
15
|
Exclude:
|
19
16
|
- 'ext/libssh_ruby/extconf.rb'
|
17
|
+
Style/GuardClause:
|
18
|
+
Enabled: false
|
20
19
|
Style/HashSyntax:
|
21
20
|
Exclude:
|
22
21
|
- 'Rakefile'
|
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.3.0 (2016-02-06)
|
2
|
+
- Add wrapper methods
|
3
|
+
- `Session#fd`
|
4
|
+
- `Session#read_nonblocking`
|
5
|
+
- `Session#disconnect`
|
6
|
+
- Make `Channel#get_exit_status` and `Channel#open_session` interruptible
|
7
|
+
- More documentations
|
8
|
+
- Add integration test
|
9
|
+
|
1
10
|
## 0.2.0 (2016-01-30)
|
2
11
|
- Add many wrapper methods
|
3
12
|
- Support `upload!` and `download!` as SSHKit backend.
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rake/extensiontask'
|
3
|
+
require 'rspec/core/rake_task'
|
3
4
|
|
4
5
|
task :build => :compile
|
5
6
|
|
@@ -7,4 +8,11 @@ Rake::ExtensionTask.new('libssh_ruby') do |ext|
|
|
7
8
|
ext.lib_dir = 'lib/libssh'
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
+
RSpec::Core::RakeTask.new(:spec)
|
12
|
+
|
13
|
+
task :default => [:clobber, :compile, :docker, :spec]
|
14
|
+
|
15
|
+
desc 'Build docker image for integration test'
|
16
|
+
task :docker do
|
17
|
+
sh 'docker build -t libssh-ruby spec'
|
18
|
+
end
|
data/example/exec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'libssh'
|
3
|
+
require 'io/wait'
|
3
4
|
|
4
5
|
GC.stress = true
|
5
6
|
puts "libssh #{LibSSH::LIBSSH_VERSION}"
|
@@ -38,17 +39,28 @@ end
|
|
38
39
|
bufsiz = 16384
|
39
40
|
|
40
41
|
channel = LibSSH::Channel.new(session)
|
42
|
+
io = IO.for_fd(session.fd, autoclose: false)
|
41
43
|
channel.open_session do
|
42
44
|
channel.request_exec('ps auxf')
|
43
45
|
until channel.eof?
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
io.wait_readable
|
47
|
+
|
48
|
+
loop do
|
49
|
+
out = channel.read_nonblocking(bufsiz)
|
50
|
+
if out && !out.empty?
|
51
|
+
$stdout.write(out)
|
52
|
+
else
|
53
|
+
break
|
54
|
+
end
|
47
55
|
end
|
48
56
|
|
49
|
-
|
50
|
-
|
51
|
-
|
57
|
+
loop do
|
58
|
+
err = channel.read_nonblocking(bufsiz, true)
|
59
|
+
if err && !err.empty?
|
60
|
+
$stderr.write(err)
|
61
|
+
else
|
62
|
+
break
|
63
|
+
end
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
data/ext/libssh_ruby/channel.c
CHANGED
@@ -57,6 +57,12 @@ static size_t channel_memsize(RB_UNUSED_VAR(const void *arg)) {
|
|
57
57
|
return sizeof(ChannelHolder);
|
58
58
|
}
|
59
59
|
|
60
|
+
/* @overload initialize(session)
|
61
|
+
* Initialize a channel from the session.
|
62
|
+
* @param [Session] session
|
63
|
+
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
64
|
+
* ssh_channel_new
|
65
|
+
*/
|
60
66
|
static VALUE m_initialize(VALUE self, VALUE session) {
|
61
67
|
ChannelHolder *holder;
|
62
68
|
SessionHolder *session_holder;
|
@@ -83,7 +89,6 @@ static void *nogvl_close(void *ptr) {
|
|
83
89
|
/*
|
84
90
|
* @overload close
|
85
91
|
* Close a channel.
|
86
|
-
* @since 0.1.0
|
87
92
|
* @return [nil]
|
88
93
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
89
94
|
* ssh_channel_close
|
@@ -100,16 +105,37 @@ static VALUE m_close(VALUE self) {
|
|
100
105
|
return Qnil;
|
101
106
|
}
|
102
107
|
|
108
|
+
static void select_session(ssh_session session) {
|
109
|
+
fd_set fds;
|
110
|
+
int fd;
|
111
|
+
|
112
|
+
FD_ZERO(&fds);
|
113
|
+
fd = ssh_get_fd(session);
|
114
|
+
FD_SET(fd, &fds);
|
115
|
+
select(fd + 1, &fds, NULL, NULL, NULL);
|
116
|
+
}
|
117
|
+
|
103
118
|
static void *nogvl_open_session(void *ptr) {
|
104
119
|
struct nogvl_channel_args *args = ptr;
|
105
|
-
|
120
|
+
ssh_session session = ssh_channel_get_session(args->channel);
|
121
|
+
int blocking = ssh_is_blocking(session);
|
122
|
+
|
123
|
+
ssh_set_blocking(session, 0);
|
124
|
+
while (1) {
|
125
|
+
args->rc = ssh_channel_open_session(args->channel);
|
126
|
+
if (args->rc != SSH_AGAIN) {
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
rb_thread_check_ints();
|
130
|
+
select_session(session);
|
131
|
+
}
|
132
|
+
ssh_set_blocking(session, blocking);
|
106
133
|
return NULL;
|
107
134
|
}
|
108
135
|
|
109
136
|
/*
|
110
137
|
* @overload open_session
|
111
138
|
* Open a session channel, and close it after the block.
|
112
|
-
* @since 0.1.0
|
113
139
|
* @yieldparam [Channel] channel self
|
114
140
|
* @return [Object] Return value of the block
|
115
141
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
@@ -120,6 +146,11 @@ static VALUE m_open_session(VALUE self) {
|
|
120
146
|
struct nogvl_channel_args args;
|
121
147
|
|
122
148
|
TypedData_Get_Struct(self, ChannelHolder, &channel_type, holder);
|
149
|
+
/* When ssh_channel_open_session is called before ssh_connect, libssh would
|
150
|
+
* crash :-< */
|
151
|
+
if (!ssh_is_connected(ssh_channel_get_session(holder->channel))) {
|
152
|
+
rb_raise(rb_eArgError, "Session isn't connected");
|
153
|
+
}
|
123
154
|
args.channel = holder->channel;
|
124
155
|
rb_thread_call_without_gvl(nogvl_open_session, &args, RUBY_UBF_IO, NULL);
|
125
156
|
RAISE_IF_ERROR(args.rc);
|
@@ -147,7 +178,6 @@ static void *nogvl_request_exec(void *ptr) {
|
|
147
178
|
/*
|
148
179
|
* @overload request_exec(cmd)
|
149
180
|
* Run a shell command without an interactive shell.
|
150
|
-
* @since 0.1.0
|
151
181
|
* @param [String] cmd The command to execute
|
152
182
|
* @return [nil]
|
153
183
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
@@ -174,7 +204,6 @@ static void *nogvl_request_pty(void *ptr) {
|
|
174
204
|
/*
|
175
205
|
* @overload request_pty
|
176
206
|
* Request a PTY.
|
177
|
-
* @since 0.1.0
|
178
207
|
* @return [nil]
|
179
208
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
180
209
|
* ssh_channel_request_pty
|
@@ -209,7 +238,6 @@ static void *nogvl_read(void *ptr) {
|
|
209
238
|
/*
|
210
239
|
* @overload read(count, is_stderr: false, timeout: -1)
|
211
240
|
* Read data from a channel.
|
212
|
-
* @since 0.1.0
|
213
241
|
* @param [Fixnum] count The count of bytes to be read.
|
214
242
|
* @param [Boolean] is_stderr Read from the stderr flow or not.
|
215
243
|
* @param [Fixnum] timeout A timeout in seconds. +-1+ means infinite timeout.
|
@@ -250,10 +278,62 @@ static VALUE m_read(int argc, VALUE *argv, VALUE self) {
|
|
250
278
|
return ret;
|
251
279
|
}
|
252
280
|
|
281
|
+
struct nogvl_read_nonblocking_args {
|
282
|
+
ssh_channel channel;
|
283
|
+
char *buf;
|
284
|
+
uint32_t count;
|
285
|
+
int is_stderr;
|
286
|
+
int rc;
|
287
|
+
};
|
288
|
+
|
289
|
+
static void *nogvl_read_nonblocking(void *ptr) {
|
290
|
+
struct nogvl_read_nonblocking_args *args = ptr;
|
291
|
+
args->rc = ssh_channel_read_nonblocking(args->channel, args->buf, args->count,
|
292
|
+
args->is_stderr);
|
293
|
+
return NULL;
|
294
|
+
}
|
295
|
+
|
296
|
+
/*
|
297
|
+
* @overload read_nonblocking(count, is_stderr = false)
|
298
|
+
* Do a nonblocking read on the channel.
|
299
|
+
* @param [Fixnum] count The count of bytes to be read.
|
300
|
+
* @param [Boolean] is_stderr Read from the stderr flow or not.
|
301
|
+
* @return [String, nil] Data read from the channel. +nil+ on EOF.
|
302
|
+
* @since 0.3.0
|
303
|
+
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
304
|
+
* ssh_channel_read_nonblocking
|
305
|
+
*/
|
306
|
+
static VALUE m_read_nonblocking(int argc, VALUE *argv, VALUE self) {
|
307
|
+
ChannelHolder *holder;
|
308
|
+
VALUE count, is_stderr;
|
309
|
+
struct nogvl_read_nonblocking_args args;
|
310
|
+
VALUE ret;
|
311
|
+
|
312
|
+
TypedData_Get_Struct(self, ChannelHolder, &channel_type, holder);
|
313
|
+
args.channel = holder->channel;
|
314
|
+
rb_scan_args(argc, argv, "11", &count, &is_stderr);
|
315
|
+
Check_Type(count, T_FIXNUM);
|
316
|
+
args.count = FIX2UINT(count);
|
317
|
+
if (is_stderr == Qundef) {
|
318
|
+
args.is_stderr = 0;
|
319
|
+
} else {
|
320
|
+
args.is_stderr = RTEST(is_stderr) ? 1 : 0;
|
321
|
+
}
|
322
|
+
args.buf = ALLOC_N(char, args.count);
|
323
|
+
rb_thread_call_without_gvl(nogvl_read_nonblocking, &args, RUBY_UBF_IO, NULL);
|
324
|
+
|
325
|
+
if (args.rc == SSH_EOF) {
|
326
|
+
ret = Qnil;
|
327
|
+
} else {
|
328
|
+
ret = rb_utf8_str_new(args.buf, args.rc);
|
329
|
+
}
|
330
|
+
ruby_xfree(args.buf);
|
331
|
+
return ret;
|
332
|
+
}
|
333
|
+
|
253
334
|
/*
|
254
335
|
* @overload eof?
|
255
336
|
* Check if remote ha sent an EOF.
|
256
|
-
* @since 0.1.0
|
257
337
|
* @return [Boolean]
|
258
338
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
259
339
|
* ssh_channel_is_eof
|
@@ -282,7 +362,6 @@ static void *nogvl_poll(void *ptr) {
|
|
282
362
|
/*
|
283
363
|
* @overload poll(is_stderr: false, timeout: -1)
|
284
364
|
* Poll a channel for data to read.
|
285
|
-
* @since 0.1.0
|
286
365
|
* @param [Boolean] is_stderr A boolean to select the stderr stream.
|
287
366
|
* @param [Fixnum] timeout A timeout in milliseconds. A negative value means an
|
288
367
|
* infinite timeout.
|
@@ -326,14 +405,25 @@ static VALUE m_poll(int argc, VALUE *argv, VALUE self) {
|
|
326
405
|
|
327
406
|
static void *nogvl_get_exit_status(void *ptr) {
|
328
407
|
struct nogvl_channel_args *args = ptr;
|
329
|
-
|
408
|
+
ssh_session session = ssh_channel_get_session(args->channel);
|
409
|
+
int blocking = ssh_is_blocking(session);
|
410
|
+
|
411
|
+
ssh_set_blocking(session, 0);
|
412
|
+
while (1) {
|
413
|
+
args->rc = ssh_channel_get_exit_status(args->channel);
|
414
|
+
if (args->rc != SSH_ERROR) {
|
415
|
+
break;
|
416
|
+
}
|
417
|
+
rb_thread_check_ints();
|
418
|
+
select_session(session);
|
419
|
+
}
|
420
|
+
ssh_set_blocking(session, blocking);
|
330
421
|
return NULL;
|
331
422
|
}
|
332
423
|
|
333
424
|
/*
|
334
425
|
* @overload get_exit_status
|
335
426
|
* Get the exit status of the channel.
|
336
|
-
* @since 0.1.0
|
337
427
|
* @return [Fixnum, nil] The exit status. +nil+ if no exit status has been
|
338
428
|
* returned.
|
339
429
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
@@ -369,7 +459,6 @@ static void *nogvl_write(void *ptr) {
|
|
369
459
|
/*
|
370
460
|
* @overload write(data)
|
371
461
|
* Write data on the channel.
|
372
|
-
* @since 0.1.0
|
373
462
|
* @param [String] data Data to write.
|
374
463
|
* @return [Fixnum] The number of bytes written.
|
375
464
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
@@ -398,7 +487,6 @@ static void *nogvl_send_eof(void *ptr) {
|
|
398
487
|
/*
|
399
488
|
* @overload send_eof
|
400
489
|
* Send EOF on the channel.
|
401
|
-
* @since 0.1.0
|
402
490
|
* @return [nil]
|
403
491
|
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
404
492
|
* ssh_channel_send_eof
|
@@ -414,6 +502,14 @@ static VALUE m_send_eof(VALUE self) {
|
|
414
502
|
return Qnil;
|
415
503
|
}
|
416
504
|
|
505
|
+
/*
|
506
|
+
* Document-class: LibSSH::Channel
|
507
|
+
* Wrapper for ssh_channel struct in libssh.
|
508
|
+
*
|
509
|
+
* @since 0.1.0
|
510
|
+
* @see http://api.libssh.org/stable/group__libssh__channel.html
|
511
|
+
*/
|
512
|
+
|
417
513
|
void Init_libssh_channel(void) {
|
418
514
|
rb_cLibSSHChannel = rb_define_class_under(rb_mLibSSH, "Channel", rb_cObject);
|
419
515
|
rb_define_alloc_func(rb_cLibSSHChannel, channel_alloc);
|
@@ -428,6 +524,8 @@ void Init_libssh_channel(void) {
|
|
428
524
|
rb_define_method(rb_cLibSSHChannel, "request_pty",
|
429
525
|
RUBY_METHOD_FUNC(m_request_pty), 0);
|
430
526
|
rb_define_method(rb_cLibSSHChannel, "read", RUBY_METHOD_FUNC(m_read), -1);
|
527
|
+
rb_define_method(rb_cLibSSHChannel, "read_nonblocking",
|
528
|
+
RUBY_METHOD_FUNC(m_read_nonblocking), -1);
|
431
529
|
rb_define_method(rb_cLibSSHChannel, "poll", RUBY_METHOD_FUNC(m_poll), -1);
|
432
530
|
rb_define_method(rb_cLibSSHChannel, "eof?", RUBY_METHOD_FUNC(m_eof_p), 0);
|
433
531
|
rb_define_method(rb_cLibSSHChannel, "get_exit_status",
|
data/ext/libssh_ruby/error.c
CHANGED
@@ -3,10 +3,22 @@
|
|
3
3
|
VALUE rb_eLibSSHError;
|
4
4
|
ID id_code;
|
5
5
|
|
6
|
+
/*
|
7
|
+
* Document-class: LibSSH::Error
|
8
|
+
* Error returned from libssh.
|
9
|
+
*
|
10
|
+
* @since 0.1.0
|
11
|
+
* @see http://api.libssh.org/stable/group__libssh__error.html
|
12
|
+
*
|
13
|
+
* @!attribute [r] code
|
14
|
+
* Error code returned from libssh.
|
15
|
+
* @return [Fixnum]
|
16
|
+
*/
|
17
|
+
|
6
18
|
void Init_libssh_error(void) {
|
7
19
|
rb_eLibSSHError =
|
8
20
|
rb_define_class_under(rb_mLibSSH, "Error", rb_eStandardError);
|
9
|
-
id_code = rb_intern("code");
|
21
|
+
id_code = rb_intern("@code");
|
10
22
|
|
11
23
|
rb_define_attr(rb_eLibSSHError, "code", 1, 0);
|
12
24
|
}
|
data/ext/libssh_ruby/key.c
CHANGED
@@ -28,6 +28,11 @@ static size_t key_memsize(RB_UNUSED_VAR(const void *arg)) {
|
|
28
28
|
return sizeof(KeyHolder);
|
29
29
|
}
|
30
30
|
|
31
|
+
/*
|
32
|
+
* @overload initialize
|
33
|
+
* Initialize an empty key.
|
34
|
+
* @see http://api.libssh.org/stable/group__libssh__pki.html ssh_key_new
|
35
|
+
*/
|
31
36
|
static VALUE m_initialize(VALUE self) {
|
32
37
|
KeyHolder *holder;
|
33
38
|
TypedData_Get_Struct(self, KeyHolder, &key_type, holder);
|
@@ -44,7 +49,6 @@ KeyHolder *libssh_ruby_key_holder(VALUE key) {
|
|
44
49
|
/*
|
45
50
|
* @overload sha1
|
46
51
|
* Return the hash in SHA1 form.
|
47
|
-
* @since 0.1.0
|
48
52
|
* @return [String]
|
49
53
|
* @see http://api.libssh.org/stable/group__libssh__pki.html
|
50
54
|
*/
|
@@ -65,7 +69,6 @@ static VALUE m_sha1(VALUE self) {
|
|
65
69
|
/*
|
66
70
|
* @overload type
|
67
71
|
* Return the type of a SSH key.
|
68
|
-
* @since 0.1.0
|
69
72
|
* @return [Fixnum]
|
70
73
|
* @see http://api.libssh.org/stable/group__libssh__pki.html ssh_key_type
|
71
74
|
*/
|
@@ -76,7 +79,6 @@ static VALUE m_type(VALUE self) {
|
|
76
79
|
/*
|
77
80
|
* @overload type_str
|
78
81
|
* Return the type of a SSH key in string format.
|
79
|
-
* @since 0.1.0
|
80
82
|
* @return [String]
|
81
83
|
* @see http://api.libssh.org/stable/group__libssh__pki.html ssh_key_type and
|
82
84
|
* ssh_key_type_to_char
|
@@ -89,7 +91,6 @@ static VALUE m_type_str(VALUE self) {
|
|
89
91
|
/*
|
90
92
|
* @overload public?
|
91
93
|
* Check if the key is a public key.
|
92
|
-
* @since 0.1.0
|
93
94
|
* @return [Boolean]
|
94
95
|
* @see http://api.libssh.org/stable/group__libssh__pki.html ssh_key_is_public
|
95
96
|
*/
|
@@ -100,7 +101,6 @@ static VALUE m_public_p(VALUE self) {
|
|
100
101
|
/*
|
101
102
|
* @overload private?
|
102
103
|
* Check if the key is a private key.
|
103
|
-
* @since 0.1.0
|
104
104
|
* @return [Boolean]
|
105
105
|
* @see http://api.libssh.org/stable/group__libssh__pki.html ssh_key_is_private
|
106
106
|
*/
|
@@ -108,6 +108,14 @@ static VALUE m_private_p(VALUE self) {
|
|
108
108
|
return ssh_key_is_private(libssh_ruby_key_holder(self)->key) ? Qtrue : Qfalse;
|
109
109
|
}
|
110
110
|
|
111
|
+
/*
|
112
|
+
* Document-class: LibSSH::Key
|
113
|
+
* Wrapper for ssh_key struct in libssh.
|
114
|
+
*
|
115
|
+
* @since 0.1.0
|
116
|
+
* @see http://api.libssh.org/stable/group__libssh__pki.html
|
117
|
+
*/
|
118
|
+
|
111
119
|
void Init_libssh_key(void) {
|
112
120
|
rb_cLibSSHKey = rb_define_class_under(rb_mLibSSH, "Key", rb_cObject);
|
113
121
|
rb_define_alloc_func(rb_cLibSSHKey, key_alloc);
|
@@ -27,30 +27,44 @@ static VALUE m_version(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self)) {
|
|
27
27
|
|
28
28
|
void Init_libssh_ruby(void) {
|
29
29
|
rb_mLibSSH = rb_define_module("LibSSH");
|
30
|
-
#define SERVER(name) \
|
31
|
-
rb_define_const(rb_mLibSSH, "SERVER_" #name, INT2FIX(SSH_SERVER_##name))
|
32
|
-
SERVER(KNOWN_OK);
|
33
|
-
SERVER(KNOWN_CHANGED);
|
34
|
-
SERVER(FOUND_OTHER);
|
35
|
-
SERVER(NOT_KNOWN);
|
36
|
-
SERVER(FILE_NOT_FOUND);
|
37
|
-
#undef SERVER
|
38
|
-
#define AUTH(name) \
|
39
|
-
rb_define_const(rb_mLibSSH, "AUTH_" #name, INT2FIX(SSH_AUTH_##name))
|
40
|
-
AUTH(DENIED);
|
41
|
-
AUTH(PARTIAL);
|
42
|
-
AUTH(SUCCESS);
|
43
|
-
AUTH(AGAIN);
|
44
|
-
#undef AUTH
|
45
30
|
|
31
|
+
/* @see Session#server_known */
|
32
|
+
rb_define_const(rb_mLibSSH, "SERVER_KNOWN_OK", INT2FIX(SSH_SERVER_KNOWN_OK));
|
33
|
+
/* @see Session#server_known */
|
34
|
+
rb_define_const(rb_mLibSSH, "SERVER_KNOWN_CHANGED",
|
35
|
+
INT2FIX(SSH_SERVER_KNOWN_CHANGED));
|
36
|
+
/* @see Session#server_known */
|
37
|
+
rb_define_const(rb_mLibSSH, "SERVER_FOUND_OTHER",
|
38
|
+
INT2FIX(SSH_SERVER_FOUND_OTHER));
|
39
|
+
/* @see Session#server_known */
|
40
|
+
rb_define_const(rb_mLibSSH, "SERVER_NOT_KNOWN",
|
41
|
+
INT2FIX(SSH_SERVER_NOT_KNOWN));
|
42
|
+
/* @see Session#server_known */
|
43
|
+
rb_define_const(rb_mLibSSH, "SERVER_FILE_NOT_FOUND",
|
44
|
+
INT2FIX(SSH_SERVER_FILE_NOT_FOUND));
|
45
|
+
|
46
|
+
/* Return value that indicates an authentication failure. */
|
47
|
+
rb_define_const(rb_mLibSSH, "AUTH_DENIED", INT2FIX(SSH_AUTH_DENIED));
|
48
|
+
/* Return value that indicates a partially authenticated. */
|
49
|
+
rb_define_const(rb_mLibSSH, "AUTH_PARTIAL", INT2FIX(SSH_AUTH_PARTIAL));
|
50
|
+
/* Return value that indicates a successful authentication. */
|
51
|
+
rb_define_const(rb_mLibSSH, "AUTH_SUCCESS", INT2FIX(SSH_AUTH_SUCCESS));
|
52
|
+
/* Return value that indicates EAGAIN in nonblocking mode. */
|
53
|
+
rb_define_const(rb_mLibSSH, "AUTH_AGAIN", INT2FIX(SSH_AUTH_AGAIN));
|
54
|
+
|
55
|
+
/* Major version defined in header. */
|
46
56
|
rb_define_const(rb_mLibSSH, "LIBSSH_VERSION_MAJOR",
|
47
57
|
INT2FIX(LIBSSH_VERSION_MAJOR));
|
58
|
+
/* Minor version defined in header. */
|
48
59
|
rb_define_const(rb_mLibSSH, "LIBSSH_VERSION_MINOR",
|
49
60
|
INT2FIX(LIBSSH_VERSION_MINOR));
|
61
|
+
/* Micro version defined in header. */
|
50
62
|
rb_define_const(rb_mLibSSH, "LIBSSH_VERSION_MICRO",
|
51
63
|
INT2FIX(LIBSSH_VERSION_MICRO));
|
64
|
+
/* Major version defined in header. */
|
52
65
|
rb_define_const(rb_mLibSSH, "LIBSSH_VERSION_INT",
|
53
66
|
INT2FIX(LIBSSH_VERSION_INT));
|
67
|
+
/* String version defined in header. */
|
54
68
|
rb_define_const(rb_mLibSSH, "LIBSSH_VERSION",
|
55
69
|
rb_str_new_cstr(SSH_STRINGIFY(LIBSSH_VERSION)));
|
56
70
|
|
data/ext/libssh_ruby/scp.c
CHANGED
@@ -54,7 +54,6 @@ static size_t scp_memsize(RB_UNUSED_VAR(const void *arg)) {
|
|
54
54
|
|
55
55
|
/* @overload initialize(session, mode, path)
|
56
56
|
* Create a new scp session.
|
57
|
-
* @since 0.2.0
|
58
57
|
* @param [Session] session The SSH session to use.
|
59
58
|
* @param [Symbol] mode +:read+ or +:write+.
|
60
59
|
* @param [String] path The directory in which write or read will be done.
|
@@ -99,7 +98,6 @@ static void *nogvl_close(void *ptr) {
|
|
99
98
|
|
100
99
|
/* @overload close
|
101
100
|
* Close the scp channel.
|
102
|
-
* @since 0.2.0
|
103
101
|
* @return [nil]
|
104
102
|
* @see http://api.libssh.org/stable/group__libssh__scp.html ssh_scp_close
|
105
103
|
*/
|
@@ -123,7 +121,6 @@ static void *nogvl_init(void *ptr) {
|
|
123
121
|
|
124
122
|
/* @overload init
|
125
123
|
* Initialize the scp channel.
|
126
|
-
* @since 0.2.0
|
127
124
|
* @yieldparam [Scp] scp self
|
128
125
|
* @return [Object] Return value of the block
|
129
126
|
* @see http://api.libssh.org/stable/group__libssh__scp.html ssh_scp_init
|
@@ -157,7 +154,6 @@ static void *nogvl_push_file(void *ptr) {
|
|
157
154
|
|
158
155
|
/* @overload push_file(filename, size, mode)
|
159
156
|
* Initialize the sending of a file to a scp in sink mode.
|
160
|
-
* @since 0.2.0
|
161
157
|
* @param [String] filename The name of the file being sent.
|
162
158
|
* @param [Integer] size Exact size in bytes of the file being sent.
|
163
159
|
* @param [Fixnum] mode The UNIX permissions for the new file.
|
@@ -194,7 +190,6 @@ static void *nogvl_write(void *ptr) {
|
|
194
190
|
|
195
191
|
/* @overload write(data)
|
196
192
|
* Write into a remote scp file.
|
197
|
-
* @since 0.2.0
|
198
193
|
* @param [String] data The data to write.
|
199
194
|
* @return [nil]
|
200
195
|
* @see http://api.libssh.org/stable/group__libssh__scp.html ssh_scp_write
|
@@ -221,7 +216,6 @@ static void *nogvl_pull_request(void *ptr) {
|
|
221
216
|
|
222
217
|
/* @overload pull_request
|
223
218
|
* Wait for a scp request.
|
224
|
-
* @since 0.2.0
|
225
219
|
* @return [Fixnum]
|
226
220
|
* REQUEST_NEWFILE: The other side is sending a file.
|
227
221
|
* REQUEST_NEWDIR: The other side is sending a directory.
|
@@ -244,7 +238,6 @@ static VALUE m_pull_request(VALUE self) {
|
|
244
238
|
|
245
239
|
/* @overload request_size
|
246
240
|
* Get the size of the file being pushed from the other party.
|
247
|
-
* @since 0.2.0
|
248
241
|
* @return [Integer] The numeric size of the file being read.
|
249
242
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
250
243
|
* ssh_scp_request_get_size64
|
@@ -260,7 +253,6 @@ static VALUE m_request_size(VALUE self) {
|
|
260
253
|
|
261
254
|
/* @overload request_filename
|
262
255
|
* Get the name of the directory or file being pushed from the other party.
|
263
|
-
* @since 0.2.0
|
264
256
|
* @return [String, nil] The filename. +nil+ on error.
|
265
257
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
266
258
|
* ssh_scp_request_get_filename
|
@@ -281,7 +273,6 @@ static VALUE m_request_filename(VALUE self) {
|
|
281
273
|
/* @overload request_permissions
|
282
274
|
* Get the permissions of the directory or file being pushed from the other
|
283
275
|
* party.
|
284
|
-
* @since 0.2.0
|
285
276
|
* @return [Fixnum] The UNIX permissions.
|
286
277
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
287
278
|
* ssh_scp_request_get_permissions
|
@@ -305,7 +296,6 @@ static void *nogvl_accept_request(void *ptr) {
|
|
305
296
|
/* @overload accept_request
|
306
297
|
* Accepts transfer of a file or creation of a directory coming from the remote
|
307
298
|
* party.
|
308
|
-
* @since 0.2.0
|
309
299
|
* @return [nil]
|
310
300
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
311
301
|
* ssh_scp_accept_request
|
@@ -336,7 +326,6 @@ static void *nogvl_deny_request(void *ptr) {
|
|
336
326
|
/* @overload deny_request
|
337
327
|
* Deny the transfer of a file or creation of a directory coming from the
|
338
328
|
* remote party.
|
339
|
-
* @since 0.2.0
|
340
329
|
* @return [nil]
|
341
330
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
342
331
|
* ssh_scp_deny_request
|
@@ -368,7 +357,6 @@ static void *nogvl_read(void *ptr) {
|
|
368
357
|
|
369
358
|
/* @overload read(size)
|
370
359
|
* Read from a remote scp file.
|
371
|
-
* @since 0.2.0
|
372
360
|
* @param [Fixnum] The size of the buffer.
|
373
361
|
* @return [String]
|
374
362
|
* @see http://api.libssh.org/stable/group__libssh__scp.html ssh_scp_read
|
@@ -396,7 +384,6 @@ static VALUE m_read(VALUE self, VALUE size) {
|
|
396
384
|
|
397
385
|
/* @overload request_warning
|
398
386
|
* Get the warning string.
|
399
|
-
* @since 0.2.0
|
400
387
|
* @return [String, nil] A warning string. +nil+ on error.
|
401
388
|
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
402
389
|
* ssh_scp_request_get_warning
|
@@ -414,18 +401,30 @@ static VALUE m_request_warning(VALUE self) {
|
|
414
401
|
}
|
415
402
|
}
|
416
403
|
|
404
|
+
/* Document-class: LibSSH::Scp
|
405
|
+
* Wrapper for ssh_scp struct in libssh.
|
406
|
+
*
|
407
|
+
* @since 0.2.0
|
408
|
+
* @see http://api.libssh.org/stable/group__libssh__scp.html
|
409
|
+
*/
|
410
|
+
|
417
411
|
void Init_libssh_scp(void) {
|
418
412
|
rb_cLibSSHScp = rb_define_class_under(rb_mLibSSH, "Scp", rb_cObject);
|
419
413
|
rb_define_alloc_func(rb_cLibSSHScp, scp_alloc);
|
420
414
|
|
415
|
+
/* @see #pull_request */
|
421
416
|
rb_define_const(rb_cLibSSHScp, "REQUEST_NEWFILE",
|
422
417
|
INT2FIX(SSH_SCP_REQUEST_NEWFILE));
|
418
|
+
/* @see #pull_request */
|
423
419
|
rb_define_const(rb_cLibSSHScp, "REQUEST_NEWDIR",
|
424
420
|
INT2FIX(SSH_SCP_REQUEST_NEWDIR));
|
421
|
+
/* @see #pull_request */
|
425
422
|
rb_define_const(rb_cLibSSHScp, "REQUEST_ENDDIR",
|
426
423
|
INT2FIX(SSH_SCP_REQUEST_ENDDIR));
|
424
|
+
/* @see #pull_request */
|
427
425
|
rb_define_const(rb_cLibSSHScp, "REQUEST_WARNING",
|
428
426
|
INT2FIX(SSH_SCP_REQUEST_WARNING));
|
427
|
+
/* @see #pull_request */
|
429
428
|
rb_define_const(rb_cLibSSHScp, "REQUEST_EOF", INT2FIX(SSH_SCP_REQUEST_EOF));
|
430
429
|
|
431
430
|
rb_define_method(rb_cLibSSHScp, "initialize", RUBY_METHOD_FUNC(m_initialize),
|
data/ext/libssh_ruby/session.c
CHANGED
@@ -49,6 +49,11 @@ static size_t session_memsize(RB_UNUSED_VAR(const void *arg)) {
|
|
49
49
|
return sizeof(SessionHolder);
|
50
50
|
}
|
51
51
|
|
52
|
+
/*
|
53
|
+
* @overload initialize
|
54
|
+
* Create a new SSH session.
|
55
|
+
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_new
|
56
|
+
*/
|
52
57
|
static VALUE m_initialize(VALUE self) {
|
53
58
|
SessionHolder *holder;
|
54
59
|
|
@@ -60,10 +65,10 @@ static VALUE m_initialize(VALUE self) {
|
|
60
65
|
/*
|
61
66
|
* @overload log_verbosity=(verbosity)
|
62
67
|
* Set the session logging verbosity.
|
63
|
-
* @since 0.1.0
|
64
68
|
* @param [Symbol] verbosity +:none+, +:warn+, +:info+, +:debug+, or +:trace+.
|
65
69
|
* @return [nil]
|
66
|
-
* @see http://api.libssh.org/stable/group__libssh__session.html
|
70
|
+
* @see http://api.libssh.org/stable/group__libssh__session.html
|
71
|
+
* ssh_options_set(SSH_OPTIONS_LOG_VERBOSITY)
|
67
72
|
*/
|
68
73
|
static VALUE m_set_log_verbosity(VALUE self, VALUE verbosity) {
|
69
74
|
ID id_verbosity;
|
@@ -104,7 +109,6 @@ static VALUE set_string_option(VALUE self, enum ssh_options_e type, VALUE str) {
|
|
104
109
|
/*
|
105
110
|
* @overload host=(host)
|
106
111
|
* Set the hostname or IP address to connect to.
|
107
|
-
* @since 0.1.0
|
108
112
|
* @param [String] host
|
109
113
|
* @return [nil]
|
110
114
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_options_set(SSH_OPTIONS_HOST)
|
@@ -289,8 +293,8 @@ static VALUE m_set_hostkeys(VALUE self, VALUE hostkeys) {
|
|
289
293
|
*/
|
290
294
|
static VALUE m_set_compression(VALUE self, VALUE compression) {
|
291
295
|
SessionHolder *holder;
|
292
|
-
char *val;
|
293
296
|
if (compression == Qtrue || compression == Qfalse) {
|
297
|
+
const char *val;
|
294
298
|
if (compression == Qtrue) {
|
295
299
|
val = "yes";
|
296
300
|
} else {
|
@@ -384,7 +388,6 @@ static VALUE m_set_gssapi_delegate_credentials(VALUE self, VALUE enable) {
|
|
384
388
|
/*
|
385
389
|
* @overload parse_config(path = nil)
|
386
390
|
* Parse the ssh_config file.
|
387
|
-
* @since 0.1.0
|
388
391
|
* @param [String, nil] Path to ssh_config. If +nil+, the default ~/.ssh/config will be used.
|
389
392
|
* @return [Boolean] Parsing the ssh_config was successful or not.
|
390
393
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_options_parse_config
|
@@ -413,7 +416,6 @@ static VALUE m_parse_config(int argc, VALUE *argv, VALUE self) {
|
|
413
416
|
/*
|
414
417
|
* @overload add_identity(path_format)
|
415
418
|
* Add the identity file name format.
|
416
|
-
* @since 0.1.0
|
417
419
|
* @param [String] path_format Format string for identity file.
|
418
420
|
* @return [nil]
|
419
421
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_options_set(SSH_OPTIONS_ADD_IDENTITY)
|
@@ -442,7 +444,6 @@ static void *nogvl_connect(void *ptr) {
|
|
442
444
|
/*
|
443
445
|
* @overload connect
|
444
446
|
* Connect to the SSH server.
|
445
|
-
* @since 0.1.0
|
446
447
|
* @return [nil]
|
447
448
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_connect
|
448
449
|
*/
|
@@ -458,10 +459,34 @@ static VALUE m_connect(VALUE self) {
|
|
458
459
|
return Qnil;
|
459
460
|
}
|
460
461
|
|
462
|
+
static void *nogvl_disconnect(void *ptr) {
|
463
|
+
struct nogvl_session_args *args = ptr;
|
464
|
+
ssh_disconnect(args->session);
|
465
|
+
args->rc = 0;
|
466
|
+
return NULL;
|
467
|
+
}
|
468
|
+
|
469
|
+
/*
|
470
|
+
* @overload disconnect
|
471
|
+
* Disconnect from a session.
|
472
|
+
* @return [nil]
|
473
|
+
* @since 0.3.0
|
474
|
+
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_disconnect
|
475
|
+
*/
|
476
|
+
static VALUE m_disconnect(VALUE self) {
|
477
|
+
SessionHolder *holder;
|
478
|
+
struct nogvl_session_args args;
|
479
|
+
|
480
|
+
TypedData_Get_Struct(self, SessionHolder, &session_type, holder);
|
481
|
+
args.session = holder->session;
|
482
|
+
rb_thread_call_without_gvl(nogvl_disconnect, &args, RUBY_UBF_IO, NULL);
|
483
|
+
|
484
|
+
return Qnil;
|
485
|
+
}
|
486
|
+
|
461
487
|
/*
|
462
488
|
* @overload server_known
|
463
489
|
* Check if the server is knonw.
|
464
|
-
* @since 0.1.0
|
465
490
|
* @return [Fixnum]
|
466
491
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_is_server_known
|
467
492
|
*/
|
@@ -475,10 +500,22 @@ static VALUE m_server_known(VALUE self) {
|
|
475
500
|
return INT2FIX(rc);
|
476
501
|
}
|
477
502
|
|
503
|
+
/*
|
504
|
+
* @overload fd
|
505
|
+
* Get the fd of a connection
|
506
|
+
* @return [Fixnum]
|
507
|
+
* @since 0.3.0
|
508
|
+
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_get_fd
|
509
|
+
*/
|
510
|
+
static VALUE m_fd(VALUE self) {
|
511
|
+
SessionHolder *holder;
|
512
|
+
TypedData_Get_Struct(self, SessionHolder, &session_type, holder);
|
513
|
+
return INT2FIX(ssh_get_fd(holder->session));
|
514
|
+
}
|
515
|
+
|
478
516
|
/*
|
479
517
|
* @overload userauth_none
|
480
518
|
* Try to authenticate through then "none" method.
|
481
|
-
* @since 0.1.0
|
482
519
|
* @return [Fixnum]
|
483
520
|
* @see http://api.libssh.org/stable/group__libssh__auth.html ssh_userauth_none
|
484
521
|
*/
|
@@ -495,7 +532,6 @@ static VALUE m_userauth_none(VALUE self) {
|
|
495
532
|
/*
|
496
533
|
* @overload userauth_list
|
497
534
|
* Get available authentication methods from the server.
|
498
|
-
* @since 0.1.0
|
499
535
|
* @return [Array<Symbol>]
|
500
536
|
* @see http://api.libssh.org/stable/group__libssh__auth.html ssh_userauth_list
|
501
537
|
*/
|
@@ -539,7 +575,6 @@ static void *nogvl_userauth_publickey_auto(void *ptr) {
|
|
539
575
|
/*
|
540
576
|
* @overload userauth_publickey_auto
|
541
577
|
* Try to automatically authenticate with public key and "none".
|
542
|
-
* @since 0.1.0
|
543
578
|
* @return [Fixnum]
|
544
579
|
* @see http://api.libssh.org/stable/group__libssh__auth.html ssh_userauth_publickey_auto
|
545
580
|
*/
|
@@ -557,7 +592,6 @@ static VALUE m_userauth_publickey_auto(VALUE self) {
|
|
557
592
|
/*
|
558
593
|
* @overload get_publickey
|
559
594
|
* Get the server public key from a session.
|
560
|
-
* @since 0.1.0
|
561
595
|
* @return [Key]
|
562
596
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_get_publickey
|
563
597
|
*/
|
@@ -576,7 +610,6 @@ static VALUE m_get_publickey(VALUE self) {
|
|
576
610
|
/*
|
577
611
|
* @overload write_knownhost
|
578
612
|
* Write the current server as known in the known_hosts file.
|
579
|
-
* @since 0.1.0
|
580
613
|
* @return [nil]
|
581
614
|
* @see http://api.libssh.org/stable/group__libssh__session.html ssh_write_knownhost
|
582
615
|
*/
|
@@ -588,6 +621,14 @@ static VALUE m_write_knownhost(VALUE self) {
|
|
588
621
|
return Qnil;
|
589
622
|
}
|
590
623
|
|
624
|
+
/*
|
625
|
+
* Document-class: LibSSH::Session
|
626
|
+
* Wrapper for ssh_session struct in libssh.
|
627
|
+
*
|
628
|
+
* @since 0.1.0
|
629
|
+
* @see http://api.libssh.org/stable/group__libssh__session.html
|
630
|
+
*/
|
631
|
+
|
591
632
|
void Init_libssh_session() {
|
592
633
|
rb_cLibSSHSession = rb_define_class_under(rb_mLibSSH, "Session", rb_cObject);
|
593
634
|
rb_define_alloc_func(rb_cLibSSHSession, session_alloc);
|
@@ -650,8 +691,12 @@ void Init_libssh_session() {
|
|
650
691
|
RUBY_METHOD_FUNC(m_add_identity), 1);
|
651
692
|
rb_define_method(rb_cLibSSHSession, "connect", RUBY_METHOD_FUNC(m_connect),
|
652
693
|
0);
|
694
|
+
rb_define_method(rb_cLibSSHSession, "disconnect",
|
695
|
+
RUBY_METHOD_FUNC(m_disconnect), 0);
|
653
696
|
rb_define_method(rb_cLibSSHSession, "server_known",
|
654
697
|
RUBY_METHOD_FUNC(m_server_known), 0);
|
698
|
+
rb_define_method(rb_cLibSSHSession, "fd", RUBY_METHOD_FUNC(m_fd), 0);
|
699
|
+
|
655
700
|
rb_define_method(rb_cLibSSHSession, "userauth_none",
|
656
701
|
RUBY_METHOD_FUNC(m_userauth_none), 0);
|
657
702
|
rb_define_method(rb_cLibSSHSession, "userauth_list",
|
data/lib/libssh/key.rb
CHANGED
data/lib/libssh/version.rb
CHANGED
@@ -1,11 +1,31 @@
|
|
1
1
|
require 'libssh'
|
2
|
+
require 'io/wait'
|
2
3
|
require 'sshkit/backends/abstract'
|
3
4
|
require 'sshkit/backends/connection_pool'
|
4
5
|
|
6
|
+
# Namespace of sshkit gem.
|
5
7
|
module SSHKit
|
8
|
+
# Namespace of sshkit gem.
|
6
9
|
module Backend
|
10
|
+
# SSHKit backend class for libssh.
|
11
|
+
# @since 0.1.0
|
12
|
+
# @see https://github.com/capistrano/sshkit
|
7
13
|
class Libssh < Abstract
|
14
|
+
# Configuration class compatible with
|
15
|
+
# {SSHKit::Backend::Netssh::Configuration}.
|
16
|
+
# @since 0.1.0
|
8
17
|
class Configuration
|
18
|
+
# @!attribute [rw] pty
|
19
|
+
# Allocate a PTY or not. Default is +false+.
|
20
|
+
# @return [Boolean]
|
21
|
+
# @!attribute [rw] connection_timeout
|
22
|
+
# Connection timeout in second. Default is +30+.
|
23
|
+
# @return [Fixnum]
|
24
|
+
# @!attribute [rw] ssh_options
|
25
|
+
# Various options for libssh. Some of them are compatible with
|
26
|
+
# {SSHKit::Backend::Netssh::Configuration#ssh_options}.
|
27
|
+
# @todo Describe supported options.
|
28
|
+
# @return [Hash]
|
9
29
|
attr_accessor :pty, :connection_timeout, :ssh_options
|
10
30
|
|
11
31
|
def initialize
|
@@ -19,7 +39,13 @@ module SSHKit
|
|
19
39
|
BUFSIZ = 16384
|
20
40
|
private_constant :BUFSIZ
|
21
41
|
|
22
|
-
#
|
42
|
+
# Upload a local file to the remote party.
|
43
|
+
# @param [String, #read] local Path to the local file to be uploaded.
|
44
|
+
# If +local+ responds to +#read+, +local+ is treated as IO-like object.
|
45
|
+
# @param [String] remote Path to the remote file.
|
46
|
+
# @since 0.2.0
|
47
|
+
# @see SSHKit::Backend::Abstract#upload!.
|
48
|
+
# @todo Make +options+ compatible with {SSHKit::Backend::Netssh#upload!}.
|
23
49
|
def upload!(local, remote, _options = {})
|
24
50
|
with_session do |session|
|
25
51
|
scp = LibSSH::Scp.new(session, :write, File.dirname(remote))
|
@@ -35,7 +61,13 @@ module SSHKit
|
|
35
61
|
end
|
36
62
|
end
|
37
63
|
|
38
|
-
#
|
64
|
+
# Download a remote file to local.
|
65
|
+
# @param [String] remote Path to the remote file to be downloaded.
|
66
|
+
# @param [String, #write] local Path to the local file.
|
67
|
+
# If +local+ responds to +#write+, +local+ is treated as IO-like object.
|
68
|
+
# @since 0.2.0
|
69
|
+
# @see SSHKit::Backend::Abstract#download!.
|
70
|
+
# @todo Make +options+ compatible with {SSHKit::Backend::Netssh#download!}.
|
39
71
|
def download!(remote, local, _options = {})
|
40
72
|
with_session do |session|
|
41
73
|
scp = LibSSH::Scp.new(session, :read, remote)
|
@@ -58,9 +90,13 @@ module SSHKit
|
|
58
90
|
@pool = SSHKit::Backend::ConnectionPool.new
|
59
91
|
|
60
92
|
class << self
|
93
|
+
# @!attribute [rw] pool
|
94
|
+
# Connection pool for libssh.
|
95
|
+
# @return [SSHKit::Backend::ConnectionPool]
|
61
96
|
attr_accessor :pool
|
62
97
|
|
63
|
-
#
|
98
|
+
# Global configuration for {SSHKit::Backend::Netssh}.
|
99
|
+
# @return [Configuration]
|
64
100
|
def config
|
65
101
|
@config ||= Configuration.new
|
66
102
|
end
|
@@ -74,24 +110,33 @@ module SSHKit
|
|
74
110
|
|
75
111
|
with_session do |session|
|
76
112
|
channel = LibSSH::Channel.new(session)
|
113
|
+
io = IO.for_fd(session.fd, autoclose: false)
|
77
114
|
channel.open_session do
|
78
115
|
if Libssh.config.pty
|
79
116
|
channel.request_pty
|
80
117
|
end
|
81
118
|
channel.request_exec(cmd.to_command)
|
82
119
|
until channel.eof?
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
120
|
+
io.wait_readable
|
121
|
+
|
122
|
+
loop do
|
123
|
+
buf = channel.read_nonblocking(BUFSIZ)
|
124
|
+
if buf && !buf.empty?
|
125
|
+
cmd.on_stdout(channel, buf)
|
126
|
+
output.log_command_data(cmd, :stdout, buf)
|
127
|
+
else
|
128
|
+
break
|
129
|
+
end
|
88
130
|
end
|
89
131
|
|
90
|
-
|
91
|
-
|
92
|
-
buf
|
93
|
-
|
94
|
-
|
132
|
+
loop do
|
133
|
+
buf = channel.read_nonblocking(BUFSIZ, true)
|
134
|
+
if buf && !buf.empty?
|
135
|
+
cmd.on_stderr(channel, buf)
|
136
|
+
output.log_command_data(cmd, :stderr, buf)
|
137
|
+
else
|
138
|
+
break
|
139
|
+
end
|
95
140
|
end
|
96
141
|
end
|
97
142
|
|
data/libssh.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'bundler'
|
25
25
|
spec.add_development_dependency 'rake'
|
26
26
|
spec.add_development_dependency 'rake-compiler'
|
27
|
+
spec.add_development_dependency 'rspec', '>= 3.0.0'
|
27
28
|
spec.add_development_dependency 'rubocop', '>= 0.36.0'
|
28
29
|
spec.add_development_dependency 'sshkit'
|
29
30
|
spec.add_development_dependency 'yard'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kohei Suzuki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.0.0
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rubocop
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,6 +118,7 @@ extra_rdoc_files: []
|
|
104
118
|
files:
|
105
119
|
- ".clang-format"
|
106
120
|
- ".gitignore"
|
121
|
+
- ".rspec"
|
107
122
|
- ".rubocop.yml"
|
108
123
|
- ".rubocop_todo.yml"
|
109
124
|
- ".travis.yml"
|