~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
2478.1.2 by Brian Aker
Fix race condition in bison build, also fix NULL issue on FreeBSD.
44
#include <libdrizzle/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
  {
2472.1.3 by Brian Aker
Mark all cases where you are using realloc.
1012
    con->command_buffer= (uint8_t*)realloc(NULL, (*total) +1);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1013
    if (con->command_buffer == NULL)
1014
    {
2472.1.3 by Brian Aker
Mark all cases where you are using realloc.
1015
      drizzle_set_error(con->drizzle, __func__, "Failed to allocate.");
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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)
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
1130
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1131
        host= DRIZZLE_DEFAULT_TCP_HOST;
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
1132
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1133
      else
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
1134
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1135
        host= tcp->host;
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
1136
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1137
    }
1138
1139
    ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
1140
    if (ret != 0)
1141
    {
2472.1.4 by Brian Aker
Remove memset in case where we are using new()
1142
      drizzle_set_error(con->drizzle, "drizzle_state_addrinfo", "getaddrinfo:%s", gai_strerror(ret));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1143
      return DRIZZLE_RETURN_GETADDRINFO;
1144
    }
1145
1146
    con->addrinfo_next= tcp->addrinfo;
1147
1148
    break;
1149
1150
  case DRIZZLE_CON_SOCKET_UDS:
1151
    con->addrinfo_next= &(con->socket.uds.addrinfo);
1152
    break;
1153
1154
  default:
1155
    break;
1156
  }
1157
1158
  drizzle_state_pop(con);
1159
  return DRIZZLE_RETURN_OK;
1160
}
1161
1162
drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
1163
{
1164
  int ret;
1165
  drizzle_return_t dret;
1166
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1167
  if (con == NULL)
1168
  {
1169
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1170
  }
1171
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1172
  drizzle_log_debug(con->drizzle, "drizzle_state_connect");
1173
1174
  if (con->fd != -1)
1175
  {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1176
    (void)closesocket(con->fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1177
    con->fd= -1;
1178
  }
1179
1180
  if (con->addrinfo_next == NULL)
1181
  {
1182
    drizzle_set_error(con->drizzle, "drizzle_state_connect",
1183
                      "could not connect");
1184
    drizzle_state_reset(con);
1185
    return DRIZZLE_RETURN_COULD_NOT_CONNECT;
1186
  }
1187
1188
  con->fd= socket(con->addrinfo_next->ai_family,
1189
                  con->addrinfo_next->ai_socktype,
1190
                  con->addrinfo_next->ai_protocol);
1191
  if (con->fd == -1)
1192
  {
1193
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "socket:%d",
1194
                      errno);
1195
    con->drizzle->last_errno= errno;
1196
    return DRIZZLE_RETURN_ERRNO;
1197
  }
1198
1199
  dret= _con_setsockopt(con);
1200
  if (dret != DRIZZLE_RETURN_OK)
1201
  {
1202
    con->drizzle->last_errno= errno;
1203
    return dret;
1204
  }
1205
1206
  while (1)
1207
  {
1208
    ret= connect(con->fd, con->addrinfo_next->ai_addr,
1209
                 con->addrinfo_next->ai_addrlen);
1210
1211
#ifdef _WIN32
1212
    errno = WSAGetLastError();
1213
    switch(errno) {
1214
    case WSAEINVAL:
1215
    case WSAEALREADY:
1216
    case WSAEWOULDBLOCK:
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1217
      errno= EINPROGRESS;
1218
      break;
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1219
    case WSAECONNREFUSED:
1220
      errno= ECONNREFUSED;
1221
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1222
    case WSAENETUNREACH:
1223
      errno= ENETUNREACH;
1224
      break;
1225
    case WSAETIMEDOUT:
1226
      errno= ETIMEDOUT;
1227
      break;
1228
    case WSAECONNRESET:
1229
      errno= ECONNRESET;
1230
      break;
1231
    case WSAEADDRINUSE:
1232
      errno= EADDRINUSE;
1233
      break;
1234
    case WSAEOPNOTSUPP:
1235
      errno= EOPNOTSUPP;
1236
      break;
1237
    case WSAENOPROTOOPT:
1238
      errno= ENOPROTOOPT;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1239
      break;
1240
    default:
1241
      break;
1242
    }
1243
#endif /* _WIN32 */
1244
	
1245
    drizzle_log_crazy(con->drizzle, "connect return=%d errno=%d", ret, errno);
1246
1247
    if (ret == 0)
1248
    {
1249
      con->addrinfo_next= NULL;
1250
      break;
1251
    }
1252
1253
    if (errno == EAGAIN || errno == EINTR)
1254
      continue;
1255
1256
    if (errno == EINPROGRESS)
1257
    {
1258
      drizzle_state_pop(con);
1259
      drizzle_state_push(con, drizzle_state_connecting);
1260
      return DRIZZLE_RETURN_OK;
1261
    }
1262
1263
    if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
1264
    {
1265
      con->addrinfo_next= con->addrinfo_next->ai_next;
1266
      return DRIZZLE_RETURN_OK;
1267
    }
1268
1269
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "connect:%d",
1270
                      errno);
1271
    con->drizzle->last_errno= errno;
1272
    return DRIZZLE_RETURN_ERRNO;
1273
  }
