Index: trunk/Server/main.c
===================================================================
--- trunk/Server/main.c	(revision 51)
+++ trunk/Server/main.c	(revision 62)
@@ -15,4 +15,5 @@
 
 #include <cm_log.h>
+#include <cm_string.h>
 
 #include "tw_config.h"
@@ -26,43 +27,103 @@
 extern bool cm_do_log;
 extern struct tw_config config;
+extern FILE* logfile;
 
 char tw_server[2048];
 
+int startup(int argc, char** argv);
+
+#ifdef SERVICE
+SERVICE_STATUS status;
+SERVICE_STATUS_HANDLE status_handle;
+
+void WINAPI servhandler(DWORD control){
+	switch(control){
+		case SERVICE_CONTROL_STOP:
+		case SERVICE_CONTROL_SHUTDOWN:
+			status.dwCurrentState = SERVICE_STOP_PENDING;
+			break;
+	}
+	SetServiceStatus(status_handle, &status);
+}
+
+void WINAPI servmain(DWORD argc, LPSTR* argv){
+	logfile = fopen(PREFIX "/logs/tewi.log", "a");
+	if(logfile == NULL) logfile = stderr;
+	status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+	status.dwCurrentState = SERVICE_START_PENDING;
+	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+	status.dwWin32ExitCode = NO_ERROR;
+	status.dwServiceSpecificExitCode = 0;
+	status.dwCheckPoint = 0;
+	status.dwWaitHint = 0;
+	status_handle = RegisterServiceCtrlHandler("Tewi HTTPd", servhandler);
+	if(status_handle == NULL) return;
+	if(SetServiceStatus(status_handle, &status) == 0) return;
+	int st = startup(argc, argv);
+	if(st != -1){
+		status.dwWin32ExitCode = NO_ERROR;
+		status.dwServiceSpecificExitCode = st;
+		status.dwCurrentState = SERVICE_STOPPED;
+		SetServiceStatus(status_handle, &status);
+		return;
+	}
+	status.dwCurrentState = SERVICE_RUNNING;
+	SetServiceStatus(status_handle, &status);
+	tw_server_loop();
+	status.dwCurrentState = SERVICE_STOPPED;
+	SetServiceStatus(status_handle, &status);
+}
+#endif
+
 int main(int argc, char** argv) {
+	logfile = stderr;
+#ifdef SERVICE
+	SERVICE_TABLE_ENTRY table[] = {{"Tewi HTTPd", servmain}, {NULL, NULL}};
+	StartServiceCtrlDispatcher(table);
+#else
+	int st = startup(argc, argv);
+	if(st != -1) return st;
+	tw_server_loop();
+#endif
+}
+
+int startup(int argc, char** argv){
 	int i;
 	const char* confpath = PREFIX "/etc/tewi.conf";
-	for(i = 1; i < argc; i++) {
-		if(argv[i][0] == '-') {
-			if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
-				if(!cm_do_log) {
-					cm_do_log = true;
-#ifndef NO_SSL
-					cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
-#else
-					cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
-#endif
+	if(argv != NULL){
+		for(i = 1; i < argc; i++) {
+			if(argv[i][0] == '-') {
+				if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
+					if(!cm_do_log) {
+						cm_do_log = true;
+	#ifndef NO_SSL
+						cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
+	#else
+						cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
+	#endif
+					} else {
+						cm_do_log = true;
+					}
+				} else if(strcmp(argv[i], "--config") == 0 || strcmp(argv[i], "-C") == 0) {
+					i++;
+					if(argv[i] == NULL) {
+						fprintf(stderr, "Missing argument\n");
+						return 1;
+					}
+					confpath = argv[i];
+				} else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
+					printf("Tewi HTTPd Tewi/%s\n", tw_get_version());
+					printf("Under public domain.\n");
+					printf("Original by 2024 Nishi\n");
+					printf("\n");
+					printf("Usage: %s [--config|-C config] [--verbose|-v] [--version|-V]\n", argv[0]);
+					printf("--config  | -C config     : Specify config\n");
+					printf("--verbose | -v            : Verbose mode\n");
+					printf("--version | -V            : Version information\n");
+					return 0;
 				} else {
-					cm_do_log = true;
-				}
-			} else if(strcmp(argv[i], "--config") == 0 || strcmp(argv[i], "-C") == 0) {
-				i++;
-				if(argv[i] == NULL) {
-					fprintf(stderr, "Missing argument\n");
+					fprintf(stderr, "Unknown option: %s\n", argv[i]);
 					return 1;
 				}
-				confpath = argv[i];
-			} else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
-				printf("Tewi HTTPd Tewi/%s\n", tw_get_version());
-				printf("Under public domain.\n");
-				printf("Original by 2024 Nishi\n");
-				printf("\n");
-				printf("Usage: %s [--config|-C config] [--verbose|-v] [--version|-V]\n", argv[0]);
-				printf("--config  | -C config     : Specify config\n");
-				printf("--verbose | -v            : Verbose mode\n");
-				printf("--version | -V            : Version information\n");
-				return 0;
-			} else {
-				fprintf(stderr, "Unknown option: %s\n", argv[i]);
-				return 1;
 			}
 		}
@@ -78,5 +139,7 @@
 	}
 	sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
-	cm_log("Daemon", "Ready, server: %s", tw_server);
+	char* r = cm_strcat(tw_server, " running...");
+	cm_force_log(r);
+	free(r);
 #ifndef __MINGW32__
 	signal(SIGCHLD, SIG_IGN);
@@ -84,4 +147,4 @@
 	SetConsoleTitle(tw_server);
 #endif
-	tw_server_loop();
+	return -1;
 }
