~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':
1992.6.2 by Monty Taylor
Cleaned up for additional gcc 4.5 warnings.
115
      switch(verbose)
116
      {
117
      case DRIZZLE_VERBOSE_NEVER:
118
        verbose= DRIZZLE_VERBOSE_FATAL;
119
        break;
120
      case DRIZZLE_VERBOSE_FATAL:
121
        verbose= DRIZZLE_VERBOSE_ERROR;
122
        break;
123
      case DRIZZLE_VERBOSE_ERROR:
124
        verbose= DRIZZLE_VERBOSE_INFO;
125
        break;
126
      case DRIZZLE_VERBOSE_INFO:
127
        verbose= DRIZZLE_VERBOSE_DEBUG;
128
        break;
129
      case DRIZZLE_VERBOSE_DEBUG:
130
        verbose= DRIZZLE_VERBOSE_CRAZY;
131
        break;
132
      case DRIZZLE_VERBOSE_CRAZY:
133
      case DRIZZLE_VERBOSE_MAX:
134
        break;
135
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
136
      break;
137
138
    default:
139
      printf("\nusage: %s [-c <count>] [-h <host>] [-H <host>] [-m] [-M] "
140
             "[-p <port>] [-p <port>] [-v]\n", argv[0]);
141
      printf("\t-c <count> - Number of connections to accept before exiting\n");
142
      printf("\t-h <host>  - Host to listen on\n");
143
      printf("\t-H <host>  - Host to connect to\n");
144
      printf("\t-m         - Use MySQL protocol for incoming connections\n");
145
      printf("\t-M         - Use MySQL protocol for outgoing connectionsn\n");
146
      printf("\t-p <port>  - Port to listen on\n");
147
      printf("\t-P <port>  - Port to connect to\n");
148
      printf("\t-v         - Increase verbosity level\n");
149
      return 1;
150
    }
151
  }
152
153
  if (drizzle_create(&drizzle) == NULL)
154
  {
155
    printf("drizzle_create:NULL\n");
156
    return 1;
157
  }
158
159
  drizzle_add_options(&drizzle, DRIZZLE_FREE_OBJECTS);
160
  drizzle_set_verbose(&drizzle, verbose);
