From 7f5a775941faa6d3fc7e6b01863cda91f1869fb2 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 12 Oct 2019 19:26:28 +0100 Subject: [PATCH] Added base for remote connection and hello packet. --- .../.idea/contentModel.xml | 6 + .../DiscImageChef.Devices.csproj | 3 + DiscImageChef.Devices/Remote/Consts.cs | 9 ++ DiscImageChef.Devices/Remote/Enums.cs | 7 + DiscImageChef.Devices/Remote/Structs.cs | 44 +++++++ DiscImageChef/Commands/Remote.cs | 123 ++++++++++++++++++ DiscImageChef/DiscImageChef.csproj | 1 + DiscImageChef/Main.cs | 59 ++++----- 8 files changed, 223 insertions(+), 29 deletions(-) create mode 100644 DiscImageChef.Devices/Remote/Consts.cs create mode 100644 DiscImageChef.Devices/Remote/Enums.cs create mode 100644 DiscImageChef.Devices/Remote/Structs.cs create mode 100644 DiscImageChef/Commands/Remote.cs diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index 2e41aa634..d25e188b4 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -42,6 +42,7 @@ + @@ -591,6 +592,11 @@ + + + + + diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index 90364e521..f07d25abf 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -53,6 +53,9 @@ + + + diff --git a/DiscImageChef.Devices/Remote/Consts.cs b/DiscImageChef.Devices/Remote/Consts.cs new file mode 100644 index 000000000..21aa41604 --- /dev/null +++ b/DiscImageChef.Devices/Remote/Consts.cs @@ -0,0 +1,9 @@ +namespace DiscImageChef.Devices.Remote +{ + public class Consts + { + public const string PacketId = "DICPACKT"; + public const int PacketVersion = 1; + public const int MaxProtocol = 1; + } +} \ No newline at end of file diff --git a/DiscImageChef.Devices/Remote/Enums.cs b/DiscImageChef.Devices/Remote/Enums.cs new file mode 100644 index 000000000..a28662450 --- /dev/null +++ b/DiscImageChef.Devices/Remote/Enums.cs @@ -0,0 +1,7 @@ +namespace DiscImageChef.Devices.Remote +{ + public enum DicPacketType : byte + { + Hello = 1 + } +} \ No newline at end of file diff --git a/DiscImageChef.Devices/Remote/Structs.cs b/DiscImageChef.Devices/Remote/Structs.cs new file mode 100644 index 000000000..cc72355c8 --- /dev/null +++ b/DiscImageChef.Devices/Remote/Structs.cs @@ -0,0 +1,44 @@ +using System.Runtime.InteropServices; + +namespace DiscImageChef.Devices.Remote +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct DicPacketHeader + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string id; + + public uint len; + public byte version; + public DicPacketType packetType; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] spare; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal struct DicPacketHello + { + public DicPacketHeader hdr; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string application; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string version; + + public byte maxProtocol; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] spare; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string sysname; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string release; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string machine; + } +} \ No newline at end of file diff --git a/DiscImageChef/Commands/Remote.cs b/DiscImageChef/Commands/Remote.cs new file mode 100644 index 000000000..af98fdd22 --- /dev/null +++ b/DiscImageChef/Commands/Remote.cs @@ -0,0 +1,123 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Remote.cs +// Author(s) : Natalia Portillo +// +// Component : Verbs. +// +// --[ Description ] ---------------------------------------------------------- +// +// Implements the 'remote' verb. +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2019 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using DiscImageChef.CommonTypes.Enums; +using DiscImageChef.CommonTypes.Structs; +using DiscImageChef.Console; +using Mono.Options; + +namespace DiscImageChef.Commands +{ + internal class RemoteCommand : Command + { + private string host; + private bool showHelp; + + public RemoteCommand() : base("remote", "Tests connection to a DiscImageChef Remote Server.") + { + Options = new OptionSet + { + $"{MainClass.AssemblyTitle} {MainClass.AssemblyVersion?.InformationalVersion}", + $"{MainClass.AssemblyCopyright}", + "", + $"usage: DiscImageChef {Name} [OPTIONS] host", + "", + Help, + {"help|h|?", "Show this message and exit.", v => showHelp = v != null} + }; + } + + public override int Invoke(IEnumerable arguments) + { + var extra = Options.Parse(arguments); + + if (showHelp) + { + Options.WriteOptionDescriptions(CommandSet.Out); + return (int) ErrorNumber.HelpRequested; + } + + MainClass.PrintCopyright(); + if (MainClass.Debug) DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; + if (MainClass.Verbose) DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; +// Statistics.AddCommand("remote"); + + if (extra.Count > 1) + { + DicConsole.ErrorWriteLine("Too many arguments."); + return (int) ErrorNumber.UnexpectedArgumentCount; + } + + if (extra.Count == 0) + { + DicConsole.ErrorWriteLine("Missing input image."); + return (int) ErrorNumber.MissingArgument; + } + + host = extra[0]; + + DicConsole.DebugWriteLine("Remote command", "--debug={0}", MainClass.Debug); + DicConsole.DebugWriteLine("Remote command", "--host={0}", host); + DicConsole.DebugWriteLine("Remote command", "--verbose={0}", MainClass.Verbose); + + var ipHostEntry = Dns.GetHostEntry(host); + var ipAddress = ipHostEntry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork); + + if (ipAddress is null) + { + DicConsole.ErrorWriteLine("Host not found"); + return (int) Errno.ENODEV; + } + + var ipEndPoint = new IPEndPoint(ipAddress, 6666); + var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + try + { + socket.Connect(ipEndPoint); + socket.Shutdown(SocketShutdown.Both); + socket.Close(); + } + catch (Exception e) + { + DicConsole.Write(e.Message); + } + + return (int) ErrorNumber.NoError; + } + } +} \ No newline at end of file diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj index 070611d21..f073a6de7 100644 --- a/DiscImageChef/DiscImageChef.csproj +++ b/DiscImageChef/DiscImageChef.csproj @@ -57,6 +57,7 @@ + diff --git a/DiscImageChef/Main.cs b/DiscImageChef/Main.cs index f1991f337..b21a63039 100644 --- a/DiscImageChef/Main.cs +++ b/DiscImageChef/Main.cs @@ -47,58 +47,58 @@ using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID; namespace DiscImageChef { - class MainClass + internal class MainClass { - internal static bool Verbose; - internal static bool Debug; - internal static string AssemblyCopyright; - internal static string AssemblyTitle; + internal static bool Verbose; + internal static bool Debug; + internal static string AssemblyCopyright; + internal static string AssemblyTitle; internal static AssemblyInformationalVersionAttribute AssemblyVersion; [STAThread] public static int Main(string[] args) { - object[] attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false); - AssemblyTitle = ((AssemblyTitleAttribute)attributes[0]).Title; - attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); + var attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false); + AssemblyTitle = ((AssemblyTitleAttribute) attributes[0]).Title; + attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); AssemblyVersion = Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; - AssemblyCopyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright; + AssemblyCopyright = ((AssemblyCopyrightAttribute) attributes[0]).Copyright; - DicConsole.WriteLineEvent += System.Console.WriteLine; - DicConsole.WriteEvent += System.Console.Write; + DicConsole.WriteLineEvent += System.Console.WriteLine; + DicConsole.WriteEvent += System.Console.Write; DicConsole.ErrorWriteLineEvent += System.Console.Error.WriteLine; Settings.Settings.LoadSettings(); - DicContext ctx = DicContext.Create(Settings.Settings.LocalDbPath); + var ctx = DicContext.Create(Settings.Settings.LocalDbPath); ctx.Database.Migrate(); ctx.SaveChanges(); - bool masterDbUpdate = false; - if(!File.Exists(Settings.Settings.MasterDbPath)) + var masterDbUpdate = false; + if (!File.Exists(Settings.Settings.MasterDbPath)) { masterDbUpdate = true; UpdateCommand.DoUpdate(true); } - DicContext mctx = DicContext.Create(Settings.Settings.MasterDbPath); + var mctx = DicContext.Create(Settings.Settings.MasterDbPath); mctx.Database.Migrate(); mctx.SaveChanges(); - if((args.Length < 1 || args[0].ToLowerInvariant() != "gui") && - Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel) + if ((args.Length < 1 || args[0].ToLowerInvariant() != "gui") && + Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel) new ConfigureCommand(true, true).Invoke(args); Statistics.LoadStats(); - if(Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.ShareStats) + if (Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.ShareStats) Task.Run(() => { Statistics.SubmitStats(); }); - PlatformID currentPlatform = DetectOS.GetRealPlatformID(); + var currentPlatform = DetectOS.GetRealPlatformID(); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - CommandSet commands = new CommandSet("DiscImageChef") + var commands = new CommandSet("DiscImageChef") { $"{AssemblyTitle} {AssemblyVersion?.InformationalVersion}", $"{AssemblyCopyright}", @@ -106,7 +106,7 @@ namespace DiscImageChef "usage: DiscImageChef COMMAND [OPTIONS]", "", "Global options:", - {"verbose|v", "Shows verbose output.", b => Verbose = b != null}, + {"verbose|v", "Shows verbose output.", b => Verbose = b != null}, {"debug|d", "Shows debug output from plugins.", b => Debug = b != null}, "", "Available commands:", @@ -120,8 +120,8 @@ namespace DiscImageChef new DecodeCommand() }; - if(currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || - currentPlatform == PlatformID.Win32NT) + if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || + currentPlatform == PlatformID.Win32NT) { commands.Add(new DeviceInfoCommand()); commands.Add(new DeviceReportCommand()); @@ -133,16 +133,16 @@ namespace DiscImageChef commands.Add(new FormatsCommand()); commands.Add(new ImageInfoCommand()); - if(currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || - currentPlatform == PlatformID.Win32NT) commands.Add(new ListDevicesCommand()); + if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || + currentPlatform == PlatformID.Win32NT) commands.Add(new ListDevicesCommand()); commands.Add(new ListEncodingsCommand()); commands.Add(new ListNamespacesCommand()); commands.Add(new ListOptionsCommand()); commands.Add(new LsCommand()); - if(currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || - currentPlatform == PlatformID.Win32NT) + if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux || + currentPlatform == PlatformID.Win32NT) { commands.Add(new MediaInfoCommand()); commands.Add(new MediaScanCommand()); @@ -152,8 +152,9 @@ namespace DiscImageChef commands.Add(new StatisticsCommand()); commands.Add(new UpdateCommand(masterDbUpdate)); commands.Add(new VerifyCommand()); + commands.Add(new RemoteCommand()); - int ret = commands.Run(args); + var ret = commands.Run(args); Statistics.SaveStats(); @@ -163,7 +164,7 @@ namespace DiscImageChef internal static void PrintCopyright() { DicConsole.WriteLine("{0} {1}", AssemblyTitle, AssemblyVersion?.InformationalVersion); - DicConsole.WriteLine("{0}", AssemblyCopyright); + DicConsole.WriteLine("{0}", AssemblyCopyright); DicConsole.WriteLine(); } }