Beispiel #1
0
        VPathToHost GetOrCreateApplication(string vhost, int port, string filepath, string virt)
        {
            string vdir       = Path.GetDirectoryName(virt);
            string pdir       = Path.GetDirectoryName(filepath);
            var    vinfo      = new DirectoryInfo(vdir);
            var    pinfo      = new DirectoryInfo(pdir);
            string final_pdir = null;
            string final_vdir = null;

            while (vinfo != null && pinfo != null)
            {
                if (CheckDirectory(pinfo))
                {
                    final_pdir = pinfo.ToString();
                    final_vdir = vinfo.ToString();
                    break;
                }

                if (pinfo.Name != vinfo.Name)
                {
                    final_vdir = vinfo.ToString();
                    break;
                }

                pinfo = pinfo.Parent;
                vinfo = vinfo.Parent;
            }

            if (final_pdir == null)
            {
                final_pdir = pinfo.ToString();
            }

            if (final_vdir == null)
            {
                final_vdir = vinfo.ToString();
            }


            //Logger.Write (LogLevel.Error, "final_pdir: {0} final_vdir: {1}", final_pdir, final_vdir);
            VPathToHost vapp = server.GetApplicationForPath(vhost, port, virt, false);

            if (vapp == null)
            {
                // Don't know why this breaks mod-mono-server2.exe, but not mod-mono-server.exe
                //final_pdir = "file://" + final_pdir;
                if (final_vdir [0] != '/')
                {
                    final_vdir = "/" + final_vdir;
                }
                server.AddApplication(vhost, port, final_vdir, final_pdir);
                vapp = server.GetApplicationForPath(vhost, port, virt, false);
            }

            return(vapp);
        }
Beispiel #2
0
        public static ApplicationHost GetApplicationForPath(string vhost,
                                                            int port,
                                                            string path,
                                                            string realPath)
        {
            VPathToHost h = appmanager.GetApplicationForPath(vhost,
                                                             port, path, realPath);

            return(h == null ? null : h.AppHost as ApplicationHost);
        }
Beispiel #3
0
        VPathToHost GetOrCreateApplication(string vhost, int port, string filepath, string virt)
        {
            string final_vdir;
            string final_pdir;

            GetPhysicalDirectory(virt, filepath, out final_vdir, out final_pdir);

            //Logger.Write (LogLevel.Error, "final_pdir: {0} final_vdir: {1}", final_pdir, final_vdir);
            VPathToHost vapp = server.GetApplicationForPath(vhost, port, virt, false);

            if (vapp == null)
            {
                // Don't know why this breaks mod-mono-server2.exe, but not mod-mono-server.exe
                //final_pdir = "file://" + final_pdir;
                if (final_vdir [0] != '/')
                {
                    final_vdir = "/" + final_vdir;
                }
                server.AddApplication(vhost, port, final_vdir, final_pdir);
                vapp = server.GetApplicationForPath(vhost, port, virt, false);
            }

            return(vapp);
        }