1274
1275
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1276
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1277
  return DRIZZLE_RETURN_OK;
1278
}
1279
1280
drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
1281
{
1282
  drizzle_return_t ret;
1283
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1284
  if (con == NULL)
1285
  {
1286
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1287
  }
1288
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1289
  drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
1290
1291
  while (1)
1292
  {
1293
    if (con->revents & POLLOUT)
1294
    {
1295
      drizzle_state_pop(con);
1296
      return DRIZZLE_RETURN_OK;
1297
    }
1298
    else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
1299
    {
1300
      con->revents= 0;
1301
      drizzle_state_pop(con);
1302
      drizzle_state_push(con, drizzle_state_connect);
1303
      con->addrinfo_next= con->addrinfo_next->ai_next;
1304
      return DRIZZLE_RETURN_OK;
1305
    }
1306
1307
    ret= drizzle_con_set_events(con, POLLOUT);
1308
    if (ret != DRIZZLE_RETURN_OK)
1309
      return ret;
1310
1311
    if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1312
      return DRIZZLE_RETURN_IO_WAIT;
1313
1314
    ret= drizzle_con_wait(con->drizzle);
1315
    if (ret != DRIZZLE_RETURN_OK)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1316
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1317
      return ret;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1318
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1319
  }
1320
}
1321
1322
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
1323
{
1324
  drizzle_return_t ret;
1325
  ssize_t read_size;
1326
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1327
  if (con == NULL)
1328
  {
1329
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1330
  }
1331
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1332
  drizzle_log_debug(con->drizzle, "drizzle_state_read");
1333
1334
  if (con->buffer_size == 0)
1335
    con->buffer_ptr= con->buffer;
1336
  else if ((con->buffer_ptr - con->buffer) > (DRIZZLE_MAX_BUFFER_SIZE / 2))
1337
  {
1338
    memmove(con->buffer, con->buffer_ptr, con->buffer_size);
1339
    con->buffer_ptr= con->buffer;
1340
  }
1341
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1342
  if ((con->revents & POLLIN) == 0 &&
1343
      (con->drizzle->options & DRIZZLE_NON_BLOCKING))
1344
  {
1345
    /* non-blocking mode: return IO_WAIT instead of attempting to read. This
1346
     * avoids reading immediately after writing a command, which typically
1347
     * returns EAGAIN. This improves performance. */
1348
    ret= drizzle_con_set_events(con, POLLIN);
1349
    if (ret != DRIZZLE_RETURN_OK)
1350
      return ret;
1351
    return DRIZZLE_RETURN_IO_WAIT;
1352
  }
1353
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1354
  while (1)
1355
  {
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1356
    size_t available_buffer= (size_t)DRIZZLE_MAX_BUFFER_SIZE -
1357
        ((size_t)(con->buffer_ptr - con->buffer) + con->buffer_size);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1358
    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.
1359
                     available_buffer, 0);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1360
#ifdef _WIN32
1361
    errno = WSAGetLastError();
1362
    switch(errno) {
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1363
    case WSAENOTCONN:
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1364
    case WSAEWOULDBLOCK:
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1365
      errno= EAGAIN;
1366
      break;
1367
    case WSAEINVAL:
1368
    case WSAEALREADY:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1369
      errno= EINPROGRESS;
1370
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1371
    case WSAECONNREFUSED:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1372
      errno= ECONNREFUSED;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1373
      break;
1374
    case WSAENETUNREACH:
1375
      errno= ENETUNREACH;
1376
      break;
1377
    case WSAETIMEDOUT:
1378
      errno= ETIMEDOUT;
1379
      break;
1380
    case WSAECONNRESET:
1381
      errno= ECONNRESET;
1382
      break;
1383
    case WSAEADDRINUSE:
1384
      errno= EADDRINUSE;
1385
      break;
1386
    case WSAEOPNOTSUPP:
1387
      errno= EOPNOTSUPP;
1388
      break;
1389
    case WSAENOPROTOOPT:
1390
      errno= ENOPROTOOPT;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1391
      break;
1392
    default:
1393
      break;
1394
    }
1395
#endif /* _WIN32 */	
1396
    drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%d", con->fd,
1397
                      read_size, errno);
