mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
316 lines
10 KiB
JavaScript
316 lines
10 KiB
JavaScript
/* module make possible connectoin thru socket.io on a server */
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
var main = global.cloudcmd.main,
|
|
SRVDIR = main.SRVDIR,
|
|
|
|
io = main.require('socket.io'),
|
|
update = main.srvrequire('update'),
|
|
exec = main.child_process.exec,
|
|
Util = main.util,
|
|
mainpackage = main.mainpackage,
|
|
equalPart = Util.isContainStrAtBegin,
|
|
CLOUDCMD = mainpackage.name,
|
|
ClientFuncs = [],
|
|
OnMessageFuncs = [],
|
|
INFO_LOG_LEVEL = 2,
|
|
WIN32 = main.WIN32,
|
|
HELP = {
|
|
stdout : CLOUDCMD + ' exit \n' +
|
|
CLOUDCMD + ' update \n',
|
|
},
|
|
|
|
/* windows commands thet require
|
|
* unicode charset on locales
|
|
* different then English
|
|
*/
|
|
Win32Commands = ['ASSOC', 'AT', 'ATTRIB', 'BREAK', 'CACLS', 'CALL',
|
|
'CD', 'CHCP', 'CHDIR', 'CHKDSK', 'CHKNTFS', 'CLS',
|
|
'CMD', 'COLOR', 'COMP', 'COMPACT', 'CONVERT', 'COPY',
|
|
'DATE', 'DEL', 'DIR', 'DISKCOMP', 'DISKCOPY', 'DOSKEY',
|
|
'ECHO', 'ENDLOCAL', 'ERASE', 'EXIT', 'FC', 'FIND',
|
|
'FINDSTR', 'FOR', 'FORMAT', 'FTYPE', 'GOTO', 'GRAFTABL',
|
|
'HELP', 'IF', 'LABEL', 'MD', 'MKDIR', 'MODE', 'MORE',
|
|
'MOVE', 'PATH', 'PAUSE', 'POPD', 'PRINT', 'PROMPT',
|
|
'PUSHD', 'RD', 'RECOVER', 'REM', 'REN', 'RENAME',
|
|
'REPLACE', 'RMDIR', 'SET', 'SETLOCAL', 'SHIFT', 'SORT',
|
|
'START', 'SUBST', 'TIME', 'TITLE', 'TREE', 'TYPE',
|
|
'VER', 'VERIFY', 'VOL', 'XCOPY'];
|
|
|
|
/**
|
|
* function listen on servers port
|
|
* @pServer {Object} started server object
|
|
*/
|
|
exports.listen = function(pServer) {
|
|
var lRet, lConnNum, lMsg, lConn_func;
|
|
|
|
if (io) {
|
|
io = io.listen(pServer);
|
|
lConnNum = 0;
|
|
|
|
io.set('log level', INFO_LOG_LEVEL);
|
|
|
|
/*
|
|
* on Win7 application is crashing,
|
|
* when options below is used.
|
|
*
|
|
* https://github.com/LearnBoost/socket.io/issues/1314
|
|
*
|
|
*/
|
|
if (!WIN32) {
|
|
io.enable('browser client minification');
|
|
io.enable('browser client gzip');
|
|
io.enable('browser client etag');
|
|
}
|
|
|
|
io.set('transports', [
|
|
'websocket',
|
|
'htmlfile',
|
|
'xhr-polling',
|
|
'jsonp-polling'
|
|
]);
|
|
|
|
lRet = io.sockets.on('connection', function (socket) {
|
|
++lConnNum;
|
|
|
|
if(!OnMessageFuncs[lConnNum]) {
|
|
lMsg = log(lConnNum, 'connected\n');
|
|
|
|
jsonSend(socket, {
|
|
stdout : lMsg
|
|
});
|
|
|
|
OnMessageFuncs[lConnNum] = onMessage(lConnNum, socket);
|
|
lConn_func = OnMessageFuncs[lConnNum];
|
|
|
|
socket.on('message', lConn_func);
|
|
socket.on('disconnect', Util.call(disconnect, lConnNum));
|
|
} else {
|
|
lMsg = log(lConnNum, ' in use. Reconnecting...');
|
|
|
|
jsonSend(socket, {
|
|
stdout: lMsg
|
|
});
|
|
|
|
socket.disconnect();
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
return lRet;
|
|
};
|
|
|
|
function disconnect(pParams) {
|
|
var lConnNum, lRet = Util.checkObj(pParams, ['params']);
|
|
|
|
if(lRet) {
|
|
lConnNum = pParams.params;
|
|
OnMessageFuncs [lConnNum] =
|
|
ClientFuncs [lConnNum] = null;
|
|
|
|
log(lConnNum, 'disconnected');
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* function gets onMessage function
|
|
* that execute needed command
|
|
*
|
|
* @param pConnNum, pSocket
|
|
*/
|
|
function onMessage(pConnNum, pSocket) {
|
|
return function(pCommand) {
|
|
var lMsg, lWinCommand, lExec_func, firstChar,
|
|
connName,
|
|
lError, lRet, lExecSymbols, isContain;
|
|
|
|
connName = '#' + pConnNum + ': ';
|
|
Util.log(connName + pCommand);
|
|
|
|
if (equalPart(pCommand, CLOUDCMD))
|
|
lRet = onCloudCmd(pCommand);
|
|
else if (equalPart(pCommand, 'cd '))
|
|
lRet = onCD(pCommand);
|
|
|
|
if (lRet)
|
|
jsonSend(pSocket, lRet);
|
|
else {
|
|
/* if we on windows and command is build in
|
|
* change code page to unicode becouse
|
|
* windows use unicode on non English versions
|
|
*/
|
|
if(WIN32) {
|
|
lWinCommand = pCommand.toUpperCase();
|
|
|
|
if (Win32Commands.indexOf(lWinCommand) >= 0)
|
|
pCommand = 'chcp 65001 |' + pCommand;
|
|
}
|
|
|
|
if(!ClientFuncs[pConnNum])
|
|
ClientFuncs[pConnNum] = getExec(function(json, pError, pStderr) {
|
|
log(pConnNum, pError, 'error');
|
|
log(pConnNum, pStderr, 'stderror');
|
|
|
|
jsonSend(pSocket, json);
|
|
});
|
|
|
|
lExec_func = ClientFuncs[pConnNum];
|
|
lExecSymbols = ['*', '&', '{', '}', '|', '\'', '"'];
|
|
isContain = Util.isContainStr(pCommand, lExecSymbols);
|
|
firstChar = pCommand[0];
|
|
|
|
if (firstChar === '#') {
|
|
pCommand = pCommand.slice(1);
|
|
pCommand = connName + pCommand;
|
|
pCommand = Util.addNewLine(pCommand);
|
|
|
|
lMsg = Util.stringifyJSON({
|
|
stdout: pCommand
|
|
});
|
|
|
|
io.sockets.emit('message', lMsg);
|
|
} else if (firstChar === ' ' || isContain)
|
|
exec(pCommand, lExec_func);
|
|
else
|
|
getSpawn(pCommand, function(json) {
|
|
jsonSend(pSocket, json);
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
* function send result of command to client
|
|
* @param pSocket
|
|
*/
|
|
function getExec(callback) {
|
|
return function(pError, pStdout, pStderr) {
|
|
var lErrorStr, lExecStr, lExec,
|
|
lError = pStderr || pError;
|
|
|
|
if (lError) {
|
|
if (Util.isString(lError))
|
|
lErrorStr = lError;
|
|
else
|
|
lErrorStr = lError.toString();
|
|
|
|
lErrorStr = Util.addNewLine(lErrorStr);
|
|
}
|
|
|
|
lExec = {
|
|
stdout : pStdout,
|
|
stderr : lErrorStr || lError
|
|
};
|
|
|
|
Util.exec(callback, lExec, pError, pStderr);
|
|
};
|
|
}
|
|
|
|
function getSpawn(pCommand, callback) {
|
|
var send, cmd, spawn,
|
|
args = pCommand.split(' ');
|
|
|
|
pCommand = args.shift();
|
|
|
|
spawn = main.child_process.spawn;
|
|
cmd = spawn(pCommand, args);
|
|
send = function(data, isError) {
|
|
var lExec = {},
|
|
msg = data.toString();
|
|
|
|
if (isError)
|
|
lExec.stderr = msg;
|
|
else
|
|
lExec.stdout = msg;
|
|
|
|
Util.exec(callback, lExec);
|
|
};
|
|
|
|
cmd.stdout.on('data', send);
|
|
|
|
cmd.stderr.on('data', function(data) {
|
|
send(data, true);
|
|
});
|
|
|
|
cmd.on('error', Util.retFalse);
|
|
}
|
|
|
|
function onCloudCmd(pCommand) {
|
|
var lRet;
|
|
|
|
pCommand = Util.removeStr(pCommand, CLOUDCMD);
|
|
|
|
if (!equalPart(pCommand, ' '))
|
|
lRet = HELP;
|
|
else {
|
|
pCommand = Util.removeStr(pCommand, ' ');
|
|
|
|
if (equalPart(pCommand, 'update') && update) {
|
|
update.get();
|
|
lRet = {
|
|
stdout: Util.addNewLine('update: ok')
|
|
};
|
|
|
|
}
|
|
|
|
if(Util.strCmp(pCommand, 'exit'))
|
|
process.exit();
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
function onCD(pCommand) {
|
|
var lRet, lDir, lHome, lError,
|
|
lMsg = '';
|
|
|
|
lDir = Util.removeStr(pCommand, 'cd ');
|
|
lHome = process.env.HOME;
|
|
|
|
if (Util.isContainStr(lDir, '~'))
|
|
lDir = Util.replaceStr(lDir, '~', lHome);
|
|
|
|
lError = Util.tryCatchLog(function() {
|
|
process.chdir(lDir);
|
|
});
|
|
|
|
if (lError) {
|
|
lError = Util.stringifyJSON(lError);
|
|
lMsg = lError;
|
|
}
|
|
|
|
lRet = {
|
|
stderr: lMsg
|
|
};
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
function log(pConnNum, pStr, pType) {
|
|
var lRet,
|
|
lType = ' ';
|
|
|
|
if (pStr) {
|
|
|
|
if (pType)
|
|
lType += pType + ':';
|
|
|
|
lRet = 'client #' + pConnNum + lType + pStr;
|
|
|
|
Util.log(lRet);
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
function jsonSend(socket, json) {
|
|
var msg = Util.stringifyJSON(json);
|
|
socket.send(msg);
|
|
}
|
|
})();
|