net_pkg.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  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.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. #include "mysql_priv.h"
  17. #include <stdarg.h>
  18. /* Send a error string to client */
  19. void send_error(NET *net, uint sql_errno, const char *err)
  20. {
  21.   uint length;
  22.   char buff[MYSQL_ERRMSG_SIZE+2];
  23.   THD *thd=current_thd;
  24.   DBUG_ENTER("send_error");
  25.   DBUG_PRINT("enter",("sql_errno: %d  err: %s", sql_errno,
  26.       err ? err : net->last_error[0] ?
  27.       net->last_error : "NULL")); 
  28.   if (thd)
  29.     thd->query_error = 1; // needed to catch query errors during replication
  30.   if (!err)
  31.   {
  32.     if (sql_errno)
  33.       err=ER(sql_errno);
  34.     else if (!err)
  35.     {
  36.       if ((err=net->last_error)[0])
  37. sql_errno=net->last_errno;
  38.       else
  39.       {
  40. sql_errno=ER_UNKNOWN_ERROR;
  41. err=ER(sql_errno);  /* purecov: inspected */
  42.       }
  43.     }
  44.   }
  45.   if (net->vio == 0)
  46.   {
  47.     if (thd && thd->bootstrap)
  48.     {
  49.       fprintf(stderr,"ERROR: %d  %sn",sql_errno,err);
  50.     }
  51.     DBUG_VOID_RETURN;
  52.   }
  53.   if (net->return_errno)
  54.   { // new client code; Add errno before message
  55.     int2store(buff,sql_errno);
  56.     length= (uint) (strmake(buff+2,err,MYSQL_ERRMSG_SIZE-1) - buff);
  57.     err=buff;
  58.   }
  59.   else
  60.   {
  61.     length=(uint) strlen(err);
  62.     set_if_smaller(length,MYSQL_ERRMSG_SIZE);
  63.   }
  64.   VOID(net_write_command(net,(uchar) 255,(char*) err,length));
  65.   if (thd)
  66.     thd->fatal_error=0; // Error message is given
  67.   DBUG_VOID_RETURN;
  68. }
  69. /*
  70.   At some point we need to be able to distinguish between warnings and
  71.   errors; The following function will help make this easier.
  72. */
  73. void send_warning(NET *net, uint sql_errno, const char *err)
  74. {
  75.   DBUG_ENTER("send_warning");
  76.   send_error(net,sql_errno,err);
  77.   DBUG_VOID_RETURN;
  78. }
  79. /**
  80. ** write error package and flush to client
  81. ** It's a little too low level, but I don't want to allow another buffer
  82. */
  83. /* VARARGS3 */
  84. void
  85. net_printf(NET *net, uint errcode, ...)
  86. {
  87.   va_list args;
  88.   uint length,offset;
  89.   const char *format,*text_pos;
  90.   int head_length= NET_HEADER_SIZE;
  91.   THD *thd=current_thd;
  92.   DBUG_ENTER("net_printf");
  93.   DBUG_PRINT("enter",("message: %u",errcode));
  94.   if(thd) thd->query_error = 1;
  95.   // if we are here, something is wrong :-)
  96.   
  97.   va_start(args,errcode);
  98.   format=ER(errcode);
  99.   offset= net->return_errno ? 2 : 0;
  100.   text_pos=(char*) net->buff+head_length+offset+1;
  101.   (void) vsprintf(my_const_cast(char*) (text_pos),format,args);
  102.   length=(uint) strlen((char*) text_pos);
  103.   if (length >= sizeof(net->last_error))
  104.     length=sizeof(net->last_error)-1; /* purecov: inspected */
  105.   va_end(args);
  106.   if (net->vio == 0)
  107.   {
  108.     if (thd && thd->bootstrap)
  109.     {
  110.       fprintf(stderr,"ERROR: %d  %sn",errcode,text_pos);
  111.       thd->fatal_error=1;
  112.     }
  113.     DBUG_VOID_RETURN;
  114.   }
  115.   int3store(net->buff,length+1+offset);
  116.   net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
  117.   net->buff[head_length]=(uchar) 255; // Error package
  118.   if (offset)
  119.     int2store(text_pos-2, errcode);
  120.   VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
  121.   if (thd)
  122.     thd->fatal_error=0; // Error message is given
  123.   DBUG_VOID_RETURN;
  124. }
  125. void
  126. send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
  127. {
  128.   if(net->no_send_ok)
  129.     return;
  130.   
  131.   char buff[MYSQL_ERRMSG_SIZE+10],*pos;
  132.   DBUG_ENTER("send_ok");
  133.   buff[0]=0; // No fields
  134.   pos=net_store_length(buff+1,(ulonglong) affected_rows);
  135.   pos=net_store_length(pos, (ulonglong) id);
  136.   if (net->return_status)
  137.   {
  138.     int2store(pos,*net->return_status);
  139.     pos+=2;
  140.   }
  141.   if (message)
  142.     pos=net_store_data((char*) pos,message);
  143.   if (net->vio != 0)
  144.   {
  145.     VOID(my_net_write(net,buff,(uint) (pos-buff)));
  146.     VOID(net_flush(net));
  147.   }
  148.   DBUG_VOID_RETURN;
  149. }
  150. void
  151. send_eof(NET *net,bool no_flush)
  152. {
  153.   static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
  154.   DBUG_ENTER("send_eof");
  155.   if (net->vio != 0)
  156.   {
  157.     VOID(my_net_write(net,eof_buff,1));
  158.     if (!no_flush)
  159.       VOID(net_flush(net));
  160.   }
  161.   DBUG_VOID_RETURN;
  162. }
  163. /****************************************************************************
  164. ** Store a field length in logical packet
  165. ****************************************************************************/
  166. char *
  167. net_store_length(char *pkg, ulonglong length)
  168. {
  169.   uchar *packet=(uchar*) pkg;
  170.   if (length < LL(251))
  171.   {
  172.     *packet=(uchar) length;
  173.     return (char*) packet+1;
  174.   }
  175.   /* 251 is reserved for NULL */
  176.   if (length < LL(65536))
  177.   {
  178.     *packet++=252;
  179.     int2store(packet,(uint) length);
  180.     return (char*) packet+2;
  181.   }
  182.   if (length < LL(16777216))
  183.   {
  184.     *packet++=253;
  185.     int3store(packet,(ulong) length);
  186.     return (char*) packet+3;
  187.   }
  188.   *packet++=254;
  189.   int8store(packet,length);
  190.   return (char*) packet+9;
  191. }
  192. char *
  193. net_store_length(char *pkg, uint length)
  194. {
  195.   uchar *packet=(uchar*) pkg;
  196.   if (length < 251)
  197.   {
  198.     *packet=(uchar) length;
  199.     return (char*) packet+1;
  200.   }
  201.   *packet++=252;
  202.   int2store(packet,(uint) length);
  203.   return (char*) packet+2;
  204. }
  205. /* The following will only be used for short strings < 65K */
  206. char *
  207. net_store_data(char *to,const char *from)
  208. {
  209.   uint length=(uint) strlen(from);
  210.   to=net_store_length(to,length);
  211.   memcpy(to,from,length);
  212.   return to+length;
  213. }
  214. char *
  215. net_store_data(char *to,int32 from)
  216. {
  217.   char buff[20];
  218.   uint length=(uint) (int10_to_str(from,buff,10)-buff);
  219.   to=net_store_length(to,length);
  220.   memcpy(to,buff,length);
  221.   return to+length;
  222. }
  223. char *
  224. net_store_data(char *to,longlong from)
  225. {
  226.   char buff[22];
  227.   uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
  228.   to=net_store_length(to,length);
  229.   memcpy(to,buff,length);
  230.   return to+length;
  231. }
  232. bool net_store_null(String *packet)
  233. {
  234.   return packet->append((char) 251);
  235. }
  236. bool
  237. net_store_data(String *packet,const char *from,uint length)
  238. {
  239.   ulong packet_length=packet->length();
  240.   if (packet_length+5+length > packet->alloced_length() &&
  241.       packet->realloc(packet_length+5+length))
  242.     return 1;
  243.   char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
  244.     (ulonglong) length);
  245.   memcpy(to,from,length);
  246.   packet->length((uint) (to+length-packet->ptr()));
  247.   return 0;
  248. }
  249. /* The following is only used at short, null terminated data */
  250. bool
  251. net_store_data(String *packet,const char *from)
  252. {
  253.   uint length=(uint) strlen(from);
  254.   uint packet_length=packet->length();
  255.   if (packet_length+5+length > packet->alloced_length() &&
  256.       packet->realloc(packet_length+5+length))
  257.     return 1;
  258.   char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
  259.     length);
  260.   memcpy(to,from,length);
  261.   packet->length((uint) (to+length-packet->ptr()));
  262.   return 0;
  263. }
  264. bool
  265. net_store_data(String *packet,uint32 from)
  266. {
  267.   char buff[20];
  268.   return net_store_data(packet,(char*) buff,
  269. (uint) (int10_to_str(from,buff,10)-buff));
  270. }
  271. bool
  272. net_store_data(String *packet, longlong from)
  273. {
  274.   char buff[22];
  275.   return net_store_data(packet,(char*) buff,
  276. (uint) (longlong10_to_str(from,buff,10)-buff));
  277. }
  278. bool
  279. net_store_data(String *packet,struct tm *tmp)
  280. {
  281.   char buff[20];
  282.   sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
  283.   ((int) (tmp->tm_year+1900)) % 10000,
  284.   (int) tmp->tm_mon+1,
  285.   (int) tmp->tm_mday,
  286.   (int) tmp->tm_hour,
  287.   (int) tmp->tm_min,
  288.   (int) tmp->tm_sec);
  289.   return net_store_data(packet,(char*) buff,19);
  290. }
  291. bool net_store_data(String* packet, I_List<i_string>* str_list)
  292. {
  293.   char buf[256];
  294.   String tmp(buf, sizeof(buf));
  295.   tmp.length(0);
  296.   I_List_iterator<i_string> it(*str_list);
  297.   i_string* s;
  298.   while((s=it++))
  299.   {
  300.     if(tmp.length())
  301.       tmp.append(',');
  302.     tmp.append(s->ptr);
  303.   }
  304.   return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
  305. }
  306. /*
  307. ** translate and store data; These are mainly used by the SHOW functions
  308. */
  309. bool
  310. net_store_data(String *packet,CONVERT *convert, const char *from,uint length)
  311. {
  312.   if (convert)
  313.     return convert->store(packet, from, length);
  314.   return net_store_data(packet,from,length);
  315. }
  316. bool
  317. net_store_data(String *packet, CONVERT *convert, const char *from)
  318. {
  319.   uint length=(uint) strlen(from);
  320.   if (convert)
  321.     return convert->store(packet, from, length);
  322.   return net_store_data(packet,from,length);
  323. }