]> Git repositories of Nishi - tewi.git/commitdiff
add installer.sh
authorNishi <nishi@nishi.boats>
Wed, 18 Sep 2024 20:02:26 +0000 (20:02 +0000)
committerNishi <nishi@nishi.boats>
Wed, 18 Sep 2024 20:02:26 +0000 (20:02 +0000)
git-svn-id: file:///raid/svn-personal/tewi/trunk@62 8739d7e6-ffea-ec47-b151-bdff447c6205

12 files changed:
Common/cm_log.h
Common/log.c
Module/Makefile
Platform/win32-service.mk [new file with mode: 0644]
Platform/win32.mk
Platform/win64-service.mk [new file with mode: 0644]
Platform/win64.mk
Server/Makefile
Server/install.nsi
Server/main.c
Server/server.c
installer.sh [new file with mode: 0755]

index b4807e2edbeef9f625f97e4b040e1d22d5dc1396..80f2fd5277c5fd20f643433d7a483c2bead9a3c5 100644 (file)
@@ -4,5 +4,6 @@
 #define __CM_LOG_H__
 
 void cm_log(const char* name, const char* log, ...);
+void cm_force_log(const char* log);
 
 #endif
index 79298c7059040228aa71edb4b0a91797903a4574..d8b512304039ff5b45e392cb5d2f4f5d4528be12 100644 (file)
@@ -4,16 +4,28 @@
 
 #include "cm_string.h"
 
+#include <time.h>
 #include <stdio.h>
 #include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
 
+FILE* logfile;
+
 bool cm_do_log = false;
 
 #define LOGNAME_LENGTH 12
 
+void cm_force_log(const char* log) {
+       time_t t = time(NULL);
+       struct tm* tm = localtime(&t);
+       char date[513];
+       strftime(date, 512, "%a %b %d %H:%M:%S %Z %Y", tm);
+       fprintf(logfile, "[%s] %s\n", date, log);
+       fflush(logfile);
+}
+
 void cm_log(const char* name, const char* log, ...) {
        if(!cm_do_log) return;
        va_list args;
@@ -56,7 +68,7 @@ void cm_log(const char* name, const char* log, ...) {
                }
        }
 
-       fprintf(stderr, "%s %s\n", namebuf, result);
+       fprintf(logfile, "%s %s\n", namebuf, result);
        va_end(args);
 
        free(result);
index 14f69229cffa97e7ae04d90534ec8f700cf991dd..48c192d5598b809f50ddd9a39cf22776b4b20977 100644 (file)
@@ -14,4 +14,4 @@ all: mod_cgi$(LIB)
        $(CC) $(CFLAGS) -c -o $@ $<
 
 clean:
-       rm -f *.o *.so *.a
+       rm -f *.o *.so *.a *.dll
diff --git a/Platform/win32-service.mk b/Platform/win32-service.mk
new file mode 100644 (file)
index 0000000..a27d077
--- /dev/null
@@ -0,0 +1,13 @@
+# $Id$
+
+PREFIX = C:/Tewi
+
+CC = i686-w64-mingw32-gcc
+AR = i686-w64-mingw32-ar
+WINDRES = i686-w64-mingw32-windres
+CFLAGS = -g -std=c99 -DPREFIX=\"$(PREFIX)\" -I $(PWD)/Common -fPIC -DSERVICE -mwindows
+LDFLAGS = -mwindows
+LIBS = -lws2_32
+EXEC = .exe
+LIB = .dll
+PREOBJS = tewi.res
index e5109e4197f5534cfba8a6fc6eb013f0cba4f608..d40fb64d38e8f7996f67b910063fc1271516390c 100644 (file)
@@ -11,4 +11,3 @@ LIBS = -lws2_32
 EXEC = .exe
 LIB = .dll
 PREOBJS = tewi.res
