~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/drizzle.c

  • Committer: Monty Taylor
  • Date: 2010-04-15 19:14:53 UTC
  • mto: This revision was merged to the branch mainline in revision 1476.
  • Revision ID: mordred@inaugust.com-20100415191453-ril2x8qdo78fny9w
Replaced test_authz with a plugin implementing a hard-coded simple
multi-tennancy policy. The policy describes:
- A root user exists which can do anything
- A user may only see a schema that is named the same has his user name
- A user may see data_dictionary and information_schema (data_dictionary
  required for show databases to work)

This way, we can more clearly test the results of the authorization
interface while providing an optional plugin that is actually useful to some
human.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Drizzle Client & Protocol Library
3
 
 *
4
 
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 
 * All rights reserved.
6
 
 *
7
 
 * Redistribution and use in source and binary forms, with or without
8
 
 * modification, are permitted provided that the following conditions are
9
 
 * met:
10
 
 *
11
 
 *     * Redistributions of source code must retain the above copyright
12
 
 * notice, this list of conditions and the following disclaimer.
13
 
 *
14
 
 *     * Redistributions in binary form must reproduce the above
15
 
 * copyright notice, this list of conditions and the following disclaimer
16
 
 * in the documentation and/or other materials provided with the
17
 
 * distribution.
18
 
 *
19
 
 *     * The names of its contributors may not be used to endorse or
20
 
 * promote products derived from this software without specific prior
21
 
 * written permission.
22
 
 *
23
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 
 *
35
 
 */
36
 
 
37
 
/**
38
 
 * @file
39
 
 * @brief Drizzle Definitions
40
 
 */
41
 
 
42
 
#include "libdrizzle/common.h"
43
 
 
44
 
 
45
 
/**
46
 
 * @addtogroup drizzle_static Static Drizzle Declarations
47
 
 * @ingroup drizzle
48
 
 * @{
49
 
 */
50
 
 
51
 
/**
52
 
 * Names of the verbose levels provided.
53
 
 */
54
 
static const char *_verbose_name[DRIZZLE_VERBOSE_MAX]=
55
 
{
56
 
  "NEVER",
57
 
  "FATAL",
58
 
  "ERROR",
59
 
  "INFO",
60
 
  "DEBUG",
61
 
  "CRAZY"
62
 
};
63
 
 
64
 
/** @} */
65
 
 
66
 
/*
67
 
 * Common Definitions
68
 
 */
69
 
 
70
 
const char *drizzle_version(void)
71
 
{
72
 
  return PACKAGE_VERSION;
73
 
}
74
 
 
75
 
const char *drizzle_bugreport(void)
76
 
{
77
 
  return PACKAGE_BUGREPORT;
78
 
}
79
 
 
80
 
const char *drizzle_verbose_name(drizzle_verbose_t verbose)
81
 
{
82
 
  if (verbose >= DRIZZLE_VERBOSE_MAX)
83
 
    return "UNKNOWN";
84
 
 
85
 
  return _verbose_name[verbose];
86
 
}
87
 
 
88
 
drizzle_st *drizzle_create(drizzle_st *drizzle)
89
 
