libdrizzle Public API Documentation

server.c
Go to the documentation of this file.
1 /*
2  * Drizzle Client & Protocol Library
3  *
4  * Copyright (C) 2008 Eric Day (eday@oddments.org)
5  * All rights reserved.
6  *
7  * Use and distribution licensed under the BSD license. See
8  * the COPYING file in this directory for full text.
9  */
10 
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 
17 
18 #define DRIZZLE_FIELD_MAX 32
19 #define DRIZZLE_RESULT_ROWS 20
20 
21 #define DRIZZLE_RETURN_CHECK(__ret, __function, __drizzle) \
22 { \
23  if ((__ret) != DRIZZLE_RETURN_OK) \
24  DRIZZLE_RETURN_ERROR(__function, __drizzle) \
25 }
26 
27 #define DRIZZLE_RETURN_ERROR(__function, __drizzle) \
28 { \
29  printf(__function ":%s\n", drizzle_error(__drizzle)); \
30  return; \
31 }
32 
33 static void server(drizzle_st *drizzle, drizzle_con_st *con,
34  drizzle_result_st *result, drizzle_column_st *column);
35 
36 int main(int argc, char *argv[])
37 {
38  int c;
39  uint32_t count= 0;
40  const char *host= NULL;
41  bool mysql= false;
42  in_port_t port= 0;
44  drizzle_return_t ret;
45  drizzle_st drizzle;
46  drizzle_con_st con_listen;
47  drizzle_con_st con;
48  drizzle_result_st result;
49  drizzle_column_st column;
50 
51  while((c = getopt(argc, argv, "c:h:mp:v")) != -1)
52  {
53  switch(c)
54  {
55  case 'c':
56  count= (uint32_t)atoi(optarg);
57  break;
58 
59  case 'h':
60  host= optarg;
61  break;
62 
63  case 'm':
64  mysql= true;
65  break;
66 
67  case 'p':
68  port= (in_port_t)atoi(optarg);
69  break;
70 
71  case 'v':
72  verbose++;
73  break;
74 
75  default:
76  printf("\nusage: %s [-c <count>] [-h <host>] [-m] [-p <port>] [-v]\n",
77  argv[0]);
78  printf("\t-c <count> - Number of connections to accept before exiting\n");
79  printf("\t-h <host> - Host to listen on\n");
80  printf("\t-m - Use the MySQL protocol\n");
81  printf("\t-p <port> - Port to listen on\n");
82  printf("\t-v - Increase verbosity level\n");
83  return 1;
84  }
85  }
86 
87  if (drizzle_create(&drizzle) == NULL)
88  {
89  printf("drizzle_create:NULL\n");
90  return 1;
91  }
92 
94  drizzle_set_verbose(&drizzle, verbose);
95 
96  if (drizzle_con_create(&drizzle, &con_listen) == NULL)
97  {
98  printf("drizzle_con_create:NULL\n");
99  return 1;
100  }
101 
103  drizzle_con_set_tcp(&con_listen, host, port);
104 
105  if (mysql)
107 
108  if (drizzle_con_listen(&con_listen) != DRIZZLE_RETURN_OK)
109  {
110  printf("drizzle_con_listen:%s\n", drizzle_error(&drizzle));
111  return 1;
112  }
113 
114  while (1)
115  {
116  (void)drizzle_con_accept(&drizzle, &con, &ret);
117  if (ret != DRIZZLE_RETURN_OK)
118  {
119  printf("drizzle_con_accept:%s\n", drizzle_error(&drizzle));
120  return 1;
121  }
122 
123  server(&drizzle, &con, &result, &column);
124 
125  drizzle_con_free(&con);
126 
127  if (count > 0)
128  {
129  count--;
130 
131  if (count == 0)
132  break;
133  }
134  }
135 
136  drizzle_con_free(&con_listen);
137  drizzle_free(&drizzle);
138 
139  return 0;
140 }
141 
142 static void server(drizzle_st *drizzle, drizzle_con_st *con,
143  drizzle_result_st *result, drizzle_column_st *column)
144 {
145  drizzle_return_t ret;
146  drizzle_command_t command;
147  uint8_t *data= NULL;
148  size_t total;
149  char *field[2];
150  char field1[DRIZZLE_FIELD_MAX];
151  char field2[DRIZZLE_FIELD_MAX];
152  size_t size[2];
153  uint64_t x;
154 
155  field[0]= field1;
156  field[1]= field2;
157 
158  /* Handshake packets. */
160  drizzle_con_set_server_version(con, "libdrizzle example 1.2.3");
162  drizzle_con_set_scramble(con, (const uint8_t *)"ABCDEFGHIJKLMNOPQRST");
164  drizzle_con_set_charset(con, 8);
167 
169  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_write", drizzle)
170 
172  DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_read", drizzle)
173 
174  if (drizzle_result_create(con, result) == NULL)
175  DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
176 
177  ret= drizzle_result_write(con, result, true);
178  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
179 
180  /* Command loop. */
181  while (1)
182  {
183  drizzle_result_free(result);
184  if (data != NULL)
185  free(data);
186 
187  data= drizzle_con_command_buffer(con, &command, &total, &ret);
188  if (ret == DRIZZLE_RETURN_LOST_CONNECTION ||
189  (ret == DRIZZLE_RETURN_OK && command == DRIZZLE_COMMAND_QUIT))
190  {
191  if (data != NULL)
192  free(data);
193  return;
194  }
195  DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_buffer", drizzle)
196 
197  if (drizzle_result_create(con, result) == NULL)
198  DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
199 
200  if (command != DRIZZLE_COMMAND_QUERY)
201  {
202  ret= drizzle_result_write(con, result, true);
203  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
204  continue;
205  }
206 
208 
209  ret= drizzle_result_write(con, result, false);
210  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
211 
212  /* Columns. */
213  if (drizzle_column_create(result, column) == NULL)
214  DRIZZLE_RETURN_ERROR("drizzle_column_create", drizzle)
215 
216  drizzle_column_set_catalog(column, "default");
217  drizzle_column_set_db(column, "drizzle_test_db");
218  drizzle_column_set_table(column, "drizzle_test_table");
219  drizzle_column_set_orig_table(column, "drizzle_test_table");
220  drizzle_column_set_name(column, "test_column_1");
221  drizzle_column_set_orig_name(column, "test_column_1");
222  drizzle_column_set_charset(column, 8);
225 
226  ret= drizzle_column_write(result, column);
227  DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
228 
229  drizzle_column_set_name(column, "test_column_2");
230  drizzle_column_set_orig_name(column, "test_column_2");
231 
232  ret= drizzle_column_write(result, column);
233  DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
234 
235  drizzle_column_free(column);
236 
237  drizzle_result_set_eof(result, true);
238 
239  ret= drizzle_result_write(con, result, false);
240  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
241 
242  /* Rows. */
243  for (x= 0; x < DRIZZLE_RESULT_ROWS; x++)
244  {
245  size[0]= (size_t)snprintf(field[0], DRIZZLE_FIELD_MAX,
246  "field %" PRIu64 "-1", x);
247  if (size[0] >= DRIZZLE_FIELD_MAX)
248  size[0]= DRIZZLE_FIELD_MAX - 1;
249 
250  size[1]= (size_t)snprintf(field[1], DRIZZLE_FIELD_MAX,
251  "field %" PRIu64 "-2", x);
252  if (size[1] >= DRIZZLE_FIELD_MAX)
253  size[1]= DRIZZLE_FIELD_MAX - 1;
254 
255  /* This is needed for MySQL and old Drizzle protocol. */
256  drizzle_result_calc_row_size(result, (drizzle_field_t *)field, size);
257 
258  ret= drizzle_row_write(result);
259  DRIZZLE_RETURN_CHECK(ret, "drizzle_row_write", drizzle)
260 
261  /* Fields. */
262  ret= drizzle_field_write(result, (drizzle_field_t)field[0], size[0],
263  size[0]);
264  DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
265 
266  ret= drizzle_field_write(result, (drizzle_field_t)field[1], size[1],
267  size[1]);
268  DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
269  }
270 
271  ret= drizzle_result_write(con, result, true);
272  DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
273  }
274 }