public Stream Open(string path, OpenMode mode) { var cMount = _clientMounts.FirstOrDefault(x => x.Path.StartsWith(path)); if (cMount != null) { string mPath = path.Remove(0, cMount.Path.Length); if (!cMount.GetFiles().Contains(mPath)) { if (mode == OpenMode.OpenOrCreate) { throw new IOException("Read-only filesystem."); } else { throw new IOException("File not found."); } } return(new MemoryStream(cMount.GetFileContents(mPath))); } var err = new Exception("Unknown error."); var ret = -1; _server.SendMessage(ServerMessageType.FS_OPENSTREAM, writePathData(path, null).Concat(BitConverter.GetBytes((int)mode)).ToArray(), (res, reader) => { if (res == ServerResponseType.REQ_SUCCESS) { ret = reader.ReadInt32(); return; } if (res == ServerResponseType.REQ_ERROR && reader.BaseStream.Length > 0) { err = new Exception(reader.ReadString()); return; } }).Wait(); if (ret < 0) { throw err; } return(_rstreams.Open(ret)); }
public void Run(ConsoleContext console, Dictionary <string, object> arguments) { int id = -1; Task.WaitAll(man.SendMessage(ServerMessageType.STREAM_TEST, new byte[] { }, (resp, read) => id = read.ReadInt32())); console.WriteLine("That's the message that I sent. (DAVID BOWIE IS NOT MC RIDE)"); using (var fobj = rstreams.Open(id)) { console.WriteLine("Remote Stream opened."); console.WriteLine($"CanRead = {fobj.CanRead}"); console.WriteLine($"CanWrite = {fobj.CanWrite}"); console.WriteLine($"CanSeek = {fobj.CanSeek}"); console.WriteLine($"Buffered = {fobj is BufferedStream}"); console.WriteLine($"Length = {fobj.Length}"); using (var read = new BinaryReader(fobj, Encoding.UTF8, true)) { console.WriteLine(Encoding.UTF8.GetString(read.ReadBytes((int)fobj.Length))); fobj.Seek(0, SeekOrigin.Begin); console.WriteLine(Encoding.UTF8.GetString(read.ReadBytes((int)fobj.Length).Reverse().ToArray())); } } }
/// <summary> /// Runs a command with the given console context. /// </summary> /// <param name="command">The command (including raw arguments) to parse and run.</param> /// <param name="console">The <see cref="ConsoleContext"/> to run the command in.</param> /// <returns>Whether the command was actually found.</returns> public bool RunCommand(string command, ConsoleContext console) { //First we need to parse the command string into something we can actually use as a query. var query = ParseCommand(command); //If query is null, don't try to run a command. There was no command. if (query == null) { return(false); } //If we get to this stage, the query is OK. Let's find a local command. var local = _localCommands.FirstOrDefault(x => x.Name == query.Name); //If this is null we'll send it off to the server. Well, I haven't implemented the server yet so we'll just return false. if (local == null) { if (!_server.Connected) { return(false); } using (var memstr = new MemoryStream()) { using (var writer = new BinaryWriter(memstr, Encoding.UTF8)) { writer.Write(query.Name); writer.Write(query.ArgumentTokens.Length); foreach (var token in query.ArgumentTokens) { writer.Write(token); } writer.Flush(); ManualResetEvent commandDone = new ManualResetEvent(false); Action <ServerBroadcastType, BinaryReader> terminalOutput = (req, r) => { if (req != ServerBroadcastType.TerminalOutput) { return; } int count = r.ReadInt32(); byte[] data = r.ReadBytes(count); string str = Encoding.UTF8.GetString(data); console.Write(str); if (str.ToCharArray().Contains((char)0x02)) { commandDone.Set(); } }; _server.BroadcastReceived += terminalOutput; Stream remoteSlave = null; Thread t = null; _server.SendMessage(ServerMessageType.TRM_INVOKE, memstr.ToArray(), (res, reader) => { if (res != ServerResponseType.REQ_SUCCESS) { console.WriteLine("Unexpected, unknown error."); return; } int remoteSlaveId = reader.ReadInt32(); remoteSlave = _remoteStreams.Open(remoteSlaveId); t = new Thread(() => { while (true) { try { char input = (char)console.StandardInput.BaseStream.ReadByte(); remoteSlave.WriteByte((byte)input); } catch (TerminationRequestException) { remoteSlave.WriteByte(0x02); remoteSlave.WriteByte((byte)'\n'); } } }); t.Start(); }).Wait(); commandDone.WaitOne(); CommandSucceeded?.Invoke(query.Name); _server.BroadcastReceived -= terminalOutput; t.Abort(); remoteSlave.Close(); } } return(true); } else { //So we have a command query, a console context, and a command. //What do we need next? Well, we need our argument dictionary. //We can use Docopt.Net and the ITerminalCommand.Usages property to get that. //First let's create a Dictionary<string, object> to store our arguments. var argumentStore = new Dictionary <string, object>(); //Next, we retrieve the usage string from the command. //The engine creates usage strings during initialization. var usage = _usages[local.Name]; //Then we pass it off to Docopt. var docoptArgs = new DocoptNet.Docopt().Apply(usage, query.ArgumentTokens, true, local.Name, false, false); //Now we just CTRL+C and CTRL+V from the debug console. foreach (var arg in docoptArgs) { if (arg.Value != null) { argumentStore.Add(arg.Key, arg.Value.Value); } else { argumentStore.Add(arg.Key, null); } } //Now we run the command - check for errors! try { local.Run(console, argumentStore); CommandSucceeded?.Invoke(query.Name); } catch (TerminationRequestException) { console.WriteLine("Killed."); return(true); } return(true); } }