~drizzle-trunk/drizzle/development

2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
3
 * Drizzle Client & Protocol Library
4
 *
5
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
6
 * All rights reserved.
7
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are
10
 * met:
11
 *
12
 *     * Redistributions of source code must retain the above copyright
13
 * notice, this list of conditions and the following disclaimer.
14
 *
15
 *     * Redistributions in binary form must reproduce the above
16
 * copyright notice, this list of conditions and the following disclaimer
17
 * in the documentation and/or other materials provided with the
18
 * distribution.
19
 *
20
 *     * The names of its contributors may not be used to endorse or
21
 * promote products derived from this software without specific prior
22
 * written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
36
 */
37
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
38
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
39
/**
40
 * @file
41
 * @brief Connection Definitions
42
 */
43
2449.1.4 by Brian Aker
Complete update of libdrizzle
44
#include <libdrizzle-1.0/common.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
45
46
/**
47
 * @addtogroup drizzle_con_static Static Connection Declarations
48
 * @ingroup drizzle_con
49
 * @{
50
 */
51
52
/**
53
 * Set socket options for a connection.
54
 *
55
 * @param[in] con Connection structure previously initialized with
56
 *  drizzle_con_create(), drizzle_con_clone(), or related functions.
57
 * @return Standard drizzle return value.
58
 */
59
static drizzle_return_t _con_setsockopt(drizzle_con_st *con);
60
61
/** @} */
62
63
/*
64
 * Common Definitions
65
 */
66
67
int drizzle_con_fd(const drizzle_con_st *con)
68
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
69
  if (con == NULL)
70
  {
71
    return -1;
72
  }
73
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
74
  return con->fd;
75
}
76
77
drizzle_return_t drizzle_con_set_fd(drizzle_con_st *con, int fd)
78
{
79
  drizzle_return_t ret;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
80
  if (con == NULL)
81
  {
82
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
83
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
84
85
  con->fd= fd;
86
87
  ret= _con_setsockopt(con);
88
  if (ret != DRIZZLE_RETURN_OK)
89
    con->drizzle->last_errno= errno;
90
91
  return ret;
92
}
93
94
void drizzle_con_close(drizzle_con_st *con)
95
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
96
  if (con == NULL)
97
  {
98
    return;
99
  }
100
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
101
  if (con->fd == -1)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
102
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
103
    return;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
104
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
105
2195.2.2 by Olaf van der Spek
Use closetsocket instead of close
106
  (void)closesocket(con->fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
107
  con->fd= -1;
108
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
109
  con->options&= int(~DRIZZLE_CON_READY);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
110
  con->packet_number= 0;
111
  con->buffer_ptr= con->buffer;
112
  con->buffer_size= 0;
113
  con->events= 0;
114
  con->revents= 0;
115
116
  drizzle_state_reset(con);
117
}
118
119
drizzle_return_t drizzle_con_set_events(drizzle_con_st *con, short events)
120
{
121
  drizzle_return_t ret;
122
123
  if ((con->events | events) == con->events)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
124
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
125
    return DRIZZLE_RETURN_OK;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
126
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
127
128
  con->events|= events;
129
130
  if (con->drizzle->event_watch_fn != NULL)
131
  {
132
    ret= con->drizzle->event_watch_fn(con, con->events,
133
                                      con->drizzle->event_watch_context);
134
    if (ret != DRIZZLE_RETURN_OK)
135
    {
136
      drizzle_con_close(con);
137
      return ret;
138
    }
139
  }
140
141
  return DRIZZLE_RETURN_OK;
142
}
143
144
drizzle_return_t drizzle_con_set_revents(drizzle_con_st *con, short revents)
145
{
146
  drizzle_return_t ret;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
147
  if (con == NULL)
148
  {
149
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
150
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
151
152
  if (revents != 0)
153
    con->options|= DRIZZLE_CON_IO_READY;
154
155
  con->revents= revents;
156
157
  /* Remove external POLLOUT watch if we didn't ask for it. Otherwise we spin
158
     forever until another POLLIN state change. This is much more efficient
159
     than removing POLLOUT on every state change since some external polling
160
     mechanisms need to use a system call to change flags (like Linux epoll). */
161
  if (revents & POLLOUT && !(con->events & POLLOUT) &&
162
      con->drizzle->event_watch_fn != NULL)
163
  {
164
    ret= con->drizzle->event_watch_fn(con, con->events,
165
                                      con->drizzle->event_watch_context);
166
    if (ret != DRIZZLE_RETURN_OK)
167
    {
168
      drizzle_con_close(con);
169
      return ret;
170
    }
171
  }
172
173
  con->events&= (short)~revents;
174
175
  return DRIZZLE_RETURN_OK;
176
}
177
178
drizzle_st *drizzle_con_drizzle(const drizzle_con_st *con)
179
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
180
  if (con == NULL)
181
  {
182
    return NULL;
183
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
184
  return con->drizzle;
185
}
186
187
const char *drizzle_con_error(const drizzle_con_st *con)
188
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
189
  if (con == NULL)
190
  {
191
    return NULL;
192
  }
193
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
194
  return drizzle_error(con->drizzle);
195
}
196
197
int drizzle_con_errno(const drizzle_con_st *con)
198
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
199
  if (con == NULL)
200
  {
201
    return 0;
202
  }
203
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
204
  return drizzle_errno(con->drizzle);
205
}
206
207
uint16_t drizzle_con_error_code(const drizzle_con_st *con)
208
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
209
  if (con == NULL)
210
  {
211
    return 0;
212
  }
213
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
214
  return drizzle_error_code(con->drizzle);
215
}
216
217
const char *drizzle_con_sqlstate(const drizzle_con_st *con)
218
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
219
  if (con == NULL)
220
  {
221
    return NULL;
222
  }
223
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
224
  return drizzle_sqlstate(con->drizzle);
225
}
226
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
227
drizzle_con_options_t drizzle_con_options(const drizzle_con_st *con)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
228
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
229
  if (con == NULL)
230
  {
231
    return drizzle_con_options_t();
232
  }
233
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
234
  return drizzle_con_options_t(con->options);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
235
}
236
237
void drizzle_con_set_options(drizzle_con_st *con,
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
238
                             drizzle_con_options_t options)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
239
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
240
  if (con == NULL)
241
  {
242
    return;
243
  }
244
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
245
  con->options= options;
246
}
247
248
void drizzle_con_add_options(drizzle_con_st *con,
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
249
                             drizzle_con_options_t options)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
250
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
251
  if (con == NULL)
252
  {
253
    return;
254
  }
255
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
256
  con->options|= options;
257
258
  /* If asking for the experimental Drizzle protocol, clean the MySQL flag. */