1398
1399
    if (read_size == 0)
1400
    {
1401
      drizzle_set_error(con->drizzle, "drizzle_state_read",
1402
                        "lost connection to server (EOF)");
1403
      return DRIZZLE_RETURN_LOST_CONNECTION;
1404
    }
1405
    else if (read_size == -1)
1406
    {
1407
      if (errno == EAGAIN)
1408
      {
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1409
        /* clear the read ready flag */
1410
        con->revents&= ~POLLIN;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1411
        ret= drizzle_con_set_events(con, POLLIN);
1412
        if (ret != DRIZZLE_RETURN_OK)
2046.1.1 by Evan Jones
libdrizzle: fix minor errors in drizzle_state_read
1413
          return ret;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1414
1415
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1416
          return DRIZZLE_RETURN_IO_WAIT;
1417
1418
        ret= drizzle_con_wait(con->drizzle);
1419
        if (ret != DRIZZLE_RETURN_OK)
1420
          return ret;
1421
1422
        continue;
1423
      }
1424
      else if (errno == ECONNREFUSED)
1425
      {
1426
        con->revents= 0;
1427
        drizzle_state_pop(con);
1428
        drizzle_state_push(con, drizzle_state_connect);
1429
        con->addrinfo_next= con->addrinfo_next->ai_next;
1430
        return DRIZZLE_RETURN_OK;
1431
      }
1432
      else if (errno == EINTR)
1433
        continue;
1434
      else if (errno == EPIPE || errno == ECONNRESET)
1435
      {
1436
        drizzle_set_error(con->drizzle, "drizzle_state_read",
1437
                          "lost connection to server (%d)", errno);
1438
        return DRIZZLE_RETURN_LOST_CONNECTION;
1439
      }
1440
1441
      drizzle_set_error(con->drizzle, "drizzle_state_read", "read:%d", errno);
1442
      con->drizzle->last_errno= errno;
1443
      return DRIZZLE_RETURN_ERRNO;
1444
    }
1445
2046.1.2 by Evan Jones
libdrizzle: drizzle_state_read: only call recv() if data is available.
1446
    /* clear the "read ready" flag if we read all available data. */
1447
    if ((size_t) read_size < available_buffer) con->revents&= ~POLLIN;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1448
    con->buffer_size+= (size_t)read_size;
