mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
282 lines
8.2 KiB
JavaScript
282 lines
8.2 KiB
JavaScript
(function() {
|
||
'use strict';
|
||
|
||
var DIR = './',
|
||
DIR_LIB = DIR + '../',
|
||
|
||
path = require('path'),
|
||
child_process = require('child_process'),
|
||
|
||
exec = child_process.exec,
|
||
|
||
WIN = process.platform === 'win32',
|
||
spawn = child_process.spawn,
|
||
|
||
Util = require(DIR_LIB + 'util'),
|
||
CloudFunc = require(DIR_LIB + 'cloudfunc'),
|
||
|
||
addNewLine = CloudFunc.addNewLine,
|
||
|
||
find = require(DIR + 'find'),
|
||
win = require(DIR + 'win');
|
||
|
||
Util.exec.try(function() {
|
||
find = require('glob');
|
||
});
|
||
|
||
module.exports = function(command, options, callback) {
|
||
Util.checkArgs(arguments, ['command', 'callback']);
|
||
|
||
if (!callback) {
|
||
callback = options;
|
||
|
||
options = {
|
||
cwd: process.cwd()
|
||
};
|
||
}
|
||
|
||
onMessage(command, options, callback);
|
||
};
|
||
|
||
function onMessage(command, options, callback) {
|
||
var funcExec, firstChar,
|
||
connName, ret,
|
||
dir = options.cwd,
|
||
isVolume = win.isChangeVolume(command),
|
||
isCD = /^cd ?/.test(command),
|
||
isCDWin = /^cd ?/i.test(command),
|
||
|
||
symbolsExec = ['*', '&', '{', '}', '|', '\'', '"', ';'],
|
||
isSymbol = Util.isContainStr(command, symbolsExec);
|
||
|
||
Util.checkArgs(arguments, ['connNum', 'callback', 'command']);
|
||
|
||
if (isCD || isCDWin && WIN || isVolume) {
|
||
ret = true;
|
||
|
||
onCD(command, dir, function(error, json) {
|
||
var path;
|
||
|
||
if (!error && json.path) {
|
||
path = json.path;
|
||
options.cwd = path;
|
||
}
|
||
|
||
callback(error, json);
|
||
});
|
||
}
|
||
|
||
if (!ret) {
|
||
if (WIN)
|
||
command = 'cmd /C ' + command;
|
||
|
||
funcExec = setExec.bind(null, callback);
|
||
|
||
firstChar = command[0];
|
||
|
||
if (firstChar === '#') {
|
||
command = command.slice(1);
|
||
command = connName + command;
|
||
command = addNewLine(command);
|
||
|
||
Util.exec(callback, {
|
||
stdout: command
|
||
}, true);
|
||
} else if (firstChar === ' ' || isSymbol)
|
||
exec(command, options, funcExec);
|
||
else
|
||
setSpawn(command, options, callback);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* function send result of command to client
|
||
* @param callback
|
||
*/
|
||
function setExec(callback, error, stdout, stderr) {
|
||
var json,
|
||
errorStr = '';
|
||
|
||
if (stderr)
|
||
errorStr = stderr;
|
||
else if (error)
|
||
errorStr = error.message;
|
||
|
||
json = {
|
||
stdout : stdout,
|
||
stderr : errorStr
|
||
};
|
||
|
||
callback(error, json);
|
||
}
|
||
|
||
function setSpawn(сommand, options, callback) {
|
||
var cmd, error,
|
||
isSended = false,
|
||
args = сommand.split(' '),
|
||
func = function(error, stdout, stderr) {
|
||
var errorStr = '';
|
||
|
||
isSended = true;
|
||
|
||
if (error)
|
||
errorStr = error.message;
|
||
else if (stderr)
|
||
errorStr = stderr;
|
||
|
||
errorStr = addNewLine(errorStr);
|
||
|
||
callback(error, {
|
||
stderr: errorStr,
|
||
stdout: stdout
|
||
});
|
||
};
|
||
|
||
Util.checkArgs(arguments, ['command', 'callback']);
|
||
|
||
if (!callback) {
|
||
callback = options;
|
||
options = null;
|
||
}
|
||
|
||
сommand = args.shift();
|
||
|
||
error = Util.exec.tryLog(function() {
|
||
cmd = spawn(сommand, args, options);
|
||
});
|
||
|
||
if (error) {
|
||
func(error);
|
||
} else {
|
||
cmd.stderr.setEncoding('utf8');
|
||
cmd.stdout.setEncoding('utf8');
|
||
|
||
cmd.stdout.on('data', function(data) {
|
||
func(null, data);
|
||
});
|
||
|
||
cmd.stderr.on('data', function(error) {
|
||
func(null, null, error);
|
||
});
|
||
|
||
cmd.on('error', function(error) {
|
||
func(error);
|
||
});
|
||
|
||
cmd.on('close', function() {
|
||
cmd = null;
|
||
|
||
if (!isSended)
|
||
func();
|
||
});
|
||
}
|
||
}
|
||
|
||
function onCD(command, currDir, callback) {
|
||
var CD = 'cd ',
|
||
HOME = process.env.HOME,
|
||
|
||
isChangeVolume = win.isChangeVolume(command),
|
||
isVolume = win.isVolume(command),
|
||
paramDir = Util.rmStrOnce(command, [CD, 'cd']),
|
||
|
||
regExpHome = new RegExp('^~'),
|
||
regExpRoot = new RegExp('^[/\\\\]'),
|
||
|
||
isWildCard = Util.isContainStr(paramDir, ['*', '?']),
|
||
isHome = regExpHome.test(paramDir) && !WIN,
|
||
isRoot = regExpRoot.test(paramDir),
|
||
|
||
onExec = function (error, stdout, stderr) {
|
||
var path = paramDir,
|
||
errorStr = '';
|
||
|
||
if (stderr) {
|
||
errorStr = stderr;
|
||
} else if (error) {
|
||
errorStr = error.message;
|
||
path = '';
|
||
}
|
||
|
||
callback(error, {
|
||
stderr : addNewLine(errorStr),
|
||
stdout : stdout,
|
||
path : path
|
||
});
|
||
};
|
||
|
||
if (isHome) {
|
||
command = command.replace('~', HOME);
|
||
paramDir = paramDir.replace('~', HOME);
|
||
}
|
||
|
||
if (!paramDir && !WIN)
|
||
paramDir = '.';
|
||
|
||
if (!isChangeVolume || isVolume) {
|
||
paramDir = getFirstWord(paramDir);
|
||
paramDir = path.normalize(paramDir);
|
||
|
||
command = Util.rmStrOnce(command, [
|
||
CD,
|
||
paramDir,
|
||
'\'' + paramDir + '\'',
|
||
'"' + paramDir + '"',
|
||
]);
|
||
|
||
if (!isHome && !isRoot)
|
||
paramDir = path.join(currDir, paramDir);
|
||
|
||
if (isWildCard)
|
||
command = CD + paramDir + ' ' + command;
|
||
else
|
||
command = CD + '"' + paramDir + '" ' + command;
|
||
}
|
||
|
||
if (!isWildCard)
|
||
exec(command, {cwd: paramDir}, onExec);
|
||
else
|
||
find(paramDir, function(error, dirs) {
|
||
var dir;
|
||
|
||
if (!error)
|
||
dir = dirs[0];
|
||
|
||
paramDir = dir;
|
||
exec(command, {cwd: dir}, onExec);
|
||
});
|
||
}
|
||
|
||
function getFirstWord(str) {
|
||
var word, result,
|
||
regStrEnd = getRegStrEnd(),
|
||
regStr = '^(.*?)',
|
||
regStrQuotes = '^"(.*)"',
|
||
regExp = new RegExp(regStr + regStrEnd),
|
||
regExpQuotes = new RegExp(regStrQuotes + regStrEnd + '?'),
|
||
is = Util.isString(str);
|
||
|
||
if (is) {
|
||
result = str.match(regExpQuotes);
|
||
|
||
if (result) {
|
||
word = result[1];
|
||
} else {
|
||
result = str.match(regExp);
|
||
word = result && result[1];
|
||
}
|
||
|
||
if (!word)
|
||
word = str;
|
||
}
|
||
|
||
return word;
|
||
}
|
||
|
||
function getRegStrEnd() {
|
||
var regStrEnd = '(\\s|\\;|&&|\\|\\|)';
|
||
|
||
return regStrEnd;
|
||
}
|
||
|
||
})();
|