using Autofac; using CommandLine; using CommandLine.Text; using Jackett.Common.Models.Config; using Jackett.Common.Plumbing; using Jackett.Common.Services.Interfaces; using Jackett.Common.Utils; using Jackett.Server.Services; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using NLog; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; namespace Jackett.Server { public class Program { public static IConfiguration Configuration { get; set; } public static void Main(string[] args) { var optionsResult = Parser.Default.ParseArguments(args); optionsResult.WithNotParsed(errors => { var text = HelpText.AutoBuild(optionsResult); text.Copyright = " "; text.Heading = "Jackett v" + EnvironmentUtil.JackettVersion + " options:"; Environment.Exit(1); return; }); var runtimeDictionary = new Dictionary(); RuntimeSettings r = new RuntimeSettings(); ConsoleOptions consoleOptions = new ConsoleOptions(); optionsResult.WithParsed(options => { r = options.ToRunTimeSettings(); consoleOptions = options; runtimeDictionary = GetValues(r); }); var builder = new ConfigurationBuilder(); builder.AddInMemoryCollection(runtimeDictionary); Configuration = builder.Build(); //hack TODO: Get the configuration without any DI var containerBuilder = new ContainerBuilder(); Initialisation.SetupLogging(r, containerBuilder); containerBuilder.RegisterModule(new JackettModule(r)); containerBuilder.RegisterType().As(); containerBuilder.RegisterType().As(); containerBuilder.RegisterType().As(); var tempContainer = containerBuilder.Build(); Logger logger = tempContainer.Resolve(); ServerConfig serverConfig = tempContainer.Resolve(); IConfigurationService configurationService = tempContainer.Resolve(); IServerService serverService = tempContainer.Resolve(); Int32.TryParse(serverConfig.Port.ToString(), out Int32 configPort); // Override port if (consoleOptions.Port != 0) { if (configPort != consoleOptions.Port) { logger.Info("Overriding port to " + consoleOptions.Port); serverConfig.Port = consoleOptions.Port; bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); if (isWindows) { if (ServerUtil.IsUserAdministrator()) { serverService.ReserveUrls(doInstall: true); } else { logger.Error("Unable to switch ports when not running as administrator"); Environment.Exit(1); } } configurationService.SaveConfig(serverConfig); } } string[] url = serverConfig.GetListenAddresses(serverConfig.AllowExternal).Take(1).ToArray(); //Kestrel doesn't need 127.0.0.1 and localhost to be registered, remove once off OWIN tempContainer.Dispose(); tempContainer = null; CreateWebHostBuilder(args, url).Build().Run(); } public static Dictionary GetValues(object obj) { return obj .GetType() .GetProperties() .ToDictionary(p => "RuntimeSettings:" + p.Name, p => p.GetValue(obj) == null ? null : p.GetValue(obj).ToString()); } public static IWebHostBuilder CreateWebHostBuilder(string[] args, string[] urls) => WebHost.CreateDefaultBuilder(args) .UseConfiguration(Configuration) .UseUrls(urls) .PreferHostingUrls(true) .UseStartup(); } }