Added NT service functionality

SVN revision: 889
This commit is contained in:
2004-06-05 21:45:55 +00:00
parent 5bd59d1f7e
commit 1bb19cac49
+307 -24
View File
@@ -6,6 +6,9 @@
Contents: Web server program for Electronic Logbook ELOG
$Log$
Revision 1.335 2004/06/05 21:45:55 midas
Added NT service functionality
Revision 1.334 2004/06/04 22:20:20 midas
Added missing translations
@@ -4523,6 +4526,39 @@ void logf(LOGBOOK * lbs, const char *format, ...)
/*------------------------------------------------------------------*/
/*
void logd(const char *format, ...)
{
va_list argptr;
char str[10000];
FILE *f;
time_t now;
char buf[1000];
va_start(argptr, format);
vsprintf(str, (char *) format, argptr);
va_end(argptr);
f = fopen("c:\\tmp\\elogd.log", "a");
if (!f)
return;
now = time(0);
strftime(buf, sizeof(buf), "%d-%b-%Y %H:%M:%S", localtime(&now));
strcat(buf, " ");
strlcat(buf, str, sizeof(buf));
if (buf[strlen(buf) - 1] != '\n')
strlcat(buf, "\n", sizeof(buf));
fprintf(f, buf);
fclose(f);
}
*/
/*------------------------------------------------------------------*/
int is_html(char *s)
{
char *str;
@@ -18395,6 +18431,214 @@ void cleanup(void)
/*------------------------------------------------------------------*/
#ifdef OS_WINNT
/* Routines for Windows service management */
// Executable name
#define ELOGDAPPNAME "elogd"
// Internal service name
#define ELOGDSERVICENAME "elgod"
// Displayed service name
#define ELOGDSERVICEDISPLAYNAME "ELOG Server"
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
int install_service(void)
{
OSVERSIONINFO vi;
char path[2048], cmd[2080];
SC_HANDLE hservice;
SC_HANDLE hsrvmanager;
/* check for Windows NT+ */
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&vi);
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
printf("Can install service only under Windows NT/2k/XP\n");
return -1;
}
if (GetModuleFileName(NULL, path, sizeof(path)) == 0) {
return -1;
}
sprintf(cmd, "\"%s\" -D", path);
/* Open the default, local Service Control Manager database */
hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hsrvmanager == NULL)
return -1;
/* Create an entry for the elogd service */
hservice = CreateService(hsrvmanager, // SCManager database
ELOGDSERVICENAME, // name of service
ELOGDSERVICEDISPLAYNAME, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
// service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
cmd, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
"", // dependencies
NULL, // LocalSystem account
NULL); // no password
if (hservice == NULL) {
if (GetLastError() == ERROR_SERVICE_EXISTS)
printf("The elogd service is already registered");
else
printf("The elogd service could not be registered");
} else {
/* Try to start the elogd service */
if (!StartService(hservice, 0, NULL))
printf("The elogd service could not be started");
CloseServiceHandle(hservice);
}
CloseServiceHandle(hsrvmanager);
return 1;
}
int remove_service(void)
{
SC_HANDLE hservice;
SC_HANDLE hsrvmanager;
SERVICE_STATUS status;
/* Open the SCM */
hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hsrvmanager == NULL)
return -1;
hservice = OpenService(hsrvmanager, ELOGDSERVICENAME, SERVICE_ALL_ACCESS);
if (hservice == NULL) {
printf("The elogd service could not be found");
return -1;
}
/* Try to stop the elogd service */
if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) {
while (QueryServiceStatus(hservice, &status)) {
if (status.dwCurrentState == SERVICE_STOP_PENDING)
Sleep(1000);
else
break;
}
if (status.dwCurrentState != SERVICE_STOPPED) {
printf("The elogd service could not be stopped");
}
}
/* Now remove the service from the SCM */
if (!DeleteService(hservice)) {
if (GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE)
printf("The elogd service is already marked to be unregistered");
else
printf("The elogd service could not be unregistered");
}
CloseServiceHandle(hservice);
CloseServiceHandle(hsrvmanager);
return 1;
}
void WINAPI ServiceControlHandler(DWORD controlCode)
{
switch (controlCode)
{
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus( serviceStatusHandle, &serviceStatus );
_abort = TRUE;
return;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
default:
if (controlCode >= 128 && controlCode <= 255)
// user defined control code
break;
else
// unrecognised control code
break;
}
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
{
// initialise service status
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwControlsAccepted = 0;
serviceStatus.dwWin32ExitCode = NO_ERROR;
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatusHandle = RegisterServiceCtrlHandler(ELOGDSERVICENAME, ServiceControlHandler);
if (serviceStatusHandle) {
// service is starting
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
// running
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
/* start main server, exit with "_abort = TRUE" */
server_loop(tcp_port, FALSE);
// service was stopped
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
// service is now stopped
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
}
void run_service(void)
{
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ ELOGDSERVICENAME, ServiceMain },
{ 0, 0 }
};
StartServiceCtrlDispatcher(serviceTable);
}
#endif
/*------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int i, fh, tcp_port_cl;
@@ -18410,14 +18654,21 @@ int main(int argc, char *argv[])
orig_gid = getegid();
orig_uid = geteuid();
#endif
/* register cleanup function */
atexit(cleanup);
tzset();
/* initialize variables */
read_pwd[0] = write_pwd[0] = admin_pwd[0] = logbook[0] = 0;
logbook_dir[0] = resource_dir[0] = logbook_dir[0] = pidfile[0] = 0;
tcp_port_cl = 0;
use_keepalive = TRUE;
/* default config file */
strcpy(config_file, "elogd.cfg");
/* evaluate predefined files and directories */
#ifdef CONFIG_FILE
strlcpy(config_file, CONFIG_FILE, sizeof(config_file));
@@ -18428,25 +18679,7 @@ int main(int argc, char *argv[])
#ifdef LOGBOOK_DIR
strlcpy(logbook_dir, LOGBOOK_DIR, sizeof(logbook_dir));
#endif
/* look for config file in command line parameters */
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == 'c')
strcpy(config_file, argv[i + 1]);
}
/* check for configuration file */
fh = open(config_file, O_RDONLY | O_BINARY);
if (fh < 0) {
printf("Configuration file \"%s\" not found.\n", config_file);
exit(EXIT_FAILURE);
}
close(fh);
/* evaluate directories fron config file */
if (getcfg("global", "Resource Dir", str))
strlcpy(resource_dir, str, sizeof(resource_dir));
if (getcfg("global", "Logbook Dir", str))
strlcpy(logbook_dir, str, sizeof(logbook_dir));
use_keepalive = TRUE;
/* parse command line parameters */
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == 'D')
@@ -18464,7 +18697,19 @@ int main(int argc, char *argv[])
tms->tm_year % 100, tms->tm_mon + 1, tms->tm_mday, tms->tm_hour,
tms->tm_min, tms->tm_sec);
exit(EXIT_SUCCESS);
} else if (argv[i][0] == '-') {
}
#ifdef OS_WINNT
else if (stricmp(argv[i], "-install") == 0) {
install_service();
exit(EXIT_SUCCESS);
} else if (stricmp(argv[i], "-remove") == 0) {
remove_service();
exit(EXIT_SUCCESS);
}
#endif
else if (argv[i][0] == '-') {
if (i + 1 >= argc || argv[i + 1][0] == '-')
goto usage;
if (argv[i][1] == 'p')
@@ -18483,17 +18728,16 @@ int main(int argc, char *argv[])
strcpy(admin_pwd, argv[++i]);
else if (argv[i][1] == 'l')
strcpy(logbook, argv[++i]);
else if (argv[i][1] == 'h')
else if (argv[i][1] == 'n')
strlcpy(tcp_hostname, argv[++i], sizeof(tcp_hostname));
else if (argv[i][1] == 'f')
strlcpy(pidfile, argv[++i], sizeof(pidfile));
else {
usage:
printf
("usage: %s [-p port] [-h hostname] [-D] [-c file] [-r pwd] [-w pwd] [-a pwd] [-l logbook] [-k] [-f file]\n\n",
argv[0]);
printf("\nusage: elogd [-p port] [-n hostname] [-D] [-c file] [-r pwd] ");
printf("[-w pwd] [-a pwd] [-l logbook] [-k] [-f file] [-x]\n\n");
printf(" -p <port> TCP/IP port\n");
printf(" -h <hostname> TCP/IP hostname\n");
printf(" -n <hostname> TCP/IP hostname\n");
printf(" -D become a daemon\n");
printf(" -c <file> specify configuration file\n");
printf(" -s <dir> specify resource directory (themes, icons, ...)\n");
@@ -18506,11 +18750,44 @@ int main(int argc, char *argv[])
printf(" -k do not use keep-alive\n");
printf(" -f path/filename for PID file\n");
printf(" -x enable execution of shell commands\n\n");
printf(" -h this help\n\n");
#ifdef OS_WINNT
printf("Windows service funtions:\n");
printf(" -install install elogd as service and start it\n");
printf(" -remove stop and remove elogd service\n");
#endif
exit(EXIT_SUCCESS);
}
}
}
#ifdef OS_WINNT
if (daemon) {
/* change to directory of executable */
strcpy(str, argv[0]);
for (i=strlen(str)-1 ; i>0 ; i--)
if (str[i] != '\\')
str[i] = 0;
else
break;
chdir(str);
}
#endif
/* check for configuration file */
fh = open(config_file, O_RDONLY | O_BINARY);
if (fh < 0) {
printf("Configuration file \"%s\" not found.\n", config_file);
exit(EXIT_FAILURE);
}
close(fh);
/* evaluate directories fron config file */
if (getcfg("global", "Resource Dir", str))
strlcpy(resource_dir, str, sizeof(resource_dir));
if (getcfg("global", "Logbook Dir", str))
strlcpy(logbook_dir, str, sizeof(logbook_dir));
if ((read_pwd[0] || write_pwd[0] || admin_pwd[0]) && !logbook[0]) {
printf("Must specify a lookbook via the -l parameter.\n");
exit(EXIT_SUCCESS);
@@ -18580,6 +18857,12 @@ int main(int argc, char *argv[])
tcp_port = atoi(str);
}
#ifdef OS_WINNT
if (daemon)
run_service();
else
#endif
server_loop(tcp_port, daemon);
exit(EXIT_SUCCESS);
}