1449
    break;
1450
  }
1451
2046.1.1 by Evan Jones
libdrizzle: fix minor errors in drizzle_state_read
1452
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1453
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1454
  return DRIZZLE_RETURN_OK;
1455
}
1456
1457
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
1458
{
1459
  drizzle_return_t ret;
1460
  ssize_t write_size;
1461
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1462
  if (con == NULL)
1463
  {
1464
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1465
  }
1466
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1467
  drizzle_log_debug(con->drizzle, "drizzle_state_write");
1468
1469
  while (con->buffer_size != 0)
1470
  {
1471
  
1877.1.5 by Andrew Hutchings
Fix min() usage for 32bit
1472
    write_size = send(con->fd,(char *) con->buffer_ptr, con->buffer_size, 0);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1473
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1474
#ifdef _WIN32
1475
    errno = WSAGetLastError();
1476
    switch(errno) {
1477
    case WSAENOTCONN:
1478
    case WSAEWOULDBLOCK:
1479
      errno= EAGAIN;
1480
      break;
1481
    case WSAEINVAL:
1482
    case WSAEALREADY:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1483
      errno= EINPROGRESS;
1484
      break;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1485
    case WSAECONNREFUSED:
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1486
      errno= ECONNREFUSED;
2263.4.1 by Monty Taylor
Updated the windows/posix error mapping as per notes from Marc Isambart.
1487
      break;
1488
    case WSAENETUNREACH:
1489
      errno= ENETUNREACH;
1490
      break;
1491
    case WSAETIMEDOUT:
1492
      errno= ETIMEDOUT;
1493
      break;
1494
    case WSAECONNRESET:
1495
      errno= ECONNRESET;
1496
      break;
1497
    case WSAEADDRINUSE:
1498
      errno= EADDRINUSE;
1499
      break;
1500
    case WSAEOPNOTSUPP:
1501
      errno= EOPNOTSUPP;
1502
      break;
1503
    case WSAENOPROTOOPT:
1504
      errno= ENOPROTOOPT;
1505
      break;
1506
    default:
1507
      break;
1508
    }
1509
#endif /* _WIN32 */	
1510
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1511
    drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%d", con->fd,
1512
                      write_size, errno);
1513
1514
    if (write_size == 0)
1515
    {
1516
      drizzle_set_error(con->drizzle, "drizzle_state_write",
1517
                        "lost connection to server (EOF)");
1518
      return DRIZZLE_RETURN_LOST_CONNECTION;
1519
    }
1520
    else if (write_size == -1)
1521
    {
1522
      if (errno == EAGAIN)
1523
      {
1524
        ret= drizzle_con_set_events(con, POLLOUT);
1525
        if (ret != DRIZZLE_RETURN_OK)
1526
          return ret;
1527
1528
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1529
          return DRIZZLE_RETURN_IO_WAIT;
1530
1531
        ret= drizzle_con_wait(con->drizzle);
1532
        if (ret != DRIZZLE_RETURN_OK)
1533
          return ret;
1534
1535
        continue;
1536
      }
1537
      else if (errno == EINTR)
1538
        continue;
1539
      else if (errno == EPIPE || errno == ECONNRESET)
1540
      {
1541
        drizzle_set_error(con->drizzle, "drizzle_state_write",
1542
                          "lost connection to server (%d)", errno);
1543
        return DRIZZLE_RETURN_LOST_CONNECTION;
1544
      }
1545
1546
      drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%d", errno);
1547
      con->drizzle->last_errno= errno;
1548
      return DRIZZLE_RETURN_ERRNO;
1549
    }
1550
1551
    con->buffer_ptr+= write_size;
1552
    con->buffer_size-= (size_t)write_size;
1553
    if (con->buffer_size == 0)
1554
      break;
1555
  }
1556
1557
  con->buffer_ptr= con->buffer;
1558
1559
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1560
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1561
  return DRIZZLE_RETURN_OK;
