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