~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to server-tools/instance-manager/protocol.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2004-2006 MySQL 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; version 2 of the License.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
#include "protocol.h"
 
17
 
 
18
#include "messages.h"
 
19
 
 
20
#include <mysql_com.h>
 
21
#include <m_string.h>
 
22
 
 
23
 
 
24
static uchar eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
 
25
static const char ERROR_PACKET_CODE= (char) 255;
 
26
 
 
27
 
 
28
int net_send_ok(struct st_net *net, unsigned long connection_id,
 
29
                const char *message)
 
30
{
 
31
  /*
 
32
            The format of a packet
 
33
    1                             packet type code
 
34
    1-9                           affected rows count
 
35
    1-9                           connection id
 
36
    2                             thread return status
 
37
    2                             warning count
 
38
    1-9 + message length          message to send (isn't stored if no message)
 
39
  */
 
40
  Buffer buff;
 
41
  uchar *pos= buff.buffer;
 
42
 
 
43
  /* check that we have space to hold mandatory fields */
 
44
  buff.reserve(0, 23);
 
45
 
 
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);
 
51
  pos+= 2;
 
52
  /* We don't support warnings, so store 0 for total warning count */
 
53
  int2store(pos, 0);
 
54
  pos+= 2;
 
55
 
 
56
  size_t position= pos - buff.buffer; /* we might need it for message */
 
57
 
 
58
  if (message != NULL)
 
59
  {
 
60
    buff.reserve(position, 9 + strlen(message));
 
61
    store_to_protocol_packet(&buff, message, &position);
 
62
  }
 
63
 
 
64
  return my_net_write(net, buff.buffer, position) || net_flush(net);
 
65
}
 
66
 
 
67
 
 
68
int net_send_error(struct st_net *net, uint sql_errno)
 
69
{
 
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
 
75
  char *pos= buff;
 
76
 
 
77
  *pos++= ERROR_PACKET_CODE;
 
78
  int2store(pos, sql_errno);
 
79
  pos+= 2;
 
80
  /* The first # is to make the protocol backward compatible */
 
81
  *pos++= '#';
 
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)) ||
 
86
          net_flush(net));
 
87
}
 
88
 
 
89
 
 
90
int net_send_error_323(struct st_net *net, uint sql_errno)
 
91
{
 
92
  const char *err= message(sql_errno);
 
93
  char buff[1 +                                 // packet type code
 
94
            2 +                                 // sql error number
 
95
            MYSQL_ERRMSG_SIZE];                 // message
 
96
  char *pos= buff;
 
97
 
 
98
  *pos++= ERROR_PACKET_CODE;
 
99
  int2store(pos, sql_errno);
 
100
  pos+= 2;
 
101
  pos= strmake(pos, err, MYSQL_ERRMSG_SIZE - 1) + 1;
 
102
  return (my_net_write(net, (uchar*) buff, (size_t) (pos - buff)) ||
 
103
          net_flush(net));
 
104
}
 
105
 
 
106
char *net_store_length(char *pkg, uint length)
 
107
{
 
108
  uchar *packet=(uchar*) pkg;
 
109
  if (length < 251)
 
110
  {
 
111
    *packet=(uchar) length;
 
112
    return (char*) packet+1;
 
113
  }
 
114
  *packet++=252;
 
115
  int2store(packet,(uint) length);
 
116
  return (char*) packet+2;
 
117
}
 
118
 
 
119
 
 
120
int store_to_protocol_packet(Buffer *buf, const char *string, size_t *position,
 
121
                             size_t string_len)
 
122
{
 
123
  uint currpos;
 
124
 
 
125
  /* reserve max amount of bytes needed to store length */
 
126
  if (buf->reserve(*position, 9))
 
127
    goto err;
 
128
  currpos= (net_store_length(buf->buffer + *position,
 
129
                             (ulonglong) string_len) - buf->buffer);
 
130
  if (buf->append(currpos, string, string_len))
 
131
    goto err;
 
132
  *position= *position + string_len + (currpos - *position);
 
133
 
 
134
  return 0;
 
135
err:
 
136
  return 1;
 
137
}
 
138
 
 
139
 
 
140
int store_to_protocol_packet(Buffer *buf, const char *string,
 
141
                             size_t *position)
 
142
{
 
143
  size_t string_len;
 
144
 
 
145
  string_len= strlen(string);
 
146
  return store_to_protocol_packet(buf, string, position, string_len);
 
147
}
 
148
 
 
149
 
 
150
int send_eof(struct st_net *net)
 
151
{
 
152
  uchar buff[1 + /* eof packet code */
 
153
             2 + /* warning count */
 
154
             2]; /* server status */
 
155
 
 
156
  buff[0]=254;
 
157
  int2store(buff+1, 0);
 
158
  int2store(buff+3, 0);
 
159
  return my_net_write(net, buff, sizeof(buff));
 
160
}
 
161
 
 
162
 
 
163
int send_fields(struct st_net *net, LIST *fields)
 
164
{
 
165
  LIST *tmp= fields;
 
166
  Buffer send_buff;
 
167
  uchar small_buff[4];
 
168
  size_t position= 0;
 
169
  LEX_STRING *field;
 
170
 
 
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))
 
174
    goto err;
 
175
 
 
176
  while (tmp)
 
177
  {
 
178
    position= 0;
 
179
    field= (LEX_STRING *) tmp->data;
 
180
 
 
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())
 
195
      goto err;
 
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;
 
205
    position+= 12;
 
206
    if (my_net_write(net, send_buff.buffer, (uint) position+1))
 
207
      goto err;
 
208
    tmp= list_rest(tmp);
 
209
  }
 
210
 
 
211
  if (my_net_write(net, eof_buff, 1))
 
212
    goto err;
 
213
  return 0;
 
214
 
 
215
err:
 
216
  return 1;
 
217
}