{
90
 
#if defined(_WIN32)
91
 
  /* if it is MS windows, invoke WSAStartup */
92
 
  WSADATA wsaData;
93
 
  if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
94
 
    printf("Error at WSAStartup()\n");
95
 
#endif
96
 
  struct sigaction act;
97
 
  memset(&act, 0, sizeof(act));
98
 
 
99
 
  act.sa_handler = SIG_IGN;
100
 
  sigaction(SIGPIPE, &act, NULL);
101
 
 
102
 
  if (drizzle == NULL)
103
 
  {
104
 
    drizzle= malloc(sizeof(drizzle_st));
105
 
    if (drizzle == NULL)
106
 
      return NULL;
107
 
 
108
 
    drizzle->options= DRIZZLE_ALLOCATED;
109
 
  }
110
 
  else
111
 
    drizzle->options= DRIZZLE_NONE;
112
 
 
113
 
  /* @todo remove this default free flag with new API. */
114
 
  drizzle->options|= DRIZZLE_FREE_OBJECTS;
115
 
  drizzle->error_code= 0;
116
 
  /* drizzle->options set above */
117
 
  drizzle->verbose= DRIZZLE_VERBOSE_NEVER;
118
 
  drizzle->con_count= 0;
119
 
  drizzle->pfds_size= 0;
120
 
  drizzle->query_count= 0;
121
 
  drizzle->query_new= 0;
122
 
  drizzle->query_running= 0;
123
 
  drizzle->last_errno= 0;
124
 
  drizzle->timeout= -1;
125
 
  drizzle->con_list= NULL;
126
 
  drizzle->context= NULL;
127
 
  drizzle->context_free_fn= NULL;
128
 
  drizzle->event_watch_fn= NULL;
129
 
  drizzle->event_watch_context= NULL;
130
 
  drizzle->log_fn= NULL;
131
 
  drizzle->log_context= NULL;
132
 
  drizzle->pfds= NULL;
133
 
  drizzle->query_list= NULL;
134
 
  drizzle->sqlstate[0]= 0;
135
 
  drizzle->last_error[0]= 0;
136
 
 
137
 
  return drizzle;
138
 
}
139
 
 
140
 
drizzle_st *drizzle_clone(drizzle_st *drizzle, const drizzle_st *from)
141
 
{
142
 
  drizzle_con_st *con;
143
 
 
144
 
  drizzle= drizzle_create(drizzle);
145
 
  if (drizzle == NULL)
146
 
    return NULL;
147
 
 
148
 
  drizzle->options|= (from->options & (drizzle_options_t)~DRIZZLE_ALLOCATED);
149
 
 
150
 
  for (con= from->con_list; con != NULL; con= con->next)
151
 
  {
152
 
    if (drizzle_con_clone(drizzle, NULL, con) == NULL)
153
 
    {
154
 
      drizzle_free(drizzle);
155
 
      return NULL;
156
 
    }
157
 
  }
158
 
 
159
 
  return drizzle;
160
 
}
161
 
 
162
 
void drizzle_free(drizzle_st *drizzle)
163
 
{
164
 
  if (drizzle->context != NULL && drizzle->context_free_fn != NULL)
165
 
    drizzle->context_free_fn(drizzle, drizzle->context);
166
 
 
167
 
  if (drizzle->options & DRIZZLE_FREE_OBJECTS)
168
 
  {
169
 
    drizzle_con_free_all(drizzle);
170
 
    drizzle_query_free_all(drizzle);
171
 
  }
172
 
  else if (drizzle->options & DRIZZLE_ASSERT_DANGLING)
173
 
  {
174
 
    assert(drizzle->con_list == NULL);
175
 
    assert(drizzle->con_list == NULL);
176
 
  }
177
 
 
178
 
  if (drizzle->pfds != NULL)
179
 
    free(drizzle->pfds);
180
 
 
181
 
  if (drizzle->options & DRIZZLE_ALLOCATED)
182
 
    free(drizzle);
183
 
#if defined(_WIN32)
184
 
  /* if it is MS windows, invoke WSACleanup() at the end*/
185
 
  WSACleanup();
186
 
#endif
187
 
}
188
 
 
189
 
const char *drizzle_error(const drizzle_st *drizzle)
190
 
{
191
 
  return (const char *)drizzle->last_error;
192
 
}
193
 
 
194
 
int drizzle_errno(const drizzle_st *drizzle)
195
 
{
196
 
  return drizzle->last_errno;
197
 
}
198
 
 
199
 
uint16_t drizzle_error_code(const drizzle_st *drizzle)
200
 
{
201
 
  return drizzle->error_code;
202
 
}
203
 
 
204
 
const char *drizzle_sqlstate(const drizzle_st *drizzle)
205
 