259
  if (con->options & DRIZZLE_CON_EXPERIMENTAL)
2191.1.3 by Brian Aker
Cleanup for interactive
260
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
261
    con->options&= int(~DRIZZLE_CON_MYSQL);
2191.1.3 by Brian Aker
Cleanup for interactive
262
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
263
}
264
265
void drizzle_con_remove_options(drizzle_con_st *con,
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
266
                                drizzle_con_options_t options)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
267
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
268
  if (con == NULL)
269
  {
270
    return;
271
  }
272
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
273
  con->options&= ~options;
274
}
275
276
const char *drizzle_con_host(const drizzle_con_st *con)
277
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
278
  if (con == NULL)
279
  {
280
    return NULL;
281
  }
282
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
283
  if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
284
  {
285
    if (con->socket.tcp.host == NULL && !(con->options & DRIZZLE_CON_LISTEN))
286
      return DRIZZLE_DEFAULT_TCP_HOST;
287
288
    return con->socket.tcp.host;
289
  }
290
291
  return NULL;
292
}
293
294
in_port_t drizzle_con_port(const drizzle_con_st *con)
295
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
296
  if (con and con->socket_type == DRIZZLE_CON_SOCKET_TCP)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
297
  {
298
    if (con->socket.tcp.port != 0)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
299
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
300
      return con->socket.tcp.port;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
301
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
302
303
    if (con->options & DRIZZLE_CON_MYSQL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
304
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
305
      return DRIZZLE_DEFAULT_TCP_PORT_MYSQL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
306
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
307
308
    return DRIZZLE_DEFAULT_TCP_PORT;
309
  }
310
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
311
  return in_port_t(0);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
312
}
313
314
void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
315
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
316
  if (con == NULL)
317
  {
318
    return;
319
  }
320
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
321
  drizzle_con_reset_addrinfo(con);
322
323
  con->socket_type= DRIZZLE_CON_SOCKET_TCP;
324
325
  if (host == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
326
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
327
    con->socket.tcp.host= NULL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
328
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
329
  else
330
  {
331
    con->socket.tcp.host= con->socket.tcp.host_buffer;
332
    strncpy(con->socket.tcp.host, host, NI_MAXHOST);
333
    con->socket.tcp.host[NI_MAXHOST - 1]= 0;
334
  }
335
336
  con->socket.tcp.port= port;
337
}
338
339
const char *drizzle_con_user(const drizzle_con_st *con)
340
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
341
  if (con == NULL)
342
  {
343
    return NULL;
344
  }
345
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
346
  return con->user;
347
}
348
349
const char *drizzle_con_password(const drizzle_con_st *con)
350
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
351
  if (con == NULL)
352
  {
353
    return NULL;
354
  }
355
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
356
  return con->password;
357
}
358
359
void drizzle_con_set_auth(drizzle_con_st *con, const char *user,
360
                          const char *password)
361
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
362
  if (con == NULL)
363
  {
364
    return;
365
  }
366
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
367
  if (user == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
368
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
369
    con->user[0]= 0;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
370
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
371
  else
372
  {
373
    strncpy(con->user, user, DRIZZLE_MAX_USER_SIZE);
374
    con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
375
  }
376
377
  if (password == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
378
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
379
    con->password[0]= 0;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
380
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
381
  else
382
  {
383
    strncpy(con->password, password, DRIZZLE_MAX_PASSWORD_SIZE);
384
    con->password[DRIZZLE_MAX_PASSWORD_SIZE - 1]= 0;
385
  }
386
}
387
388
const char *drizzle_con_db(const drizzle_con_st *con)
389
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
390
  if (con == NULL)
391
  {
392
    return NULL;
393
  }
394
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
395
  return con->db;
396
}
397
398
void drizzle_con_set_db(drizzle_con_st *con, const char *db)
399
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
400
  if (con == NULL)
401
  {
402
    return;
403
  }
404
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
405
  if (db == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
406
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
407
    con->db[0]= 0;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
408
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
409
  else
410
  {
411
    strncpy(con->db, db, DRIZZLE_MAX_DB_SIZE);
412
    con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
413
  }
414
}
415
416
void *drizzle_con_context(const drizzle_con_st *con)
417
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
418
  if (con == NULL)
419
  {
420
    return NULL;
421
  }
422
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
423
  return con->context;
424
}
425
426
void drizzle_con_set_context(drizzle_con_st *con, void *context)
427
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
428
  if (con == NULL)
429
  {
430
    return;
431
  }
432
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
433
  con->context= context;
434
}
435
436
void drizzle_con_set_context_free_fn(drizzle_con_st *con,
437
                                     drizzle_con_context_free_fn *function)
438
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
439
  if (con == NULL)
440
  {
441
    return;
442
  }
443
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
444
  con->context_free_fn= function;
445
}
446
447
uint8_t drizzle_con_protocol_version(const drizzle_con_st *con)
448
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
449
  if (con == NULL)
450
  {
451
    return 0;
452
  }
453
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
454
  return con->protocol_version;
455
}
456
457
const char *drizzle_con_server_version(const drizzle_con_st *con)
458
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
459
  if (con == NULL)
460
  {
461
    return NULL;
462
  }
463
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
464
  return con->server_version;
465
}
466
467
uint32_t drizzle_con_server_version_number(const drizzle_con_st *con)
468
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
469
  if (con)
470
  {
471
    const char *current= con->server_version;
472
    char *end;
473
474
    uint32_t major= (uint32_t)strtoul(current, &end, 10);
475
    current= end +1;
476
    uint32_t minor= (uint32_t)strtoul(current, &end, 10);
477
    current= end +1;
478
    uint32_t version= (uint32_t)strtoul(current, &end, 10);
479
480
    return (major * 10000) +(minor * 100) +version;
481
  }
482
483
  return 0;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
484
}
485
486
uint32_t drizzle_con_thread_id(const drizzle_con_st *con)
487
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
488
  if (con == NULL)
489
  {
490
    return 0;
491
  }
492
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
493
  return con->thread_id;
494
}
495
496
const uint8_t *drizzle_con_scramble(const drizzle_con_st *con)
497
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
498
  if (con == NULL)
499
  {
500
    return NULL;
501
  }
502
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
503
  return con->scramble;
504
}
505
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
506
drizzle_capabilities_t drizzle_con_capabilities(const drizzle_con_st *con)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
507
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
508
  if (con == NULL)
509
  {
510
    return drizzle_capabilities_t();
511
  }
512
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
513
  return drizzle_capabilities_t(con->capabilities);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
514
}
515
516
drizzle_charset_t drizzle_con_charset(const drizzle_con_st *con)
517
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
518
  if (con == NULL)
519
  {
520
    return drizzle_charset_t();
521
  }
