1
/* Copyright (C) 2004-2006 MySQL AB
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; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
#include <mysql_com.h>
24
static uchar eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
25
static const char ERROR_PACKET_CODE= (char) 255;
28
int net_send_ok(struct st_net *net, unsigned long connection_id,
32
The format of a packet
34
1-9 affected rows count
36
2 thread return status
38
1-9 + message length message to send (isn't stored if no message)
41
uchar *pos= buff.buffer;
43
/* check that we have space to hold mandatory fields */
46
enum { OK_PACKET_CODE= 0 };
47
*pos++= OK_PACKET_CODE;
48
pos= net_store_length(pos, (ulonglong) 0);
49
pos= net_store_length(pos, (ulonglong) connection_id);
50
int2store(pos, *net->return_status);
52
/* We don't support warnings, so store 0 for total warning count */
56
size_t position= pos - buff.buffer; /* we might need it for message */
60
buff.reserve(position, 9 + strlen(message));
61
store_to_protocol_packet(&buff, message, &position);
64
return my_net_write(net, buff.buffer, position) || net_flush(net);
68
int net_send_error(struct st_net *net, uint sql_errno)
70
const char *err= message(sql_errno);
71
char buff[1 + // packet type code
72
2 + // sql error number
73
1 + SQLSTATE_LENGTH + // sql state
74
MYSQL_ERRMSG_SIZE]; // message
77
*pos++= ERROR_PACKET_CODE;
78
int2store(pos, sql_errno);
80
/* The first # is to make the protocol backward compatible */
82
memcpy(pos, errno_to_sqlstate(sql_errno), SQLSTATE_LENGTH);
83
pos+= SQLSTATE_LENGTH;
84
pos= strmake(pos, err, MYSQL_ERRMSG_SIZE - 1) + 1;
85
return (my_net_write(net, (uchar*) buff, (size_t) (pos - buff)) ||
90
int net_send_error_323(struct st_net *net, uint sql_errno)
92
const char *err= message(sql_errno);
93
char buff[1 + // packet type code
94
2 + // sql error number
95
MYSQL_ERRMSG_SIZE]; // message
98
*pos++= ERROR_PACKET_CODE;
99
int2store(pos, sql_errno);
101
pos= strmake(pos, err, MYSQL_ERRMSG_SIZE - 1) + 1;
102
return (my_net_write(net, (uchar*) buff, (size_t) (pos - buff)) ||
106
char *net_store_length(char *pkg, uint length)
108
uchar *packet=(uchar*) pkg;
111
*packet=(uchar) length;
112
return (char*) packet+1;
115
int2store(packet,(uint) length);
116
return (char*) packet+2;
120
int store_to_protocol_packet(Buffer *buf, const char *string, size_t *position,
125
/* reserve max amount of bytes needed to store length */
126
if (buf->reserve(*position, 9))
128
currpos= (net_store_length(buf->buffer + *position,
129
(ulonglong) string_len) - buf->buffer);
130
if (buf->append(currpos, string, string_len))
132
*position= *position + string_len + (currpos - *position);
140
int store_to_protocol_packet(Buffer *buf, const char *string,
145
string_len= strlen(string);
146
return store_to_protocol_packet(buf, string, position, string_len);
150
int send_eof(struct st_net *net)
152
uchar buff[1 + /* eof packet code */
153
2 + /* warning count */
154
2]; /* server status */
157
int2store(buff+1, 0);
158
int2store(buff+3, 0);
159
return my_net_write(net, buff, sizeof(buff));
163
int send_fields(struct st_net *net, LIST *fields)
171
/* send the number of fileds */
172
net_store_length(small_buff, (uint) list_length(fields));
173
if (my_net_write(net, small_buff, (uint) 1))
179
field= (LEX_STRING *) tmp->data;
181
store_to_protocol_packet(&send_buff,
182
(char*) "", &position); /* catalog name */
183
store_to_protocol_packet(&send_buff,
184
(char*) "", &position); /* db name */
185
store_to_protocol_packet(&send_buff,
186
(char*) "", &position); /* table name */
187
store_to_protocol_packet(&send_buff,
188
(char*) "", &position); /* table name alias */
189
store_to_protocol_packet(&send_buff,
190
field->str, &position); /* column name */
191
store_to_protocol_packet(&send_buff,
192
field->str, &position); /* column name alias */
193
send_buff.reserve(position, 12);
194
if (send_buff.is_error())
196
send_buff.buffer[position++]= 12;
197
int2store(send_buff.buffer + position, 1); /* charsetnr */
198
int4store(send_buff.buffer + position + 2,
199
field->length); /* field length */
200
send_buff.buffer[position+6]= (char) MYSQL_TYPE_STRING; /* type */
201
int2store(send_buff.buffer + position + 7, 0); /* flags */
202
send_buff.buffer[position + 9]= (char) 0; /* decimals */
203
send_buff.buffer[position + 10]= 0;
204
send_buff.buffer[position + 11]= 0;
206
if (my_net_write(net, send_buff.buffer, (uint) position+1))
211
if (my_net_write(net, eof_buff, 1))