mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	 b93102422b
			
		
	
	b93102422b
	
	
	
		
			
			renamed client_test to mysql_client_test
    fixed name for lstat in removef()
    added mysql-debug.exe for Windows
    added enviroment variable MYSQL_CLIENT_TEST
    added cleaning directory before tests
    New BitKeeper file ``VC++Files/tests/mysql_client_test.dsp''
    Delete: VC++Files/tests/client_test.dsp
		
	
		
			
				
	
	
		
			888 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			888 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|   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, i;
 | |
|   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 created\n");
 | |
|     /* 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= '\0';
 | |
| 
 | |
|       /* check for a '\r' */
 | |
|       if ((p= strchr(buf, '\r')) != NULL)
 | |
|       {
 | |
|         *p= '\0';
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       buf[err]= '\0';
 | |
|     }
 | |
| 
 | |
|     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= '\0';
 | |
| 
 | |
|     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= '\0';
 | |
|   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= '\0';
 | |
|     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 != '\0')
 | |
|   {
 | |
|     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);
 | |
|   }
 | |
| }
 |