522
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
523
  return con->charset;
524
}
525
526
drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
527
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
528
  if (con == NULL)
529
  {
530
    return drizzle_con_status_t();
531
  }
532
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
533
  return con->status;
534
}
535
536
uint32_t drizzle_con_max_packet_size(const drizzle_con_st *con)
537
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
538
  if (con == NULL)
539
  {
540
    return 0;
541
  }
542
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
543
  return con->max_packet_size;
544
}
545
546
/*
547
 * Client Definitions
548
 */
549
550
drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
551
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
552
  if (con == NULL)
553
  {
554
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
555
  }
556
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
557
  if (con->options & DRIZZLE_CON_READY)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
558
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
559
    return DRIZZLE_RETURN_OK;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
560
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
561
562
  if (drizzle_state_none(con))
563
  {
564
    if (!(con->options & DRIZZLE_CON_RAW_PACKET))
565
    {
566
      drizzle_state_push(con, drizzle_state_handshake_server_read);
567
      drizzle_state_push(con, drizzle_state_packet_read);
568
    }
569
570
    drizzle_state_push(con, drizzle_state_connect);
571
    drizzle_state_push(con, drizzle_state_addrinfo);
572
  }
573
574
  return drizzle_state_loop(con);
575
}
576
577
drizzle_result_st *drizzle_con_quit(drizzle_con_st *con,
578
                                    drizzle_result_st *result,
579
                                    drizzle_return_t *ret_ptr)
580
{
581
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0,
582
                                   0, ret_ptr);
583
}
584
585
drizzle_result_st *drizzle_quit(drizzle_con_st *con,
586
                                drizzle_result_st *result,
587
                                drizzle_return_t *ret_ptr)
588
{
589
  return drizzle_con_quit(con, result, ret_ptr);
590
}
591
592
drizzle_result_st *drizzle_con_select_db(drizzle_con_st *con,
593
                                         drizzle_result_st *result,
594
                                         const char *db,
595
                                         drizzle_return_t *ret_ptr)
596
{
597
  drizzle_con_set_db(con, db);
598
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_INIT_DB,
599
                                   db, strlen(db), strlen(db), ret_ptr);
600
}
601
602
drizzle_result_st *drizzle_select_db(drizzle_con_st *con,
603
                                     drizzle_result_st *result,
604
                                     const char *db,
605
                                     drizzle_return_t *ret_ptr)
606
{
607
  return drizzle_con_select_db(con, result, db, ret_ptr);
608
}
609
610
drizzle_result_st *drizzle_con_shutdown(drizzle_con_st *con,
611
                                        drizzle_result_st *result,
612
                                        drizzle_return_t *ret_ptr)
613
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
614
  drizzle_return_t unused;
615
  if (ret_ptr == NULL)
616
  {
617
    ret_ptr= &unused;
618
  }
619
620
  if (con and con->options & DRIZZLE_CON_MYSQL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
621
  {
622
    return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN,
623
                                     "0", 1, 1, ret_ptr);
624
  }
625
626
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL,
627
                                   0, 0, ret_ptr);
628
}
629
630
drizzle_result_st *drizzle_shutdown(drizzle_con_st *con,
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
631
                                    drizzle_result_st *result, uint32_t, // level is unused
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
632
                                    drizzle_return_t *ret_ptr)
633
{
634
  return drizzle_con_shutdown(con, result, ret_ptr);
635
}
636
2191.1.1 by Brian Aker
Add in KILL protocol support.
637
drizzle_result_st *drizzle_kill(drizzle_con_st *con,
638
                                drizzle_result_st *result,
639
                                uint32_t query_id,
640
                                drizzle_return_t *ret_ptr)
641
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
642
  drizzle_return_t unused;
643
  if (ret_ptr == NULL)
644
  {
645
    ret_ptr= &unused;
646
  }
647
2191.1.1 by Brian Aker
Add in KILL protocol support.
648
  uint32_t sent= htonl(query_id);
649
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PROCESS_KILL,
650
                                   &sent, sizeof(uint32_t), sizeof(uint32_t), ret_ptr);
651
}
652
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
653
drizzle_result_st *drizzle_con_ping(drizzle_con_st *con,
654
                                    drizzle_result_st *result,
655
                                    drizzle_return_t *ret_ptr)
656
{
657
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0,
658
                                   0, ret_ptr);
659
}
660
661
drizzle_result_st *drizzle_ping(drizzle_con_st *con,
662
                                drizzle_result_st *result,
663
                                drizzle_return_t *ret_ptr)
664
{
665
  return drizzle_con_ping(con, result, ret_ptr);
666
}
667
668
drizzle_result_st *drizzle_con_command_write(drizzle_con_st *con,
669
                                             drizzle_result_st *result,
670
                                             drizzle_command_t command,
671
                                             const void *data, size_t size,
672
                                             size_t total,
673
                                             drizzle_return_t *ret_ptr)
674
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
675
  drizzle_return_t unused;
676
  if (ret_ptr == NULL)
677
  {
678
    ret_ptr= &unused;
679
  }
680
681
  if (con == NULL)
682
  {
683
    *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
684
    return NULL;
685
  }
686
2217.1.3 by Andrew Hutchings
Fix for ICC?
687
  drizzle_result_st *old_result;
688
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
689
  if (!(con->options & DRIZZLE_CON_READY))
690
  {
691
    if (con->options & DRIZZLE_CON_RAW_PACKET)
692
    {
693
      drizzle_set_error(con->drizzle, "drizzle_command_write",
694
                        "connection not ready");
695
      *ret_ptr= DRIZZLE_RETURN_NOT_READY;
696
      return result;
697
    }
698
699
    *ret_ptr= drizzle_con_connect(con);
700
    if (*ret_ptr != DRIZZLE_RETURN_OK)
701
      return result;
702
  }
703
704
  if (drizzle_state_none(con))
705
  {
706
    if (con->options & (DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_NO_RESULT_READ))
707
      con->result= NULL;
708
    else
709
    {
2221.3.1 by Andrew Hutchings
Fixing result re-use issues broke drizzle_query_run_all(). This fixes that too.
710
      for (old_result= con->result_list; old_result != NULL; old_result= old_result->next)
711
      {
712
        if (result == old_result)
713
        {
714
          drizzle_set_error(con->drizzle, "drizzle_command_write", "result struct already in use");
715
          *ret_ptr= DRIZZLE_RETURN_INTERNAL_ERROR;
716
          return result;
717
        }
718
      }
719
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
720
      con->result= drizzle_result_create(con, result);
721
      if (con->result == NULL)
722
      {
723
        *ret_ptr= DRIZZLE_RETURN_MEMORY;
724
        return NULL;
725
      }
726
    }
727
728
    con->command= command;
729
    con->command_data= (uint8_t *)data;
730
    con->command_size= size;
731
    con->command_offset= 0;
732
    con->command_total= total;
733
734
    drizzle_state_push(con, drizzle_state_command_write);
735
  }
