using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Google.Protobuf.WellKnownTypes; using Google.Protobuf; namespace SMCenter { public class CmdProcInfo { public ResResultCode AckResultCode; public string AckMessage; public string AckAddInfo; public long SendCmdToHostTime; public SMProcApp SMApp; } public class CmdInfo { public int SeqNum; public long SessionId; public string ConsoleInput; // console原始输入 public string CMD; public List CmdParams; public long CreateTime; public uint HttpId; // 匹配当前指令的proc public Dictionary m_procs; public CmdInfo() { CmdParams = new List(); m_procs = new Dictionary(); } } public class ConsoleCmd : Singleton { private BaseCmdProc m_cmdProc; //用于进入指定的Agent的shell或CMD 命令行 public string m_nowCmdModel = "Console"; public List m_EnterAgent; public void ProcessCmd(long sessionId, string command,uint Httpid) { if (m_nowCmdModel != "Console") //这里是进入了Agent的Shell { if (command.ToLower() == "exit" || command.ToLower() == "quit") { ExitAgentShell(sessionId, command); return; } if (m_EnterAgent == null) { ExitAgentShell(sessionId, command); return; } ProcessAgentShellCmd(sessionId, command, Httpid); } else { ProcessConsoleCmd(sessionId, command, Httpid); } } private void ExitAgentShell(long sessionId, string command) { m_nowCmdModel = "Console"; m_EnterAgent = null; var res = new SMConsoleCommandRes(); res.Command = command; res.Message = "#exit"; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res); } private void ProcessAgentShellCmd(long sessionId, string command,uint Httpid) { if (m_cmdProc != null) { var res = new SMConsoleCommandRes(); res.Command = command; res.Message = string.Format("{0} {1} task already running! please wait and try again...", m_nowCmdModel , m_cmdProc.m_nowCmd.CMD); SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res); return; } if (m_EnterAgent.Count > 1) { command = "shell " + "*.*.* " + command; } else { Dictionary AllProc = new Dictionary(); ; SMProcAppMgr.Instance.GetAllMatchingProc("*.*.*", AllProc); CmdProcInfo getProc = AllProc.FirstOrDefault(p => p.Value.SMApp.HostName == m_EnterAgent[0].HostName).Value; if (getProc == null || getProc.SMApp.HostName != m_EnterAgent[0].HostName) { ExitAgentShell(sessionId, command); } command = "shell " + getProc.SMApp.ServerIDStr + " " + command; } ProcessConsoleCmd(sessionId, command, Httpid); } private void ProcessConsoleCmd(long sessionId, string command, uint httpid ) { CmdInfo cmdInfo = CmdProcFactory.GetCmdInfo(command); if (cmdInfo == null) { var res = new SMConsoleCommandRes(); res.Command = command; res.Message = "invalid cmd command..."; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res, httpid); return; } cmdInfo.HttpId = httpid; // 最后1个参数是\tab时, 补全cmd后发回console if (cmdInfo.CmdParams[cmdInfo.CmdParams.Count - 1] == "#tab") { BaseCmdProc tempCmd = new DontTransAgentCmdProc(); tempCmd.InitCmd(cmdInfo); if (tempCmd.DoCmd(out string str) != 0) { var res = new SMConsoleCommandRes(); res.Command = command; res.Message = str; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res, httpid); } return; } // m_cmdProc是执行中的命令, cancel命令可以同步执行 if (m_cmdProc != null) { CheckCancelCommand(sessionId, cmdInfo, command, httpid); return; } var cmdProc = CmdProcFactory.GetCmdProc(cmdInfo); if (cmdProc == null) { TraceLog.Error("ConsoleCmd.ProcessConsoleCmd CMD {0} no proc", command); var res = new SMConsoleCommandRes(); res.Command = command; res.Message = "invalid cmd command..."; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res, httpid); return; } m_cmdProc = cmdProc; m_cmdProc.m_nowCmd.SessionId = sessionId; string msg; if (m_cmdProc.DoCmd(out msg) != 0) { var res = new SMConsoleCommandRes(); res.Command = command; res.Message = msg; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res, httpid); } } private void CheckCancelCommand(long sessionId, CmdInfo cmdInfo, string command, uint httpid) { string msg; var res = new SMConsoleCommandRes(); if (cmdInfo.CMD == "cancelpush") { FileTransCmdProc filetrans = (FileTransCmdProc)m_cmdProc; filetrans.CancelPush(); return; } if (cmdInfo.CMD == "cancelshell") { ShellCmdProc shellcmd = (ShellCmdProc)m_cmdProc; if (shellcmd.DoCancel(out msg) != 0) { res.Command = command; res.Message = msg; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res, httpid); } return; } if (cmdInfo.CMD == "cancelpull") { FilePullCmdProc pullcmd = (FilePullCmdProc)m_cmdProc; pullcmd.CancelPull(); return; } string str; if (cmdInfo.CMD == "killcmd") { str = string.Format("\tlast cmd [{0}] not finish, kill now...", m_cmdProc.m_nowCmd.ConsoleInput); } else { str = string.Format("\tlast cmd [{0}] not finish, please wait and try again...", m_cmdProc.m_nowCmd.ConsoleInput); } foreach (CmdProcInfo proc in m_cmdProc.m_nowCmd.m_procs.Values) { string time = "0"; if (proc.SendCmdToHostTime > 0) { time = AppTime.ConvertUnixTimeToDateTime(proc.SendCmdToHostTime * 1000).ToString("yyyy-MM-dd HH:mm:ss"); } str += string.Format("\n\t{0}\t{1} (INFO:{2}) \t{3}", proc.SMApp.ServerIDStr, proc.AckResultCode, proc.AckMessage, time); } // 特殊指令, 清空cmd, 防止控制台被卡住, 谨慎使用 if (cmdInfo.CMD == "killcmd") { m_cmdProc = null; } res.Command = command; res.Message = str; SMCenterNet.Instance.SendMsg(sessionId, SMMsgID.ConsoleCommandRes, res,httpid); } public void Update(long tMs) { if (m_cmdProc == null) { return; } if (m_cmdProc.UpdateCmd(tMs) <= 0) { m_cmdProc = null; } } public void OnAgentDoCommandRes(ClientInfo client, SMAgentDoCommandRes res) { if (m_cmdProc == null) { TraceLog.Error("ConsoleCmd.OnAgentDoCommandRes CMD {0} ServerId {1}, cmdProc is null, skip" , res.Command, res.ServerId); return; } m_cmdProc.OnAgentDoCommandRes(client, res); } public CmdInfo GetCurCmdInfo() { return m_cmdProc == null ? null : m_cmdProc.m_nowCmd; } } }