(main,close_files,loc_NT_Term,empth_exit):
Add Windows Service to the server. This includes adding install service and remove service option. Move the start code from main to separate function. Make close_files() and loc_NT_Term() global. Move disassoc() to be earlier in the startup sequence.
This commit is contained in:
parent
99ad950d9c
commit
e342a73130
6 changed files with 416 additions and 31 deletions
|
@ -48,8 +48,13 @@
|
||||||
#include "commodity.h"
|
#include "commodity.h"
|
||||||
|
|
||||||
/* src/server/main.c */
|
/* src/server/main.c */
|
||||||
|
extern void close_files(void);
|
||||||
extern void panic(int sig);
|
extern void panic(int sig);
|
||||||
extern void shutdwn(int sig);
|
extern void shutdwn(int sig);
|
||||||
|
extern void start_server(int, char *);
|
||||||
|
#if defined(_WIN32)
|
||||||
|
extern void loc_NTTerm(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* src/lib/ * / *.c
|
* src/lib/ * / *.c
|
||||||
|
@ -270,6 +275,10 @@ extern int command(void);
|
||||||
/* recvclient.c */
|
/* recvclient.c */
|
||||||
extern int recvclient(s_char *, int);
|
extern int recvclient(s_char *, int);
|
||||||
|
|
||||||
|
/* service.c */
|
||||||
|
extern int service_stopped(void);
|
||||||
|
/* more in service.h */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* src/lib/subs/ *.c
|
* src/lib/subs/ *.c
|
||||||
*/
|
*/
|
||||||
|
|
40
include/service.h
Normal file
40
include/service.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Empire - A multi-player, client/server Internet based war game.
|
||||||
|
* Copyright (C) 1986-2004, Dave Pare, Jeff Bailey, Thomas Ruschak,
|
||||||
|
* Ken Stevens, Steve McClure
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
|
||||||
|
* related information and legal notices. It is expected that any future
|
||||||
|
* projects/authors will amend these files as needed.
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* server.h: Windows services support
|
||||||
|
*
|
||||||
|
* Known contributors to this file:
|
||||||
|
* Ron Koenderink, 2004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERVICE_H
|
||||||
|
#define SERVICE_H
|
||||||
|
|
||||||
|
extern int install_service(char *program_name);
|
||||||
|
extern int remove_service(void);
|
||||||
|
extern void WINAPI service_main(DWORD argc, LPTSTR *argv);
|
||||||
|
#endif
|
|
@ -468,14 +468,20 @@ empth_exit(void)
|
||||||
loc_debug("empth_exit");
|
loc_debug("empth_exit");
|
||||||
|
|
||||||
if (pThread->bMainThread) {
|
if (pThread->bMainThread) {
|
||||||
char buf[20];
|
|
||||||
/* The main line. Wait forever. */
|
/* The main line. Wait forever. */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
if (!debug) {
|
||||||
|
if (service_stopped())
|
||||||
|
shutdwn(0);
|
||||||
|
Sleep(3);
|
||||||
|
} else {
|
||||||
|
char buf[20];
|
||||||
printf("\nEmpire Server>");
|
printf("\nEmpire Server>");
|
||||||
fgets(buf, sizeof(buf), stdin);
|
fgets(buf, sizeof(buf), stdin);
|
||||||
if (!strnicmp(buf, "quit", 4))
|
if (!strnicmp(buf, "quit", 4))
|
||||||
shutdwn(0);
|
shutdwn(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TlsSetValue(loc_GVAR.dwTLSIndex, NULL);
|
TlsSetValue(loc_GVAR.dwTLSIndex, NULL);
|
||||||
loc_FreeThreadInfo(pThread);
|
loc_FreeThreadInfo(pThread);
|
||||||
|
|
|
@ -45,7 +45,7 @@ NTOBJS = chance.obj copy.obj disassoc.obj \
|
||||||
emp_config.obj getstarg.obj getstring.obj \
|
emp_config.obj getstarg.obj getstring.obj \
|
||||||
io.obj ioqueue.obj mapdist.obj minmax.obj \
|
io.obj ioqueue.obj mapdist.obj minmax.obj \
|
||||||
numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \
|
numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \
|
||||||
scthash.obj strdup.obj getopt.obj
|
scthash.obj strdup.obj getopt.obj service.obj
|
||||||
|
|
||||||
all: $(LIB)
|
all: $(LIB)
|
||||||
|
|
||||||
|
|
270
src/lib/gen/service.c
Normal file
270
src/lib/gen/service.c
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
* Empire - A multi-player, client/server Internet based war game.
|
||||||
|
* Copyright (C) 1986-2004, Dave Pare, Jeff Bailey, Thomas Ruschak,
|
||||||
|
* Ken Stevens, Steve McClure
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
|
||||||
|
* related information and legal notices. It is expected that any future
|
||||||
|
* projects/authors will amend these files as needed.
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* service.c: Windows services support
|
||||||
|
*
|
||||||
|
* Known contributors to this file:
|
||||||
|
* Ron Koenderink, 2004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "prototypes.h"
|
||||||
|
#include "service.h"
|
||||||
|
#include "../gen/getopt.h"
|
||||||
|
#include "optlist.h"
|
||||||
|
|
||||||
|
#define SERVICE_NAME "Empire Server"
|
||||||
|
|
||||||
|
int
|
||||||
|
install_service(char *program_name)
|
||||||
|
{
|
||||||
|
char strDir[1024];
|
||||||
|
HANDLE schSCManager,schService;
|
||||||
|
LPCTSTR lpszBinaryPathName;
|
||||||
|
SERVICE_DESCRIPTION sdBuf;
|
||||||
|
|
||||||
|
if (strrchr(program_name,'\\') == NULL) {
|
||||||
|
GetCurrentDirectory(1024,strDir);
|
||||||
|
strcat(strDir, "\\");
|
||||||
|
strcat(strDir, program_name);
|
||||||
|
} else
|
||||||
|
strcpy(strDir, program_name);
|
||||||
|
|
||||||
|
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
|
||||||
|
|
||||||
|
if (schSCManager == NULL) {
|
||||||
|
logerror("install_service failed to open Service Control Manager");
|
||||||
|
printf("Install service: failed to open Service Control Manager.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpszBinaryPathName = strDir;
|
||||||
|
|
||||||
|
schService = CreateService(schSCManager,
|
||||||
|
SERVICE_NAME,
|
||||||
|
SERVICE_NAME, /* service name to display */
|
||||||
|
SERVICE_ALL_ACCESS, /* desired access */
|
||||||
|
SERVICE_WIN32_OWN_PROCESS, /* service type */
|
||||||
|
SERVICE_AUTO_START, /* start type */
|
||||||
|
SERVICE_ERROR_NORMAL, /* error control type */
|
||||||
|
lpszBinaryPathName, /* service's binary */
|
||||||
|
NULL, /* no load ordering group */
|
||||||
|
NULL, /* no tag identifier */
|
||||||
|
NULL, /* database service dependency */
|
||||||
|
NULL, /* LocalSystem account */
|
||||||
|
NULL); /* no password */
|
||||||
|
|
||||||
|
if (schService == NULL) {
|
||||||
|
logerror("install_service failed to create service");
|
||||||
|
printf("Install service: failed to create service.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
sdBuf.lpDescription = "Server for Empire game";
|
||||||
|
|
||||||
|
if(!ChangeServiceConfig2(
|
||||||
|
schService, /* handle to service */
|
||||||
|
SERVICE_CONFIG_DESCRIPTION, /* change: description */
|
||||||
|
&sdBuf)) { /* value: new description */
|
||||||
|
logerror("install_service failed to set the description");
|
||||||
|
printf("Install service: failed to set the description.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
logerror("install_service successfully created the service");
|
||||||
|
printf("Service installed.\n");
|
||||||
|
CloseServiceHandle(schService);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
remove_service(void)
|
||||||
|
{
|
||||||
|
HANDLE schSCManager;
|
||||||
|
SC_HANDLE hService;
|
||||||
|
|
||||||
|
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
|
||||||
|
|
||||||
|
if (schSCManager == NULL) {
|
||||||
|
logerror("remove_service failed to open Service Control Manager");
|
||||||
|
printf("remove service: failed to open Service Control Manager.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hService = OpenService(schSCManager,SERVICE_NAME,SERVICE_ALL_ACCESS);
|
||||||
|
|
||||||
|
if (hService == NULL) {
|
||||||
|
logerror("remove_service failed to open service");
|
||||||
|
printf("Remove service: failed to open service.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeleteService(hService) == 0) {
|
||||||
|
logerror("remove_service failed to remove service");
|
||||||
|
printf("Remove service: failed to remove service.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CloseServiceHandle(hService) == 0) {
|
||||||
|
logerror("remove_service failed to close service");
|
||||||
|
printf("Remove service: failed to close service.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
logerror("remove_service successfully removed service");
|
||||||
|
printf("Service removed.\n");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SERVICE_STATUS service_status;
|
||||||
|
static SERVICE_STATUS_HANDLE service_status_handle;
|
||||||
|
|
||||||
|
void WINAPI
|
||||||
|
service_ctrl_handler(DWORD Opcode)
|
||||||
|
{
|
||||||
|
DWORD status;
|
||||||
|
|
||||||
|
switch(Opcode)
|
||||||
|
{
|
||||||
|
case SERVICE_CONTROL_PAUSE:
|
||||||
|
service_status.dwCurrentState = SERVICE_PAUSED;
|
||||||
|
logerror("Pausing the service not supported");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_CONTROL_CONTINUE:
|
||||||
|
logerror("Continuing the service not supported");
|
||||||
|
service_status.dwCurrentState = SERVICE_RUNNING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_CONTROL_STOP:
|
||||||
|
service_status.dwWin32ExitCode = 0;
|
||||||
|
service_status.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
service_status.dwCheckPoint = 0;
|
||||||
|
service_status.dwWaitHint = 0;
|
||||||
|
|
||||||
|
if (!SetServiceStatus (service_status_handle,
|
||||||
|
&service_status)) {
|
||||||
|
status = GetLastError();
|
||||||
|
logerror("Error while stopping service SetServiceStatus"
|
||||||
|
" error %ld", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
logerror("Service stopped");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SERVICE_CONTROL_INTERROGATE:
|
||||||
|
/* Fall through to send current status. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logerror("Unrecognized opcode %ld in ServiceCtrlHandler",
|
||||||
|
Opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send current status. */
|
||||||
|
if (!SetServiceStatus (service_status_handle, &service_status)) {
|
||||||
|
status = GetLastError();
|
||||||
|
logerror("SetServiceStatus error %ld",status);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WINAPI
|
||||||
|
service_main(DWORD argc, LPTSTR *argv)
|
||||||
|
{
|
||||||
|
char *config_file = NULL;
|
||||||
|
int op;
|
||||||
|
s_char tbuf[256];
|
||||||
|
DWORD status;
|
||||||
|
|
||||||
|
while ((op = getopt(argc, argv, "D:e:")) != EOF) {
|
||||||
|
switch (op) {
|
||||||
|
case 'D':
|
||||||
|
datadir = optarg;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
config_file = optarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_file == NULL) {
|
||||||
|
sprintf(tbuf, "%s/econfig", datadir);
|
||||||
|
config_file = tbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
service_status.dwServiceType = SERVICE_WIN32;
|
||||||
|
service_status.dwCurrentState = SERVICE_START_PENDING;
|
||||||
|
service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||||
|
service_status.dwWin32ExitCode = 0;
|
||||||
|
service_status.dwServiceSpecificExitCode = 0;
|
||||||
|
service_status.dwCheckPoint = 0;
|
||||||
|
service_status.dwWaitHint = 0;
|
||||||
|
|
||||||
|
service_status_handle = RegisterServiceCtrlHandler(
|
||||||
|
SERVICE_NAME, service_ctrl_handler);
|
||||||
|
|
||||||
|
if (service_status_handle == (SERVICE_STATUS_HANDLE)0) {
|
||||||
|
logerror("RegisterServiceCtrlHandler failed %d\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialization code goes here. */
|
||||||
|
start_server(0, config_file);
|
||||||
|
|
||||||
|
/* Initialization complete - report running status. */
|
||||||
|
service_status.dwCurrentState = SERVICE_RUNNING;
|
||||||
|
service_status.dwCheckPoint = 0;
|
||||||
|
service_status.dwWaitHint = 0;
|
||||||
|
|
||||||
|
if (!SetServiceStatus (service_status_handle, &service_status)) {
|
||||||
|
status = GetLastError();
|
||||||
|
logerror("SetServiceStatus error %ld\n",status);
|
||||||
|
}
|
||||||
|
|
||||||
|
empth_exit();
|
||||||
|
|
||||||
|
/* We should never get here. But, just in case... */
|
||||||
|
close_files();
|
||||||
|
|
||||||
|
loc_NTTerm();
|
||||||
|
|
||||||
|
// This is where the service does its work.
|
||||||
|
logerror("Returning the Main Thread \n",0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
service_stopped(void)
|
||||||
|
{
|
||||||
|
if (service_status.dwCurrentState == SERVICE_STOPPED)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -49,6 +49,7 @@
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include "../lib/gen/getopt.h"
|
#include "../lib/gen/getopt.h"
|
||||||
|
#include "service.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -69,11 +70,9 @@
|
||||||
|
|
||||||
static void nullify_objects(void);
|
static void nullify_objects(void);
|
||||||
static void init_files(void);
|
static void init_files(void);
|
||||||
static void close_files(void);
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
static void loc_NTInit(void);
|
static void loc_NTInit(void);
|
||||||
static void loc_NTTerm(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int mainpid = 0;
|
static int mainpid = 0;
|
||||||
|
@ -89,7 +88,9 @@ static void
|
||||||
print_usage(char *program_name)
|
print_usage(char *program_name)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
printf("Usage: %s -D datadir -e config_file -d\n", program_name);
|
printf("Usage: %s -i -r -D datadir -e config_file -d\n", program_name);
|
||||||
|
printf("-i install service\n");
|
||||||
|
printf("-r remove service\n");
|
||||||
#else
|
#else
|
||||||
printf("Usage: %s -D datadir -e config_file -d -p -s\n", program_name);
|
printf("Usage: %s -D datadir -e config_file -d -p -s\n", program_name);
|
||||||
printf("-p print flag\n");
|
printf("-p print flag\n");
|
||||||
|
@ -102,25 +103,30 @@ int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
int install_service_set = 0;
|
||||||
|
int remove_service_set = 0;
|
||||||
|
int datadir_set = 0;
|
||||||
|
#endif
|
||||||
int op;
|
int op;
|
||||||
char *config_file = NULL;
|
char *config_file = NULL;
|
||||||
s_char tbuf[256];
|
s_char tbuf[256];
|
||||||
#ifdef POSIXSIGNALS
|
|
||||||
struct sigaction act;
|
|
||||||
#endif /* POSIXSIGNALS */
|
|
||||||
|
|
||||||
loginit("server");
|
loginit("server");
|
||||||
|
|
||||||
mainpid = getpid();
|
mainpid = getpid();
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
while ((op = getopt(argc, argv, "D:de:h")) != EOF) {
|
while ((op = getopt(argc, argv, "D:de:irh")) != EOF) {
|
||||||
#else
|
#else
|
||||||
while ((op = getopt(argc, argv, "D:de:psh")) != EOF) {
|
while ((op = getopt(argc, argv, "D:de:psh")) != EOF) {
|
||||||
#endif
|
#endif
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 'D':
|
case 'D':
|
||||||
datadir = optarg;
|
datadir = optarg;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
datadir_set++;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
debug++;
|
debug++;
|
||||||
|
@ -128,7 +134,14 @@ main(int argc, char **argv)
|
||||||
case 'e':
|
case 'e':
|
||||||
config_file = optarg;
|
config_file = optarg;
|
||||||
break;
|
break;
|
||||||
#if !defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
case 'i':
|
||||||
|
install_service_set++;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
remove_service_set++;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
case 'p':
|
case 'p':
|
||||||
flags |= EMPTH_PRINT;
|
flags |= EMPTH_PRINT;
|
||||||
break;
|
break;
|
||||||
|
@ -139,10 +152,31 @@ main(int argc, char **argv)
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
return 0;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if ((debug || datadir_set || config_file != NULL) &&
|
||||||
|
(install_service_set || remove_service_set)) {
|
||||||
|
logerror("Can't use -d or -D or -e with either "
|
||||||
|
"-r or -i options when starting the server");
|
||||||
|
printf("Can't use -d or -D or -e with either -r "
|
||||||
|
"or -i options\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (install_service_set && remove_service_set) {
|
||||||
|
logerror("Can't use both -r and -i options when starting "
|
||||||
|
"the server");
|
||||||
|
printf("Can't use both -r and -i options\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (install_service_set)
|
||||||
|
return install_service(argv[0]);
|
||||||
|
if (remove_service_set)
|
||||||
|
return remove_service();
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
if (config_file == NULL) {
|
if (config_file == NULL) {
|
||||||
sprintf(tbuf, "%s/econfig", datadir);
|
sprintf(tbuf, "%s/econfig", datadir);
|
||||||
config_file = tbuf;
|
config_file = tbuf;
|
||||||
|
@ -151,6 +185,46 @@ main(int argc, char **argv)
|
||||||
logerror("------------------------------------------------------");
|
logerror("------------------------------------------------------");
|
||||||
logerror("Empire server (pid %d) started", (int)getpid());
|
logerror("Empire server (pid %d) started", (int)getpid());
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if (debug == 0) {
|
||||||
|
SERVICE_TABLE_ENTRY DispatchTable[]={{"Empire Server", service_main},{NULL, NULL}};
|
||||||
|
if (StartServiceCtrlDispatcher(DispatchTable))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
if (GetLastError() != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
|
||||||
|
logerror("Failed to dispatch service (%d)", GetLastError());
|
||||||
|
printf("Failed to dispatch service (%d)\n", GetLastError());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else /* start in the foreground */
|
||||||
|
debug = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (debug == 0 && flags == 0) {
|
||||||
|
disassoc();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
start_server(flags, config_file);
|
||||||
|
|
||||||
|
empth_exit();
|
||||||
|
|
||||||
|
/* We should never get here. But, just in case... */
|
||||||
|
close_files();
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
loc_NTTerm();
|
||||||
|
#endif
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
start_server(int flags, char *config_file)
|
||||||
|
{
|
||||||
|
#ifdef POSIXSIGNALS
|
||||||
|
struct sigaction act;
|
||||||
|
#endif /* POSIXSIGNALS */
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
loc_NTInit();
|
loc_NTInit();
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,9 +241,6 @@ main(int argc, char **argv)
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
#endif
|
#endif
|
||||||
sigemptyset(&act.sa_mask);
|
sigemptyset(&act.sa_mask);
|
||||||
if (debug == 0 && flags == 0) {
|
|
||||||
disassoc();
|
|
||||||
}
|
|
||||||
act.sa_handler = shutdwn;
|
act.sa_handler = shutdwn;
|
||||||
/* pthreads on Linux use SIGUSR1 (*shrug*) so only catch it if not on
|
/* pthreads on Linux use SIGUSR1 (*shrug*) so only catch it if not on
|
||||||
a Linux box running POSIX threads -- STM */
|
a Linux box running POSIX threads -- STM */
|
||||||
|
@ -187,7 +258,6 @@ main(int argc, char **argv)
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
#else
|
#else
|
||||||
if (debug == 0 && flags == 0) {
|
if (debug == 0 && flags == 0) {
|
||||||
disassoc();
|
|
||||||
/* pthreads on Linux use SIGUSR1 (*shrug*) so only catch it if not on
|
/* pthreads on Linux use SIGUSR1 (*shrug*) so only catch it if not on
|
||||||
a Linux box running POSIX threads -- STM */
|
a Linux box running POSIX threads -- STM */
|
||||||
#if !(defined(__linux__) && defined(_EMPTH_POSIX))
|
#if !(defined(__linux__) && defined(_EMPTH_POSIX))
|
||||||
|
@ -243,16 +313,6 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
sprintf(argv[0], "%s (main pid: %d)", tbuf, getpid());
|
sprintf(argv[0], "%s (main pid: %d)", tbuf, getpid());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
empth_exit();
|
|
||||||
|
|
||||||
/* We should never get here. But, just in case... */
|
|
||||||
close_files();
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
loc_NTTerm();
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -275,7 +335,7 @@ init_files(void)
|
||||||
ef_open(EF_LOST, O_RDWR, 0);
|
ef_open(EF_LOST, O_RDWR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
close_files(void)
|
close_files(void)
|
||||||
{
|
{
|
||||||
ef_close(EF_NATION);
|
ef_close(EF_NATION);
|
||||||
|
@ -483,7 +543,7 @@ loc_NTInit()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
static void
|
void
|
||||||
loc_NTTerm()
|
loc_NTTerm()
|
||||||
{
|
{
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue