]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add first revision of windows services. fix breakage of -stop.
authorMichael Jerris <mike@jerris.com>
Sun, 20 Aug 2006 03:04:55 +0000 (03:04 +0000)
committerMichael Jerris <mike@jerris.com>
Sun, 20 Aug 2006 03:04:55 +0000 (03:04 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2339 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/switch.c
src/switch_core.c

index 3966f5f9ee9acd9111f62d63101063606b584f0c..5e298b67d9f17ceb3b465f370e6a16c0cc71d6fe 100644 (file)
@@ -37,6 +37,7 @@
 static int RUNNING = 0;
 static char *lfile = LOGFILE;
 static char *pfile = PIDFILE;
+#define SERVICENAME "Freeswitch"
 
 #ifdef __ICC
 #pragma warning (disable:167)
@@ -44,6 +45,8 @@ static char *pfile = PIDFILE;
 
 
 #ifdef WIN32
+#include <winsock2.h>
+#include <windows.h>
 static HANDLE shutdown_event;
 #endif
 
@@ -86,6 +89,7 @@ static int freeswitch_kill_background()
        FILE *f;
        char path[256] = "";
        pid_t pid = 0;
+       switch_core_set_globals();
        snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile);
        if ((f = fopen(path, "r")) == 0) {
                fprintf(stderr, "Cannot open pid file %s.\n", path);
@@ -113,6 +117,55 @@ static int freeswitch_kill_background()
        return 0;
 }
 
+#ifdef WIN32
+SERVICE_STATUS_HANDLE hStatus;\r
+SERVICE_STATUS status;\r
+\r
+void WINAPI ServiceCtrlHandler( DWORD control )\r
+{\r
+    switch( control )\r
+    {\r
+    case SERVICE_CONTROL_SHUTDOWN:\r
+    case SERVICE_CONTROL_STOP:\r
+        // do shutdown stuff here\r
+               switch_core_destroy();\r
+        status.dwCurrentState = SERVICE_STOPPED;\r
+        status.dwWin32ExitCode = 0;\r
+        status.dwCheckPoint = 0;\r
+        status.dwWaitHint = 0;\r
+        break;\r
+    case SERVICE_CONTROL_INTERROGATE:\r
+        // just set the current state to whatever it is...\r
+        break;\r
+    }\r
+\r
+    SetServiceStatus( hStatus, &status );\r
+}\r
+\r
+void WINAPI service_main( DWORD numArgs, char **args )\r
+{\r
+       const char *err = NULL;
+    // we have to initialize the service-specific stuff\r
+    memset( &status, 0, sizeof(SERVICE_STATUS) );\r
+    status.dwServiceType = SERVICE_WIN32;\r
+    status.dwCurrentState = SERVICE_START_PENDING;\r
+    status.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
+\r
+    hStatus = RegisterServiceCtrlHandler( SERVICENAME, &ServiceCtrlHandler );\r
+\r
+    SetServiceStatus( hStatus, &status );\r
+       set_high_priority();
+       if (switch_core_init_and_modload(lfile, &err) != SWITCH_STATUS_SUCCESS) {
+           status.dwCurrentState = SERVICE_STOPPED;\r
+       } else {
+               status.dwCurrentState = SERVICE_RUNNING;
+       }
+\r
+    SetServiceStatus( hStatus, &status );\r
+}\r
+\r
+#endif
+
 int main(int argc, char *argv[])
 {
        char path[256] = "";
@@ -122,8 +175,59 @@ int main(int argc, char *argv[])
        FILE *f;
        pid_t pid = 0;
 
+#ifdef WIN32
+    SERVICE_TABLE_ENTRY dispatchTable[] =
+    {
+        { SERVICENAME, &service_main },
+        { NULL, NULL }
+    };
+
+       if (argv[1] && !strcmp(argv[1], "-service")) {
+               if(StartServiceCtrlDispatcher( dispatchTable ) == 0 )\r
+               {\r
+                       //Not loaded as a service\r
+                       fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
+                       fprintf(stderr, "To install the service load freeswitch with -install\n");
+               }\r
+               exit(0);\r
+       }
+       if (argv[1] && !strcmp(argv[1], "-install")) {
+               char exePath[1024];
+           char servicePath[1024];
+
+               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );\r
+               GetModuleFileName( NULL, exePath, 1024 );
+               snprintf(servicePath, sizeof(servicePath), "%s -service", exePath);
+               CreateService(\r
+                       handle,\r
+                       SERVICENAME,\r
+                       SERVICENAME,\r
+                       GENERIC_READ | GENERIC_EXECUTE,\r
+                       SERVICE_WIN32_OWN_PROCESS,\r
+                       SERVICE_AUTO_START,\r
+                       SERVICE_ERROR_IGNORE,\r
+                       servicePath,\r
+                       NULL,\r
+                       NULL,\r
+                       NULL,\r
+                       NULL,\r
+                       NULL\r
+               );\r
+               exit(0);
+       }
+       if (argv[1] && !strcmp(argv[1], "-uninstall")) {
+               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );\r
+               SC_HANDLE service = OpenService( handle, SERVICENAME, DELETE );\r
+               if( service != NULL )\r
+               {\r
+                       // remove the service!\r
+                       DeleteService( service );\r
+               }\r
+               exit(0);
+       }
+#endif
+
        set_high_priority();
