~drizzle-trunk/drizzle/development

1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are
9
 * met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 * notice, this list of conditions and the following disclaimer.
13
 *
14
 *     * Redistributions in binary form must reproduce the above
15
 * copyright notice, this list of conditions and the following disclaimer
16
 * in the documentation and/or other materials provided with the
17
 * distribution.
18
 *
19
 *     * The names of its contributors may not be used to endorse or
20
 * promote products derived from this software without specific prior
21
 * written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
35
 */
36
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
37
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
38
#include <errno.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
43
#include <libdrizzle/drizzle_client.h>
44
#include <libdrizzle/drizzle_server.h>
45
46
#define DRIZZLE_RETURN_CHECK(__ret, __function, __drizzle) \
47
{ \
48
  if ((__ret) != DRIZZLE_RETURN_OK) \
49
    DRIZZLE_RETURN_ERROR(__function, __drizzle) \
50
}
51
52
#define DRIZZLE_RETURN_ERROR(__function, __drizzle) \
53
{ \
54
  printf(__function ":%s\n", drizzle_error(__drizzle)); \
55
  return; \
56
}
57
58
static void proxy(drizzle_st *drizzle, drizzle_con_st *server,
59
                  drizzle_con_st *client, drizzle_result_st *server_result,
60
                  drizzle_result_st *client_result, drizzle_column_st *column);
