diff options
author | unknown <miguel@hegel.br> | 2002-10-16 21:51:03 -0200 |
---|---|---|
committer | unknown <miguel@hegel.br> | 2002-10-16 21:51:03 -0200 |
commit | 2e6dff75ad0ae9ef8fc6664f4b4d78c90b3fe199 (patch) | |
tree | c02a595ff949f725ab6f96f5305d88a7e48dc746 | |
parent | 74b73109c1304e62430faa85d2a63a6f2ffa626d (diff) | |
download | mariadb-git-2e6dff75ad0ae9ef8fc6664f4b4d78c90b3fe199.tar.gz |
Added optional NT service and fix the TZ variable bug
mysys/my_init.c:
Fix the TZ variable bug: 100% CPU usage
sql/mysqld.cc:
Added optional NT service
sql/nt_servc.cc:
Added optional NT service
sql/nt_servc.h:
Added optional NT service
-rw-r--r-- | mysys/my_init.c | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 130 | ||||
-rw-r--r-- | sql/nt_servc.cc | 91 | ||||
-rw-r--r-- | sql/nt_servc.h | 4 |
4 files changed, 195 insertions, 34 deletions
diff --git a/mysys/my_init.c b/mysys/my_init.c index 31e49731c94..6a0e2444a62 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -219,6 +219,10 @@ static void my_win_init(void) setlocale(LC_CTYPE, ""); /* To get right sortorder */ + /* Clear the OS system variable TZ and avoid the 100% CPU usage */ + _putenv( "TZ=" ); + _tzset(); + /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0, KEY_READ,&hSoftMysql) != ERROR_SUCCESS) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2edde0ed684..0c30db6f82e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -175,7 +175,9 @@ static uint handler_count; static bool opt_enable_named_pipe = 0; #endif #ifdef __WIN__ -static bool opt_console=0,start_mode=0; +static bool opt_console=0,start_mode=0, use_opt_args; +static int opt_argc; +static char **opt_argv; #endif /* Set prefix for windows binary */ @@ -381,6 +383,7 @@ enum db_type default_table_type=DB_TYPE_MYISAM; #undef getpid #include <process.h> HANDLE hEventShutdown; +static char *event_name; #include "nt_servc.h" static NTService Service; // Service object for WinNT #endif @@ -2120,63 +2123,126 @@ The server will not act as a slave."); } -#ifdef __WIN__ -/* ------------------------------------------------------------------------ - main and thread entry function for Win32 - (all this is needed only to run mysqld as a service on WinNT) - -------------------------------------------------------------------------- */ +#if defined(__WIN__) int mysql_service(void *p) { - win_main(Service.my_argc, Service.my_argv); + if (use_opt_args) + win_main(opt_argc, opt_argv); + else + win_main(Service.my_argc, Service.my_argv); return 0; } +/* + Handle basic handling of services, like installation and removal + + SYNOPSIS + default_service_handling() + argv Pointer to argument list + servicename Internal name of service + displayname Display name of service (in taskbar ?) + file_path Path to this program + + RETURN VALUES + 0 option handled + 1 Could not handle option + */ + +bool default_service_handling(char **argv, + const char *servicename, + const char *displayname, + const char *file_path) +{ + if (Service.got_service_option(argv, "install")) + { + Service.Install(1, servicename, displayname, file_path); + return 0; + } + if (Service.got_service_option(argv, "install-manual")) + { + Service.Install(0, servicename, displayname, file_path); + return 0; + } + if (Service.got_service_option(argv, "remove")) + { + Service.Remove(servicename); + return 0; + } + return 1; +} + + int main(int argc, char **argv) { - // check environment variable OS - if (Service.GetOS()) // "OS" defined; Should be NT + if (Service.GetOS()) /* true NT family */ { + char file_path[FN_REFLEN]; + my_path(file_path, argv[0], ""); /* Find name in path */ + fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */ + if (argc == 2) + { + if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME, + file_path)) + return 0; + if (Service.IsService(argv[1])) + { + /* start an optional service */ + event_name= argv[1]; + load_default_groups[0]= argv[1]; + start_mode= 1; + Service.Init(event_name, mysql_service); + return 0; + } + } + else if (argc == 3) /* install or remove any optional service */ { - char path[FN_REFLEN]; - my_path(path, argv[0], ""); // Find name in path - fn_format(path,argv[0],path,"",1+4+16); // Force use of full path + /* Add service name after filename */ + uint length=strlen(file_path); + *strxnmov(file_path + length, sizeof(file_path)-length-2, " ", + argv[2], NullS)= '\0'; - if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install")) - { - Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); + if (!default_service_handling(argv, argv[2], argv[2], file_path)) return 0; - } - else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual")) + if (Service.IsService(argv[2])) { - Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); + /* start an optional service */ + use_opt_args=1; + opt_argc=argc; + opt_argv=argv; + event_name= argv[2]; + start_mode= 1; + Service.Init(event_name, mysql_service); return 0; } - else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove")) - { - Service.Remove(MYSQL_SERVICENAME); + } + else if (argc == 4) + { + /* + Install an optional service with optional config file + mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini + */ + uint length=strlen(file_path); + *strxnmov(file_path + length, sizeof(file_path)-length-2, " ", + argv[3], " ", argv[2], NullS)= '\0'; + if (!default_service_handling(argv, argv[2], argv[2], file_path)) return 0; - } } - else if (argc == 1) // No arguments; start as a service + else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME)) { - // init service - start_mode = 1; - long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service); + /* start the default service */ + start_mode= 1; + event_name= "MySqlShutdown"; + Service.Init(MYSQL_SERVICENAME, mysql_service); return 0; } } - - // This is a WIN95 machine or a start of mysqld as a standalone program - // we have to pass the arguments, in case of NT-service this will be done - // by ServiceMain() - + /* Start as standalone server */ Service.my_argc=argc; Service.my_argv=argv; mysql_service(NULL); return 0; } -/* ------------------------------------------------------------------------ */ #endif diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 8c705a94f55..b917c91ce15 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -426,7 +426,17 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) // open a connection to the SCM if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE))) - printf("There is a problem with the Service Control Manager!\n"); + { + DWORD ret_error=GetLastError(); + if (ret_error == ERROR_ACCESS_DENIED) + { + printf("Install/Remove of the Service Denied!\n"); + if(!is_super_user()) + printf("That operation should be made by an user with Administrator privileges!\n"); + } + else + printf("There is a problem for to open the Service Control Manager!\n"); + } else { if (OperationType == 1) @@ -479,3 +489,82 @@ If this condition persist, reboot the machine and try again\n"); return ret_value; } +/* ------------------------------------------------------------------------ + -------------------------------------------------------------------------- */ +BOOL NTService::IsService(LPCSTR ServiceName) +{ + BOOL ret_value=FALSE; + SC_HANDLE service, scm; + + if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE)) + { + if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS ))) + { + ret_value=TRUE; + CloseServiceHandle(service); + } + CloseServiceHandle(scm); + } + return ret_value; +} +/* ------------------------------------------------------------------------ + -------------------------------------------------------------------------- */ +BOOL NTService::got_service_option(char **argv, char *service_option) +{ + char *option; + for (option= argv[1]; *option; option++) + if (!strcmp(option, service_option)) + return TRUE; + return FALSE; +} +/* ------------------------------------------------------------------------ + -------------------------------------------------------------------------- */ +BOOL NTService::is_super_user() +{ + HANDLE hAccessToken; + UCHAR InfoBuffer[1024]; + PTOKEN_GROUPS ptgGroups=(PTOKEN_GROUPS)InfoBuffer; + DWORD dwInfoBufferSize; + PSID psidAdministrators; + SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY; + UINT x; + BOOL ret_value=FALSE; + + if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,&hAccessToken )) + { + if(GetLastError() != ERROR_NO_TOKEN) + return FALSE; + + if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken)) + return FALSE; + } + + ret_value= GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer, + 1024, &dwInfoBufferSize); + + CloseHandle(hAccessToken); + + if(!ret_value ) + return FALSE; + + if(!AllocateAndInitializeSid(&siaNtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &psidAdministrators)) + return FALSE; + + ret_value = FALSE; + + for(x=0;x<ptgGroups->GroupCount;x++) + { + if( EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid) ) + { + ret_value = TRUE; + break; + } + + } + FreeSid(psidAdministrators); + return ret_value; +} diff --git a/sql/nt_servc.h b/sql/nt_servc.h index 40d1a8c03fa..6d74eaccea2 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -52,7 +52,9 @@ class NTService LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL); BOOL SeekStatus(LPCSTR szInternName, int OperationType); BOOL Remove(LPCSTR szInternName); - + BOOL IsService(LPCSTR ServiceName); + BOOL got_service_option(char **argv, char *service_option); + BOOL is_super_user(); void Stop(void); //to be called from app. to stop service protected: |