{
206
 
  return drizzle->sqlstate;
207
 
}
208
 
 
209
 
drizzle_options_t drizzle_options(const drizzle_st *drizzle)
210
 
{
211
 
  return drizzle->options;
212
 
}
213
 
 
214
 
void drizzle_set_options(drizzle_st *drizzle, drizzle_options_t options)
215
 
{
216
 
  drizzle->options= options;
217
 
}
218
 
 
219
 
void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options)
220
 
{
221
 
  drizzle->options|= options;
222
 
}
223
 
 
224
 
void drizzle_remove_options(drizzle_st *drizzle, drizzle_options_t options)
225
 
{
226
 
  drizzle->options&= ~options;
227
 
}
228
 
 
229
 
void *drizzle_context(const drizzle_st *drizzle)
230
 
{
231
 
  return drizzle->context;
232
 
}
233
 
 
234
 
void drizzle_set_context(drizzle_st *drizzle, void *context)
235
 
{
236
 
  drizzle->context= context;
237
 
}
238
 
 
239
 
void drizzle_set_context_free_fn(drizzle_st *drizzle,
240
 
                                 drizzle_context_free_fn *function)
241
 
{
242
 
  drizzle->context_free_fn= function;
243
 
}
244
 
 
245
 
int drizzle_timeout(const drizzle_st *drizzle)
246
 
{
247
 
  return drizzle->timeout;
248
 
}
249
 
 
250
 
void drizzle_set_timeout(drizzle_st *drizzle, int timeout)
251
 
{
252
 
  drizzle->timeout= timeout;
253
 
}
254
 
 
255
 
drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle)
256
 
{
257
 
  return drizzle->verbose;
258
 
}
259
 
 
260
 
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
261
 
{
262
 
  drizzle->verbose= verbose;
263
 
}
264
 
 
265
 
void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
266
 
                        void *context)
267
 
{
268
 
  drizzle->log_fn= function;
269
 
  drizzle->log_context= context;
270
 
}
271
 
 
272
 
void drizzle_set_event_watch_fn(drizzle_st *drizzle,
273
 
                                drizzle_event_watch_fn *function,
274
 
                                void *context)
275
 
{
276
 
  drizzle->event_watch_fn= function;
277
 
  drizzle->event_watch_context= context;
278
 
}
279
 
 
280
 
drizzle_con_st *drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con)
281
 
{
282
 
  if (con == NULL)
283
 
  {
284
 
    con= malloc(sizeof(drizzle_con_st));
285
 
    if (con == NULL)
286
 
    {
287
 
      if (drizzle != NULL)
288
 
        drizzle_set_error(drizzle, "drizzle_con_create", "malloc");
289
 
      return NULL;
290
 
    }
291
 
 
292
 
    con->options= DRIZZLE_CON_ALLOCATED;
293
 
  }
294
 
  else
295
 
    con->options= 0;
296
 
 
297
 
  if (drizzle->con_list != NULL)
298
 
    drizzle->con_list->prev= con;
299
 
  con->next= drizzle->con_list;
300
 
  con->prev= NULL;
301
 
  drizzle->con_list= con;
302
 
  drizzle->con_count++;
303
 
 
304
 
  con->packet_number= 0;
305
 
  con->protocol_version= 0;
306
 
  con->state_current= 0;
307
 
  con->events= 0;
308
 
  con->revents= 0;
309
 
  con->capabilities= DRIZZLE_CAPABILITIES_NONE;
310
 
  con->charset= 0;
311
 
  con->command= 0;
312
 
  con->options|= DRIZZLE_CON_MYSQL;
313
 
  con->socket_type= DRIZZLE_CON_SOCKET_TCP;
314
 
  con->status= DRIZZLE_CON_STATUS_NONE;
315
 
  con->max_packet_size= DRIZZLE_MAX_PACKET_SIZE;
316
 
  con->result_count= 0;
317
 
  con->thread_id= 0;
318
 
  con->backlog= DRIZZLE_DEFAULT_BACKLOG;
319
 
  con->fd= -1;
320
 
  con->buffer_size= 0;
321
 
  con->command_offset= 0;
322
 
  con->command_size= 0;
323
 
  con->command_total= 0;
324
 
  con->packet_size= 0;
325
 
  con->addrinfo_next= NULL;
326
 
  con->buffer_ptr= con->buffer;
327
 
  con->command_buffer= NULL;
328
 
  con->command_data= NULL;
329
 
  con->context= NULL;
330
 
  con->context_free_fn= NULL;
331
 
  con->drizzle= drizzle;
332
 
  /* con->next set above */
333
 
  /* con->prev set above */
334
 
  con->query= NULL;
335
 
  /* con->result doesn't need to be set */
336
 
  con->result_list= NULL;
337
 
  con->scramble= NULL;
338
 
  con->socket.tcp.addrinfo= NULL;
339
 
  con->socket.tcp.host= NULL;
340
 
  con->socket.tcp.port= 0;
341
 
  /* con->buffer doesn't need to be set */
342
 
  con->db[0]= 0;
343
 
  con->password[0]= 0;
344
 
  /* con->scramble_buffer doesn't need to be set */
345
 
  con->server_version[0]= 0;
346
 
  /* con->state_stack doesn't need to be set */
347
 
  con->user[0]= 0;
348
 
 
349
 
  return con;
350
 
}
351
 
 
352
 
drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con,
353
 
                                  const drizzle_con_st *from)
354
 
{
355
 
  con= drizzle_con_create(drizzle, con);
356
 
  if (con == NULL)
357
 
    return NULL;
358
 
 
359
 
  /* Clear "operational" options such as IO status. */
360
 
  con->options|= (from->options & (drizzle_con_options_t)~(
361
 
                  DRIZZLE_CON_ALLOCATED|DRIZZLE_CON_READY|
362
 
                  DRIZZLE_CON_NO_RESULT_READ|DRIZZLE_CON_IO_READY|
363
 
                  DRIZZLE_CON_LISTEN));
364
 
  con->backlog= from->backlog;
365
 
  strcpy(con->db, from->db);
366
 
  strcpy(con->password, from->password);
367
 
  strcpy(con->user, from->user);
368
 
 
369
 
  switch (from->socket_type)
370
 
  {
371
 
  case DRIZZLE_CON_SOCKET_TCP:
372
 
    drizzle_con_set_tcp(con, from->socket.tcp.host, from->socket.tcp.port);
373
 
    break;
374
 
 
375
 
  case DRIZZLE_CON_SOCKET_UDS:
376
 
    drizzle_con_set_uds(con, from->socket.uds.sockaddr.sun_path);
377
 
    break;
378
 
 
379
 
  default:
380
 
    break;
381
 
  }
382
 
 
383
 
  return con;
384
 
}
385
 
 
386
 
void drizzle_con_free(drizzle_con_st *con)
387
 
{
388
 
  if (con->context != NULL && con->context_free_fn != NULL)
389
 
    con->context_free_fn(con, con->context);
390
 
 
391
 
  if (con->drizzle->options & DRIZZLE_FREE_OBJECTS)
392
 
    drizzle_result_free_all(con);
393
 
  else if (con->drizzle->options & DRIZZLE_ASSERT_DANGLING)
394
 
    assert(con->result_list == NULL);
395
 
 
396
 
  if (con->fd != -1)
397
 
    drizzle_con_close(con);
398
 
 
399
 
  drizzle_con_reset_addrinfo(con);
400
 
 
401
 
  if (con->drizzle->con_list == con)
402
 
    con->drizzle->con_list= con->next;
403
 
  if (con->prev != NULL)
404
 
    con->prev->next= con->next;
405
 
  if (con->next != NULL)
406
 
    con->next->prev= con->prev;
407
 
  con->drizzle->con_count--;
408
 
 
409
 
  if (con->options & DRIZZLE_CON_ALLOCATED)
410
 
    free(con);
411
 
}
412
 
 
413
 