161
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
162
  if (drizzle_con_create(&drizzle, con_listen) == NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
163
  {
164
    printf("drizzle_con_create:NULL\n");
165
    return 1;
166
  }
167
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
168
  drizzle_con_add_options(con_listen, DRIZZLE_CON_LISTEN);
169
  drizzle_con_set_tcp(con_listen, server_host, server_port);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
170
171
  if (server_mysql)
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
172
    drizzle_con_add_options(con_listen, DRIZZLE_CON_MYSQL);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
173
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
174
  if (drizzle_con_listen(con_listen) != DRIZZLE_RETURN_OK)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
175
  {
176
    printf("drizzle_con_listen:%s\n", drizzle_error(&drizzle));
177
    return 1;
178
  }
179
180
  while (1)
181
  {
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
182
    (void)drizzle_con_accept(&drizzle, server, &ret);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
183
    if (ret != DRIZZLE_RETURN_OK)
184
    {
185
      printf("drizzle_con_accept:%s\n", drizzle_error(&drizzle));
186
      return 1;
187
    }
188
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
189
    if (drizzle_con_create(&drizzle, client) == NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
190
    {
191
      printf("drizzle_con_create:NULL\n");
192
      return 1;
193
    }
194
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
195
    drizzle_con_add_options(client,
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
196
                            DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_RAW_SCRAMBLE);
197
    if (client_mysql)
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
198
      drizzle_con_add_options(client, DRIZZLE_CON_MYSQL);
199
    drizzle_con_set_tcp(client, client_host, client_port);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
200
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
201
    ret= drizzle_con_connect(client);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
202
    if (ret != DRIZZLE_RETURN_OK)
203
    {
204
      printf("drizzle_con_connect:%s\n", drizzle_error(&drizzle));
205
      return 1;
206
    }
207
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
208
    proxy(&drizzle, server, client, &server_result, &client_result, &column);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
209
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
210
    drizzle_con_free(client);
211
    drizzle_con_free(server);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
212
213
    if (count > 0)
214
    {
215
      count--;
216
217
      if (count == 0)
218
        break;
219
    }
220
  }
221
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
222
  drizzle_con_free(con_listen);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
223
  drizzle_free(&drizzle);
224
1929.1.32 by Stewart Smith
fix excessive stack usage in examples/proxy.c:
225
  free(con_listen);
226
  free(server);
227
  free(client);
228
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
229
  return 0;
230
}
231
232
static void proxy(drizzle_st *drizzle, drizzle_con_st *server,
233
                  drizzle_con_st *client, drizzle_result_st *server_result,
234
                  drizzle_result_st *client_result, drizzle_column_st *column)
235
{
236
  drizzle_return_t ret;
237
  drizzle_command_t command;
1992.6.2 by Monty Taylor
Cleaned up for additional gcc 4.5 warnings.
238
  uint8_t *data;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
239
  size_t offset;
240
  size_t size;
241
  size_t total;
242
  uint64_t row;
243
  bool row_break;
244
  drizzle_field_t field;
245
246
  /* Handshake packets. */
247
  ret= drizzle_handshake_server_read(client);
248
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_read", drizzle)
249
250
  drizzle_con_copy_handshake(server, client);
251
252
  ret= drizzle_handshake_server_write(server);
253
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_write", drizzle)
254
255
  ret= drizzle_handshake_client_read(server);
256
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_read", drizzle)
257
258
  drizzle_con_copy_handshake(client, server);
259
260
  ret= drizzle_handshake_client_write(client);
261
  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_write", drizzle)
262
263
  (void)drizzle_result_read(client, client_result, &ret);
264
  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
265
266
  drizzle_con_set_status(server, drizzle_con_status(client));
267
268
  if (drizzle_result_clone(server, server_result, client_result) == NULL)
269
    DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
270
271
  ret= drizzle_result_write(server, server_result, true);
272
  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
273
274
  if (drizzle_result_error_code(client_result) != 0 ||
275
      drizzle_result_eof(client_result))
276
  {
277
    /* There was a handshake or authentication error. */
278
    return;
279
  }
280
281
  drizzle_con_add_options(client, DRIZZLE_CON_READY);
282
283
  /* Command loop. */
284
  while (1)
285
  {
286
    drizzle_result_free(server_result);
287
    drizzle_result_free(client_result);
288
289
    while (1)
290
    {
1992.6.2 by Monty Taylor
Cleaned up for additional gcc 4.5 warnings.
291
      data= (uint8_t *)drizzle_con_command_read(server, &command, &offset, &size, &total,
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
292
                                     &ret);
293
      if (ret == DRIZZLE_RETURN_LOST_CONNECTION)
294
        return;
295
296
      DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_read", drizzle)
297
298
      (void)drizzle_con_command_write(client, NULL, command, data, size, total,
299
                                      &ret);
300
      DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_write", drizzle)
301
302
      if ((offset + size) == total)
303
        break;
304
    }
305
306
    if (command == DRIZZLE_COMMAND_QUIT)
307
      return;
308
    else if (command == DRIZZLE_COMMAND_FIELD_LIST)
309
    {
310
      if (drizzle_result_create(client, client_result) == NULL)
311
        DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
312
313
      if (drizzle_result_create(server, server_result) == NULL)
314
        DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
315
    }
316
    else
317
    {
318
      (void)drizzle_result_read(client, client_result, &ret);
319
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
320
321
      drizzle_con_set_status(server, drizzle_con_status(client));
322
      if (drizzle_result_clone(server, server_result, client_result) == NULL)
323
        DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
324
325
      if (drizzle_result_column_count(client_result) == 0)
326
      {
327
        /* Simple result with no column, row, or field data. */
328
        ret= drizzle_result_write(server, server_result, true);
329
        DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
330
331
        continue;
332
      }
333
334
      ret= drizzle_result_write(server, server_result, false);
335
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
336
    }
337
338
    /* Columns. */
339
    while (1)
340
    {
341
      if (drizzle_column_read(client_result, column, &ret) == NULL)
342
      {
343
        DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
344
        break;
345
      }
346
347
      DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
348
349
      ret= drizzle_column_write(server_result, column);
350
      DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
351
352
      drizzle_column_free(column);
353
    }
354
355
    drizzle_con_set_status(server, drizzle_con_status(client));
356
    drizzle_result_set_eof(server_result, true);
357
358
    if (command == DRIZZLE_COMMAND_FIELD_LIST)
359
    {
360
      ret= drizzle_result_write(server, server_result, true);
361
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
362
      continue;
363
    }
364
    else
365
    {
366
      ret= drizzle_result_write(server, server_result, false);
367
      DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
368
    }
369
370
    /* Rows. */
371
    while (1)
372
    {
373
      row= drizzle_row_read(client_result, &ret);
374
      DRIZZLE_RETURN_CHECK(ret, "drizzle_row_read", drizzle)
375
376
      if (row == 0)
377
        break;
378
379
      drizzle_result_set_row_size(server_result,
380
                                  drizzle_result_row_size(client_result));
381
382
      ret= drizzle_row_write(server_result);
383
      DRIZZLE_RETURN_CHECK(ret, "drizzle_row_write", drizzle)
384
385
      /* Fields. */
386
      row_break= false;
387
      while (row_break == false)
388
      {
389
        field= drizzle_field_read(client_result, &offset, &size, &total, &ret);
390
        if (ret == DRIZZLE_RETURN_ROW_END)
391
          break;
392
        else if (ret == DRIZZLE_RETURN_ROW_BREAK)
393
        {
394
          if (size == 0)
395
            break;
396
397
          row_break= true;
398
        }
399
        else
400
          DRIZZLE_RETURN_CHECK(ret, "drizzle_field_read", drizzle)
401
402
        ret= drizzle_field_write(server_result, field, size, total);
403
        DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
404
      }
405
    }
406
407
    ret= drizzle_result_write(server, server_result, true);
408
    DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
409
  }
410
}