736
  else if (con->command_data == NULL)
737
  {
738
    con->command_data= (uint8_t *)data;
739
    con->command_size= size;
740
  }
741
742
  *ret_ptr= drizzle_state_loop(con);
743
  if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
744
    *ret_ptr= DRIZZLE_RETURN_OK;
745
  else if (*ret_ptr != DRIZZLE_RETURN_OK &&
746
           *ret_ptr != DRIZZLE_RETURN_IO_WAIT &&
747
           *ret_ptr != DRIZZLE_RETURN_ERROR_CODE)
748
  {
749
    drizzle_result_free(con->result);
750
    con->result= result;
751
  }
752
753
  return con->result;
754
}
755
756
/*
757
 * Server Definitions
758
 */
759
760
drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
761
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
762
  if (con == NULL)
763
  {
764
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
765
  }
766
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
767
  if (con->options & DRIZZLE_CON_READY)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
768
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
769
    return DRIZZLE_RETURN_OK;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
770
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
771
772
  if (drizzle_state_none(con))
773
  {
774
    drizzle_state_push(con, drizzle_state_listen);
775
    drizzle_state_push(con, drizzle_state_addrinfo);
776
  }
777
778
  return drizzle_state_loop(con);
779
}
780
781
int drizzle_con_backlog(const drizzle_con_st *con)
782
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
783
  if (con == NULL)
784
  {
785
    return 0;
786
  }
787
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
788
  return con->backlog;
789
}
790
791
void drizzle_con_set_backlog(drizzle_con_st *con, int backlog)
792
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
793
  if (con == NULL)
794
  {
795
    return;
796
  }
797
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
798
  con->backlog= backlog;
799
}
800
801
void drizzle_con_set_protocol_version(drizzle_con_st *con,
802
                                      uint8_t protocol_version)
803
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
804
  if (con == NULL)
805
  {
806
    return;
807
  }
808
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
809
  con->protocol_version= protocol_version;
810
}
811
812
void drizzle_con_set_server_version(drizzle_con_st *con,
813
                                    const char *server_version)
814
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
815
  if (con == NULL)
816
  {
817
    return;
818
  }
819
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
820
  if (server_version == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
821
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
822
    con->server_version[0]= 0;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
823
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
824
  else
825
  {
826
    strncpy(con->server_version, server_version,
827
            DRIZZLE_MAX_SERVER_VERSION_SIZE);
828
    con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
829
  }
830
}
831
832
void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
833
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
834
  if (con == NULL)
835
  {
836
    return;
837
  }
838
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
839
  con->thread_id= thread_id;
840
}
841
842
void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
843
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
844
  if (con == NULL)
845
  {
846
    return;
847
  }
848
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
849
  if (scramble == NULL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
850
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
851
    con->scramble= NULL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
852
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
853
  else
854
  {
855
    con->scramble= con->scramble_buffer;
856
    memcpy(con->scramble, scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
857
  }
858
}
859
860
void drizzle_con_set_capabilities(drizzle_con_st *con,
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
861
                                  drizzle_capabilities_t capabilities)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
862
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
863
  if (con == NULL)
864
  {
865
    return;
866
  }
867
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
868
  con->capabilities= capabilities;
869
}
870
871
void drizzle_con_set_charset(drizzle_con_st *con, drizzle_charset_t charset)
872
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
873
  if (con == NULL)
874
  {
875
    return;
876
  }
877
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
878
  con->charset= charset;
879
}
880
881
void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
882
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
883
  if (con == NULL)
884
  {
885
    return;
886
  }
887
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
888
  con->status= status;
889
}
890
891
void drizzle_con_set_max_packet_size(drizzle_con_st *con,
892
                                     uint32_t max_packet_size)
893
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
894
  if (con == NULL)
895
  {
896
    return;
897
  }
898
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
899
  con->max_packet_size= max_packet_size;
900
}
901
902
void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
903
{
904
  drizzle_con_set_auth(con, from->user, NULL);
905
  drizzle_con_set_scramble(con, from->scramble);
906
  drizzle_con_set_db(con, from->db);
907
  drizzle_con_set_protocol_version(con, from->protocol_version);
908
  drizzle_con_set_server_version(con, from->server_version);
909
  drizzle_con_set_thread_id(con, from->thread_id);
910
  drizzle_con_set_scramble(con, from->scramble);
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
911
  drizzle_con_set_capabilities(con, drizzle_capabilities_t(from->capabilities));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
912
  drizzle_con_set_charset(con, from->charset);
913
  drizzle_con_set_status(con, from->status);
914
  drizzle_con_set_max_packet_size(con, from->max_packet_size);
915
}
916
917
void *drizzle_con_command_read(drizzle_con_st *con,
918
                               drizzle_command_t *command, size_t *offset,
919
                               size_t *size, size_t *total,
920
                               drizzle_return_t *ret_ptr)
921
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
922
  drizzle_return_t unused_ret;
923
  if (ret_ptr == NULL)
924
  {
925
    ret_ptr= &unused_ret;
926
  }
927
928
  if (con == NULL)
929
  {
930
    *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
931
    return NULL;
932
  }
933
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
934
  if (drizzle_state_none(con))
935
  {
936
    con->packet_number= 0;
937
    con->command_offset= 0;
938
    con->command_total= 0;
939
940
    drizzle_state_push(con, drizzle_state_command_read);
941
    drizzle_state_push(con, drizzle_state_packet_read);
942
  }
943
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
944
  if (offset)
945
  {
946
    *offset= con->command_offset;
947
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
948
949
  *ret_ptr= drizzle_state_loop(con);
950
  if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
951
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
952
    *ret_ptr= DRIZZLE_RETURN_OK;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
953
  }
954
955
  if (command)
956
  {
957
    *command= con->command;
958
  }
959
960
  if (size)
961
  {
962
    *size= con->command_size;
963
  }
964
965
  if (total)
966
  {
967
    *total= con->command_total;
968
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
969
970
  return con->command_data;
971
}
972
973
void *drizzle_con_command_buffer(drizzle_con_st *con,
974
                                 drizzle_command_t *command, size_t *total,
975
                                 drizzle_return_t *ret_ptr)
