my_manage.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:18k
- /*
- Copyright (c) 2003 Novell, Inc. All Rights Reserved.
- 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
- */
- #include <stdio.h>
- #include <errno.h>
- #ifndef __WIN__
- #include <dirent.h>
- #endif
- #include <string.h>
- #ifdef __NETWARE__
- #include <screen.h>
- #include <proc.h>
- #else
- #include <sys/types.h>
- #ifndef __WIN__
- #include <sys/wait.h>
- #include <unistd.h>
- #include <signal.h>
- #include <fnmatch.h> /* FIXME HAVE_FNMATCH_H or something */
- #else
- #include <direct.h>
- #include <stdlib.h>
- #include <stdio.h>
- #endif
- #endif
- #include <ctype.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- #include "my_manage.h"
- #ifndef __NETWARE__
- #define ASSERT assert
- extern char **environ;
- #endif
- /******************************************************************************
- macros
- ******************************************************************************/
- /******************************************************************************
- global variables
- ******************************************************************************/
- /******************************************************************************
- functions
- ******************************************************************************/
- /******************************************************************************
- init_args()
- Init an argument list.
- ******************************************************************************/
- void init_args(arg_list_t *al)
- {
- ASSERT(al != NULL);
- al->argc= 0;
- al->size= ARG_BUF;
- al->argv= malloc(al->size * sizeof(char *));
- ASSERT(al->argv != NULL);
- return;
- }
- /******************************************************************************
- add_arg()
- Add an argument to a list.
- ******************************************************************************/
- void add_arg(arg_list_t *al, const char *format, ...)
- {
- va_list ap;
- char temp[FN_REFLEN];
- ASSERT(al != NULL);
- /* increase size */
- if (al->argc >= (int)al->size)
- {
- al->size+= ARG_BUF;
- al->argv= realloc(al->argv, al->size * sizeof(char *));
- ASSERT(al->argv != NULL);
- }
- if (format)
- {
- va_start(ap, format);
- vsprintf(temp, format, ap);
- va_end(ap);
- al->argv[al->argc]= malloc(strlen(temp)+1);
- ASSERT(al->argv[al->argc] != NULL);
- strcpy(al->argv[al->argc], temp);
-
- ++(al->argc);
- }
- else
- {
- al->argv[al->argc]= NULL;
- }
- return;
- }
- /******************************************************************************
- free_args()
- Free an argument list.
- ******************************************************************************/
- void free_args(arg_list_t *al)
- {
- int i;
- ASSERT(al != NULL);
- for (i= 0; i < al->argc; i++)
- {
- ASSERT(al->argv[i] != NULL);
- free(al->argv[i]);
- al->argv[i]= NULL;
- }
- free(al->argv);
- al->argc= 0;
- al->argv= NULL;
- return;
- }
- /******************************************************************************
- sleep_until_file_deleted()
- Sleep until the given file is no longer found.
- ******************************************************************************/
- #ifndef __WIN__
- int sleep_until_file_deleted(char *pid_file)
- #else
- int sleep_until_file_deleted(HANDLE pid_file)
- #endif
- {
- int err= 0; /* Initiate to supress warning */
- #ifndef __WIN__
- struct stat buf;
- int i;
- for (i= 0; (i < TRY_MAX) && (err= !stat(pid_file, &buf)); i++) sleep(1);
- if (err != 0) err= errno;
- #else
- err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
- #endif
- return err;
- }
- /******************************************************************************
- sleep_until_file_exists()
- Sleep until the given file exists.
- ******************************************************************************/
- #ifndef __WIN__
- int sleep_until_file_exists(char *pid_file)
- #else
- int sleep_until_file_exists(HANDLE pid_file)
- #endif
- {
- int err= 0; /* Initiate to supress warning */
- #ifndef __WIN__
- struct stat buf;
- int i;
- for (i= 0; (i < TRY_MAX) && (err= stat(pid_file, &buf)); i++) sleep(1);
- if (err != 0) err= errno;
- #else
- err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
- #endif
- return err;
- }
- /******************************************************************************
- wait_for_server_start()
- Wait for the server on the given port to start.
- ******************************************************************************/
- int wait_for_server_start(char *bin_dir __attribute__((unused)),
- char *mysqladmin_file,
- char *user, char *password, int port,char *tmp_dir)
- {
- arg_list_t al;
- int err= 0;
- #ifndef __WIN__
- int i;
- #endif
- char trash[FN_REFLEN];
- /* mysqladmin file */
- snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir);
- /* args */
- init_args(&al);
- add_arg(&al, "%s", mysqladmin_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--port=%u", port);
- add_arg(&al, "--user=%s", user);
- add_arg(&al, "--password=%s", password);
- add_arg(&al, "--silent");
- /* #ifdef NOT_USED */
- #ifndef __NETWARE__
- add_arg(&al, "-O");
- add_arg(&al, "connect_timeout=10");
- add_arg(&al, "-w");
- #endif
- add_arg(&al, "--host=localhost");
- #ifndef __NETWARE__
- add_arg(&al, "--protocol=tcp");
- #endif
- add_arg(&al, "ping");
- /*
- NetWare does not support the connect timeout in the TCP/IP stack
- -- we will try the ping multiple times
- */
- #ifndef __WIN__
- for (i= 0; (i < TRY_MAX)
- && (err= spawn(mysqladmin_file, &al, TRUE, NULL,
- trash, NULL, NULL)); i++) sleep(1);
- #else
- err= spawn(mysqladmin_file, &al, TRUE, NULL,trash, NULL, NULL);
- #endif
- /* free args */
- free_args(&al);
- return err;
- }
- /******************************************************************************
- spawn()
- Spawn the given path with the given arguments.
- ******************************************************************************/
- #ifdef __NETWARE__
- int spawn(char *path, arg_list_t *al, int join, char *input,
- char *output, char *error, char *pid_file)
- {
- pid_t pid;
- int result= 0;
- wiring_t wiring= { FD_UNUSED, FD_UNUSED, FD_UNUSED };
- unsigned long flags= PROC_CURRENT_SPACE | PROC_INHERIT_CWD;
- /* open wiring */
- if (input)
- wiring.infd= open(input, O_RDONLY);
- if (output)
- wiring.outfd= open(output, O_WRONLY | O_CREAT | O_TRUNC);
- if (error)
- wiring.errfd= open(error, O_WRONLY | O_CREAT | O_TRUNC);
- /* procve requires a NULL */
- add_arg(al, NULL);
- /* go */
- pid= procve(path, flags, NULL, &wiring, NULL, NULL, 0,
- NULL, (const char **)al->argv);
- /* close wiring */
- if (wiring.infd != -1)
- close(wiring.infd);
- if (wiring.outfd != -1)
- close(wiring.outfd);
- if (wiring.errfd != -1)
- close(wiring.errfd);
- return result;
- }
- #elif __WIN__
- int spawn(char *path, arg_list_t *al, int join, char *input,
- char *output, char *error, HANDLE *pid)
- {
- bool result;
- int i;
- STARTUPINFO startup_info;
- PROCESS_INFORMATION process_information;
- DWORD exit_code;
- char win_args[1024]= "";
- /* Skip the first parameter */
- for (i= 1; i < al->argc; i++)
- {
- ASSERT(al->argv[i] != NULL);
- strcat(win_args,al->argv[i]);
- strcat(win_args," ");
- }
- memset(&startup_info,0,sizeof(STARTUPINFO));
- startup_info.cb= sizeof(STARTUPINFO);
- if (input)
- freopen(input, "rb", stdin);
- if (output)
- freopen(output, "wb", stdout);
- if (error)
- freopen(error, "wb", stderr);
- result= CreateProcess(
- path,
- (LPSTR)&win_args,
- NULL,
- NULL,
- TRUE,
- 0,
- NULL,
- NULL,
- &startup_info,
- &process_information
- );
- if (result && process_information.hProcess)
- {
- if (join)
- {
- if (WaitForSingleObject(process_information.hProcess, mysqld_timeout)
- == WAIT_TIMEOUT)
- {
- exit_code= -1;
- }
- else
- {
- GetExitCodeProcess(process_information.hProcess, &exit_code);
- }
- CloseHandle(process_information.hProcess);
- }
- else
- {
- exit_code= 0;
- }
- if (pid != NULL)
- *pid= process_information.hProcess;
- }
- else
- {
- exit_code= -1;
- }
- if (input)
- freopen("CONIN$","rb",stdin);
- if (output)
- freopen("CONOUT$","wb",stdout);
- if (error)
- freopen("CONOUT$","wb",stderr);
- return exit_code;
- }
- #else
- int spawn(char *path, arg_list_t *al, int join, char *input,
- char *output, char *error, char *pid_file __attribute__((unused)))
- {
- pid_t pid;
- int res_exec= 0;
- int result= 0;
- pid= fork();
- if (pid == -1)
- {
- fprintf(stderr, "fork was't createdn");
- /* We can't create the fork...exit with error */
- return EXIT_FAILURE;
- }
- if (pid > 0)
- {
- /* The parent process is waiting for child process if join is not zero */
- if (join)
- {
- waitpid(pid, &result, 0);
- if (WIFEXITED(result) != 0)
- {
- result= WEXITSTATUS(result);
- }
- else
- {
- result= EXIT_FAILURE;
- }
- }
- }
- else
- {
- /* Child process */
- add_arg(al, NULL);
- /* Reassign streams */
- if (input)
- freopen(input, "r", stdin);
- if (output)
- freopen(output, "w", stdout);
- if (error)
- freopen(error, "w", stderr);
- /* Spawn the process */
- if ((res_exec= execve(path, al->argv, environ)) < 0)
- exit(EXIT_FAILURE);
- /* Restore streams */
- if (input)
- freopen("/dev/tty", "r", stdin);
- if (output)
- freopen("/dev/tty", "w", stdout);
- if (error)
- freopen("/dev/tty", "w", stderr);
- exit(0);
- }
- return result;
- }
- #endif
- /******************************************************************************
- stop_server()
- Stop the server with the given port and pid file.
- ******************************************************************************/
- int stop_server(char *bin_dir __attribute__((unused)), char *mysqladmin_file,
- char *user, char *password, int port,
- #ifndef __WIN__
- char *pid_file,
- #else
- HANDLE pid_file,
- #endif
- char *tmp_dir)
- {
- arg_list_t al;
- int err= 0;
- char trash[FN_REFLEN];
- snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir);
- /* args */
- init_args(&al);
- add_arg(&al, "%s", mysqladmin_file);
- add_arg(&al, "--no-defaults");
- add_arg(&al, "--port=%u", port);
- add_arg(&al, "--user=%s", user);
- add_arg(&al, "--password=%s", password);
- add_arg(&al, "-O");
- add_arg(&al, "shutdown_timeout=20");
- #ifndef __NETWARE__
- add_arg(&al, "--protocol=tcp");
- #endif
- add_arg(&al, "shutdown");
- /* spawn */
- if ((err= spawn(mysqladmin_file, &al, TRUE, NULL,
- trash, NULL, NULL)) == 0)
- {
- sleep_until_file_deleted(pid_file);
- }
- else
- {
- #ifndef __WIN__
- pid_t pid= get_server_pid(pid_file);
- /* shutdown failed - kill server */
- kill_server(pid);
- sleep(TRY_MAX);
- /* remove pid file if possible */
- err= remove(pid_file);
- #else
- TerminateProcess(pid_file,err);
- #endif
- }
- /* free args */
- free_args(&al);
- return err;
- }
- /******************************************************************************
- get_server_pid()
- Get the VM id with the given pid file.
- ******************************************************************************/
- #ifndef __WIN__
- pid_t get_server_pid(char *pid_file)
- {
- char buf[FN_REFLEN];
- int fd, err;
- char *p;
- pid_t id= 0;
- /* discover id */
- fd= open(pid_file, O_RDONLY);
- err= read(fd, buf, FN_REFLEN);
- close(fd);
- if (err > 0)
- {
- /* terminate string */
- if ((p= strchr(buf, 'n')) != NULL)
- {
- *p= ' ';
- /* check for a 'r' */
- if ((p= strchr(buf, 'r')) != NULL)
- {
- *p= ' ';
- }
- }
- else
- {
- buf[err]= ' ';
- }
- id= strtol(buf, NULL, 0);
- }
- return id;
- }
- /******************************************************************************
- kill_server()
- Force a kill of the server with the given pid.
- ******************************************************************************/
- void kill_server(pid_t pid)
- {
- if (pid > 0)
- {
- #if !defined(__NETWARE__)
- /* Send SIGTERM to pid */
- kill(pid, SIGTERM);
- #else /* __NETWARE__ */
- /* destroy vm */
- NXVmDestroy(pid);
- #endif
- }
- }
- #endif
- /******************************************************************************
- del_tree()
- Delete the directory and subdirectories.
- ******************************************************************************/
- void del_tree(char *dir)
- {
- #ifndef __WIN__
- DIR *parent= opendir(dir);
- struct dirent *entry;
- char temp[FN_REFLEN];
- if (parent == NULL)
- {
- return;
- }
- while ((entry= readdir(parent)) != NULL)
- {
- /* create long name */
- snprintf(temp, FN_REFLEN, "%s/%s", dir, entry->d_name);
- if (entry->d_name[0] == '.')
- {
- /* Skip */
- }
- else
- {
- /* FIXME missing test in acinclude.m4 */
- #ifndef STRUCT_DIRENT_HAS_D_TYPE
- struct stat st;
- if (lstat(entry->d_name, &st) == -1)
- {
- /* FIXME error */
- return;
- }
- if (S_ISDIR(st.st_mode))
- #else
- if (S_ISDIR(entry->d_type))
- #endif
- {
- /* delete subdirectory */
- del_tree(temp);
- }
- else
- {
- /* remove file */
- remove(temp);
- }
- }
- }
- /* remove directory */
- rmdir(dir);
- #else
- struct _finddata_t parent;
- #if defined(_MSC_VER) && _MSC_VER > 1200
- intptr_t handle;
- #else
- long handle;
- #endif /* _MSC_VER && _MSC_VER > 1200 */
- char temp[FN_REFLEN];
- char mask[FN_REFLEN];
- snprintf(mask,FN_REFLEN,"%s/*.*",dir);
- if ((handle=_findfirst(mask,&parent)) == -1L)
- {
- return;
- }
- do
- {
- /* create long name */
- snprintf(temp, FN_REFLEN, "%s/%s", dir, parent.name);
- if (parent.name[0] == '.')
- {
- /* Skip */
- }
- else
- if (parent.attrib & _A_SUBDIR)
- {
- /* delete subdirectory */
- del_tree(temp);
- }
- else
- {
- /* remove file */
- remove(temp);
- }
- } while (_findnext(handle,&parent) == 0);
- _findclose(handle);
- /* remove directory */
- _rmdir(dir);
- #endif
- }
- /******************************************************************************
- removef()
- ******************************************************************************/
- int removef(const char *format, ...)
- {
- #ifdef __NETWARE__
- va_list ap;
- char path[FN_REFLEN];
- va_start(ap, format);
- vsnprintf(path, FN_REFLEN, format, ap);
- va_end(ap);
- return remove(path);
- #elif __WIN__
- {
- va_list ap;
- char path[FN_REFLEN];
- struct _finddata_t parent;
- #if defined(_MSC_VER) && _MSC_VER > 1200
- intptr_t handle;
- #else
- long handle;
- #endif /* _MSC_VER && _MSC_VER > 1200 */
- char temp[FN_REFLEN];
- char *p;
- va_start(ap, format);
- vsnprintf(path, FN_REFLEN, format, ap);
- va_end(ap);
- p= path + strlen(path);
- while (*p != '\' && *p != '/' && p > path) p--;
- if ((handle=_findfirst(path,&parent)) == -1L)
- {
- /* if there is not files....it's ok */
- return 0;
- }
- *p= ' ';
- do
- {
- if (! (parent.attrib & _A_SUBDIR))
- {
- snprintf(temp, FN_REFLEN, "%s/%s", path, parent.name);
- remove(temp);
- }
- }while (_findnext(handle,&parent) == 0);
- _findclose(handle);
- }
- #else
- DIR *parent;
- struct dirent *entry;
- char temp[FN_REFLEN];
- va_list ap;
- char path[FN_REFLEN];
- char *p;
- /* Get path with mask */
- va_start(ap, format);
- vsnprintf(path, FN_REFLEN, format, ap);
- va_end(ap);
- p= path + strlen(path);
- while (*p != '\' && *p != '/' && p > path) p--;
- *p= ' ';
- p++;
- parent= opendir(path);
- if (parent == NULL)
- {
- return 1; /* Error, directory missing */
- }
- while ((entry= readdir(parent)) != NULL)
- {
- /* entry is not directory and entry matches with mask */
- #ifndef STRUCT_DIRENT_HAS_D_TYPE
- struct stat st;
- /* create long name */
- snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name);
- if (lstat(temp, &st) == -1)
- {
- return 1; /* Error couldn't lstat file */
- }
- if (!S_ISDIR(st.st_mode) && !fnmatch(p, entry->d_name,0))
- #else
- if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0))
- #endif
- {
- /* create long name */
- snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name);
- /* Delete only files */
- remove(temp);
- }
- }
- #endif
- return 0;
- }
- /******************************************************************************
- get_basedir()
- ******************************************************************************/
- void get_basedir(char *argv0, char *basedir)
- {
- char temp[FN_REFLEN];
- char *p;
- int position;
- ASSERT(argv0 != NULL);
- ASSERT(basedir != NULL);
- strcpy(temp, strlwr(argv0));
- while ((p= strchr(temp, '\')) != NULL) *p= '/';
- if ((position= strinstr(temp, "/bin/")) != 0)
- {
- p= temp + position;
- *p= ' ';
- strcpy(basedir, temp);
- }
- }
- uint strinstr(reg1 const char *str,reg4 const char *search)
- {
- reg2 my_string i,j;
- my_string start= (my_string) str;
- skipp:
- while (*str != ' ')
- {
- if (*str++ == *search)
- {
- i=(my_string) str;
- j= (my_string) search+1;
- while (*j)
- if (*i++ != *j++) goto skipp;
- return ((uint) (str - start));
- }
- }
- return (0);
- }
- /******************************************************************************
- remove_empty_file()
- ******************************************************************************/
- void remove_empty_file(const char *file_name)
- {
- struct stat file;
- if (!stat(file_name,&file))
- {
- if (!file.st_size)
- remove(file_name);
- }
- }