Beispiel #4
0
        /// <param name="args">Original args passed to the program.</param>
        /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param>
        /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param>
        /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param>
        internal CompatTuple <int, string, ApplicationServer> DebugMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
        {
            var configurationManager = new ConfigurationManager("xsp", quiet);
            var security             = new SecurityConfiguration();

            if (!ParseOptions(configurationManager, args, security))
            {
                return(new CompatTuple <int, string, ApplicationServer> (1, "Error while parsing options", null));
            }

            // Show the help and exit.
            if (configurationManager.Help)
            {
                configurationManager.PrintHelp();
#if DEBUG
                Console.WriteLine("Press any key...");
                Console.ReadKey();
#endif
                return(success);
            }

            // Show the version and exit.
            if (configurationManager.Version)
            {
                Version.Show();
                return(success);
            }

            if (!configurationManager.LoadConfigFile())
            {
                return(new CompatTuple <int, string, ApplicationServer> (1, "Error while loading the configuration file", null));
            }

            configurationManager.SetupLogger();

            WebSource webSource;
            if (security.Enabled)
            {
                try {
                    key       = security.KeyPair;
                    webSource = new XSPWebSource(configurationManager.Address,
                                                 configurationManager.RandomPort ? default(ushort) : configurationManager.Port,
                                                 security.Protocol, security.ServerCertificate,
                                                 GetPrivateKey, security.AcceptClientCertificates,
                                                 security.RequireClientCertificates, !root);
                }
                catch (CryptographicException ce) {
                    Logger.Write(ce);
                    return(new CompatTuple <int, string, ApplicationServer> (1, "Error while setting up https", null));
                }
            }
            else
            {
                webSource = new XSPWebSource(configurationManager.Address, configurationManager.Port, !root);
            }

            var server = new ApplicationServer(webSource, configurationManager.Root)
            {
                Verbose           = configurationManager.Verbose,
                SingleApplication = !root
            };

            if (configurationManager.Applications != null)
            {
                server.AddApplicationsFromCommandLine(configurationManager.Applications);
            }

            if (configurationManager.AppConfigFile != null)
            {
                server.AddApplicationsFromConfigFile(configurationManager.AppConfigFile);
            }

            if (configurationManager.AppConfigDir != null)
            {
                server.AddApplicationsFromConfigDirectory(configurationManager.AppConfigDir);
            }

            if (configurationManager.Applications == null && configurationManager.AppConfigDir == null && configurationManager.AppConfigFile == null)
            {
                server.AddApplicationsFromCommandLine("/:.");
            }


            VPathToHost vh = server.GetSingleApp();
            if (root && vh != null)
            {
                // Redo in new domain
                vh.CreateHost(server, webSource);
                var svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName);
                webSource.Dispose();
                return(svr.DebugMain(args, false, vh.AppHost, configurationManager.Quiet));
            }
            server.AppHost = ext_apphost;

            if (!configurationManager.Quiet)
            {
                Logger.Write(LogLevel.Notice, Assembly.GetExecutingAssembly().GetName().Name);
                Logger.Write(LogLevel.Notice, "Listening on address: {0}", configurationManager.Address);
                Logger.Write(LogLevel.Notice, "Root directory: {0}", configurationManager.Root);
            }

            try {
                if (!server.Start(!configurationManager.NonStop, (int)configurationManager.Backlog))
                {
                    return(new CompatTuple <int, string, ApplicationServer> (2, "Error while starting server", server));
                }

                if (!configurationManager.Quiet)
                {
                    // MonoDevelop depends on this string. If you change it, let them know.
                    Logger.Write(LogLevel.Notice, "Listening on port: {0} {1}", server.Port, security);
                }
                if (configurationManager.RandomPort && !configurationManager.Quiet)
                {
                    Logger.Write(LogLevel.Notice, "Random port: {0}", server.Port);
                }

                if (!configurationManager.NonStop)
                {
                    if (!configurationManager.Quiet)
                    {
                        Console.WriteLine("Hit Return to stop the server.");
                    }

                    while (true)
                    {
                        bool doSleep;
                        try {
                            Console.ReadLine();
                            break;
                        } catch (IOException) {
                            // This might happen on appdomain unload
                            // until the previous threads are terminated.
                            doSleep = true;
                        } catch (ThreadAbortException) {
                            doSleep = true;
                        }

                        if (doSleep)
                        {
                            Thread.Sleep(500);
                        }
                    }
                    server.Stop();
                }
            } catch (Exception e) {
                if (!(e is ThreadAbortException))
                {
                    Logger.Write(e);
                }
                else
                {
                    server.ShutdownSockets();
                }
                return(new CompatTuple <int, string, ApplicationServer> (1, "Error running server", server));
            }

            return(new CompatTuple <int, string, ApplicationServer> (0, null, server));
        }