1562
}
1563
1564
drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
1565
{
1566
  char host[NI_MAXHOST];
1567
  char port[NI_MAXSERV];
1568
  int fd;
1569
  int opt;
1570
  drizzle_con_st *new_con;
1571
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1572
  if (con == NULL)
1573
  {
1574
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
1575
  }
1576
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1577
  for (; con->addrinfo_next != NULL;
1578
       con->addrinfo_next= con->addrinfo_next->ai_next)
1579
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1580
    int ret= getnameinfo(con->addrinfo_next->ai_addr,
1581
                         con->addrinfo_next->ai_addrlen, host, NI_MAXHOST, port,
1582
                         NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1583
    if (ret != 0)
1584
    {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1585
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "getnameinfo:%s", gai_strerror(ret));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1586
      return DRIZZLE_RETURN_GETADDRINFO;
1587
    }
1588
1589
    /* Call to socket() can fail for some getaddrinfo results, try another. */
1590
    fd= socket(con->addrinfo_next->ai_family, con->addrinfo_next->ai_socktype,
1591
               con->addrinfo_next->ai_protocol);
1592
    if (fd == -1)
1593
    {
1594
      drizzle_log_info(con->drizzle, "could not listen on %s:%s", host, port);
1595
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "socket:%d",
1596
                        errno);
1597
      continue;
1598
    }
1599
	
1600
	opt= 1;
1601
#ifdef _WIN32
1602
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const char*) &opt, sizeof(opt));
1603
#else
1604
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1605
#endif /* _WIN32 */
1606
    if (ret == -1)
1607
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1608
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1609
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "setsockopt:%d",
1610
                        errno);
1611
      return DRIZZLE_RETURN_ERRNO;
1612
    }
1613
1614
    ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
1615
    if (ret == -1)
1616
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1617
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1618
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "bind:%d", errno);
1619
      if (errno == EADDRINUSE)
1620
      {
1621
        if (con->fd == -1)
1622
        {
1623
          drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
1624
                           port);
1625
        }
1626
1627
        continue;
1628
      }
1629
1630
      return DRIZZLE_RETURN_ERRNO;
1631
    }
1632
1633
    if (listen(fd, con->backlog) == -1)
1634
    {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1635
      closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1636
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "listen:%d",
1637
                        errno);
1638
      return DRIZZLE_RETURN_ERRNO;
1639
    }
1640
1641
    if (con->fd == -1)
1642
    {
1643
      con->fd= fd;
1644
      new_con= con;
1645
    }
1646
    else
1647
    {
1648
      new_con= drizzle_con_clone(con->drizzle, NULL, con);
1649
      if (new_con == NULL)
1650
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
1651
        closesocket(fd);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1652
        return DRIZZLE_RETURN_MEMORY;
1653
      }
1654
1655
      new_con->fd= fd;
1656
    }
1657
1658
    /* Wait for read events on the listening socket. */
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1659
    drizzle_return_t local_ret= drizzle_con_set_events(new_con, POLLIN);
1660
    if (local_ret != DRIZZLE_RETURN_OK)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1661
    {
1662
      drizzle_con_free(new_con);
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
1663
      return local_ret;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1664
    }
1665
1666
    drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
1667
  }
1668
1669
  /* Report last socket() error if we couldn't find an address to bind. */
1670
  if (con->fd == -1)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1671
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1672
    return DRIZZLE_RETURN_ERRNO;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1673
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1674
1675
  drizzle_state_pop(con);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1676
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1677
  return DRIZZLE_RETURN_OK;
1678
}
1679
1680
/*
1681
 * Static Definitions
1682
 */
1683
1684
static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
1685
{
1686
  int ret;
1687
  struct linger linger;
1688
  struct timeval waittime;
1689
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
1690
  assert(con);
1691
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1692
  ret= 1;
1693
1694
#ifdef _WIN32
1695
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&ret,
1696
                  (socklen_t)sizeof(int));
