⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libmysql.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind */#include <global.h>#if defined(__WIN__) || defined(_WIN32) || defined(_WIN64)#include <winsock.h>#include <odbcinst.h>#endif#include <my_sys.h>#include <mysys_err.h>#include <m_string.h>#include <m_ctype.h>#include "mysql.h"#include "mysql_version.h"#include "mysqld_error.h"#include "errmsg.h"#include <violite.h>#include <sys/stat.h>#include <signal.h>#include <time.h>#ifdef	 HAVE_PWD_H#include <pwd.h>#endif#if !defined(MSDOS) && !defined(__WIN__)#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#ifdef HAVE_SELECT_H#  include <select.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#endif#ifdef HAVE_SYS_UN_H#  include <sys/un.h>#endif#if defined(THREAD) && !defined(__WIN__)#include <my_pthread.h>				/* because of signal()	*/#endif#ifndef INADDR_NONE#define INADDR_NONE	-1#endifstatic my_bool	mysql_client_init=0;uint		mysql_port=0;my_string	mysql_unix_port=0;#define CLIENT_CAPABILITIES	(CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)#ifdef __WIN__#define CONNECT_TIMEOUT 20#else#define CONNECT_TIMEOUT 0#endif#if defined(MSDOS) || defined(__WIN__)/* socket_errno is defined in global.h for all platforms */#define perror(A)#else#include <errno.h>#define SOCKET_ERROR -1#endif /* __WIN__ */static void mysql_once_init(void);static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,			      uint field_count);static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,			ulong *lengths);static void end_server(MYSQL *mysql);static void read_user_name(char *name);static void append_wild(char *to,char *end,const char *wild);static my_bool mysql_reconnect(MYSQL *mysql);static int send_file_to_server(MYSQL *mysql,const char *filename);static sig_handler pipe_sig_handler(int sig);static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,				     const char *from, ulong length);/*  Let the user specify that we don't want SIGPIPE;  This doesn't however work  with threaded applications as we can have multiple read in progress.*/#if !defined(__WIN__) && defined(SIGPIPE) && !defined(THREAD)#define init_sigpipe_variables  sig_return old_signal_handler=(sig_return) 0;#define set_sigpipe(mysql)     if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE,pipe_sig_handler)#define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler);#else#define init_sigpipe_variables#define set_sigpipe(mysql)#define reset_sigpipe(mysql)#endif/***************************************************************************** A modified version of connect().  connect2() allows you to specify* a timeout value, in seconds, that we should wait until we* derermine we can't connect to a particular host.  If timeout is 0,* connect2() will behave exactly like connect().** Base version coded by Steve Bernacki, Jr. <steve@navinet.net>*****************************************************************************/static int connect2(my_socket s, const struct sockaddr *name, uint namelen,		    uint timeout){#if defined(__WIN__) || defined(OS2)  return connect(s, (struct sockaddr*) name, namelen);#else  int flags, res, s_err;  SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);  fd_set sfds;  struct timeval tv;  time_t start_time, now_time;  /* If they passed us a timeout of zero, we should behave   * exactly like the normal connect() call does.   */  if (timeout == 0)    return connect(s, (struct sockaddr*) name, namelen);  flags = fcntl(s, F_GETFL, 0);		  /* Set socket to not block */#ifdef O_NONBLOCK  fcntl(s, F_SETFL, flags | O_NONBLOCK);  /* and save the flags..  */#endif  res = connect(s, (struct sockaddr*) name, namelen);  s_err = errno;			/* Save the error... */  fcntl(s, F_SETFL, flags);  if ((res != 0) && (s_err != EINPROGRESS))  {    errno = s_err;			/* Restore it */    return(-1);  }  if (res == 0)				/* Connected quickly! */    return(0);  /* Otherwise, our connection is "in progress."  We can use   * the select() call to wait up to a specified period of time   * for the connection to suceed.  If select() returns 0   * (after waiting howevermany seconds), our socket never became   * writable (host is probably unreachable.)  Otherwise, if   * select() returns 1, then one of two conditions exist:   *   * 1. An error occured.  We use getsockopt() to check for this.   * 2. The connection was set up sucessfully: getsockopt() will   * return 0 as an error.   *   * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>   * who posted this method of timing out a connect() in   * comp.unix.programmer on August 15th, 1997.   */  FD_ZERO(&sfds);  FD_SET(s, &sfds);  /*   * select could be interrupted by a signal, and if it is,    * the timeout should be adjusted and the select restarted   * to work around OSes that don't restart select and    * implementations of select that don't adjust tv upon   * failure to reflect the time remaining   */  start_time = time(NULL);  for (;;)  {    tv.tv_sec = (long) timeout;    tv.tv_usec = 0;    if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)      break;    now_time=time(NULL);    timeout-= (uint) (now_time - start_time);    if (errno != EINTR || (int) timeout <= 0)      return -1;  }  /* select() returned something more interesting than zero, let's   * see if we have any errors.  If the next two statements pass,   * we've got an open socket!   */  s_err=0;  if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)    return(-1);  if (s_err)  {						/* getsockopt could succeed */    errno = s_err;    return(-1);					/* but return an error... */  }  return(0);					/* It's all good! */#endif}/*** Create a named pipe connection*/#ifdef __WIN__HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,			 char **arg_unix_socket){  HANDLE hPipe=INVALID_HANDLE_VALUE;  char szPipeName [ 257 ];  DWORD dwMode;  int i;  my_bool testing_named_pipes=0;  char *host= *arg_host, *unix_socket= *arg_unix_socket;  if ( ! unix_socket || (unix_socket)[0] == 0x00)    unix_socket = mysql_unix_port;  if (!host || !strcmp(host,LOCAL_HOST))    host=LOCAL_HOST_NAMEDPIPE;  if (sizeof(szPipeName) <= (strlen(host) + strlen(unix_socket) + sizeof("\\\\\\pipe\\"))) {	return INVALID_HANDLE_VALUE;  }  sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket);  DBUG_PRINT("info",("Server name: '%s'.  Named Pipe: %s",		     host, unix_socket));  for (i=0 ; i < 100 ; i++)			/* Don't retry forever */  {    if ((hPipe = CreateFile(szPipeName,			    GENERIC_READ | GENERIC_WRITE,			    0,			    NULL,			    OPEN_EXISTING,			    0,			    NULL )) != INVALID_HANDLE_VALUE)      break;    if (GetLastError() != ERROR_PIPE_BUSY)    {      net->last_errno=CR_NAMEDPIPEOPEN_ERROR;      sprintf(net->last_error,ER(net->last_errno),host, unix_socket,	      (ulong) GetLastError());      return INVALID_HANDLE_VALUE;    }    /* wait for for an other instance */    if (! WaitNamedPipe(szPipeName, connect_timeout*1000) )    {      net->last_errno=CR_NAMEDPIPEWAIT_ERROR;      sprintf(net->last_error,ER(net->last_errno),host, unix_socket,	      (ulong) GetLastError());      return INVALID_HANDLE_VALUE;    }  }  if (hPipe == INVALID_HANDLE_VALUE)  {    net->last_errno=CR_NAMEDPIPEOPEN_ERROR;    sprintf(net->last_error,ER(net->last_errno),host, unix_socket,	    (ulong) GetLastError());    return INVALID_HANDLE_VALUE;  }  dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;  if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )  {    CloseHandle( hPipe );    net->last_errno=CR_NAMEDPIPESETSTATE_ERROR;    sprintf(net->last_error,ER(net->last_errno),host, unix_socket,	    (ulong) GetLastError());    return INVALID_HANDLE_VALUE;  }  *arg_host=host ; *arg_unix_socket=unix_socket;	/* connect arg */  return (hPipe);}#endif/******************************************************************************* read a packet from server. Give error message if socket was down** or packet is an error message*****************************************************************************/uintnet_safe_read(MYSQL *mysql){  NET *net= &mysql->net;  uint len=0;  init_sigpipe_variables  /* Don't give sigpipe errors if the client doesn't want them */  set_sigpipe(mysql);  if (net->vio != 0)    len=my_net_read(net);  reset_sigpipe(mysql);  if (len == packet_error || len == 0)  {    DBUG_PRINT("error",("Wrong connection or packet. fd: %s  len: %d",			vio_description(net->vio),len));    end_server(mysql);    net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ? 		     CR_NET_PACKET_TOO_LARGE:		     CR_SERVER_LOST);    strmov(net->last_error,ER(net->last_errno));    return(packet_error);  }  if (net->read_pos[0] == 255)  {    if (len > 3)    {      char *pos=(char*) net->read_pos+1;      if (mysql->protocol_version > 9)      {						/* New client protocol */	net->last_errno=uint2korr(pos);	pos+=2;	len-=2;      }      else      {	net->last_errno=CR_UNKNOWN_ERROR;	len--;      }      (void) strmake(net->last_error,(char*) pos,		     min(len,sizeof(net->last_error)-1));    }    else    {      net->last_errno=CR_UNKNOWN_ERROR;      (void) strmov(net->last_error,ER(net->last_errno));    }    DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno,			net->last_error));    return(packet_error);  }  return len;}/* Get the length of next field. Change parameter to point at fieldstart */static ulongnet_field_length(uchar **packet){  reg1 uchar *pos= *packet;  if (*pos < 251)  {    (*packet)++;    return (ulong) *pos;  }  if (*pos == 251)  {    (*packet)++;    return NULL_LENGTH;  }  if (*pos == 252)  {    (*packet)+=3;    return (ulong) uint2korr(pos+1);  }  if (*pos == 253)  {    (*packet)+=4;    return (ulong) uint3korr(pos+1);  }  (*packet)+=9;					/* Must be 254 when here */  return (ulong) uint4korr(pos+1);}/* Same as above, but returns ulonglong values */static my_ulonglongnet_field_length_ll(uchar **packet){  reg1 uchar *pos= *packet;  if (*pos < 251)  {    (*packet)++;    return (my_ulonglong) *pos;  }  if (*pos == 251)  {    (*packet)++;    return (my_ulonglong) NULL_LENGTH;  }  if (*pos == 252)  {    (*packet)+=3;    return (my_ulonglong) uint2korr(pos+1);  }  if (*pos == 253)  {    (*packet)+=4;    return (my_ulonglong) uint3korr(pos+1);  }  (*packet)+=9;					/* Must be 254 when here */#ifdef NO_CLIENT_LONGLONG  return (my_ulonglong) uint4korr(pos+1);#else  return (my_ulonglong) uint8korr(pos+1);#endif}static void free_rows(MYSQL_DATA *cur){  if (cur)  {    free_root(&cur->alloc,MYF(0));    my_free((gptr) cur,MYF(0));  }}intsimple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,	       uint length, my_bool skipp_check){  NET *net= &mysql->net;  int result= -1;  init_sigpipe_variables  /* Don't give sigpipe errors if the client doesn't want them */  set_sigpipe(mysql);  if (mysql->net.vio == 0)  {						/* Do reconnect if possible */    if (mysql_reconnect(mysql))    {      net->last_errno=CR_SERVER_GONE_ERROR;      strmov(net->last_error,ER(net->last_errno));      goto end;    }  }  if (mysql->status != MYSQL_STATUS_READY)  {    strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));    goto end;  }  mysql->net.last_error[0]=0;  mysql->net.last_errno=0;  mysql->info=0;  mysql->affected_rows= ~(my_ulonglong) 0;  net_clear(net);			/* Clear receive buffer */  if (!arg)    arg="";  if (net_write_command(net,(uchar) command,arg,			length ? length : (ulong) strlen(arg)))  {    DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno));    end_server(mysql);    if (mysql_reconnect(mysql) ||	net_write_command(net,(uchar) command,arg,			  length ? length : (ulong) strlen(arg)))    {      net->last_errno=CR_SERVER_GONE_ERROR;      strmov(net->last_error,ER(net->last_errno));      goto end;    }  }  result=0;  if (!skipp_check)    result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?	     -1 : 0); end:  reset_sigpipe(mysql);  return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -