// See https://aka.ms/new-console-template for more information using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using ArcaneLibs; using LibMatrix.Helpers; using LibMatrix.Homeservers; using LibMatrix.RoomTypes; using MatrixLogFwd; using Microsoft.VisualBasic.CompilerServices; Console.WriteLine("Hello, World!"); var cfgPath = Util.ExpandPath($"~/.config/MatrixLogFwd/config.json"); var cfg = JsonSerializer.Deserialize(System.IO.File.ReadAllText(cfgPath)); var hs = new AuthenticatedHomeserverGeneric(cfg.HomeserverBaseUrl, new(){Client = cfg.HomeserverBaseUrl}, null, cfg.AccessToken); await hs.Initialise(); Console.WriteLine(hs); string mode = "lines"; int chunkSize = 1000; bool stripIpv4 = false; string? command = null; GenericRoom? room = null; var argsEnum = args.AsEnumerable().GetEnumerator(); while (argsEnum.MoveNext()) { var arg = argsEnum.Current; switch (arg) { case "--help": Console.WriteLine("Usage: MatrixLogFwd [--help] [--mode ] [--chunk-size ] [-- ]"); break; case "--mode": argsEnum.MoveNext(); mode = argsEnum.Current; if (mode != "file" && mode != "lines") { Console.WriteLine("Invalid mode"); return; } break; case "--strip-ipv4": stripIpv4 = true; break; case "--chunk-size": argsEnum.MoveNext(); chunkSize = Conversions.ToInteger(argsEnum.Current); break; case "--roomid": argsEnum.MoveNext(); var roomId = argsEnum.Current; room = hs.GetRoom(roomId); break; case "--": command = ""; while (argsEnum.MoveNext()) { command += argsEnum.Current + " "; } break; } } if (room == null) { Console.WriteLine("No room specified, creating new room"); room = await hs.CreateRoom(new() { Name = $"MatrixLogFwd logs from {Environment.MachineName} at {DateTime.Now}", }); } var stream = Console.OpenStandardInput(); if (!string.IsNullOrWhiteSpace(command)) { var proc = new System.Diagnostics.Process { StartInfo = new() { FileName = "/bin/sh", Arguments = $"-c \"{command}\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true } }; proc.Start(); stream = proc.StandardOutput.BaseStream; } if (mode == "lines") { var buffer = new byte[1024]; var line = new StringBuilder(); int linesInBuffer = 0; while (true) { var read = await stream.ReadAsync(buffer); Console.WriteLine($"Read {read} bytes"); if (read == 0) { await room.SendMessageEventAsync(new MessageBuilder().WithCodeBlock(line.ToString()).Build()); break; } for (int i = 0; i < read; i++) { if (buffer[i] == '\n') { linesInBuffer++; if (linesInBuffer > chunkSize) { if (stripIpv4) { var lineStr = line.ToString(); lineStr = Ipv4Regex().Replace(lineStr, "[REDACTED_IP]"); line.Clear(); line.Append(lineStr); } await room.SendMessageEventAsync(new MessageBuilder().WithCodeBlock(line.ToString()).Build()); line.Clear(); linesInBuffer = 0; } else { line.Append((char)buffer[i]); } } else { line.Append((char)buffer[i]); } } } } else { var buffer = new byte[chunkSize]; while (true) { var read = await stream.ReadAtLeastAsync(buffer, chunkSize, false); if (read == 0) { break; } Console.WriteLine($"Read {read} bytes"); var ms = new MemoryStream(buffer, 0, read); var filename = $"log-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt"; await room.SendFileAsync(filename, ms); } } partial class Program { [GeneratedRegex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")] private static partial Regex Ipv4Regex(); } // await room.LeaveAsync();