976
{
977
  size_t offset= 0;
978
  size_t size= 0;
979
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
980
  drizzle_return_t unused_ret;
981
  if (ret_ptr == NULL)
982
  {
983
    ret_ptr= &unused_ret;
984
  }
985
986
  size_t unused_total;
987
  if (total == NULL)
988
  {
989
    total= &unused_total;
990
  }
991
992
  if (con == NULL)
993
  {
994
    *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
995
    return NULL;
996
  }
997
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
998
  char *command_data= (char *)drizzle_con_command_read(con, command, &offset, &size, total, ret_ptr);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
999
  if (*ret_ptr != DRIZZLE_RETURN_OK)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1000
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1001
    return NULL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1002
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1003
1004
  if (command_data == NULL)
1005
  {
1006
    *total= 0;
1007
    return NULL;
1008
  }
1009
1010
  if (con->command_buffer == NULL)
1011
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1012
    con->command_buffer= (uint8_t*)malloc((*total) + 1);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1013
    if (con->command_buffer == NULL)
1014
    {
1015
      drizzle_set_error(con->drizzle, "drizzle_command_buffer", "malloc");
1016
      *ret_ptr= DRIZZLE_RETURN_MEMORY;
1017
      return NULL;
1018
    }
1019
  }
1020
1021
  memcpy(con->command_buffer + offset, command_data, size);
1022
1023
  while ((offset + size) != (*total))
1024
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1025
    command_data= (char *)drizzle_con_command_read(con, command, &offset, &size, total, ret_ptr);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1026
    if (*ret_ptr != DRIZZLE_RETURN_OK)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1027
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1028
      return NULL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1029
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1030
1031
    memcpy(con->command_buffer + offset, command_data, size);
1032
  }
1033
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1034
  command_data= (char *)con->command_buffer;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1035
  con->command_buffer= NULL;
1036
  command_data[*total]= 0;
1037
1038
  return command_data;
1039
}
1040
1041
/*
1042
 * Local Definitions
1043
 */
1044
1045
void drizzle_con_reset_addrinfo(drizzle_con_st *con)
1046
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1047
  if (con == NULL)
1048
  {
1049
    return;
1050
  }
1051
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1052
  switch (con->socket_type)
1053
  {
1054
  case DRIZZLE_CON_SOCKET_TCP:
1055
    if (con->socket.tcp.addrinfo != NULL)
1056
    {
1057
      freeaddrinfo(con->socket.tcp.addrinfo);
1058
      con->socket.tcp.addrinfo= NULL;
1059
    }
1060
    break;
1061
1062
  case DRIZZLE_CON_SOCKET_UDS:
1063
    con->socket.uds.addrinfo.ai_addr= NULL;
1064
    break;
1065
1066
  default:
1067
    break;
1068
  }
1069
1070
  con->addrinfo_next= NULL;
1071
}
1072
1073
/*
1074
 * State Definitions
1075
 */
1076
1077
drizzle_return_t drizzle_state_addrinfo(drizzle_con_st *con)
1078
{
1079
  drizzle_con_tcp_st *tcp;
1080
  const char *host;
1081
  char port[NI_MAXSERV];
1082
  struct addrinfo ai;
1083
  int ret;
1084
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1085
  if (con == NULL)
1086
  {
1087
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1088
  }
1089
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1090
  drizzle_log_debug(con->drizzle, "drizzle_state_addrinfo");
1091
1092
  switch (con->socket_type)
1093
  {
1094
  case DRIZZLE_CON_SOCKET_TCP:
1095
    tcp= &(con->socket.tcp);
1096
1097
    if (tcp->addrinfo != NULL)
1098
    {
1099
      freeaddrinfo(tcp->addrinfo);
1100
      tcp->addrinfo= NULL;
1101
    }
1102
1103
    if (tcp->port != 0)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1104
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1105
      snprintf(port, NI_MAXSERV, "%u", tcp->port);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1106
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1107
    else if (con->options & DRIZZLE_CON_MYSQL)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1108
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1109
      snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT_MYSQL);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1110
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1111
    else
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1112
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1113
      snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1114
    }
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1115
    port[NI_MAXSERV-1]= 0;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1116
1117
    memset(&ai, 0, sizeof(struct addrinfo));
1118
    ai.ai_socktype= SOCK_STREAM;
1119
    ai.ai_protocol= IPPROTO_TCP;
2235.1.3 by Andrew Hutchings
Fix addrinfo flags not set correctly
1120
    ai.ai_flags = AI_PASSIVE;
1121
    ai.ai_family = AF_UNSPEC;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1122
1123
    if (con->options & DRIZZLE_CON_LISTEN)
1124
    {
1125
      host= tcp->host;
1126
    }
1127
    else
1128
    {
1129
      if (tcp->host == NULL)
1130
        host= DRIZZLE_DEFAULT_TCP_HOST;
1131
      else
1132
        host= tcp->host;
1133
    }
1134
1135
    ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
1136
    if (ret != 0)
1137
    {
1138
      drizzle_set_error(con->drizzle, "drizzle_state_addrinfo",
1139
                        "getaddrinfo:%s", gai_strerror(ret));
1140
      return DRIZZLE_RETURN_GETADDRINFO;
1141
    }
1142
1143
    con->addrinfo_next= tcp->addrinfo;
1144
1145
    break;
1146
1147
  case DRIZZLE_CON_SOCKET_UDS:
1148
    con->addrinfo_next= &(con->socket.uds.addrinfo);
1149
    break;
1150
1151
  default:
1152
    break;
1153
  }
1154
1155
  drizzle_state_pop(con);
1156
  return DRIZZLE_RETURN_OK;
