public static int Main(string [] args) { // Load the configuration file stored in the // executable's resources. configmanager = new ConfigurationManager( typeof(Server).Assembly, "ConfigurationManager.xml"); configmanager.LoadCommandLineArgs(args); // Show the help and exit. if ((bool)configmanager ["help"] || (bool)configmanager ["?"]) { ShowHelp(); return(0); } // Show the version and exit. if ((bool)configmanager ["version"]) { ShowVersion(); return(0); } try { string config_file = (string) configmanager ["configfile"]; if (config_file != null) { configmanager.LoadXmlConfig( config_file); } } catch (ApplicationException e) { Console.WriteLine(e.Message); return(1); } catch (System.Xml.XmlException e) { Console.WriteLine( "Error reading XML configuration: {0}", e.Message); return(1); } try { string log_level = (string) configmanager ["loglevels"]; if (log_level != null) { Logger.Level = (LogLevel) Enum.Parse(typeof(LogLevel), log_level); } } catch { Console.WriteLine("Failed to parse log levels."); Console.WriteLine("Using default levels: {0}", Logger.Level); } try { string log_file = (string) configmanager ["logfile"]; if (log_file != null) { Logger.Open(log_file); } } catch (Exception e) { Console.WriteLine("Error opening log file: {0}", e.Message); Console.WriteLine("Events will not be logged."); } Logger.WriteToConsole = (bool)configmanager ["printlog"]; // Send the trace to the console. Trace.Listeners.Add( new TextWriterTraceListener(Console.Out)); Console.WriteLine( Assembly.GetExecutingAssembly().GetName().Name); // Create the socket. Socket socket; // Socket strings are in the format // "type[:ARG1[:ARG2[:...]]]". string socket_type = configmanager ["socket"] as string; if (socket_type == null) { socket_type = "pipe"; } string [] socket_parts = socket_type.Split( new char [] { ':' }, 3); switch (socket_parts [0].ToLower()) { case "pipe": try { socket = SocketFactory.CreatePipeSocket( IntPtr.Zero); } catch (System.Net.Sockets.SocketException) { Console.WriteLine( "Error: Pipe socket is not bound."); return(1); } break; // The FILE sockets is of the format // "file[:PATH]". case "unix": case "file": if (socket_parts.Length == 2) { configmanager ["filename"] = socket_parts [1]; } string path = (string)configmanager ["filename"]; try { socket = SocketFactory.CreateUnixSocket( path); } catch (System.Net.Sockets.SocketException e) { Console.WriteLine( "Error creating the socket: {0}", e.Message); return(1); } Console.WriteLine("Listening on file: {0}", path); break; // The TCP socket is of the format // "tcp[[:ADDRESS]:PORT]". case "tcp": if (socket_parts.Length > 1) { configmanager ["port"] = socket_parts [ socket_parts.Length - 1]; } if (socket_parts.Length == 3) { configmanager ["address"] = socket_parts [1]; } ushort port; try { port = (ushort)configmanager ["port"]; } catch (ApplicationException e) { Console.WriteLine(e.Message); return(1); } string address_str = (string)configmanager ["address"]; IPAddress address; try { address = IPAddress.Parse(address_str); } catch { Console.WriteLine( "Error in argument \"address\". \"{0}\" cannot be converted to an IP address.", address_str); return(1); } try { socket = SocketFactory.CreateTcpSocket( address, port); } catch (System.Net.Sockets.SocketException e) { Console.WriteLine( "Error creating the socket: {0}", e.Message); return(1); } Console.WriteLine("Listening on port: {0}", address_str); Console.WriteLine("Listening on address: {0}", port); break; default: Console.WriteLine( "Error in argument \"socket\". \"{0}\" is not a supported type. Use \"pipe\", \"tcp\" or \"unix\".", socket_parts [0]); return(1); } string root_dir = configmanager ["root"] as string; if (root_dir != null && root_dir.Length != 0) { try { Environment.CurrentDirectory = root_dir; } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); return(1); } } root_dir = Environment.CurrentDirectory; bool auto_map = (bool)configmanager ["automappaths"]; appmanager = new ApplicationManager( typeof(ApplicationHost), auto_map, false); appmanager.Verbose = (bool)configmanager ["verbose"]; string applications = (string) configmanager ["applications"]; string app_config_file; string app_config_dir; try { app_config_file = (string) configmanager ["appconfigfile"]; app_config_dir = (string) configmanager ["appconfigdir"]; } catch (ApplicationException e) { Console.WriteLine(e.Message); return(1); } if (applications != null) { appmanager.AddApplicationsFromCommandLine( applications); } if (app_config_file != null) { appmanager.AddApplicationsFromConfigFile( app_config_file); } if (app_config_dir != null) { appmanager.AddApplicationsFromConfigDirectory( app_config_dir); } if (applications == null && app_config_dir == null && app_config_file == null && !auto_map) { Console.WriteLine( "There are no applications defined, and path mapping is disabled."); Console.WriteLine( "Define an application using /applications, /appconfigfile, /appconfigdir"); Console.WriteLine( "or by enabling application mapping with /automappaths=True."); return(1); } Console.WriteLine("Root directory: {0}", root_dir); Mono.FastCgi.Server server = new Mono.FastCgi.Server( socket); server.SetResponder(typeof(Responder)); server.MaxConnections = (ushort) configmanager ["maxconns"]; server.MaxRequests = (ushort) configmanager ["maxreqs"]; server.MultiplexConnections = (bool) configmanager ["multiplex"]; Console.WriteLine("Max connections: {0}", server.MaxConnections); Console.WriteLine("Max requests: {0}", server.MaxRequests); Console.WriteLine("Multiplex connections: {0}", server.MultiplexConnections); bool stopable = (bool)configmanager ["stopable"]; if (!stopable) { Console.WriteLine( "Use /stopable=True to enable stopping from the console."); } server.Start(stopable); configmanager = null; if (stopable) { Console.WriteLine( "Hit Return to stop the server."); Console.ReadLine(); server.Stop(); } return(0); }