61
62
int main(int argc, char *argv[])
63
{
64
  int c;
65
  uint32_t count= 0;
66
  const char *server_host= NULL;
67
  const char *client_host= NULL;
68
  bool server_mysql= false;
69
  bool client_mysql= false;
70
  in_port_t server_port= 0;
71
  in_port_t client_port= 0;
72
  drizzle_verbose_t verbose= DRIZZLE_VERBOSE_NEVER;
73
  drizzle_return_t ret;
74
  drizzle_st drizzle;
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
75
  drizzle_con_st *con_listen= (drizzle_con_st*)malloc(sizeof(drizzle_con_st));
76
  drizzle_con_st *server= (drizzle_con_st*)malloc(sizeof(drizzle_con_st));
77
  drizzle_con_st *client= (drizzle_con_st*)malloc(sizeof(drizzle_con_st));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
78
  drizzle_result_st server_result;
79
  drizzle_result_st client_result;
80
  drizzle_column_st column;
81
82
  while((c = getopt(argc, argv, "c:h:H:mMp:P:v")) != -1)
83
  {
84
    switch(c)
85
    {
86
    case 'c':
87
      count= (uint32_t)atoi(optarg);
88
      break;
89
90
    case 'h':
91
      server_host= optarg;
92
      break;
93
94
    case 'H':
95
      client_host= optarg;
96
      break;
97
98
    case 'm':
99
      server_mysql= true;
100
      break;
101
102
    case 'M':
103
      client_mysql= true;
104
      break;
105
106
    case 'p':
107
      server_port= (in_port_t)atoi(optarg);
108
      break;
109
110
    case 'P':
111
      client_port= (in_port_t)atoi(optarg);
112
      break;
113
114
    case 'v':
115
      verbose++;
116
      break;
117
118
    default:
119
      printf("\nusage: %s [-c <count>] [-h <host>] [-H <host>] [-m] [-M] "
120
             "[-p <port>] [-p <port>] [-v]\n", argv[0]);
121
      printf("\t-c <count> - Number of connections to accept before exiting\n");
122
      printf("\t-h <host>  - Host to listen on\n");
123
      printf("\t-H <host>  - Host to connect to\n");
124
      printf("\t-m         - Use MySQL protocol for incoming connections\n");
125
      printf("\t-M         - Use MySQL protocol for outgoing connectionsn\n");
126
      printf("\t-p <port>  - Port to listen on\n");
127
      printf("\t-P <port>  - Port to connect to\n");
128
      printf("\t-v         - Increase verbosity level\n");
129
      return 1;
130
    }
131
  }
132
133
  if (drizzle_create(&drizzle) == NULL)
134
  {
135
    printf("drizzle_create:NULL\n");
136
    return 1;
137
  }
138
139
  drizzle_add_options(&drizzle, DRIZZLE_FREE_OBJECTS);
140
  drizzle_set_verbose(&drizzle, verbose);
141
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
142
  if (drizzle_con_create(&drizzle, con_listen) == NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
143
  {
144
    printf("drizzle_con_create:NULL\n");
145
    return 1;
146
  }
147
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
148
  drizzle_con_add_options(con_listen, DRIZZLE_CON_LISTEN);
149
  drizzle_con_set_tcp(con_listen, server_host, server_port);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
150
151
  if (server_mysql)
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
152
    drizzle_con_add_options(con_listen, DRIZZLE_CON_MYSQL);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
153
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
154
  if (drizzle_con_listen(con_listen) != DRIZZLE_RETURN_OK)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
155
  {
156
    printf("drizzle_con_listen:%s\n", drizzle_error(&drizzle));
157
    return 1;
158
  }
159
160
  while (1)
161
  {
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
162
    (void)drizzle_con_accept(&drizzle, server, &ret);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
163
    if (ret != DRIZZLE_RETURN_OK)
164
    {
165
      printf("drizzle_con_accept:%s\n", drizzle_error(&drizzle));
166
      return 1;
167
    }
168
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
169
    if (drizzle_con_create(&drizzle, client) == NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
170
    {
171
      printf("drizzle_con_create:NULL\n");
172
      return 1;
173
    }
174
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
175
    drizzle_con_add_options(client,
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
176
                            DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_RAW_SCRAMBLE);
177
    if (client_mysql)
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
178
      drizzle_con_add_options(client, DRIZZLE_CON_MYSQL);
179
    drizzle_con_set_tcp(client, client_host, client_port);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
180
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
181
    ret= drizzle_con_connect(client);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
182
    if (ret != DRIZZLE_RETURN_OK)
183
    {
184
      printf("drizzle_con_connect:%s\n", drizzle_error(&drizzle));
185
      return 1;
186
    }
187
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
188
    proxy(&drizzle, server, client, &server_result, &client_result, &column);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
189
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
190
    drizzle_con_free(client);
191
    drizzle_con_free(server);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
192
193
    if (count > 0)
194
    {
195
      count--;
196
197
      if (count == 0)
198
        break;
199
    }
200
  }
201
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
202
  drizzle_con_free(con_listen);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
203
  drizzle_free(&drizzle);
204
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
205
  free(con_listen);
206
  free(server);
207
  free(client);
208
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
209
  return 0;
210
}
211
212
static void proxy(drizzle_st *drizzle, drizzle_con_st *server,
213
                  drizzle_con_st *client, drizzle_result_st *server_result,
214
                  drizzle_result_st *client_result, drizzle_column_st *column)
215
{
216
  drizzle_return_t ret;
217
  drizzle_command_t command;
218
  const uint8_t *data;
219
  size_t offset;
220
  size_t size;
221
  size_t total;
222
  uint64_t row;
223
  bool row_break;
224
  drizzle_field_t field;
225
226
  /* Handshake packets. */
227
  ret= drizzle_handshake_server_read(client);
228
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_read", drizzle)
229
230
  drizzle_con_copy_handshake(server, client);
231
232
  ret= drizzle_handshake_server_write(server);
233
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_write", drizzle)
234
235
  ret= drizzle_handshake_client_read(server);
236
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_read", drizzle)
237
238
  drizzle_con_copy_handshake(client, server);
239
240
  ret= drizzle_handshake_client_write(client);
241
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_write", drizzle)
242
243
  (void)drizzle_result_read(client, client_result, &ret);
244
  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
245
246
  drizzle_con_set_status(server, drizzle_con_status(client));
247
248
  if (drizzle_result_clone(server, server_result, client_result) == NULL)
249
    DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
250
251
  ret= drizzle_result_write(server, server_result, true);
252
  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
253
254
  if (drizzle_result_error_code(client_result) != 0 ||
255
      drizzle_result_eof(client_result))
256
  {
257
    /* There was a handshake or authentication error. */
258
    return;
259
  }
260
261
  drizzle_con_add_options(client, DRIZZLE_CON_READY);
262
263
  /* Command loop. */
264
  while (1)
265
  {
266
    drizzle_result_free(server_result);
267
    drizzle_result_free(client_result);
268
269
    while (1)
270
    {
271
      data= drizzle_con_command_read(server, &command, &offset, &size, &total,
272
                                     &ret);
273
      if (ret == DRIZZLE_RETURN_LOST_CONNECTION)
274
        return;
275
276
      DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_read", drizzle)
277
278
      (void)drizzle_con_command_write(client, NULL, command, data, size, total,
279
                                      &ret);
280
      DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_write", drizzle)
281
282
      if ((offset + size) == total)
283
        break;
284
    }
285
286
    if (command == DRIZZLE_COMMAND_QUIT)
287
      return;
288
    else if (command == DRIZZLE_COMMAND_FIELD_LIST)
289
    {
290
      if (drizzle_result_create(client, client_result) == NULL)
291
        DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
292
293
      if (drizzle_result_create(server, server_result) == NULL)
294
        DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
295
    }
296
    else
297
    {
298
      (void)drizzle_result_read(client, client_result, &ret);
299
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
300
301
      drizzle_con_set_status(server, drizzle_con_status(client));
302
      if (drizzle_result_clone(server, server_result, client_result) == NULL)
303
        DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
304
305
      if (drizzle_result_column_count(client_result) == 0)
306
      {
307
        /* Simple result with no column, row, or field data. */
308
        ret= drizzle_result_write(server, server_result, true);
309
        DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
310
311
        continue;
312
      }
313
314
      ret= drizzle_result_write(server, server_result, false);
315
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
316
    }
317
318
    /* Columns. */
319
    while (1)
320
    {
321
      if (drizzle_column_read(client_result, column, &ret) == NULL)
322
      {
323
        DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
324
        break;
325
      }
326
327
      DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
328
329
      ret= drizzle_column_write(server_result, column);
330
      DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
331
332
      drizzle_column_free(column);
333
    }
334
335
    drizzle_con_set_status(server, drizzle_con_status(client));
336
    drizzle_result_set_eof(server_result, true);
337
338
    if (command == DRIZZLE_COMMAND_FIELD_LIST)
339
    {
340
      ret= drizzle_result_write(server, server_result, true);
341
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
342
      continue;
343
    }
344
    else
345
    {
346
      ret= drizzle_result_write(server, server_result, false);
347
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
348
    }
349
350
    /* Rows. */
351
    while (1)
352
    {
353
      row= drizzle_row_read(client_result, &ret);
354
      DRIZZLE_RETURN_CHECK(ret, "drizzle_row_read", drizzle)
355
356
      if (row == 0)
357
        break;
358
359
      drizzle_result_set_row_size(server_result,
360
                                  drizzle_result_row_size(client_result));
361
362
      ret= drizzle_row_write(server_result);
363
      DRIZZLE_RETURN_CHECK(ret, "drizzle_row_write", drizzle)
364
365
      /* Fields. */
366
      row_break= false;
367
      while (row_break == false)
368
      {
369
        field= drizzle_field_read(client_result, &offset, &size, &total, &ret);
370
        if (ret == DRIZZLE_RETURN_ROW_END)
371
          break;
372
        else if (ret == DRIZZLE_RETURN_ROW_BREAK)
373
        {
374
          if (size == 0)
375
            break;
376
377
          row_break= true;
378
        }
379
        else
380
          DRIZZLE_RETURN_CHECK(ret, "drizzle_field_read", drizzle)
381
382
        ret= drizzle_field_write(server_result, field, size, total);
383
        DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
384
      }
385
    }
386
387
    ret= drizzle_result_write(server, server_result, true);
388
    DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
389
  }
390
}