1157
}
1158
1159
drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
1160
{
1161
  int ret;
1162
  drizzle_return_t dret;
1163
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1164
  if (con == NULL)
1165
  {
1166
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1167
  }
1168
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1169
  drizzle_log_debug(con->drizzle, "drizzle_state_connect");
1170
1171
  if (con->fd != -1)
1172
  {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1173
    (void)closesocket(con->fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1174
    con->fd= -1;
1175
  }
1176
1177
  if (con->addrinfo_next == NULL)
1178
  {
1179
    drizzle_set_error(con->drizzle, "drizzle_state_connect",
1180
                      "could not connect");
1181
    drizzle_state_reset(con);
1182
    return DRIZZLE_RETURN_COULD_NOT_CONNECT;
1183
  }
1184
1185
  con->fd= socket(con->addrinfo_next->ai_family,
1186
                  con->addrinfo_next->ai_socktype,
1187
                  con->addrinfo_next->ai_protocol);
1188
  if (con->fd == -1)
1189
  {
1190
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "socket:%d",
1191
                      errno);
1192
    con->drizzle->last_errno= errno;
1193
    return DRIZZLE_RETURN_ERRNO;
1194
  }
1195
1196
  dret= _con_setsockopt(con);
1197
  if (dret != DRIZZLE_RETURN_OK)
1198
  {
1199
    con->drizzle->last_errno= errno;
1200
    return dret;
1201
  }
1202
1203
  while (1)
1204
  {
1205
    ret= connect(con->fd, con->addrinfo_next->ai_addr,
1206
                 con->addrinfo_next->ai_addrlen);
1207
1208
#ifdef _WIN32
1209
    errno = WSAGetLastError();
1210
    switch(errno) {
1211
    case WSAEINVAL:
1212
    case WSAEALREADY:
1213
    case WSAEWOULDBLOCK:
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1214
      errno= EINPROGRESS;
1215
      break;
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1216
    case WSAECONNREFUSED:
1217
      errno= ECONNREFUSED;
1218
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1219
    case WSAENETUNREACH:
1220
      errno= ENETUNREACH;
1221
      break;
1222
    case WSAETIMEDOUT:
1223
      errno= ETIMEDOUT;
1224
      break;
1225
    case WSAECONNRESET:
1226
      errno= ECONNRESET;
1227
      break;
1228
    case WSAEADDRINUSE:
1229
      errno= EADDRINUSE;
1230
      break;
1231
    case WSAEOPNOTSUPP:
1232
      errno= EOPNOTSUPP;
1233
      break;
1234
    case WSAENOPROTOOPT:
1235
      errno= ENOPROTOOPT;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1236
      break;
1237
    default:
1238
      break;
1239
    }
1240
#endif /* _WIN32 */
1241
	
1242
    drizzle_log_crazy(con->drizzle, "connect return=%d errno=%d", ret, errno);
1243
1244
    if (ret == 0)
1245
    {
1246
      con->addrinfo_next= NULL;
1247
      break;
1248
    }
1249
1250
    if (errno == EAGAIN || errno == EINTR)
1251
      continue;
1252
1253
    if (errno == EINPROGRESS)
1254
    {
1255
      drizzle_state_pop(con);
1256
      drizzle_state_push(con, drizzle_state_connecting);
1257
      return DRIZZLE_RETURN_OK;
1258
    }
1259
1260
    if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
1261
    {
1262
      con->addrinfo_next= con->addrinfo_next->ai_next;
1263
      return DRIZZLE_RETURN_OK;
1264
    }
1265
1266
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "connect:%d",
1267
                      errno);
1268
    con->drizzle->last_errno= errno;
1269
    return DRIZZLE_RETURN_ERRNO;
1270
  }
1271
1272
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1273
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1274
  return DRIZZLE_RETURN_OK;
1275
}
1276
1277
drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
1278
{
1279
  drizzle_return_t ret;
1280
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1281
  if (con == NULL)
1282
  {
1283
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1284
  }
1285
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1286
  drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
1287
1288
  while (1)
1289
  {
1290
    if (con->revents & POLLOUT)
1291
    {
1292
      drizzle_state_pop(con);
1293
      return DRIZZLE_RETURN_OK;
1294
    }
1295
    else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
1296
    {
1297
      con->revents= 0;
1298
      drizzle_state_pop(con);
1299
      drizzle_state_push(con, drizzle_state_connect);
1300
      con->addrinfo_next= con->addrinfo_next->ai_next;
1301
      return DRIZZLE_RETURN_OK;
1302
    }
1303
1304
    ret= drizzle_con_set_events(con, POLLOUT);
1305
    if (ret != DRIZZLE_RETURN_OK)
1306
      return ret;
1307
1308
    if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1309
      return DRIZZLE_RETURN_IO_WAIT;
1310
1311
    ret= drizzle_con_wait(con->drizzle);
1312
    if (ret != DRIZZLE_RETURN_OK)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1313
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1314
      return ret;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1315
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1316
  }
1317
}
1318
1319
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
1320
{
1321
  drizzle_return_t ret;
1322
  ssize_t read_size;
1323
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1324
  if (con == NULL)
1325
  {
1326
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1327
  }
1328
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1329
  drizzle_log_debug(con->drizzle, "drizzle_state_read");
1330
1331
  if (con->buffer_size == 0)
1332
    con->buffer_ptr= con->buffer;
1333
  else if ((con->buffer_ptr - con->buffer) > (DRIZZLE_MAX_BUFFER_SIZE / 2))
1334
  {
1335
    memmove(con->buffer, con->buffer_ptr, con->buffer_size);
1336
    con->buffer_ptr= con->buffer;
1337
  }
1338
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1339
  if ((con->revents & POLLIN) == 0 &&
1340
      (con->drizzle->options & DRIZZLE_NON_BLOCKING))
1341
  {
1342
    /* non-blocking mode: return IO_WAIT instead of attempting to read. This
1343
     * avoids reading immediately after writing a command, which typically
1344
     * returns EAGAIN. This improves performance. */
1345
    ret= drizzle_con_set_events(con, POLLIN);
1346
    if (ret != DRIZZLE_RETURN_OK)
1347
      return ret;
1348
    return DRIZZLE_RETURN_IO_WAIT;
1349
  }
1350
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1351
  while (1)
1352
  {
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1353
    size_t available_buffer= (size_t)DRIZZLE_MAX_BUFFER_SIZE -
1354
        ((size_t)(con->buffer_ptr - con->buffer) + con->buffer_size);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1355
    read_size = recv(con->fd, (char *)con->buffer_ptr + con->buffer_size,
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1356
                     available_buffer, 0);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1357
#ifdef _WIN32
1358
    errno = WSAGetLastError();
1359
    switch(errno) {
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1360
    case WSAENOTCONN:
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1361
    case WSAEWOULDBLOCK:
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1362
      errno= EAGAIN;
1363
      break;
1364
    case WSAEINVAL:
1365
    case WSAEALREADY:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1366
      errno= EINPROGRESS;
1367
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1368
    case WSAECONNREFUSED:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1369
      errno= ECONNREFUSED;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1370
      break;
1371
    case WSAENETUNREACH:
1372
      errno= ENETUNREACH;
1373
      break;
1374
    case WSAETIMEDOUT:
1375
      errno= ETIMEDOUT;
1376
      break;
1377
    case WSAECONNRESET:
1378
      errno= ECONNRESET;
1379
      break;
1380
    case WSAEADDRINUSE:
1381
      errno= EADDRINUSE;
1382
      break;
1383
    case WSAEOPNOTSUPP:
1384
      errno= EOPNOTSUPP;
1385
      break;
1386
    case WSAENOPROTOOPT:
1387
      errno= ENOPROTOOPT;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1388
      break;
1389
    default:
1390
      break;
1391
    }
1392
#endif /* _WIN32 */	
1393
    drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%d", con->fd,
1394
                      read_size, errno);
1395
1396
    if (read_size == 0)
1397
    {
1398
      drizzle_set_error(con->drizzle, "drizzle_state_read",
1399
                        "lost connection to server (EOF)");
1400
      return DRIZZLE_RETURN_LOST_CONNECTION;
1401
    }
1402
    else if (read_size == -1)
1403
    {
1404
      if (errno == EAGAIN)
1405
      {
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1406
        /* clear the read ready flag */
1407
        con->revents&= ~POLLIN;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1408
        ret= drizzle_con_set_events(con, POLLIN);
1409
        if (ret != DRIZZLE_RETURN_OK)
2046.1.1 by Evan Jones
libdrizzle: fix minor errors in drizzle_state_read
1410
          return ret;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1411
1412
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1413
          return DRIZZLE_RETURN_IO_WAIT;
1414
1415
        ret= drizzle_con_wait(con->drizzle);
1416
        if (ret != DRIZZLE_RETURN_OK)
1417
          return ret;
1418
1419
        continue;
1420
      }
1421
      else if (errno == ECONNREFUSED)
1422
      {
1423
        con->revents= 0;
1424
        drizzle_state_pop(con);
1425
        drizzle_state_push(con, drizzle_state_connect);
1426
        con->addrinfo_next= con->addrinfo_next->ai_next;
1427
        return DRIZZLE_RETURN_OK;
1428
      }
1429
      else if (errno == EINTR)
1430
        continue;
1431
      else if (errno == EPIPE || errno == ECONNRESET)
1432
      {
1433
        drizzle_set_error(con->drizzle, "drizzle_state_read",
1434
                          "lost connection to server (%d)", errno);
1435
        return DRIZZLE_RETURN_LOST_CONNECTION;
1436
      }
1437
1438
      drizzle_set_error(con->drizzle, "drizzle_state_read", "read:%d", errno);
1439
      con->drizzle->last_errno= errno;
1440
      return DRIZZLE_RETURN_ERRNO;
1441
    }
1442
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1443
    /* clear the "read ready" flag if we read all available data. */
1444
    if ((size_t) read_size < available_buffer) con->revents&= ~POLLIN;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1445
    con->buffer_size+= (size_t)read_size;
1446
    break;
1447
  }
