config->parseXML(read_file(JORINDE_HTTPD_CONFIG_DIR + "server.xml"));
config->loadXML(JORINDE_HTTPD_CONFIG_DIR + "server.xml");
static void create(varargs int clone){	int i, j;	object *elts, elt, config;	mixed *ports;		props::create();	default_apps = ([ ]);	binaryd = find_object(SYS_BINARYD);	/* Each application will maintain its own copy of this mapping */	status = ([		1   : ({ "!.!", "Internal: Default Status",         nil }),		100 : ({ "1.1", "Continue",                         nil }),		101 : ({ "1.1", "Switching Protocols",              nil }),		102 : ({ "W.D", "Processing",						nil }),		200 : ({ "1.0", "OK",                               nil }),		201 : ({ "1.0", "Created",                          nil }),		202 : ({ "1.0", "Accepted",                         nil }),		203 : ({ "1.?", "Non-Authoritative Information",    nil }),		204 : ({ "1.0", "No Content",                       nil }),		205 : ({ "1.1", "Reset Content",                    nil }),		206 : ({ "1.1", "Partial Content",                  nil }),		207 : ({ "W.D", "Multi-Status",						nil }),		300 : ({ "1.?", "Multiple Choices",                 nil }),		301 : ({ "1.0", "Moved Permanently",                nil }),		302 : ({ "1.0", "Found. Moved Temporarily",         nil }),		303 : ({ "1.1", "See Other",                        nil }),		304 : ({ "1.0", "Not Modified",                     nil }),		305 : ({ "1.1", "Use Proxy",                        nil }),		306 : ({ "?.?", "(Unused)",                         nil }),		307 : ({ "1.1", "Temporary Redirect",               nil }),		400 : ({ "1.0", "Bad Request",                      nil }),		401 : ({ "1.0", "Unauthorized",                     nil }),		402 : ({ "1.1", "Payment Required",                 nil }),		403 : ({ "1.0", "Forbidden",                        nil }),		404 : ({ "1.0", "Not Found",                        nil }),		405 : ({ "1.1", "Method not allowed",               nil }),		406 : ({ "1.1", "Not Acceptable",                   nil }),		407 : ({ "1.1", "Proxy Authentication Required",    nil }),		408 : ({ "1.1", "Request Timeout",                  nil }),		409 : ({ "1.1", "Conflict",                         nil }),		410 : ({ "1.1", "Gone",                             nil }),		411 : ({ "1.1", "Length Required",                  nil }),		412 : ({ "1.1", "Precondition Failed",              nil }),		413 : ({ "1.1", "Request Entity Too Large",         nil }),		414 : ({ "1.1", "Request-URI Too Long",             nil }),		415 : ({ "1.1", "Unsupported Media Type",           nil }),		416 : ({ "1.1", "Requested Range Not Satisfiable",  nil }),		417 : ({ "1.1", "Expectation Failed",               nil }),		422 : ({ "W.D", "Unprocessable Entity",				nil }),		423 : ({ "W.D", "Locked",							nil }),		424 : ({ "W.D", "Failed Dependency",				nil }),		500 : ({ "1.0", "Internal Server Error",            nil }),		501 : ({ "1.0", "Not Implemented",                  nil }),		502 : ({ "1.0", "Bad Gateway",                      nil }),		503 : ({ "1.0", "Service Unavailable",              nil }),		504 : ({ "1.1", "Gateway Timeout",                  nil }),		505 : ({ "1.1", "HTTP Version Not Supported",       nil }),		507 : ({ "W.D", "Insufficient Storage",				nil }),	]);	ports = status()[ST_BINARYPORTS];	if(ports == nil || !sizeof(ports)) {		SYSLOG("No binary ports defined, will not start Jorinde");		return;	}	/* Stringify elements of array (for comparing) */	for(i = 0; i < sizeof(ports); i++) {		ports[i] += "";	}	/* Load configuration */	config = (JXMLROOTD)->new();	config->parseXML(read_file(JORINDE_HTTPD_CONFIG_DIR + "server.xml"));	if(!config) {		error("Could not load httpd configuration\n");	}	/* Set misc properties */	keep_alive_time = (int)config->xpath("server/timeout")[0]->getValue();	timeout = (int)config->xpath("server/keep-alive")[0]->getValue();	/* Get all applications from configuration */	elts = config->xpath( "server/applications/application" );	applications = ([ ]);	for(j = 0; j < sizeof(elts); j++) {		object app, appconfig;		string hostname, tmp;		elt = elts[j];		/* Get index of port this application wants */		for(i = 0; i < sizeof(ports); i++) {			if(ports[i] == elt->getAttribute("port")) {				break;			}		}		if(i >= sizeof(ports)) {			error("binding to port "+elt->getAttribute("port")+" failed");		}		/* Get application configuration */		appconfig = (JXMLROOTD)->new();		appconfig->parseXML(read_file(				JORINDE_HTTPD_CONFIG_DIR + elt->getAttribute("config-file"))			);		if(!sizeof(appconfig->xpath("application"))) {			error("invalid configuration: " + JORINDE_HTTPD_CONFIG_DIR + 					elt->getAttribute("config-file"));		}		hostname = appconfig->xpath("application/hostname")[0]->getValue() +				":" + ports[i];		/* Make server (me) aware of this application */		tmp = appconfig->xpath("application/program/path")[0]->getValue();		COMPILE(tmp);		app = clone_object(tmp);		applications[hostname] = allocate(HTAPP_SIZE);		applications[hostname][HTAPP_INDEX] = i;		applications[hostname][HTAPP_OBJECT] = app;		applications[hostname][HTAPP_PORT] = ports[i];		/* Initialize application */		app->initialize(appconfig);		app->set_port(ports[i]);		if(elt->getAttribute("default") == "yes") {			default_apps[(int)ports[i]] = hostname;		}	}	/* Get plugins */	/* All applications will get commands from the server. To enable or	 * disable what can be executed; modify 'allowed methods' node in	 * in each application configuration.	 */	plugins  = ({ });	elts = config->xpath( "server/plugins/method/plugin" );	for(i = 0; i < sizeof(elts); i++) {		string program;		if(elts[i]->dummy()) continue;		program = elts[i]->xpath("program")[0]->getCleanValue();		COMPILE(program);		plugins += ({ program });	}	if(sizeof(plugins) == 0) {		error("no method plugins in server.xml");	}	if(binaryd == nil) {		error("no binary manager found");	}	binaryd->init_httpd(timeout, applications);	authend = find_object( HTTP_AUTHENTICATE );	elts = config->xpath( "server/plugins/authentication/plugin" );	if(authend != nil && !elts[0]->dummy()) {		authend->xml_parameter( "authentication", 							elts[0]->xpath( "program" )[0]->getCleanValue() );	} else {		error("no authentication daemon in server.xml");	}	accessd = find_object( HTTP_AUTHORIZE );	elts = config->xpath( "server/plugins/authorization/plugin" );	if(accessd != nil && !elts[0]->dummy()) {		accessd->xml_parameter( "authorization", 							elts[0]->xpath( "program" )[0]->getCleanValue() );	} else {		error("no authorization daemon in server.xml");	}	logd = find_object( HTTP_LOGD );	elts = config->xpath( "server/plugins/loghandler/plugin" );	if(accessd != nil && !elts[0]->dummy()) {		logd->xml_parameter( "logging", 							elts[0]->xpath( "program" )[0]->getCleanValue() );	} else {		error("no logger daemon in server.xml");	}	LOG(get_server_string() + " started");}