Beispiel #5
0
        //
        // Parameters:
        //
        //   args - original args passed to the program
        //   root - true means caller is in the root domain
        //   ext_apphost - used when single app mode is used, in a recursive call to
        //        RealMain from the single app domain
        //   quiet - don't show messages. Used to avoid double printing of the banner
        //
        public int RealMain(string [] args, bool root, IApplicationHost ext_apphost, bool v_quiet)
        {
            var configurationManager = new ConfigurationManager("mod_mono", v_quiet,
                                                                ext_apphost == null ? null : ext_apphost.Path);

            if (!configurationManager.LoadCommandLineArgs(args))
            {
                return(1);
            }

            // Show the help and exit.
            if (configurationManager.Help)
            {
                configurationManager.PrintHelp();
#if DEBUG
                Console.WriteLine("Press any key...");
                Console.ReadKey();
#endif
                return(0);
            }

            // Show the version and exit.
            if (configurationManager.Version)
            {
                Version.Show();
                return(0);
            }

            var hash = GetHash(args);
            if (hash == -1)
            {
                Logger.Write(LogLevel.Error, "Couldn't calculate hash - should have left earlier - something is really wrong");
                return(1);
            }
            if (hash == -2)
            {
                Logger.Write(LogLevel.Error, "Couldn't calculate hash - unrecognized parameter");
                return(1);
            }

            if (!configurationManager.LoadConfigFile())
            {
                return(1);
            }

            configurationManager.SetupLogger();

            ushort port     = configurationManager.Port ?? 0;
            bool   useTCP   = port != 0;
            string lockfile = useTCP ? Path.Combine(Path.GetTempPath(), "mod_mono_TCP_") : configurationManager.Filename;
            lockfile = String.Format("{0}_{1}", lockfile, hash);

            ModMonoWebSource webSource = useTCP
                                ? new ModMonoTCPWebSource(configurationManager.Address, port, lockfile)
                                : new ModMonoWebSource(configurationManager.Filename, lockfile);

            if (configurationManager.Terminate)
            {
                if (configurationManager.Verbose)
                {
                    Logger.Write(LogLevel.Notice, "Shutting down running mod-mono-server...");
                }

                bool res = webSource.GracefulShutdown();
                if (configurationManager.Verbose)
                {
                    if (res)
                    {
                        Logger.Write(LogLevel.Notice, "Done");
                    }
                    else
                    {
                        Logger.Write(LogLevel.Error, "Failed.");
                    }
                }

                return(res ? 0 : 1);
            }

            var server = new ApplicationServer(webSource, configurationManager.Root)
            {
                Verbose           = configurationManager.Verbose,
                SingleApplication = !root
            };

#if DEBUG
            Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name);
#endif
            if (configurationManager.Applications != null)
            {
                server.AddApplicationsFromCommandLine(configurationManager.Applications);
            }

            if (configurationManager.AppConfigFile != null)
            {
                server.AddApplicationsFromConfigFile(configurationManager.AppConfigFile);
            }

            if (configurationManager.AppConfigDir != null)
            {
                server.AddApplicationsFromConfigDirectory(configurationManager.AppConfigDir);
            }

            if (!configurationManager.Master && configurationManager.Applications == null &&
                configurationManager.AppConfigDir == null && configurationManager.AppConfigFile == null)
            {
                server.AddApplicationsFromCommandLine("/:.");                  // TODO: do we really want this?
            }
            VPathToHost vh = server.GetSingleApp();
            if (root && vh != null)
            {
                // Redo in new domain
                vh.CreateHost(server, webSource);
                var svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName);
                webSource.Dispose();
                return(svr.RealMain(args, false, vh.AppHost, configurationManager.Quiet));
            }
            if (ext_apphost != null)
            {
                ext_apphost.Server = server;
                server.AppHost     = ext_apphost;
            }
            if (!configurationManager.Quiet)
            {
                if (!useTCP)
                {
                    Logger.Write(LogLevel.Notice, "Listening on: {0}", configurationManager.Filename);
                }
                else
                {
                    Logger.Write(LogLevel.Notice, "Listening on port: {0}", port);
                    Logger.Write(LogLevel.Notice, "Listening on address: {0}", configurationManager.Address);
                }
                Logger.Write(LogLevel.Notice, "Root directory: {0}", configurationManager.Root);
            }

            try {
                if (!server.Start(!configurationManager.NonStop, (int)configurationManager.Backlog))
                {
                    return(2);
                }

                if (!configurationManager.NonStop)
                {
                    Logger.Write(LogLevel.Notice, "Hit Return to stop the server.");
                    while (true)
                    {
                        try {
                            Console.ReadLine();
                            break;
                        } catch (IOException) {
                            // This might happen on appdomain unload
                            // until the previous threads are terminated.
                            Thread.Sleep(500);
                        }
                    }
                    server.Stop();
                }
            } catch (Exception e) {
                if (!(e is ThreadAbortException))
                {
                    Logger.Write(e);
                }
                else
                {
                    server.ShutdownSockets();
                }
                return(1);
            }

            return(0);
        }