1448
2046.1.1 by Evan Jones
libdrizzle: fix minor errors in drizzle_state_read
1449
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1450
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1451
  return DRIZZLE_RETURN_OK;
1452
}
1453
1454
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
1455
{
1456
  drizzle_return_t ret;
1457
  ssize_t write_size;
1458
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1459
  if (con == NULL)
1460
  {
1461
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1462
  }
1463
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1464
  drizzle_log_debug(con->drizzle, "drizzle_state_write");
1465
1466
  while (con->buffer_size != 0)
1467
  {
1468
  
1877.1.5 by Andrew Hutchings
Fix min() usage for 32bit
1469
    write_size = send(con->fd,(char *) con->buffer_ptr, con->buffer_size, 0);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1470
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1471
#ifdef _WIN32
1472
    errno = WSAGetLastError();
1473
    switch(errno) {
1474
    case WSAENOTCONN:
1475
    case WSAEWOULDBLOCK:
1476
      errno= EAGAIN;
1477
      break;
1478
    case WSAEINVAL:
1479
    case WSAEALREADY:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1480
      errno= EINPROGRESS;
1481
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1482
    case WSAECONNREFUSED:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1483
      errno= ECONNREFUSED;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1484
      break;
1485
    case WSAENETUNREACH:
1486
      errno= ENETUNREACH;
1487
      break;
1488
    case WSAETIMEDOUT:
1489
      errno= ETIMEDOUT;
1490
      break;
1491
    case WSAECONNRESET:
1492
      errno= ECONNRESET;
1493
      break;
1494
    case WSAEADDRINUSE:
1495
      errno= EADDRINUSE;
1496
      break;
1497
    case WSAEOPNOTSUPP:
1498
      errno= EOPNOTSUPP;
1499
      break;
1500
    case WSAENOPROTOOPT:
1501
      errno= ENOPROTOOPT;
1502
      break;
1503
    default:
1504
      break;
1505
    }
1506
#endif /* _WIN32 */	
1507
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1508
    drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%d", con->fd,
1509
                      write_size, errno);
1510
1511
    if (write_size == 0)
1512
    {
1513
      drizzle_set_error(con->drizzle, "drizzle_state_write",
1514
                        "lost connection to server (EOF)");
1515
      return DRIZZLE_RETURN_LOST_CONNECTION;
1516
    }
1517
    else if (write_size == -1)
1518
    {
1519
      if (errno == EAGAIN)
1520
      {
1521
        ret= drizzle_con_set_events(con, POLLOUT);
1522
        if (ret != DRIZZLE_RETURN_OK)
1523
          return ret;
1524
1525
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1526
          return DRIZZLE_RETURN_IO_WAIT;
1527
1528
        ret= drizzle_con_wait(con->drizzle);
1529
        if (ret != DRIZZLE_RETURN_OK)
1530
          return ret;
1531
1532
        continue;
1533
      }
1534
      else if (errno == EINTR)
1535
        continue;
1536
      else if (errno == EPIPE || errno == ECONNRESET)
1537
      {
1538
        drizzle_set_error(con->drizzle, "drizzle_state_write",
1539
                          "lost connection to server (%d)", errno);
1540
        return DRIZZLE_RETURN_LOST_CONNECTION;
1541
      }
1542
1543
      drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%d", errno);
1544
      con->drizzle->last_errno= errno;
1545
      return DRIZZLE_RETURN_ERRNO;
1546
    }
1547
1548
    con->buffer_ptr+= write_size;
1549
    con->buffer_size-= (size_t)write_size;
1550
    if (con->buffer_size == 0)
1551
      break;
1552
  }
1553
1554
  con->buffer_ptr= con->buffer;
1555
1556
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1557
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1558
  return DRIZZLE_RETURN_OK;
1559
}
1560
1561
drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
1562
{
1563
  char host[NI_MAXHOST];
1564
  char port[NI_MAXSERV];
1565
  int fd;
1566
  int opt;
1567
  drizzle_con_st *new_con;
1568
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1569
  if (con == NULL)
1570
  {
1571
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1572
  }
1573
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1574
  for (; con->addrinfo_next != NULL;
1575
       con->addrinfo_next= con->addrinfo_next->ai_next)
1576
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1577
    int ret= getnameinfo(con->addrinfo_next->ai_addr,
1578
                         con->addrinfo_next->ai_addrlen, host, NI_MAXHOST, port,
1579
                         NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1580
    if (ret != 0)
1581
    {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1582
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "getnameinfo:%s", gai_strerror(ret));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1583
      return DRIZZLE_RETURN_GETADDRINFO;
1584
    }
1585
1586
    /* Call to socket() can fail for some getaddrinfo results, try another. */
1587
    fd= socket(con->addrinfo_next->ai_family, con->addrinfo_next->ai_socktype,
1588
               con->addrinfo_next->ai_protocol);
1589
    if (fd == -1)
1590
    {
1591
      drizzle_log_info(con->drizzle, "could not listen on %s:%s", host, port);
1592
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "socket:%d",
1593
                        errno);
1594
      continue;
1595
    }