void drizzle_con_free_all(drizzle_st *drizzle)
414
 
{
415
 
  while (drizzle->con_list != NULL)
416
 
    drizzle_con_free(drizzle->con_list);
417
 
}
418
 
 
419
 
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
420
 
{
421
 
  drizzle_con_st *con;
422
 
  struct pollfd *pfds;
423
 
  uint32_t x;
424
 
  int ret;
425
 
  drizzle_return_t dret;
426
 
 
427
 
  if (drizzle->pfds_size < drizzle->con_count)
428
 
  {
429
 
    pfds= realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
430
 
    if (pfds == NULL)
431
 
    {
432
 
      drizzle_set_error(drizzle, "drizzle_con_wait", "realloc");
433
 
      return DRIZZLE_RETURN_MEMORY;
434
 
    }
435
 
 
436
 
    drizzle->pfds= pfds;
437
 
    drizzle->pfds_size= drizzle->con_count;
438
 
  }
439
 
  else
440
 
    pfds= drizzle->pfds;
441
 
 
442
 
  x= 0;
443
 
  for (con= drizzle->con_list; con != NULL; con= con->next)
444
 
  {
445
 
    if (con->events == 0)
446
 
      continue;
447
 
 
448
 
    pfds[x].fd= con->fd;
449
 
    pfds[x].events= con->events;
450
 
    pfds[x].revents= 0;
451
 
    x++;
452
 
  }
453
 
 
454
 
  if (x == 0)
455
 
  {
456
 
    drizzle_set_error(drizzle, "drizzle_con_wait",
457
 
                      "no active file descriptors");
458
 
    return DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS;
459
 
  }
460
 
 
461
 
  while (1)
462
 
  {
463
 
    drizzle_log_crazy(drizzle, "poll count=%d timeout=%d", x,
464
 
                      drizzle->timeout);
465
 
 
466
 
    ret= poll(pfds, x, drizzle->timeout);
467
 
 
468
 
    drizzle_log_crazy(drizzle, "poll return=%d errno=%d", ret, errno);
469
 
 
470
 
    if (ret == -1)
471
 
    {
472
 
      if (errno == EINTR)
473
 
        continue;
474
 
 
475
 
      drizzle_set_error(drizzle, "drizzle_con_wait", "poll:%d", errno);
476
 
      drizzle->last_errno= errno;
477
 
      return DRIZZLE_RETURN_ERRNO;
478
 
    }
479
 
 
480
 
    break;
481
 
  }
482
 
 
483
 
  if (ret == 0)
484
 
  {
485
 
    drizzle_set_error(drizzle, "drizzle_con_wait", "timeout reached");
486
 
    return DRIZZLE_RETURN_TIMEOUT;
487
 
  }
488
 
 
489
 
  x= 0;
490
 
  for (con= drizzle->con_list; con != NULL; con= con->next)
491
 
  {
492
 
    if (con->events == 0)
493
 
      continue;
494
 
 
495
 
    dret= drizzle_con_set_revents(con, pfds[x].revents);
496
 
    if (dret != DRIZZLE_RETURN_OK)
497
 
      return dret;
498
 
 
499
 
    x++;
500
 
  }
501
 
 
502
 
  return DRIZZLE_RETURN_OK;
503
 
}
504
 
 
505
 
drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle)
506
 
{
507
 
  drizzle_con_st *con;
508
 
 
509
 
  /* We can't keep state between calls since connections may be removed during
510
 
     processing. If this list ever gets big, we may want something faster. */
511
 
 
512
 
  for (con= drizzle->con_list; con != NULL; con= con->next)
513
 
  {
514
 
    if (con->options & DRIZZLE_CON_IO_READY)
515
 
    {
516
 
      con->options&= (drizzle_con_options_t)~DRIZZLE_CON_IO_READY;
517
 
      return con;
518
 
    }
519
 
  }
520
 
 
521
 
  return NULL;
522
 
}
523
 
 
524
 