Beispiel #6
0
        //
        // Parameters:
        //
        //   args - original args passed to the program
        //   root - true means caller is in the root domain
        //   ext_apphost - used when single app mode is used, in a recursive call to
        //        RealMain from the single app domain
        //   quiet - don't show messages. Used to avoid double printing of the banner
        //
        public int RealMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
        {
            SecurityConfiguration security = new SecurityConfiguration();
            ApplicationSettings   settings = new ApplicationSettings();

            if (settings.IP == null || settings.IP.Length == 0)
            {
                settings.IP = "0.0.0.0";
            }

            if (settings.Oport == null)
            {
                settings.Oport = 8080;
            }

            Options options = 0;
            int     hash    = 0;
            int     backlog = 500;

            for (int i = 0; i < args.Length; i++)
            {
                string a   = args [i];
                int    idx = (i + 1 < args.Length) ? i + 1 : i;
                hash ^= args [idx].GetHashCode() + i;

                switch (a)
                {
                case "--https":
                    CheckAndSetOptions(a, Options.Https, ref options);
                    security.Enabled = true;
                    break;

                case "--https-client-accept":
                    CheckAndSetOptions(a, Options.Https, ref options);
                    security.Enabled = true;
                    security.AcceptClientCertificates  = true;
                    security.RequireClientCertificates = false;
                    break;

                case "--https-client-require":
                    CheckAndSetOptions(a, Options.Https, ref options);
                    security.Enabled = true;
                    security.AcceptClientCertificates  = true;
                    security.RequireClientCertificates = true;
                    break;

                case "--p12file":
                    security.Pkcs12File = args [++i];
                    break;

                case "--cert":
                    security.CertificateFile = args [++i];
                    break;

                case "--pkfile":
                    security.PvkFile = args [++i];
                    break;

                case "--pkpwd":
                    security.Password = args [++i];
                    break;

                case "--protocols":
                    security.SetProtocol(args [++i]);
                    break;

                case "--port":
                    CheckAndSetOptions(a, Options.Port, ref options);
                    settings.Oport = args [++i];
                    break;

                case "--random-port":
                    CheckAndSetOptions(a, Options.RandomPort, ref options);
                    settings.Oport = 0;
                    break;

                case "--address":
                    CheckAndSetOptions(a, Options.Address, ref options);
                    settings.IP = args [++i];
                    break;

                case "--backlog":
                    string backlogstr = args [++i];
                    try {
                        backlog = Convert.ToInt32(backlogstr);
                    } catch (Exception) {
                        Console.WriteLine("The value given for backlog is not valid {0}", backlogstr);
                        return(1);
                    }
                    break;

                case "--root":
                    CheckAndSetOptions(a, Options.Root, ref options);
                    settings.RootDir = args [++i];
                    break;

                case "--applications":
                    CheckAndSetOptions(a, Options.Applications, ref options);
                    settings.Apps = args [++i];
                    break;

                case "--appconfigfile":
                    CheckAndSetOptions(a, Options.AppConfigFile, ref options);
                    settings.AppConfigFile = args [++i];
                    break;

                case "--appconfigdir":
                    CheckAndSetOptions(a, Options.AppConfigDir, ref options);
                    settings.AppConfigDir = args [++i];
                    break;

                case "--minThreads":
                    string mtstr      = args [++i];
                    int    minThreads = 0;
                    try {
                        minThreads = Convert.ToInt32(mtstr);
                    } catch (Exception) {
                        Console.WriteLine("The value given for minThreads is not valid {0}", mtstr);
                        return(1);
                    }

                    if (minThreads > 0)
                    {
                        ThreadPool.SetMinThreads(minThreads, minThreads);
                    }

                    break;

                case "--nonstop":
                    settings.NonStop = true;
                    break;

                case "--help":
                    ShowHelp();
                    return(0);

                case "--quiet":
                    quiet = true;
                    break;

                case "--version":
                    ShowVersion();
                    return(0);

                case "--verbose":
                    settings.Verbose = true;
                    break;

                case "--pidfile": {
                    string pidfile = args[++i];
                    if (pidfile != null && pidfile.Length > 0)
                    {
                        try {
                            using (StreamWriter sw = File.CreateText(pidfile))
                                sw.Write(Process.GetCurrentProcess().Id);
                        } catch (Exception ex) {
                            Console.Error.WriteLine("Failed to write pidfile {0}: {1}", pidfile, ex.Message);
                        }
                    }
                    break;
                }

                case "--no-hidden":
                    MonoWorkerRequest.CheckFileAccess = false;
                    break;

                default:
                    ShowHelp();
                    return(1);
                }
            }

            IPAddress ipaddr = null;
            ushort    port;

            try {
                port = Convert.ToUInt16(settings.Oport);
            } catch (Exception) {
                Console.WriteLine("The value given for the listen port is not valid: " + settings.Oport);
                return(1);
            }

            try {
                ipaddr = IPAddress.Parse(settings.IP);
            } catch (Exception) {
                Console.WriteLine("The value given for the address is not valid: " + settings.IP);
                return(1);
            }

            if (settings.RootDir != null && settings.RootDir.Length != 0)
            {
                try {
                    Environment.CurrentDirectory = settings.RootDir;
                } catch (Exception e) {
                    Console.WriteLine("Error: {0}", e.Message);
                    return(1);
                }
            }

            settings.RootDir = Directory.GetCurrentDirectory();

            WebSource webSource;

            if (security.Enabled)
            {
                try {
                    key       = security.KeyPair;
                    webSource = new XSPWebSource(ipaddr, port, security.Protocol, security.ServerCertificate,
                                                 new PrivateKeySelectionCallback(GetPrivateKey),
                                                 security.AcceptClientCertificates, security.RequireClientCertificates, !root);
                }
                catch (CryptographicException ce) {
                    Console.WriteLine(ce.Message);
                    return(1);
                }
            }
            else
            {
                webSource = new XSPWebSource(ipaddr, port, !root);
            }

            ApplicationServer server = new ApplicationServer(webSource, settings.RootDir);

            server.Verbose           = settings.Verbose;
            server.SingleApplication = !root;

            if (settings.Apps != null)
            {
                server.AddApplicationsFromCommandLine(settings.Apps);
            }

            if (settings.AppConfigFile != null)
            {
                server.AddApplicationsFromConfigFile(settings.AppConfigFile);
            }

            if (settings.AppConfigDir != null)
            {
                server.AddApplicationsFromConfigDirectory(settings.AppConfigDir);
            }

            if (settings.Apps == null && settings.AppConfigDir == null && settings.AppConfigFile == null)
            {
                server.AddApplicationsFromCommandLine("/:.");
            }


            VPathToHost vh = server.GetSingleApp();

            if (root && vh != null)
            {
                // Redo in new domain
                vh.CreateHost(server, webSource);
                Server svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName);
                webSource.Dispose();
                return(svr.RealMain(args, false, vh.AppHost, quiet));
            }
            server.AppHost = ext_apphost;

            if (!quiet)
            {
                Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name);
                Console.WriteLine("Listening on address: {0}", settings.IP);
                Console.WriteLine("Root directory: {0}", settings.RootDir);
            }

            try {
                if (server.Start(!settings.NonStop, settings.Exception, backlog) == false)
                {
                    return(2);
                }

                if (!quiet)
                {
                    // MonoDevelop depends on this string. If you change it, let them know.
                    Console.WriteLine("Listening on port: {0} {1}", server.Port, security);
                }
                if (port == 0 && !quiet)
                {
                    Console.Error.WriteLine("Random port: {0}", server.Port);
                }

                if (!settings.NonStop)
                {
                    if (!quiet)
                    {
                        Console.WriteLine("Hit Return to stop the server.");
                    }

                    bool doSleep;
                    while (true)
                    {
                        doSleep = false;
                        try {
                            Console.ReadLine();
                            break;
                        } catch (IOException) {
                            // This might happen on appdomain unload
                            // until the previous threads are terminated.
                            doSleep = true;
                        } catch (ThreadAbortException) {
                            doSleep = true;
                        }

                        if (doSleep)
                        {
                            Thread.Sleep(500);
                        }
                    }
                    server.Stop();
                }
            } catch (Exception e) {
                if (!(e is ThreadAbortException))
                {
                    Console.WriteLine("Error: {0}", e);
                }
                else
                {
                    server.ShutdownSockets();
                }
                return(1);
            }

            return(0);
        }