1697
#else
1698
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret,
1699
                  (socklen_t)sizeof(int));
1700
#endif /* _WIN32 */
1701
1702
  if (ret == -1 && errno != EOPNOTSUPP)
1703
  {
1704
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1705
                      "setsockopt:TCP_NODELAY:%d", errno);
1706
    return DRIZZLE_RETURN_ERRNO;
1707
  }
1708
1709
  linger.l_onoff= 1;
1710
  linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1711
1712
#ifdef _WIN32
1713
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, (const char*)&linger,
1714
                  (socklen_t)sizeof(struct linger));
1715
#else
1716
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
1717
                  (socklen_t)sizeof(struct linger));
1718
#endif /* _WIN32 */
1719
1720
  if (ret == -1)
1721
  {
1722
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1723
                      "setsockopt:SO_LINGER:%d", errno);
1724
    return DRIZZLE_RETURN_ERRNO;
1725
  }
1726
1727
  waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1728
  waittime.tv_usec= 0;
1729
1730
#ifdef _WIN32
1731
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&waittime,
1732
                  (socklen_t)sizeof(struct timeval));
1733
#else
1734
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
1735
                  (socklen_t)sizeof(struct timeval));
1736
#endif /* _WIN32 */
1737
1738
  if (ret == -1 && errno != ENOPROTOOPT)
1739
  {
1740
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1741
                      "setsockopt:SO_SNDTIMEO:%d", errno);
1742
    return DRIZZLE_RETURN_ERRNO;
1743
  }
1744
1745
#ifdef _WIN32
1746
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&waittime,
1747
                  (socklen_t)sizeof(struct timeval));
1748
#else
1749
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
1750
                  (socklen_t)sizeof(struct timeval));
1751
#endif /* _WIN32 */
1752
1753
  if (ret == -1 && errno != ENOPROTOOPT)
1754
  {
1755
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1756
                      "setsockopt:SO_RCVTIMEO:%d", errno);
1757
    return DRIZZLE_RETURN_ERRNO;
1758
  }
1759
1760
  ret= DRIZZLE_DEFAULT_SOCKET_SEND_SIZE;
1761
#ifdef _WIN32
1762
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, (const char*)&ret, (socklen_t)sizeof(int));
1763
#else
1764
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
1765
#endif /* _WIN32 */
1766
  if (ret == -1)
1767
  {
1768
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1769
                      "setsockopt:SO_SNDBUF:%d", errno);
1770
    return DRIZZLE_RETURN_ERRNO;
1771
  }
1772
1773
  ret= DRIZZLE_DEFAULT_SOCKET_RECV_SIZE;
1774
#ifdef _WIN32
1775
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, (const char*)&ret, (socklen_t)sizeof(int));
1776
#else
1777
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
1778
#endif /* _WIN32 */
1779
  if (ret == -1)
1780
  {
1781
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1782
                      "setsockopt:SO_RCVBUF:%d", errno);
1783
    return DRIZZLE_RETURN_ERRNO;
1784
  }
1785
1786
#if defined (_WIN32)
2164.1.1 by Monty Taylor
Merged in outstanding changes from the win32 work.
1787
  {
1788
    unsigned long asyncmode;
1789
    asyncmode= 1;
1790
    ioctlsocket(con->fd, FIONBIO, &asyncmode);
1791
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1792
#else
1793
  ret= fcntl(con->fd, F_GETFL, 0);
1794
  if (ret == -1)
1795
  {
1796
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_GETFL:%d",
1797
                      errno);
1798
    return DRIZZLE_RETURN_ERRNO;
1799
  }
1800
1801
  ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
1802
  if (ret == -1)
1803
  {
1804
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_SETFL:%d",
1805
                      errno);
1806
    return DRIZZLE_RETURN_ERRNO;
1807
  }
1808
#endif
1809
1810
  return DRIZZLE_RETURN_OK;
1811
}