~drizzle-trunk/drizzle/development

1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are
9
 * met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 * notice, this list of conditions and the following disclaimer.
13
 *
14
 *     * Redistributions in binary form must reproduce the above
15
 * copyright notice, this list of conditions and the following disclaimer
16
 * in the documentation and/or other materials provided with the
17
 * distribution.
18
 *
19
 *     * The names of its contributors may not be used to endorse or
20
 * promote products derived from this software without specific prior
21
 * written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
35
 */
36
37
/**
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
1877.1.5 by Andrew Hutchings
Fix min() usage for 32bit
96
  struct sigaction act;
1912.2.1 by Andrew Hutchings
Keep dtr client connection alive during lengthy drizzleslap tests (made longer when using valgrind)
97
  memset(&act, 0, sizeof(act));
1877.1.5 by Andrew Hutchings
Fix min() usage for 32bit
98
99
  act.sa_handler = SIG_IGN;
100
  sigaction(SIGPIPE, &act, NULL);
101
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
102
  if (drizzle == NULL)
103
  {
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
104
    drizzle= malloc(sizeof(drizzle_st));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
209
drizzle_options_t drizzle_options(const drizzle_st *drizzle)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
210
{
211
  return drizzle->options;
212
}
213
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
214
void drizzle_set_options(drizzle_st *drizzle, drizzle_options_t options)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
215
{
216
  drizzle->options= options;
217
}
218
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
219
void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
  {
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
284
    con= malloc(sizeof(drizzle_con_st));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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;
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
311
  con->command= 0;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
  {
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
429
    pfds= realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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);
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
599
  drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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);
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
615
  drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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);
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
685
  ptr= memcpy(log_buffer, function, size);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
}