const util = require(
'util'
);
const events = require(
'events'
);
const { Client } = require(
'ssh2'
);
const fs = require(
'fs'
);
const path = require(
'path'
);
function
Connect(server, then) {
const conn =
new
Client();
conn.on(
'ready'
, () => {
then(conn);
}).on(
'error'
, (err) => {
}).on(
'end'
, () => {
}).on(
'close'
, (had_error) => {
})
.connect(server);
}
function
Shell(server, cmd, then) {
Connect(server, (conn) => {
conn.shell((err, stream) => {
if
(err) {
then(err);
}
else
{
let
buf =
''
;
stream.on(
'close'
, () => {
conn.end();
then(err, buf);
}).on(
'data'
, (data) => {
buf += data;
}).stderr.on(
'data'
, (data) => {
console.log(`stderr: ${data}`);
});
stream.end(cmd);
}
});
});
}
function
UploadFile(server, localPath, remotePath, then) {
Connect(server, (conn) => {
conn.sftp((err, sftp) => {
if
(err) {
then(err);
}
else
{
sftp.fastPut(localPath, remotePath, (err, result) => {
conn.end();
then(err, result);
});
}
});
});
}
function
DownloadFile(server, remotePath, localPath, then) {
Connect(server, (conn) => {
conn.sftp((err, sftp) => {
if
(err) {
then(err);
}
else
{
sftp.fastGet(remotePath, localPath, (err, result) => {
if
(err) {
then(err);
}
else
{
conn.end();
then(err, result);
}
});
}
});
});
}
function
GetFileOrDirList(server, remotePath, isFile, then) {
const cmd = `find ${remotePath} -type ${isFile ==
true
?
'f'
:
'd'
}\r\nexit\r\n`;
Shell(server, cmd, (err, data) => {
let
arr = [];
const remoteFile = [];
arr = data.split(
'\r\n'
);
arr.forEach((dir) => {
if
(dir.indexOf(remotePath) == 0) {
remoteFile.push(dir);
}
});
then(err, remoteFile);
});
}
function
Control() {
events.EventEmitter.call(
this
);
}
util.inherits(Control, events.EventEmitter);
const control =
new
Control();
control.on(
'donext'
, (todos, then) => {
if
(todos.length > 0) {
const func = todos.shift();
func((err, result) => {
if
(err) {
throw
err;
then(err);
}
else
{
control.emit(
'donext'
, todos, then);
}
});
}
else
{
then(
null
);
}
});
function
DownloadDir(server, remoteDir, localDir, then) {
GetFileOrDirList(server, remoteDir,
false
, (err, dirs) => {
if
(err) {
throw
err;
}
else
{
GetFileOrDirList(server, remoteDir,
true
, (err, files) => {
if
(err) {
throw
err;
}
else
{
dirs.shift();
dirs.forEach((dir) => {
const tmpDir = path.join(localDir, dir.slice(remoteDir.length + 1)).replace(/[
fs.mkdirSync(tmpDir);
});
const todoFiles = [];
files.forEach((file) => {
const tmpPath = path.join(localDir, file.slice(remoteDir.length + 1)).replace(/[
todoFiles.push((done) => {
DownloadFile(server, file, tmpPath, done);
console.log(`downloading the ${file}`);
});
});
control.emit(
'donext'
, todoFiles, then);
}
});
}
});
}
function
GetFileAndDirList(localDir, dirs, files) {
const dir = fs.readdirSync(localDir);
for
(
let
i = 0; i < dir.length; i++) {
const p = path.join(localDir, dir[i]);
const stat = fs.statSync(p);
if
(stat.isDirectory()) {
dirs.push(p);
GetFileAndDirList(p, dirs, files);
}
else
{
files.push(p);
}
}
}
function
UploadDir(server, localDir, remoteDir, then) {
const dirs = [];
const files = [];
GetFileAndDirList(localDir, dirs, files);
const deleteDir = [(done) => {
const cmd = `rm -rf ${remoteDir}* \r\nexit\r\n`;
console.log(cmd);
Shell(server, cmd, done);
}];
const todoDir = [];
dirs.forEach((dir) => {
todoDir.push((done) => {
const to = path.join(remoteDir, dir.slice(localDir.length)).replace(/[\\]/g,
'/'
);
const cmd = `mkdir -p ${to}\r\nexit\r\n`;
console.log(cmd);
Shell(server, cmd, done);
});
});
const todoFile = [];
files.forEach((file) => {
todoFile.push((done) => {
const to = path.join(remoteDir, file.slice(localDir.length)).replace(/[\\]/g,
'/'
);
console.log(`upload ${to}`);
UploadFile(server, file, to, done);
});
});
control.emit(
'donext'
, deleteDir, (err) => {
if
(err) {
throw
err;
}
else
{
control.emit(
'donext'
, todoDir, (err) => {
if
(err) {
throw
err;
}
else
{
control.emit(
'donext'
, todoFile, then);
}
});
}
});
}
exports.Shell = Shell;
exports.UploadFile = UploadFile;
exports.DownloadFile = DownloadFile;
exports.GetFileOrDirList = GetFileOrDirList;
exports.DownloadDir = DownloadDir;
exports.UploadDir = UploadDir;