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