-INSTALLER = install.exe
diff --git a/Platform/win64-service.mk b/Platform/win64-service.mk
new file mode 100644 (file)
index 0000000..dca3a01
--- /dev/null
@@ -0,0 +1,13 @@
+# $Id$
+
+PREFIX = C:/Tewi
+
+CC = x86_64-w64-mingw32-gcc
+AR = x86_64-w64-mingw32-ar
+WINDRES = x86_64-w64-mingw32-windres
+CFLAGS = -g -std=c99 -DPREFIX=\"$(PREFIX)\" -I $(PWD)/Common -fPIC -mwindows
+LDFLAGS = -mwindows
+LIBS = -lws2_32
+EXEC = .exe
+LIB = .dll
+PREOBJS = tewi.res
index a9c745637690f17b0531969667281ae2e5de6d12..187462ad4283eb5d51ecd5793146711bdb941efd 100644 (file)
@@ -11,4 +11,3 @@ LIBS = -lws2_32
 EXEC = .exe
 LIB = .dll
 PREOBJS = tewi.res
-INSTALLER = install.exe
index 01bc1514a39af17b60d4d94d239b9a66782843d0..c746f1d415a32f2f505d05a3380a251559039a34 100644 (file)
@@ -7,10 +7,7 @@ include $(PWD)/Platform/$(PLATFORM).mk
 
 OBJS = version.o main.o config.o server.o http.o module.o strptime.o $(EXTOBJS) $(PREOBJS)
 
-all: tewi$(EXEC) $(INSTALLER)
-
-install.exe: tewi$(EXEC) install.nsi
-       makensis install.nsi
+all: tewi$(EXEC)
 
 tewi$(EXEC): $(OBJS) ../Common/common.a
        $(CC) $(LDFLAGS) $(EXTLDFLAGS) -o $@ $(OBJS) $(EXTLIBS) $(LIBS) ../Common/common.a
index ec67f26cfdec23ed249783667c1e8cc5fb122836..b03a5db7f2a3e3d0da346e2f25ea65d091357ab4 100644 (file)
@@ -5,7 +5,12 @@ OutFile "install.exe"
 InstallDir "C:\Tewi"
 Icon "tewi.ico"
 LicenseData ../LICENSE
+
+!include "LogicLib.nsh"
+!include "Sections.nsh"
+
 Page license
+Page components
 Page instfiles
 UninstPage uninstConfirm
 UninstPage instfiles
@@ -17,8 +22,6 @@ Section
        CreateDirectory "$INSTDIR\bin"
        SetOutPath "$INSTDIR"
        File /oname=LICENSE.txt "../LICENSE"
-       SetOutPath "$INSTDIR\bin"
-       File "tewi.exe"
        SetOutPath "$INSTDIR\modules"
        File "../Module/*.dll"
        SetOutPath "$INSTDIR\etc"
@@ -42,7 +45,64 @@ Section
        WriteUninstaller "$INSTDIR\uninstall.exe"
 SectionEnd
 
+Section "Install the executable only" SEL_EXEC
+       SetOutPath "$INSTDIR\bin"
+       File "../tewi.exe"
+       WriteINIStr $INSTDIR\install.ini uninstall service false
+SectionEnd
+
+Section /o "Install the service too (NT-only)" SEL_SERVICE
+       WriteINIStr $INSTDIR\install.ini uninstall service true
+       FileOpen $9 $INSTDIR\install.bat w
+       FileWrite $9 '"$SYSDIR\sc.exe" stop "TewiHTTPd"$\r$\n'
+       FileClose $9
+       nsExec::Exec '"$INSTDIR\install.bat"'
+       Pop $0
+       DetailPrint "Waiting for 1s so service can stop..."
+       Sleep 1000
+       CreateDirectory "$INSTDIR\logs"
+       SetOutPath "$INSTDIR\bin"
+       File "../tewi.exe"
+       File /oname=tewisrv.exe "../tewi-service.exe"
+       FileOpen $9 $INSTDIR\install.bat w
+       FileWrite $9 '"$SYSDIR\sc.exe" delete "TewiHTTPd"$\r$\n'
+       FileWrite $9 '"$SYSDIR\sc.exe" create "TewiHTTPd" DisplayName= "Tewi HTTPd" binpath= "$INSTDIR\bin\tewisrv.exe" start= "auto"$\r$\n'
+       FileWrite $9 '"$SYSDIR\sc.exe" start "TewiHTTPd"$\r$\n'
+       FileClose $9
+       nsExec::Exec '"$INSTDIR\install.bat"'
+       Pop $0
+       Delete $INSTDIR\install.bat
+SectionEnd
+
+Function .onInit
+       StrCpy $1 ${SEL_EXEC}
+FunctionEnd
+
+Function .onSelChange
+       !insertmacro StartRadioButtons $1
+       !insertmacro RadioButton ${SEL_EXEC}
+       !insertmacro RadioButton ${SEL_SERVICE}
+       !insertmacro EndRadioButtons
+FunctionEnd
+
 Section "Uninstall"
+       ReadINIStr $8 $INSTDIR\install.ini uninstall service
+       ${If} $8 == "true"
+               FileOpen $9 $INSTDIR\uninstall.bat w
+               FileWrite $9 '"$SYSDIR\sc.exe" stop "TewiHTTPd"$\r$\n'
+               FileClose $9
+               nsExec::Exec '"$INSTDIR\uninstall.bat"'
+               Pop $0
+               FileOpen $9 $INSTDIR\uninstall.bat w
+               DetailPrint "Waiting for 1s so service can stop..."
+               Sleep 1000
+               FileWrite $9 '"$SYSDIR\sc.exe" delete "TewiHTTPd"$\r$\n'
+               FileClose $9
+               nsExec::Exec '"$INSTDIR\uninstall.bat"'
+               Pop $0
+               Delete $INSTDIR\uninstall.bat
+       ${EndIf}
+
        RMDir /r "$INSTDIR"
        RMDir /r "$SMPROGRAMS\Tewi HTTPd"
 
index bb7bf7a1d208bb6e991448bc21ec08254437615e..6105f9c6cccb6dae9f3c6263b6a6ffff74250bfc 100644 (file)
@@ -14,6 +14,7 @@
 #endif
 
 #include <cm_log.h>
+#include <cm_string.h>
 
 #include "tw_config.h"
 #include "tw_server.h"
 
 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) {
-       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);
+       logfile = stderr;
+#ifdef SERVICE
+       SERVICE_TABLE_ENTRY table[] = {{"Tewi HTTPd", servmain}, {NULL, NULL}};
+       StartServiceCtrlDispatcher(table);
 #else
-                                       cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
+       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";
+       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;
                        }
                }
        }
@@ -77,11 +138,13 @@ int main(int argc, char** argv) {
                return 1;
        }
        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);
 #else
        SetConsoleTitle(tw_server);
 #endif
-       tw_server_loop();
+       return -1;
 }
index 330ad678eccaa6cb1c0e196baff5a0665bee4cf9..1b3556625061babd3526a36e074f582b5525ae23 100644 (file)
@@ -31,6 +31,7 @@
 #ifdef __MINGW32__
 #include <winsock2.h>
 #include <process.h>
+#include <windows.h>
 
 #include "strptime.h"
 #else
@@ -696,6 +697,11 @@ cleanup:
        ;
 }
 
+#ifdef SERVICE
+extern SERVICE_STATUS status;
+extern SERVICE_STATUS_HANDLE status_handle;
+#endif
+
 void tw_server_loop(void) {
        struct timeval tv;
        while(1) {
@@ -709,6 +715,12 @@ void tw_server_loop(void) {
                int ret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
                if(ret == -1) {
                        break;
+               }else if(ret == 0){
+#ifdef SERVICE
+                       if(status.dwCurrentState == SERVICE_STOP_PENDING){
+                               break;
+                       }
+#endif
                } else if(ret > 0) {
                        /* connection */
                        int i;
diff --git a/installer.sh b/installer.sh
new file mode 100755 (executable)
index 0000000..60bcba7
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $Id$
+
+fail() {
+       rm -f tewi-service.exe
+       rm -f tewi.exe
+       exit 1
+}
+
+make clean || fail
+make PLATFORM=$1 -j4 || fail
+cp Server/tewi.exe tewi.exe
+make clean || fail
+make PLATFORM=$1-service -j4 || fail
+cp Server/tewi.exe tewi-service.exe
+cd Server
+makensis install.nsi
+rm -f tewi.exe tewi-service.exe
+cd ..