my_manage.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:18k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.   Copyright (c) 2003 Novell, Inc. All Rights Reserved. 
  3.   This program is free software; you can redistribute it and/or modify 
  4.   it under the terms of the GNU General Public License as published by 
  5.   the Free Software Foundation; either version 2 of the License, or 
  6.   (at your option) any later version. 
  7.   This program is distributed in the hope that it will be useful, 
  8.   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  9.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
  10.   GNU General Public License for more details. 
  11.   You should have received a copy of the GNU General Public License 
  12.   along with this program; if not, write to the Free Software 
  13.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */ 
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #ifndef __WIN__
  18. #include <dirent.h>
  19. #endif
  20. #include <string.h>
  21. #ifdef __NETWARE__
  22. #include <screen.h>
  23. #include <proc.h>
  24. #else
  25. #include <sys/types.h>
  26. #ifndef __WIN__
  27. #include <sys/wait.h>
  28. #include <unistd.h>
  29. #include <signal.h>
  30. #include <fnmatch.h>                            /* FIXME HAVE_FNMATCH_H or something */
  31. #else
  32. #include <direct.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #endif
  36. #endif
  37. #include <ctype.h>
  38. #include <sys/stat.h>
  39. #include <fcntl.h>
  40. #include <assert.h>
  41. #include "my_manage.h"
  42. #ifndef __NETWARE__
  43. #define ASSERT assert
  44. extern char **environ;
  45. #endif
  46. /******************************************************************************
  47.         macros
  48. ******************************************************************************/
  49. /******************************************************************************
  50.         global variables
  51. ******************************************************************************/
  52. /******************************************************************************
  53.         functions
  54. ******************************************************************************/
  55. /******************************************************************************
  56.         init_args()
  57.         Init an argument list.
  58. ******************************************************************************/
  59. void init_args(arg_list_t *al)
  60. {
  61.   ASSERT(al != NULL);
  62.   al->argc= 0;
  63.   al->size= ARG_BUF;
  64.   al->argv= malloc(al->size * sizeof(char *));
  65.   ASSERT(al->argv != NULL);
  66.   return;
  67. }
  68. /******************************************************************************
  69.         add_arg()
  70.         Add an argument to a list.
  71. ******************************************************************************/
  72. void add_arg(arg_list_t *al, const char *format, ...)
  73. {
  74.   va_list ap;
  75.   char temp[FN_REFLEN];
  76.   ASSERT(al != NULL);
  77.   /* increase size */
  78.   if (al->argc >= (int)al->size)
  79.   {
  80.     al->size+= ARG_BUF;
  81.     al->argv= realloc(al->argv, al->size * sizeof(char *));
  82.     ASSERT(al->argv != NULL);
  83.   }
  84.   if (format)
  85.   {
  86.     va_start(ap, format);
  87.     vsprintf(temp, format, ap);
  88.     va_end(ap);
  89.     al->argv[al->argc]= malloc(strlen(temp)+1);
  90.     ASSERT(al->argv[al->argc] != NULL);
  91.     strcpy(al->argv[al->argc], temp);
  92.     
  93.     ++(al->argc);
  94.   }
  95.   else
  96.   {
  97.     al->argv[al->argc]= NULL;
  98.   }
  99.   return;
  100. }
  101. /******************************************************************************
  102.         free_args()
  103.         Free an argument list.
  104. ******************************************************************************/
  105. void free_args(arg_list_t *al)
  106. {
  107.   int i;
  108.   ASSERT(al != NULL);
  109.   for (i= 0; i < al->argc; i++)
  110.   {
  111.     ASSERT(al->argv[i] != NULL);
  112.     free(al->argv[i]);
  113.     al->argv[i]= NULL;
  114.   }
  115.   free(al->argv);
  116.   al->argc= 0;
  117.   al->argv= NULL;
  118.   return;
  119. }
  120. /******************************************************************************
  121.         sleep_until_file_deleted()
  122.         Sleep until the given file is no longer found.
  123. ******************************************************************************/
  124. #ifndef __WIN__
  125. int sleep_until_file_deleted(char *pid_file)
  126. #else
  127. int sleep_until_file_deleted(HANDLE pid_file)
  128. #endif
  129. {
  130.   int err= 0;            /* Initiate to supress warning */
  131. #ifndef __WIN__
  132.   struct stat buf;
  133.   int i;
  134.   for (i= 0; (i < TRY_MAX) && (err= !stat(pid_file, &buf)); i++) sleep(1);
  135.   if (err != 0) err= errno;
  136. #else
  137.   err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
  138. #endif
  139.   return err;
  140. }
  141. /******************************************************************************
  142.         sleep_until_file_exists()
  143.         Sleep until the given file exists.
  144. ******************************************************************************/
  145. #ifndef __WIN__
  146. int sleep_until_file_exists(char *pid_file)
  147. #else
  148. int sleep_until_file_exists(HANDLE pid_file)
  149. #endif
  150. {
  151.   int err= 0;            /* Initiate to supress warning */
  152. #ifndef __WIN__
  153.   struct stat buf;
  154.   int i;
  155.   for (i= 0; (i < TRY_MAX) && (err= stat(pid_file, &buf)); i++) sleep(1);
  156.   if (err != 0) err= errno;
  157. #else
  158.   err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
  159. #endif
  160.   return err;
  161. }
  162. /******************************************************************************
  163.         wait_for_server_start()
  164.         Wait for the server on the given port to start.
  165. ******************************************************************************/
  166. int wait_for_server_start(char *bin_dir __attribute__((unused)),
  167.                           char *mysqladmin_file,
  168.                           char *user, char *password, int port,char *tmp_dir)
  169. {
  170.   arg_list_t al;
  171.   int err= 0;
  172. #ifndef __WIN__
  173.   int i;
  174. #endif
  175.   char trash[FN_REFLEN];
  176.   /* mysqladmin file */
  177.   snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir);
  178.   /* args */
  179.   init_args(&al);
  180.   add_arg(&al, "%s", mysqladmin_file);
  181.   add_arg(&al, "--no-defaults");
  182.   add_arg(&al, "--port=%u", port);
  183.   add_arg(&al, "--user=%s", user);
  184.   add_arg(&al, "--password=%s", password);
  185.   add_arg(&al, "--silent");
  186. /* #ifdef NOT_USED */
  187. #ifndef __NETWARE__
  188.   add_arg(&al, "-O");
  189.   add_arg(&al, "connect_timeout=10");
  190.   add_arg(&al, "-w");
  191. #endif
  192.   add_arg(&al, "--host=localhost");
  193. #ifndef __NETWARE__
  194.   add_arg(&al, "--protocol=tcp");
  195. #endif
  196.   add_arg(&al, "ping");
  197.   /*
  198.     NetWare does not support the connect timeout in the TCP/IP stack
  199.     -- we will try the ping multiple times
  200.   */
  201. #ifndef __WIN__
  202.   for (i= 0; (i < TRY_MAX)
  203.          && (err= spawn(mysqladmin_file, &al, TRUE, NULL,
  204.                         trash, NULL, NULL)); i++) sleep(1);
  205. #else
  206.   err= spawn(mysqladmin_file, &al, TRUE, NULL,trash, NULL, NULL);
  207. #endif
  208.   /* free args */
  209.   free_args(&al);
  210.   return err;
  211. }
  212. /******************************************************************************
  213.         spawn()
  214.         Spawn the given path with the given arguments.
  215. ******************************************************************************/
  216. #ifdef __NETWARE__
  217. int spawn(char *path, arg_list_t *al, int join, char *input,
  218.           char *output, char *error, char *pid_file)
  219. {
  220.   pid_t pid;
  221.   int result= 0;
  222.   wiring_t wiring= { FD_UNUSED, FD_UNUSED, FD_UNUSED };
  223.   unsigned long flags= PROC_CURRENT_SPACE | PROC_INHERIT_CWD;
  224.   /* open wiring */
  225.   if (input)
  226.     wiring.infd= open(input, O_RDONLY);
  227.   if (output)
  228.     wiring.outfd= open(output, O_WRONLY | O_CREAT | O_TRUNC);
  229.   if (error)
  230.     wiring.errfd= open(error, O_WRONLY | O_CREAT | O_TRUNC);
  231.   /* procve requires a NULL */
  232.   add_arg(al, NULL);
  233.   /* go */
  234.   pid= procve(path, flags, NULL, &wiring, NULL, NULL, 0,
  235.               NULL, (const char **)al->argv);
  236.   /* close wiring */
  237.   if (wiring.infd != -1)
  238.     close(wiring.infd);
  239.   if (wiring.outfd != -1)
  240.     close(wiring.outfd);
  241.   if (wiring.errfd != -1)
  242.     close(wiring.errfd);
  243.   return result;
  244. }
  245. #elif __WIN__
  246. int spawn(char *path, arg_list_t *al, int join, char *input,
  247.           char *output, char *error, HANDLE *pid)
  248. {
  249.   bool result;
  250.   int i;
  251.   STARTUPINFO startup_info;
  252.   PROCESS_INFORMATION process_information;
  253.   DWORD exit_code;
  254.   char win_args[1024]= "";
  255.   /* Skip the first parameter */
  256.   for (i= 1; i < al->argc; i++)
  257.   {
  258.     ASSERT(al->argv[i] != NULL);
  259.     strcat(win_args,al->argv[i]);
  260.     strcat(win_args," ");
  261.   }
  262.   memset(&startup_info,0,sizeof(STARTUPINFO));
  263.   startup_info.cb= sizeof(STARTUPINFO);
  264.   if (input)
  265.     freopen(input, "rb", stdin);
  266.   if (output)
  267.     freopen(output, "wb", stdout);
  268.   if (error)
  269.     freopen(error, "wb", stderr);
  270.   result= CreateProcess(
  271.     path,
  272.     (LPSTR)&win_args,
  273.     NULL,
  274.     NULL,
  275.     TRUE,
  276.     0,
  277.     NULL,
  278.     NULL,
  279.     &startup_info,
  280.     &process_information
  281.   );
  282.   if (result && process_information.hProcess)
  283.   {
  284.     if (join)
  285.     {
  286.       if (WaitForSingleObject(process_information.hProcess, mysqld_timeout)
  287.           == WAIT_TIMEOUT)
  288.       {
  289.         exit_code= -1;
  290.       }
  291.       else
  292.       {
  293.         GetExitCodeProcess(process_information.hProcess, &exit_code);
  294.       }
  295.       CloseHandle(process_information.hProcess);
  296.     }
  297.     else
  298.     {
  299.       exit_code= 0;
  300.     }
  301.     if (pid != NULL)
  302.       *pid= process_information.hProcess;
  303.   }
  304.   else
  305.   {
  306.     exit_code= -1;
  307.   }
  308.   if (input)
  309.     freopen("CONIN$","rb",stdin);
  310.   if (output)
  311.     freopen("CONOUT$","wb",stdout);
  312.   if (error)
  313.     freopen("CONOUT$","wb",stderr);
  314.   return exit_code;
  315. }
  316. #else
  317. int spawn(char *path, arg_list_t *al, int join, char *input,
  318.           char *output, char *error, char *pid_file __attribute__((unused)))
  319. {
  320.   pid_t pid;
  321.   int res_exec= 0;
  322.   int result= 0;
  323.   pid= fork();
  324.   if (pid == -1)
  325.   {
  326.     fprintf(stderr, "fork was't createdn");
  327.     /* We can't create the fork...exit with error */
  328.     return EXIT_FAILURE;
  329.   }
  330.   if (pid  > 0)
  331.   {
  332.     /* The parent process is waiting for child process if join is not zero */
  333.     if (join)
  334.     {
  335.       waitpid(pid, &result, 0);
  336.       if (WIFEXITED(result) != 0)
  337.       {
  338.         result= WEXITSTATUS(result);
  339.       }
  340.       else
  341.       {
  342.         result= EXIT_FAILURE;
  343.       }
  344.     }
  345.   }
  346.   else
  347.   {
  348.     /* Child process */
  349.     add_arg(al, NULL);
  350.     /* Reassign streams */
  351.     if (input)
  352.       freopen(input, "r", stdin);
  353.     if (output)
  354.       freopen(output, "w", stdout);
  355.     if (error)
  356.       freopen(error, "w", stderr);
  357.     /* Spawn the process */
  358.     if ((res_exec= execve(path, al->argv, environ)) < 0)
  359.       exit(EXIT_FAILURE);
  360.     /* Restore streams */
  361.     if (input)
  362.       freopen("/dev/tty", "r", stdin);
  363.     if (output)
  364.       freopen("/dev/tty", "w", stdout);
  365.     if (error)
  366.       freopen("/dev/tty", "w", stderr);
  367.     exit(0);
  368.   }
  369.   return result;
  370. }
  371. #endif
  372. /******************************************************************************
  373.         stop_server()
  374.         Stop the server with the given port and pid file.
  375. ******************************************************************************/
  376. int stop_server(char *bin_dir __attribute__((unused)), char *mysqladmin_file,
  377.                 char *user, char *password, int port,
  378. #ifndef __WIN__
  379.                 char *pid_file,
  380. #else
  381.                 HANDLE pid_file,
  382. #endif
  383.                 char *tmp_dir)
  384. {
  385.   arg_list_t al;
  386.   int err= 0;
  387.   char trash[FN_REFLEN];
  388.   snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir);
  389.   /* args */
  390.   init_args(&al);
  391.   add_arg(&al, "%s", mysqladmin_file);
  392.   add_arg(&al, "--no-defaults");
  393.   add_arg(&al, "--port=%u", port);
  394.   add_arg(&al, "--user=%s", user);
  395.   add_arg(&al, "--password=%s", password);
  396.   add_arg(&al, "-O");
  397.   add_arg(&al, "shutdown_timeout=20");
  398. #ifndef __NETWARE__
  399.   add_arg(&al, "--protocol=tcp");
  400. #endif
  401.   add_arg(&al, "shutdown");
  402.   /* spawn */
  403.   if ((err= spawn(mysqladmin_file, &al, TRUE, NULL,
  404.                   trash, NULL, NULL)) == 0)
  405.   {
  406.     sleep_until_file_deleted(pid_file);
  407.   }
  408.   else
  409.   {
  410. #ifndef __WIN__
  411.     pid_t pid= get_server_pid(pid_file);
  412.     /* shutdown failed - kill server */
  413.    kill_server(pid);
  414.    sleep(TRY_MAX);
  415.    /* remove pid file if possible */
  416.    err= remove(pid_file);
  417. #else
  418.   TerminateProcess(pid_file,err);
  419. #endif
  420.   }
  421.   /* free args */
  422.   free_args(&al);
  423.   return err;
  424. }
  425. /******************************************************************************
  426.         get_server_pid()
  427.         Get the VM id with the given pid file.
  428. ******************************************************************************/
  429. #ifndef __WIN__
  430. pid_t get_server_pid(char *pid_file)
  431. {
  432.   char buf[FN_REFLEN];
  433.   int fd, err;
  434.   char *p;
  435.   pid_t id= 0;
  436.   /* discover id */
  437.   fd= open(pid_file, O_RDONLY);
  438.   err= read(fd, buf, FN_REFLEN);
  439.   close(fd);
  440.   if (err > 0)
  441.   {
  442.     /* terminate string */
  443.     if ((p= strchr(buf, 'n')) != NULL)
  444.     {
  445.       *p= '';
  446.       /* check for a 'r' */
  447.       if ((p= strchr(buf, 'r')) != NULL)
  448.       {
  449.         *p= '';
  450.       }
  451.     }
  452.     else
  453.     {
  454.       buf[err]= '';
  455.     }
  456.     id= strtol(buf, NULL, 0);
  457.   }
  458.   return id;
  459. }
  460. /******************************************************************************
  461.         kill_server()
  462.         Force a kill of the server with the given pid.
  463. ******************************************************************************/
  464. void kill_server(pid_t pid)
  465. {
  466.   if (pid > 0)
  467.   {
  468. #if !defined(__NETWARE__)
  469.     /* Send SIGTERM to pid */
  470.     kill(pid, SIGTERM);
  471. #else /* __NETWARE__ */
  472.     /* destroy vm */
  473.     NXVmDestroy(pid);
  474. #endif
  475.   }
  476. }
  477. #endif
  478. /******************************************************************************
  479.         del_tree()
  480.         Delete the directory and subdirectories.
  481. ******************************************************************************/
  482. void del_tree(char *dir)
  483. {
  484. #ifndef __WIN__
  485.   DIR *parent= opendir(dir);
  486.   struct dirent *entry;
  487.   char temp[FN_REFLEN];
  488.   if (parent == NULL)
  489.   {
  490.     return;
  491.   }
  492.   while ((entry= readdir(parent)) != NULL)
  493.   {
  494.     /* create long name */
  495.     snprintf(temp, FN_REFLEN, "%s/%s", dir, entry->d_name);
  496.     if (entry->d_name[0] == '.')
  497.     {
  498.       /* Skip */
  499.     }
  500.     else
  501.     {
  502. /* FIXME missing test in acinclude.m4 */
  503. #ifndef STRUCT_DIRENT_HAS_D_TYPE
  504.       struct stat st;
  505.       if (lstat(entry->d_name, &st) == -1)
  506.       {
  507.         /* FIXME error */
  508.         return;  
  509.       }
  510.       if (S_ISDIR(st.st_mode))
  511. #else
  512.       if (S_ISDIR(entry->d_type))
  513. #endif
  514.       {
  515.         /* delete subdirectory */
  516.         del_tree(temp);
  517.       }
  518.       else
  519.       {
  520.         /* remove file */
  521.         remove(temp);
  522.       }
  523.     }
  524.   }
  525.   /* remove directory */
  526.   rmdir(dir);
  527. #else
  528.   struct _finddata_t parent;
  529. #if defined(_MSC_VER) && _MSC_VER > 1200
  530.   intptr_t handle;
  531. #else
  532.   long handle;
  533. #endif  /* _MSC_VER && _MSC_VER > 1200  */ 
  534.   char temp[FN_REFLEN];
  535.   char mask[FN_REFLEN];
  536.   snprintf(mask,FN_REFLEN,"%s/*.*",dir);
  537.   if ((handle=_findfirst(mask,&parent)) == -1L)
  538.   {
  539.     return;
  540.   }
  541.   do
  542.   {
  543.     /* create long name */
  544.     snprintf(temp, FN_REFLEN, "%s/%s", dir, parent.name);
  545.     if (parent.name[0] == '.')
  546.     {
  547.       /* Skip */
  548.     }
  549.     else
  550.     if (parent.attrib & _A_SUBDIR)
  551.     {
  552.       /* delete subdirectory */
  553.       del_tree(temp);
  554.     }
  555.     else
  556.     {
  557.       /* remove file */
  558.       remove(temp);
  559.     }
  560.   } while (_findnext(handle,&parent) == 0);
  561.    _findclose(handle);
  562.    /* remove directory */
  563.    _rmdir(dir);
  564. #endif
  565. }
  566. /******************************************************************************
  567.         removef()
  568. ******************************************************************************/
  569. int removef(const char *format, ...)
  570. {
  571. #ifdef __NETWARE__
  572.   va_list ap;
  573.   char path[FN_REFLEN];
  574.   va_start(ap, format);
  575.   vsnprintf(path, FN_REFLEN, format, ap);
  576.   va_end(ap);
  577.   return remove(path);
  578. #elif __WIN__
  579.   {
  580.     va_list ap;
  581.     char path[FN_REFLEN];
  582.     struct _finddata_t parent;
  583. #if defined(_MSC_VER) && _MSC_VER > 1200
  584.     intptr_t handle;
  585. #else
  586.     long handle;
  587. #endif  /* _MSC_VER && _MSC_VER > 1200  */ 
  588.     char temp[FN_REFLEN];
  589.     char *p;
  590.     va_start(ap, format);
  591.     vsnprintf(path, FN_REFLEN, format, ap);
  592.     va_end(ap);
  593.     p= path + strlen(path);
  594.     while (*p != '\' && *p != '/' && p > path) p--;
  595.     if ((handle=_findfirst(path,&parent)) == -1L)
  596.     {
  597.       /* if there is not files....it's ok */
  598.       return 0;
  599.     }
  600.     *p= '';
  601.     do
  602.     {
  603.       if (! (parent.attrib & _A_SUBDIR))
  604.       {
  605.         snprintf(temp, FN_REFLEN, "%s/%s", path, parent.name);
  606.         remove(temp);
  607.       }
  608.     }while (_findnext(handle,&parent) == 0);
  609.     _findclose(handle);
  610.   }
  611. #else
  612.   DIR *parent;
  613.   struct dirent *entry;
  614.   char temp[FN_REFLEN];
  615.   va_list ap;
  616.   char path[FN_REFLEN];
  617.   char *p;
  618.   /* Get path with mask */
  619.   va_start(ap, format);
  620.   vsnprintf(path, FN_REFLEN, format, ap);
  621.   va_end(ap);
  622.   p= path + strlen(path);
  623.   while (*p != '\' && *p != '/' && p > path) p--;
  624.   *p= '';
  625.   p++;
  626.   parent= opendir(path);
  627.   if (parent == NULL)
  628.   {
  629.     return 1;            /* Error, directory missing */
  630.   }
  631.   while ((entry= readdir(parent)) != NULL)
  632.   {
  633.     /* entry is not directory and entry matches with mask */
  634. #ifndef STRUCT_DIRENT_HAS_D_TYPE
  635.     struct stat st;
  636.     /* create long name */
  637.     snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name);
  638.     if (lstat(temp, &st) == -1)
  639.     {
  640.       return 1;  /* Error couldn't lstat file */
  641.     }
  642.     if (!S_ISDIR(st.st_mode) && !fnmatch(p, entry->d_name,0))
  643. #else
  644.     if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0))
  645. #endif
  646.     {
  647.       /* create long name */
  648.       snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name);
  649.       /* Delete only files */
  650.       remove(temp);
  651.     }
  652.   }
  653. #endif
  654.   return 0;
  655. }
  656. /******************************************************************************
  657.         get_basedir()
  658. ******************************************************************************/
  659. void get_basedir(char *argv0, char *basedir)
  660. {
  661.   char temp[FN_REFLEN];
  662.   char *p;
  663.   int position;
  664.   ASSERT(argv0 != NULL);
  665.   ASSERT(basedir != NULL);
  666.   strcpy(temp, strlwr(argv0));
  667.   while ((p= strchr(temp, '\')) != NULL) *p= '/';
  668.   if ((position= strinstr(temp, "/bin/")) != 0)
  669.   {
  670.     p= temp + position;
  671.     *p= '';
  672.     strcpy(basedir, temp);
  673.   }
  674. }
  675. uint strinstr(reg1 const char *str,reg4 const char *search)
  676. {
  677.   reg2 my_string i,j;
  678.   my_string start= (my_string) str;
  679.  skipp:
  680.   while (*str != '')
  681.   {
  682.     if (*str++ == *search)
  683.     {
  684.       i=(my_string) str;
  685.       j= (my_string) search+1;
  686.       while (*j)
  687.         if (*i++ != *j++) goto skipp;
  688.       return ((uint) (str - start));
  689.     }
  690.   }
  691.   return (0);
  692. }
  693. /******************************************************************************
  694.         remove_empty_file()
  695. ******************************************************************************/
  696. void remove_empty_file(const char *file_name)
  697. {
  698.   struct stat file;
  699.   if (!stat(file_name,&file))
  700.   {
  701.     if (!file.st_size)
  702.       remove(file_name);
  703.   }
  704. }