drizzle_con_st *drizzle_con_ready_listen(drizzle_st *drizzle)
525
 
{
526
 
  drizzle_con_st *con;
527
 
 
528
 
  /* We can't keep state between calls since connections may be removed during
529
 
     processing. If this list ever gets big, we may want something faster. */
530
 
 
531
 
  for (con= drizzle->con_list; con != NULL; con= con->next)
532
 
  {
533
 
    if ((con->options & (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN)) ==
534
 
        (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN))
535
 
    {
536
 
      con->options&= (drizzle_con_options_t)~DRIZZLE_CON_IO_READY;
537
 
      return con;
538
 
    }
539
 
  }
540
 
 
541
 
  return NULL;
542
 
}
543
 
 
544
 
/*
545
 
 * Client Definitions
546
 
 */
547
 
 
548
 
drizzle_con_st *drizzle_con_add_tcp(drizzle_st *drizzle, drizzle_con_st *con,
549
 
                                    const char *host, in_port_t port,
550
 
                                    const char *user, const char *password,
551
 
                                    const char *db,
552
 
                                    drizzle_con_options_t options)
553
 
{
554
 
  con= drizzle_con_create(drizzle, con);
555
 
  if (con == NULL)
556
 
    return NULL;
557
 
 
558
 
  drizzle_con_set_tcp(con, host, port);
559
 
  drizzle_con_set_auth(con, user, password);
560
 
  drizzle_con_set_db(con, db);
561
 
  drizzle_con_add_options(con, options);
562
 
 
563
 
  return con;
564
 
}
565
 
 
566
 
drizzle_con_st *drizzle_con_add_uds(drizzle_st *drizzle, drizzle_con_st *con,
567
 
                                    const char *uds, const char *user,
568
 
                                    const char *password, const char *db,
569
 
                                    drizzle_con_options_t options)
570
 
{
571
 
  con= drizzle_con_create(drizzle, con);
572
 
  if (con == NULL)
573
 
    return NULL;
574
 
 
575
 
  drizzle_con_set_uds(con, uds);
576
 
  drizzle_con_set_auth(con, user, password);
577
 
  drizzle_con_set_db(con, db);
578
 
  drizzle_con_add_options(con, options);
579
 
 
580
 
  return con;
581
 
}
582
 
 
583
 
/*
584
 
 * Server Definitions
585
 
 */
586
 
 
587
 
drizzle_con_st *drizzle_con_add_tcp_listen(drizzle_st *drizzle,
588
 
                                           drizzle_con_st *con,
589
 
                                           const char *host, in_port_t port,
590
 
                                           int backlog,
591
 
                                           drizzle_con_options_t options)
592
 
{
593
 
  con= drizzle_con_create(drizzle, con);
594
 
  if (con == NULL)
595
 
    return NULL;
596
 
 
597
 
  drizzle_con_set_tcp(con, host, port);
598
 
  drizzle_con_set_backlog(con, backlog);
599
 
  drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
600
 
 
601
 
  return con;
602
 
}
603
 
 
604
 
drizzle_con_st *drizzle_con_add_uds_listen(drizzle_st *drizzle,
605
 
                                           drizzle_con_st *con,
606
 
                                           const char *uds, int backlog,
607
 
                                           drizzle_con_options_t options)
608
 
{
609
 
  con= drizzle_con_create(drizzle, con);
610
 
  if (con == NULL)
611
 
    return NULL;
612
 
 
613
 
  drizzle_con_set_uds(con, uds);
614
 
  drizzle_con_set_backlog(con, backlog);
615
 
  drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
616
 
 
617
 
  return con;
618
 
}
619
 
 
620
 
drizzle_con_st *drizzle_con_accept(drizzle_st *drizzle, drizzle_con_st *con,
621
 
                                   drizzle_return_t *ret_ptr)
