home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / net_pkg.cpp < prev    next >
C/C++ Source or Header  |  2000-11-16  |  8KB  |  330 lines

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