Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ You can find more examples in the `examples` directory of this repository.

* **setNoDelay**([< _boolean_ >noDelay]) - _Client_ - Calls [`setNoDelay()`](https://nodejs.org/docs/latest/api/net.html#socketsetnodelaynodelay) on the underlying socket. Disabling Nagle's algorithm improves latency at the expense of lower throughput.

* **sftp**(< _function_ >callback) - _(void)_ - Starts an SFTP session. `callback` has 2 parameters: < _Error_ >err, < _SFTP_ >sftp. For methods available on `sftp`, see the [`SFTP` client documentation](https://github.com/mscdex/ssh2/blob/master/SFTP.md).
* **sftp**([< _object_ >env, ]< _function_ >callback) - _(void)_ - Starts an SFTP session. `env` is an environment to use when executing `sftp` methods. `callback` has 2 parameters: < _Error_ >err, < _SFTP_ >sftp. For methods available on `sftp`, see the [`SFTP` client documentation](https://github.com/mscdex/ssh2/blob/master/SFTP.md).

* **shell**([[< _mixed_ >window,] < _object_ >options]< _function_ >callback) - _(void)_ - Starts an interactive shell session on the server, with an optional `window` object containing pseudo-tty settings (see 'Pseudo-TTY settings'). If `window === false`, then no pseudo-tty is allocated. `options` supports the `x11` and `env` options as described in `exec()`. `callback` has 2 parameters: < _Error_ >err, < _Channel_ >stream.

Expand Down
41 changes: 35 additions & 6 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1552,17 +1552,22 @@ class Client extends EventEmitter {
return this;
}

sftp(cb) {
sftp(env, cb) {
if (!this._sock || !isWritable(this._sock))
throw new Error('Not connected');

if (typeof env === 'function') {
cb = env;
env = undefined;
}

openChannel(this, 'sftp', (err, sftp) => {
if (err) {
cb(err);
return;
}

reqSubsystem(sftp, 'sftp', (err, sftp_) => {
const reqSubsystemCb = (err, sftp_) => {
if (err) {
cb(err);
return;
Expand Down Expand Up @@ -1608,7 +1613,14 @@ class Client extends EventEmitter {
.on('close', onExit);

sftp._init();
});
};

if (typeof env === 'object' && env !== null) {
reqEnv(sftp, env, () => reqSubsystem(sftp, 'sftp', reqSubsystemCb));
Comment thread
mscdex marked this conversation as resolved.
Outdated

} else {
reqSubsystem(sftp, 'sftp', reqSubsystemCb);
}
});

return this;
Expand Down Expand Up @@ -1842,16 +1854,33 @@ function reqExec(chan, cmd, opts, cb) {
chan._client._protocol.exec(chan.outgoing.id, cmd, true);
}

function reqEnv(chan, env) {
if (chan.outgoing.state !== 'open')
function reqEnv(chan, env, cb) {
const wantReply = (typeof cb === 'function');

if (chan.outgoing.state !== 'open') {
if (wantReply)
cb(new Error('Channel is not open'));
return;
}

if (wantReply) {
chan._callbacks.push((had_err) => {
if (had_err) {
cb(had_err !== true
? had_err
: new Error('Unable to set env'));
Comment thread
di-ov marked this conversation as resolved.
Outdated
return;
}
cb();
});
}

const keys = Object.keys(env || {});

for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
const val = env[key];
chan._client._protocol.env(chan.outgoing.id, key, val, false);
chan._client._protocol.env(chan.outgoing.id, key, val, wantReply);
}
}

Expand Down