libssh 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|