622
 
{
623
 
  drizzle_con_st *ready;
624
 
  int fd;
625
 
 
626
 
  while (1)
627
 
  {
628
 
    if ((ready= drizzle_con_ready_listen(drizzle)) != NULL)
629
 
    {
630
 
      fd= accept(ready->fd, NULL, NULL);
631
 
 
632
 
      con= drizzle_con_create(drizzle, con);
633
 
      if (con == NULL)
634
 
      {
635
 
        (void)close(fd);
636
 
        *ret_ptr= DRIZZLE_RETURN_MEMORY;
637
 
        return NULL;
638
 
      }
639
 
 
640
 
      *ret_ptr= drizzle_con_set_fd(con, fd);
641
 
      if (*ret_ptr != DRIZZLE_RETURN_OK)
642
 
      {
643
 
        (void)close(fd);
644
 
        return NULL;
645
 
      }
646
 
 
647
 
      if (ready->options & DRIZZLE_CON_MYSQL)
648
 
        drizzle_con_add_options(con, DRIZZLE_CON_MYSQL);
649
 
 
650
 
      *ret_ptr= DRIZZLE_RETURN_OK;
651
 
      return con;
652
 
    }
653
 
 
654
 
    if (drizzle->options & DRIZZLE_NON_BLOCKING)
655
 
    {
656
 
      *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
657
 
      return NULL;
658
 
    }
659
 
 
660
 
    for (ready= drizzle->con_list; ready != NULL; ready= ready->next)
661
 
    {
662
 
      if (ready->options & DRIZZLE_CON_LISTEN)
663
 
        drizzle_con_set_events(ready, POLLIN);
664
 
    }
665
 
 
666
 
    *ret_ptr= drizzle_con_wait(drizzle);
667
 
    if (*ret_ptr != DRIZZLE_RETURN_OK)
668
 
      return NULL;
669
 
  }
670
 
}
671
 
 
672
 
/*
673
 
 * Local Definitions
674
 
 */
675
 
 
676
 
void drizzle_set_error(drizzle_st *drizzle, const char *function,
677
 
                       const char *format, ...)
678
 
{
679
 
  size_t size;
680
 
  char *ptr;
681
 
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
682
 
  va_list args;
683
 
 
684
 
  size= strlen(function);
685
 
  ptr= memcpy(log_buffer, function, size);
686
 
  ptr+= size;
687
 
  ptr[0]= ':';
688
 
  size++;
689
 
  ptr++;
690
 
 
691
 
  va_start(args, format);
692
 
  size+= (size_t)vsnprintf(ptr, DRIZZLE_MAX_ERROR_SIZE - size, format, args);
693
 
  va_end(args);
694
 
 
695
 
  if (drizzle->log_fn == NULL)
696
 
  {
697
 
    if (size >= DRIZZLE_MAX_ERROR_SIZE)
698
 
      size= DRIZZLE_MAX_ERROR_SIZE - 1;
699
 
 
700
 
    memcpy(drizzle->last_error, log_buffer, size + 1);
701
 
  }
702
 
  else
703
 
    drizzle->log_fn(log_buffer, DRIZZLE_VERBOSE_ERROR, drizzle->log_context);
704
 
}
705
 
 
706
 
void drizzle_log(drizzle_st *drizzle, drizzle_verbose_t verbose,
707
 
                 const char *format, va_list args)
708
 
{
709
 
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
710
 
 
711
 
  if (drizzle->log_fn == NULL)
712
 
  {
713
 
    printf("%5s: ", drizzle_verbose_name(verbose));
714
 
    vprintf(format, args);
715
 
    printf("\n");
716
 
  }
717
 
  else
718
 
  {
719
 
    vsnprintf(log_buffer, DRIZZLE_MAX_ERROR_SIZE, format, args);
720
 
    drizzle->log_fn(log_buffer, verbose, drizzle->log_context);
721
 
  }
722
 
}