net_pkg.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:9k
- /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- 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 "mysql_priv.h"
- #include <stdarg.h>
- /* Send a error string to client */
- void send_error(NET *net, uint sql_errno, const char *err)
- {
- uint length;
- char buff[MYSQL_ERRMSG_SIZE+2];
- THD *thd=current_thd;
- DBUG_ENTER("send_error");
- DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno,
- err ? err : net->last_error[0] ?
- net->last_error : "NULL"));
- if (thd)
- thd->query_error = 1; // needed to catch query errors during replication
- if (!err)
- {
- if (sql_errno)
- err=ER(sql_errno);
- else if (!err)
- {
- if ((err=net->last_error)[0])
- sql_errno=net->last_errno;
- else
- {
- sql_errno=ER_UNKNOWN_ERROR;
- err=ER(sql_errno); /* purecov: inspected */
- }
- }
- }
- if (net->vio == 0)
- {
- if (thd && thd->bootstrap)
- {
- fprintf(stderr,"ERROR: %d %sn",sql_errno,err);
- }
- DBUG_VOID_RETURN;
- }
- if (net->return_errno)
- { // new client code; Add errno before message
- int2store(buff,sql_errno);
- length= (uint) (strmake(buff+2,err,MYSQL_ERRMSG_SIZE-1) - buff);
- err=buff;
- }
- else
- {
- length=(uint) strlen(err);
- set_if_smaller(length,MYSQL_ERRMSG_SIZE);
- }
- VOID(net_write_command(net,(uchar) 255,(char*) err,length));
- if (thd)
- thd->fatal_error=0; // Error message is given
- DBUG_VOID_RETURN;
- }
- /*
- At some point we need to be able to distinguish between warnings and
- errors; The following function will help make this easier.
- */
- void send_warning(NET *net, uint sql_errno, const char *err)
- {
- DBUG_ENTER("send_warning");
- send_error(net,sql_errno,err);
- DBUG_VOID_RETURN;
- }
- /**
- ** write error package and flush to client
- ** It's a little too low level, but I don't want to allow another buffer
- */
- /* VARARGS3 */
- void
- net_printf(NET *net, uint errcode, ...)
- {
- va_list args;
- uint length,offset;
- const char *format,*text_pos;
- int head_length= NET_HEADER_SIZE;
- THD *thd=current_thd;
- DBUG_ENTER("net_printf");
- DBUG_PRINT("enter",("message: %u",errcode));
- if(thd) thd->query_error = 1;
- // if we are here, something is wrong :-)
-
- va_start(args,errcode);
- format=ER(errcode);
- offset= net->return_errno ? 2 : 0;
- text_pos=(char*) net->buff+head_length+offset+1;
- (void) vsprintf(my_const_cast(char*) (text_pos),format,args);
- length=(uint) strlen((char*) text_pos);
- if (length >= sizeof(net->last_error))
- length=sizeof(net->last_error)-1; /* purecov: inspected */
- va_end(args);
- if (net->vio == 0)
- {
- if (thd && thd->bootstrap)
- {
- fprintf(stderr,"ERROR: %d %sn",errcode,text_pos);
- thd->fatal_error=1;
- }
- DBUG_VOID_RETURN;
- }
- int3store(net->buff,length+1+offset);
- net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
- net->buff[head_length]=(uchar) 255; // Error package
- if (offset)
- int2store(text_pos-2, errcode);
- VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
- if (thd)
- thd->fatal_error=0; // Error message is given
- DBUG_VOID_RETURN;
- }
- void
- send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
- {
- if(net->no_send_ok)
- return;
-
- char buff[MYSQL_ERRMSG_SIZE+10],*pos;
- DBUG_ENTER("send_ok");
- buff[0]=0; // No fields
- pos=net_store_length(buff+1,(ulonglong) affected_rows);
- pos=net_store_length(pos, (ulonglong) id);
- if (net->return_status)
- {
- int2store(pos,*net->return_status);
- pos+=2;
- }
- if (message)
- pos=net_store_data((char*) pos,message);
- if (net->vio != 0)
- {
- VOID(my_net_write(net,buff,(uint) (pos-buff)));
- VOID(net_flush(net));
- }
- DBUG_VOID_RETURN;
- }
- void
- send_eof(NET *net,bool no_flush)
- {
- static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
- DBUG_ENTER("send_eof");
- if (net->vio != 0)
- {
- VOID(my_net_write(net,eof_buff,1));
- if (!no_flush)
- VOID(net_flush(net));
- }
- DBUG_VOID_RETURN;
- }
- /****************************************************************************
- ** Store a field length in logical packet
- ****************************************************************************/
- char *
- net_store_length(char *pkg, ulonglong length)
- {
- uchar *packet=(uchar*) pkg;
- if (length < LL(251))
- {
- *packet=(uchar) length;
- return (char*) packet+1;
- }
- /* 251 is reserved for NULL */
- if (length < LL(65536))
- {
- *packet++=252;
- int2store(packet,(uint) length);
- return (char*) packet+2;
- }
- if (length < LL(16777216))
- {
- *packet++=253;
- int3store(packet,(ulong) length);
- return (char*) packet+3;
- }
- *packet++=254;
- int8store(packet,length);
- return (char*) packet+9;
- }
- char *
- net_store_length(char *pkg, uint length)
- {
- uchar *packet=(uchar*) pkg;
- if (length < 251)
- {
- *packet=(uchar) length;
- return (char*) packet+1;
- }
- *packet++=252;
- int2store(packet,(uint) length);
- return (char*) packet+2;
- }
- /* The following will only be used for short strings < 65K */
- char *
- net_store_data(char *to,const char *from)
- {
- uint length=(uint) strlen(from);
- to=net_store_length(to,length);
- memcpy(to,from,length);
- return to+length;
- }
- char *
- net_store_data(char *to,int32 from)
- {
- char buff[20];
- uint length=(uint) (int10_to_str(from,buff,10)-buff);
- to=net_store_length(to,length);
- memcpy(to,buff,length);
- return to+length;
- }
- char *
- net_store_data(char *to,longlong from)
- {
- char buff[22];
- uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
- to=net_store_length(to,length);
- memcpy(to,buff,length);
- return to+length;
- }
- bool net_store_null(String *packet)
- {
- return packet->append((char) 251);
- }
- bool
- net_store_data(String *packet,const char *from,uint length)
- {
- ulong packet_length=packet->length();
- if (packet_length+5+length > packet->alloced_length() &&
- packet->realloc(packet_length+5+length))
- return 1;
- char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
- (ulonglong) length);
- memcpy(to,from,length);
- packet->length((uint) (to+length-packet->ptr()));
- return 0;
- }
- /* The following is only used at short, null terminated data */
- bool
- net_store_data(String *packet,const char *from)
- {
- uint length=(uint) strlen(from);
- uint packet_length=packet->length();
- if (packet_length+5+length > packet->alloced_length() &&
- packet->realloc(packet_length+5+length))
- return 1;
- char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
- length);
- memcpy(to,from,length);
- packet->length((uint) (to+length-packet->ptr()));
- return 0;
- }
- bool
- net_store_data(String *packet,uint32 from)
- {
- char buff[20];
- return net_store_data(packet,(char*) buff,
- (uint) (int10_to_str(from,buff,10)-buff));
- }
- bool
- net_store_data(String *packet, longlong from)
- {
- char buff[22];
- return net_store_data(packet,(char*) buff,
- (uint) (longlong10_to_str(from,buff,10)-buff));
- }
- bool
- net_store_data(String *packet,struct tm *tmp)
- {
- char buff[20];
- sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
- ((int) (tmp->tm_year+1900)) % 10000,
- (int) tmp->tm_mon+1,
- (int) tmp->tm_mday,
- (int) tmp->tm_hour,
- (int) tmp->tm_min,
- (int) tmp->tm_sec);
- return net_store_data(packet,(char*) buff,19);
- }
- bool net_store_data(String* packet, I_List<i_string>* str_list)
- {
- char buf[256];
- String tmp(buf, sizeof(buf));
- tmp.length(0);
- I_List_iterator<i_string> it(*str_list);
- i_string* s;
- while((s=it++))
- {
- if(tmp.length())
- tmp.append(',');
- tmp.append(s->ptr);
- }
- return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
- }
- /*
- ** translate and store data; These are mainly used by the SHOW functions
- */
- bool
- net_store_data(String *packet,CONVERT *convert, const char *from,uint length)
- {
- if (convert)
- return convert->store(packet, from, length);
- return net_store_data(packet,from,length);
- }
- bool
- net_store_data(String *packet, CONVERT *convert, const char *from)
- {
- uint length=(uint) strlen(from);
- if (convert)
- return convert->store(packet, from, length);
- return net_store_data(packet,from,length);
- }