-       switch_core_set_globals();
 
        if (argv[1] && !strcmp(argv[1], "-stop")) {
                return freeswitch_kill_background();
@@ -133,15 +237,6 @@ int main(int argc, char *argv[])
                bg++;
        }
 
-       snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile);
-       if ((f = fopen(path, "w")) == 0) {
-               fprintf(stderr, "Cannot open pid file %s.\n", path);
-               return 255;
-       }
-
-       fprintf(f, "%d", pid = getpid());
-       fclose(f);
-
        if (bg) {
                ppath = lfile;
 
@@ -150,7 +245,7 @@ int main(int argc, char *argv[])
 
 #ifdef WIN32
                FreeConsole();
-               snprintf(path, sizeof(path), "Global\\Freeswitch.%d", pid);
+               snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid());
                shutdown_event = CreateEvent(NULL, FALSE, FALSE, path);         
 #else
                if ((pid = fork())) {
@@ -165,6 +260,15 @@ int main(int argc, char *argv[])
                return 255;
        }
 
+       snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile);
+       if ((f = fopen(path, "w")) == 0) {
+               fprintf(stderr, "Cannot open pid file %s.\n", path);
+               return 255;
+       }
+
+       fprintf(f, "%d", pid = getpid());
+       fclose(f);
+
        freeswitch_runtime_loop(bg);
 
        return switch_core_destroy();
index 25ef90660fac3a4dc3084480da390778487b2df4..d9cf79e9b1ff8a717f22c31e39d1e472d358638e 100644 (file)
@@ -2955,10 +2955,36 @@ static void core_event_handler(switch_event_t *event)
 SWITCH_DECLARE(void) switch_core_set_globals(void)
 {
 #ifdef WIN32
-#define BUFSIZE 50
+#define BUFSIZE 1024
     char lpPathBuffer[BUFSIZE];
        DWORD dwBufSize=BUFSIZE;
-#endif
+       char exePath[1024];
+       char *lastbacklash;
+       GetModuleFileName( NULL, exePath, BUFSIZE );
+       lastbacklash = strrchr( exePath, '\\');\r
+       exePath[(lastbacklash - exePath + 1)] = '\0';
+       if ((SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s\\mod", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s\\conf", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s\\log", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s\\db", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s\\scripts", exePath);
+       }
+       if ((SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s\\mod", exePath);
+       }
+#else
        SWITCH_GLOBAL_dirs.base_dir = SWITCH_PREFIX_DIR;
        SWITCH_GLOBAL_dirs.mod_dir = SWITCH_MOD_DIR;
        SWITCH_GLOBAL_dirs.conf_dir = SWITCH_CONF_DIR;
@@ -2966,12 +2992,15 @@ SWITCH_DECLARE(void) switch_core_set_globals(void)
        SWITCH_GLOBAL_dirs.db_dir = SWITCH_DB_DIR;
        SWITCH_GLOBAL_dirs.script_dir = SWITCH_SCRIPT_DIR;
        SWITCH_GLOBAL_dirs.htdocs_dir = SWITCH_HTDOCS_DIR;
+#endif
 #ifdef SWITCH_TEMP_DIR
        SWITCH_GLOBAL_dirs.temp_dir = SWITCH_TEMP_DIR;
 #else
 #ifdef WIN32
        GetTempPath(dwBufSize, lpPathBuffer);
-       SWITCH_GLOBAL_dirs.temp_dir = lpPathBuffer;
+       if ((SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) {
+               snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", lpPathBuffer);
+       }
 #else
        SWITCH_GLOBAL_dirs.temp_dir = "/tmp/";
 #endif