Beispiel #7
0
        //
        // Parameters:
        //
        //   args - original args passed to the program
        //   root - true means caller is in the root domain
        //   ext_apphost - used when single app mode is used, in a recursive call to
        //        RealMain from the single app domain
        //   quiet - don't show messages. Used to avoid double printing of the banner
        //
        public int RealMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet)
        {
            ApplicationSettings settings = new ApplicationSettings();

            if (ext_apphost != null)
            {
                settings.RootDir = ext_apphost.Path;
            }

            Options options = 0;
            int     backlog = 500;
            int     hash    = 0;

            for (int i = 0; i < args.Length; i++)
            {
                string a   = args [i];
                int    idx = (i + 1 < args.Length) ? i + 1 : i;
                hash ^= args [idx].GetHashCode() + i;

                switch (a)
                {
                case "--filename":
                    CheckAndSetOptions(a, Options.FileName, ref options);
                    settings.FileName = args [++i];
                    break;

                case "--terminate":
                    CheckAndSetOptions(a, Options.Terminate, ref options);
                    break;

                case "--master":
                    CheckAndSetOptions(a, Options.Master, ref options);
                    settings.Master = true;
                    break;

                case "--port":
                    CheckAndSetOptions(a, Options.Port, ref options);
                    settings.Oport = args [++i];
                    break;

                case "--address":
                    CheckAndSetOptions(a, Options.Address, ref options);
                    settings.IP = args [++i];
                    break;

                case "--backlog":
                    string backlogstr = args [++i];
                    try {
                        backlog = Convert.ToInt32(backlogstr);
                    } catch (Exception) {
                        Console.WriteLine("The value given for backlog is not valid {0}", backlogstr);
                        return(1);
                    }
                    break;

                case "--root":
                    CheckAndSetOptions(a, Options.Root, ref options);
                    settings.RootDir = args [++i];
                    break;

                case "--applications":
                    CheckAndSetOptions(a, Options.Applications, ref options);
                    settings.Apps = args [++i];
                    break;

                case "--appconfigfile":
                    CheckAndSetOptions(a, Options.AppConfigFile, ref options);
                    settings.AppConfigFile = args [++i];
                    break;

                case "--appconfigdir":
                    CheckAndSetOptions(a, Options.AppConfigDir, ref options);
                    settings.AppConfigDir = args [++i];
                    break;

                case "--minThreads":
                    string mtstr      = args [++i];
                    int    minThreads = 0;
                    try {
                        minThreads = Convert.ToInt32(mtstr);
                    } catch (Exception) {
                        Console.WriteLine("The value given for minThreads is not valid {0}", mtstr);
                        return(1);
                    }

                    if (minThreads > 0)
                    {
                        ThreadPool.SetMinThreads(minThreads, minThreads);
                    }

                    break;

                case "--nonstop":
                    settings.NonStop = true;
                    break;

                case "--help":
                    ShowHelp();
                    return(0);

                case "--version":
                    ShowVersion();
                    return(0);

                case "--verbose":
                    settings.Verbose = true;
                    break;

                case "--pidfile": {
                    string pidfile = args[++i];
                    if (pidfile != null && pidfile.Length > 0)
                    {
                        try {
                            using (StreamWriter sw = File.CreateText(pidfile))
                                sw.Write(Process.GetCurrentProcess().Id);
                        } catch (Exception ex) {
                            Console.Error.WriteLine("Failed to write pidfile {0}: {1}", pidfile, ex.Message);
                        }
                    }
                    break;
                }

                case "--no-hidden":
                    MonoWorkerRequest.CheckFileAccess = false;
                    break;

                default:
                    Console.Error.WriteLine("Unknown argument: {0}", a);
                    ShowHelp();
                    return(1);
                }
            }

            if (hash < 0)
            {
                hash = -hash;
            }

            string lockfile;
            bool   useTCP = ((options & Options.Port) != 0);

            if (!useTCP)
            {
                if (settings.FileName == null || settings.FileName.Length == 0)
                {
                    settings.FileName = "/tmp/mod_mono_server";
                }

                if ((options & Options.Address) != 0)
                {
                    ShowHelp();
                    Console.Error.WriteLine();
                    Console.Error.WriteLine("ERROR: --address without --port");
                    Environment.Exit(1);
                }
                lockfile = Path.Combine(Path.GetTempPath(), Path.GetFileName(settings.FileName));
                lockfile = String.Format("{0}_{1}", lockfile, hash);
            }
            else
            {
                lockfile = Path.Combine(Path.GetTempPath(), "mod_mono_TCP_");
                lockfile = String.Format("{0}_{1}", lockfile, hash);
            }

            IPAddress ipaddr = null;
            ushort    port;

            try {
                port = Convert.ToUInt16(settings.Oport);
            } catch (Exception) {
                Console.Error.WriteLine("The value given for the listen port is not valid: " + settings.Oport);
                return(1);
            }

            try {
                ipaddr = IPAddress.Parse(settings.IP);
            } catch (Exception) {
                Console.Error.WriteLine("The value given for the address is not valid: " + settings.IP);
                return(1);
            }

            if (settings.RootDir != null && settings.RootDir.Length > 0)
            {
                try {
                    Environment.CurrentDirectory = settings.RootDir;
                } catch (Exception e) {
                    Console.Error.WriteLine("Error: {0}", e.Message);
                    return(1);
                }
            }

            settings.RootDir = Directory.GetCurrentDirectory();

            WebSource webSource;

            if (useTCP)
            {
                webSource = new ModMonoTCPWebSource(ipaddr, port, lockfile);
            }
            else
            {
                webSource = new ModMonoWebSource(settings.FileName, lockfile);
            }

            if ((options & Options.Terminate) != 0)
            {
                if (settings.Verbose)
                {
                    Console.Error.WriteLine("Shutting down running mod-mono-server...");
                }

                bool res = ((ModMonoWebSource)webSource).GracefulShutdown();
                if (settings.Verbose)
                {
                    Console.Error.WriteLine(res ? "Done." : "Failed");
                }

                return((res) ? 0 : 1);
            }

            ApplicationServer server = new ApplicationServer(webSource, settings.RootDir);

            server.Verbose           = settings.Verbose;
            server.SingleApplication = !root;

            Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name);
            if (settings.Apps != null)
            {
                server.AddApplicationsFromCommandLine(settings.Apps);
            }

            if (settings.AppConfigFile != null)
            {
                server.AddApplicationsFromConfigFile(settings.AppConfigFile);
            }

            if (settings.AppConfigDir != null)
            {
                server.AddApplicationsFromConfigDirectory(settings.AppConfigDir);
            }

            if (!settings.Master && settings.Apps == null && settings.AppConfigDir == null && settings.AppConfigFile == null)
            {
                server.AddApplicationsFromCommandLine("/:.");
            }

            VPathToHost vh = server.GetSingleApp();

            if (root && vh != null)
            {
                // Redo in new domain
                vh.CreateHost(server, webSource);
                Server svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName);
                webSource.Dispose();
                return(svr.RealMain(args, false, vh.AppHost, quiet));
            }
            if (ext_apphost != null)
            {
                ext_apphost.Server = server;
                server.AppHost     = ext_apphost;
            }
            if (!useTCP && !quiet)
            {
                Console.Error.WriteLine("Listening on: {0}", settings.FileName);
            }
            else if (!quiet)
            {
                Console.Error.WriteLine("Listening on port: {0}", port);
                Console.Error.WriteLine("Listening on address: {0}", settings.IP);
            }

            if (!quiet)
            {
                Console.Error.WriteLine("Root directory: {0}", settings.RootDir);
            }

            try {
                if (server.Start(!settings.NonStop, backlog) == false)
                {
                    return(2);
                }

                if (!settings.NonStop)
                {
                    Console.Error.WriteLine("Hit Return to stop the server.");
                    while (true)
                    {
                        try {
                            Console.ReadLine();
                            break;
                        } catch (IOException) {
                            // This might happen on appdomain unload
                            // until the previous threads are terminated.
                            Thread.Sleep(500);
                        }
                    }
                    server.Stop();
                }
            } catch (Exception e) {
                if (!(e is ThreadAbortException))
                {
                    Console.Error.WriteLine("Error: {0}", e.Message);
                }
                else
                {
                    server.ShutdownSockets();
                }
                return(1);
            }

            return(0);
        }