1596
	
1597
	opt= 1;
1598
#ifdef _WIN32
1599
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const char*) &opt, sizeof(opt));
1600
#else
1601
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1602
#endif /* _WIN32 */
1603
    if (ret == -1)
1604
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1605
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1606
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "setsockopt:%d",
1607
                        errno);
1608
      return DRIZZLE_RETURN_ERRNO;
1609
    }
1610
1611
    ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
1612
    if (ret == -1)
1613
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1614
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1615
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "bind:%d", errno);
1616
      if (errno == EADDRINUSE)
1617
      {
1618
        if (con->fd == -1)
1619
        {
1620
          drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
1621
                           port);
1622
        }
1623
1624
        continue;
1625
      }
1626
1627
      return DRIZZLE_RETURN_ERRNO;
1628
    }
1629
1630
    if (listen(fd, con->backlog) == -1)
1631
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1632
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1633
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "listen:%d",
1634
                        errno);
1635
      return DRIZZLE_RETURN_ERRNO;
1636
    }
1637
1638
    if (con->fd == -1)
1639
    {
1640
      con->fd= fd;
1641
      new_con= con;
1642
    }
1643
    else
1644
    {
1645
      new_con= drizzle_con_clone(con->drizzle, NULL, con);
1646
      if (new_con == NULL)
1647
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1648
        closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1649
        return DRIZZLE_RETURN_MEMORY;
1650
      }
1651
1652
      new_con->fd= fd;
1653
    }
1654
1655
    /* Wait for read events on the listening socket. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1656
    drizzle_return_t local_ret= drizzle_con_set_events(new_con, POLLIN);
1657
    if (local_ret != DRIZZLE_RETURN_OK)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1658
    {
1659
      drizzle_con_free(new_con);
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1660
      return local_ret;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1661
    }
1662
1663
    drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
1664
  }
1665
1666
  /* Report last socket() error if we couldn't find an address to bind. */
1667
  if (con->fd == -1)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1668
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1669
    return DRIZZLE_RETURN_ERRNO;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1670
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1671
1672
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1673
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1674
  return DRIZZLE_RETURN_OK;
1675
}
1676
1677
/*
1678
 * Static Definitions
1679
 */
1680
1681
static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
1682
{
1683
  int ret;
1684
  struct linger linger;
1685
  struct timeval waittime;
1686
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1687
  assert(con);
1688
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1689
  ret= 1;
1690
1691
#ifdef _WIN32
1692
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&ret,
1693
                  (socklen_t)sizeof(int));
1694
#else
1695
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret,
1696
                  (socklen_t)sizeof(int));
1697
#endif /* _WIN32 */
1698
1699
  if (ret == -1 && errno != EOPNOTSUPP)
1700
  {
1701
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1702
                      "setsockopt:TCP_NODELAY:%d", errno);
1703
    return DRIZZLE_RETURN_ERRNO;
1704
  }
1705
1706
  linger.l_onoff= 1;
1707
  linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1708
1709
#ifdef _WIN32
1710
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, (const char*)&linger,
1711
                  (socklen_t)sizeof(struct linger));
1712
#else
1713
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
1714
                  (socklen_t)sizeof(struct linger));
1715
#endif /* _WIN32 */
1716
1717
  if (ret == -1)
1718
  {
1719
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1720
                      "setsockopt:SO_LINGER:%d", errno);
1721
    return DRIZZLE_RETURN_ERRNO;
1722
  }
1723
1724
  waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1725
  waittime.tv_usec= 0;
1726
1727
#ifdef _WIN32
1728
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&waittime,
1729
                  (socklen_t)sizeof(struct timeval));
1730
#else
1731
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
1732
                  (socklen_t)sizeof(struct timeval));
1733
#endif /* _WIN32 */
1734
1735
  if (ret == -1 && errno != ENOPROTOOPT)
1736
  {
1737
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1738
                      "setsockopt:SO_SNDTIMEO:%d", errno);
1739
    return DRIZZLE_RETURN_ERRNO;
1740
  }
1741
1742
#ifdef _WIN32
1743
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&waittime,
1744
                  (socklen_t)sizeof(struct timeval));
1745
#else
1746
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
1747
                  (socklen_t)sizeof(struct timeval));
1748
#endif /* _WIN32 */
1749
1750
  if (ret == -1 && errno != ENOPROTOOPT)
1751
  {
1752
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1753
                      "setsockopt:SO_RCVTIMEO:%d", errno);
1754
    return DRIZZLE_RETURN_ERRNO;
1755
  }
1756
1757
  ret= DRIZZLE_DEFAULT_SOCKET_SEND_SIZE;
1758
#ifdef _WIN32
1759
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, (const char*)&ret, (socklen_t)sizeof(int));
1760
#else
1761
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
1762
#endif /* _WIN32 */
1763
  if (ret == -1)
1764
  {
1765
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1766
                      "setsockopt:SO_SNDBUF:%d", errno);
1767
    return DRIZZLE_RETURN_ERRNO;
1768
  }
1769
1770
  ret= DRIZZLE_DEFAULT_SOCKET_RECV_SIZE;
1771
#ifdef _WIN32
1772
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, (const char*)&ret, (socklen_t)sizeof(int));
1773
#else
1774
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
1775
#endif /* _WIN32 */
1776
  if (ret == -1)
1777
  {
1778
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1779
                      "setsockopt:SO_RCVBUF:%d", errno);
1780
    return DRIZZLE_RETURN_ERRNO;
1781
  }
1782
1783
#if defined (_WIN32)
2164.1.1 by Monty Taylor
Merged in outstanding changes from the win32 work.
1784
  {
1785
    unsigned long asyncmode;
1786
    asyncmode= 1;
1787
    ioctlsocket(con->fd, FIONBIO, &asyncmode);
1788
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1789
#else
1790
  ret= fcntl(con->fd, F_GETFL, 0);
1791
  if (ret == -1)
1792
  {
1793
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_GETFL:%d",
1794
                      errno);
1795
    return DRIZZLE_RETURN_ERRNO;
1796
  }
1797
1798
  ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
1799
  if (ret == -1)
1800
  {
1801
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_SETFL:%d",
1802
                      errno);
1803
    return DRIZZLE_RETURN_ERRNO;
1804
  }
1805
#endif
1806
1807
  return DRIZZLE_RETURN_OK;
1808
}