This file is indexed.

/usr/include/memcache.h is in libmemcache-dev 1.4.0.rc2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
/* -*- mode: C -*-
 *
 * Copyright (c) 2004-2005 Sean Chittenden <sean@chittenden.org>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/*
 * The following copyright is included as the TAILQ_* macros come from
 * sys/queue.h which has the following LICENSE/Copyright notice.  XXX
 *
 * Copyright (c) 1991, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)queue.h     8.5 (Berkeley) 8/20/94
 * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $
 */

#ifndef MEMCACHE_H
#define MEMCACHE_H

/* fix FTBFS on powerpc for Debian libmemcache */
#ifndef __USE_POSIX
#define __USE_POSIX
#endif

#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>

#ifdef __MEMCACHE__
# define mc_const
#else
# define mc_const const
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Macros for the platform int definitions */
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;


/* Macros for testing versions */
#define MEMCACHE_VER		"1.4.0.rc2"
#define MEMCACHE_VERNUM		10400
#define MEMCACHE_RELDATE	20060220

/* A handful of #define's for callbacks that discourage developers
 * from improperly using the interface. */
#define MCM_CALLBACK_CTXT	md5md517e9be250407e8a37fb60180a76510d7
#define MCM_CALLBACK_KEY	md5md5c029c91da86138a5ad1489427e1d71b0
#define MCM_CALLBACK_LEN	md5md5a07b51f993c7254fcb18197565700326
#define MCM_CALLBACK_MC		md5md5897e5e464792802e78a18e0fdd437b7c
#define MCM_CALLBACK_PTR	md5md57b4ac6d3ad66bcb14ca7584f9a3eff43
#define MCM_CALLBACK_RES	md5md5e252857f6eaeebe7e61573a2a5bfa564
#define MCM_ERR_MASK		md5md51ba931bcdf1b3f122e9b86617155853e
#define MCM_ERR_FUNC_ERR_CTXT	md5md5314e69877a17018a14789a1a7fb8025c
#define MCM_ERR_FUNC_MC_CTXT	md5md57c7c80036a426539d819e35ebab5192f
#define MCM_KEY_VALID_KEY	md5md5537bb21da67eb92e5898f9911c607217
#define MCM_KEY_VALID_LEN	md5md55ecd4a9c706b439f8eebaca09eeadacf

/* Our initial read(2) buffer has to be long enough to read the
 * first line of the response.  ie:
 *
 * "VALUE #{'k' * 250} #{2 ** 15} #{2 ** 32}\r\n.length => 275
 *
 * However, since we want to avoid the number of system calls
 * necessary, include trailing part of the protocol in our estimate:
 *
 * "\r\nEND\r\n".length => 7
 *
 * Which yields a mandatory limit of 282 bytes for a successful
 * response.  If we wish to try and get lucky with our first read(2)
 * call and be able to read(2) in small values without making a second
 * read(2) call, pad this number with a sufficiently large byte value.
 * If most of your keys are 512B, then a INIT_GET_BUF_SIZE of 794
 * would be prudent (512 + 282).
 *
 * The default value of 4096 means that values less than 724 bytes
 * will always be read(2) via the first read(2) call.  Increasing this
 * value to large values is not beneficial.  If a second read(2) call
 * is necessary, the read(2) will be made with a sufficiently large
 * buffer already allocated. */
#ifndef INIT_GET_BUF_SIZE
# define INIT_GET_BUF_SIZE ((size_t)4096)
#endif

#define MAX_KEY_LEN 250

/* Error severity levels */
#define MCM_ERR_LVL_NONE	0x00
/* INFO: Execution information */
#define MCM_ERR_LVL_INFO	0x01
/* NOTICE: Routine usage information (ie: deactivated a down server) */
#define MCM_ERR_LVL_NOTICE	0x02
/* WARN: Problem during execution (ie: invalid data of sorts) */
#define MCM_ERR_LVL_WARN	0x04
/* ERR: Severe problem during execution (ie: OS system/library call failed) */
#define MCM_ERR_LVL_ERR		0x08
/* FATAL: Unable to proceed with execution (ie: protocol ) */
#define MCM_ERR_LVL_FATAL	0x10

/* MC_ compatiblity for severity */
#define MC_ERR_LVL_INFO		MCM_ERR_LVL_INFO
#define MC_ERR_LVL_NOTICE	MCM_ERR_LVL_NOTICE
#define MC_ERR_LVL_WARN		MCM_ERR_LVL_WARN
#define MC_ERR_LVL_ERR		MCM_ERR_LVL_ERR
#define MC_ERR_LVL_FATAL	MCM_ERR_LVL_FATAL

/* Set various error codes */
#define MCM_ERR_NONE			 0
#define MCM_ERR_ASSERT		 	 1
#define MCM_ERR_LIB_SNPRINTF		 2
#define MCM_ERR_LIB_STRTOL		 3
#define MCM_ERR_LIB_STRTOLL		 4
#define MCM_ERR_MC_RECONN		 5
#define MCM_ERR_MC_SEND_CMD		 6
#define MCM_ERR_MC_SERV_LIST		 7
#define MCM_ERR_MC_STORE		 8
#define MCM_ERR_MC_VALID_SERVER		 9
#define MCM_ERR_MEM_MALLOC		10
#define MCM_ERR_MEM_REALLOC		11
#define MCM_ERR_NET_CONNECT		12
#define MCM_ERR_NET_HOST		13
#define MCM_ERR_PROTO			14
#define MCM_ERR_SYS_CLOSE		16
#define MCM_ERR_SYS_CONNECT		17
#define MCM_ERR_SYS_FCNTL		18
#define MCM_ERR_SYS_READ		19
#define MCM_ERR_SYS_SELECT		20
#define MCM_ERR_SYS_SETSOCKOPT		21
#define MCM_ERR_SYS_SOCKET		22
#define MCM_ERR_SYS_WRITEV		23
#define MCM_ERR_TEST			24
#define MCM_ERR_TIMEOUT			25
#define MCM_ERR_TRACE			26
#define MCM_ERR_UNKNOWN_STAT		27


/* Various values for _flags.  Use their function counterparts instead
 * of testing these bits directly (ie: mcm_res_free_on_delete(),
 * mcm_res_found(), and mcm_res_attempted()). */
#define MCM_RES_FREE_ON_DELETE		0x01
#define MCM_RES_NO_FREE_ON_DELETE	0x02
#define MCM_RES_FOUND			0x04
#define MCM_RES_ATTEMPTED		0x08
#define MCM_RES_NEED_FREE_KEY		0x10

/* Aliases for MCM_RES_* #define's. Use their function counterparts
 * instead of testing these bits directly (ie:
 * mc_res_free_on_delete(), mc_res_found(), and
 * mc_res_attempted()).  */
#define MC_RES_FREE_ON_DELETE		MCM_RES_FREE_ON_DELETE
#define MC_RES_NO_FREE_ON_DELETE	MCM_RES_NO_FREE_ON_DELETE
#define MC_RES_FOUND			MCM_RES_FOUND
#define MC_RES_ATTEMPTED		MCM_RES_ATTEMPTED
#define MC_RES_NEED_FREE_KEY		MCM_RES_NEED_FREE_KEY

/* A convenience macro that lets people avoid the expense of strlen(3)
 * if they're using a string that's defined at compile time. */
#define MCM_CSTRLEN(_str) (sizeof(_str) - 1)

/*
 * Function authors MUST use the following two macros instead of
 * explicitly defining the various struct members.  These MD5s *will*
 * change every release to ensure developers (ie, YOU!) use these
 * macros.  Consider yourself warned. */

/* Error function signature and arguments */
#define MCM_CALLBACK_FUNC	const struct memcache_ctxt *MCM_CALLBACK_CTXT, struct memcache_res *MCM_CALLBACK_RES, void *MCM_CALLBACK_PTR
#define MCM_CALLBACK_SIG	const struct memcache_ctxt *, struct memcache_res *, void *
#define MCM_ERR_FUNC_ARGS	const void *MCM_ERR_FUNC_MC_CTXT, void *MCM_ERR_FUNC_ERR_CTXT
#define MCM_ERR_FUNC_SIG	const void *, void *

/* This see memcache.c:mcm_err_func() for an example on how to use
 * this. */
#define MCM_ERR_INIT_CTXT(_ctxt, _ectxt) do { \
	_ctxt = (const struct memcache_ctxt *)MCM_ERR_FUNC_MC_CTXT; \
	_ectxt = (struct memcache_err_ctxt *)MCM_ERR_FUNC_ERR_CTXT; \
} while (0)

/* Key validation function signature and arguments */
#define MCM_KEY_VALID_FUNC_ARGS	const void *MCM_KEY_VALID_CTXT, char *MCM_KEY_VALID_KEY, size_t MCM_KEY_VALID_LEN
#define MCM_KEY_VALID_FUNC_SIG	const void *, char *, size_t

#define MCM_KEY_VALID_INIT(_ctxt, _key, _len) do { \
	_ctxt = (const struct memcache_ctxt *)MCM_KEY_VALID_CTXT; \
	_key = (char *)MCM_KEY_VALID_KEY; \
	_len = MCM_KEY_VALID_LEN; \
} while (0)

/* Hash function signature and arguments.
 *
 * Arg 1: struct memcache_ctxt *
 * Arg 2: struct memcache *
 * Arg 3: key
 * Arg 4: key length
 */
#define MCM_HASH_FUNC		const void *MCM_CALLBACK_CTXT, const void *MCM_CALLBACK_MC, const char *MCM_CALLBACK_KEY, const size_t MCM_CALLBACK_LEN
#define MCM_HASH_SIG		const void *, const void *, const char *, const size_t

#define MCM_HASH_INIT(_ctxt, _mc, _key, _len) do { \
	_ctxt = (const struct memcache_ctxt *)MCM_CALLBACK_CTXT; \
	_mc = (const struct memcache *)MCM_CALLBACK_MC; \
	_key = (const char *)MCM_CALLBACK_KEY; \
	_len = MCM_CALLBACK_LEN; \
} while (0)

/* Begin various TAILQ macros */
#define TRASHIT(x)	do {(x) = (void *)-1;} while (0)

#define TAILQ_HEAD_INITIALIZER(head)	{ NULL, &(head).tqh_first }

#define TAILQ_HEAD(name, type)					\
struct name {							\
	struct type *tqh_first; /* first element */		\
	struct type **tqh_last; /* addr of last next element */	\
}

#define TAILQ_ENTRY(type)						\
struct {								\
	struct type *tqe_next;	/* next element */			\
	struct type **tqe_prev;	/* address of previous next element */	\
}

#define TAILQ_FIRST(head)	((head)->tqh_first)

#define TAILQ_NEXT(elm, field)	((elm)->field.tqe_next)

#define TAILQ_FOREACH(var, head, field)                                 \
	for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))

#define TAILQ_INIT(head) do {				\
	TAILQ_FIRST((head)) = NULL;			\
	(head)->tqh_last = &TAILQ_FIRST((head));	\
} while (0)

#define TAILQ_INSERT_TAIL(head, elm, field) do {	\
	TAILQ_NEXT((elm), field) = NULL;		\
	(elm)->field.tqe_prev = (head)->tqh_last;	\
	*(head)->tqh_last = (elm);			\
	(head)->tqh_last = &TAILQ_NEXT((elm), field);	\
} while (0)

#define TAILQ_REMOVE(head, elm, field) do {						\
	if ((TAILQ_NEXT((elm), field)) != NULL)						\
		TAILQ_NEXT((elm), field)->field.tqe_prev = (elm)->field.tqe_prev;	\
	else										\
		(head)->tqh_last = (elm)->field.tqe_prev;				\
	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);				\
	TRASHIT((elm)->field.tqe_next);							\
	TRASHIT((elm)->field.tqe_prev);							\
} while (0)
/* End various TAILQ macros */


/* Load struct memcache_buf, but none of the prototypes that operate
 * on struct memcache_buf. */
#include <memcache/_buffer.h>


/* Error handling information struct */
struct memcache_err_ctxt {
  /* A generic pointer not used by memcache(3), but can be used by
   * calling programs. */
  void *misc;

  /* The function name that generated the error */
  const char *funcname;

  /* The line number in source file that had the problem */
  mc_const u_int32_t lineno;

  /* The errno.  If zero, there was no errno set. */
  mc_const u_int32_t errnum;

  /* memcache(3) specific error code */
  mc_const u_int32_t errcode;

  /* Severity of the error (INFO, NOTICE, WARN, ERR, FATAL) */
  mc_const char severity;

  /* Should we continue executing after we return from this error
   * handler?  'y'es, 'n'o, or 'a'bort?  Handlers can modify this
   * value and change the execution of the error handler
   * dispatcher. */
  char cont;

  /* An optional return code that error handlers can set to return
   * application specific status codes to memcache(3) callers.  Where
   * integers are returned, this value will be returned to the caller
   * if it is a non-zero value. */
  int32_t retcode;

  /* If memcache(3) causes the program to exit from an error handler,
   * it will use the following exit status. */
  int sysexit;

  /* The error message that pertains to the given error code */
  const char *errstr;

  /* Per-error specific error message (null terminated) */
  const char *errmsg;

  /* The length of the error message. */
  mc_const size_t errlen;

  /* Pointer to the struct memcache_ctxt of the calling function. */
  const void *ctxt;
};

/* The memcache API allows callers to provide their own memory
 * allocation routines to aid in embedability with existing programs,
 * libraries, programming languages, and environments that have their
 * own memory handling routines. */
typedef void	 (*mcFreeFunc)(void *mem);
typedef void	*(*mcMallocFunc)(const size_t size);
typedef void	*(*mcReallocFunc)(void *mem, const size_t size);

/* See the MCM_ERR_FUNC_* macros for details on the arguments and
 * memcache.c:mcm_err_func() for an example of how to use this. */
typedef int32_t	 (*mcErrFunc)(MCM_ERR_FUNC_ARGS);

/* Function prototype for scanning keys and either changing values of
 * invalid keys, or returning an error code. See the MCM_KEY_VALID_*
 * macros to gain access to the passed in values. */
typedef int32_t	 (*mcKeyValidFunc)(const void *, char *, size_t);

/* Function prototype for hashing keys.  See MCM_HASH_FUNC docs for
 * argument explaination. */
typedef u_int32_t	(*mcHashKeyFunc)(MCM_HASH_FUNC);

/* Function prototype for finding a server.
 *
 * Arg1: struct memcache_ctxt *
 * Arg2: struct memcache *
 * Arg3: hash value */
typedef void *(*mcServerFindFunc)(const void *, void *, const u_int32_t);

/* This structure is only used to support multiple memory contexts.
 * By default, all memcache(3) API calls use the global memory
 * context, mcGlobalCtxt.  Under special circumstances (ie, Apache),
 * it is necessary to have multiple memory contexts that correspond
 * with their various different calling libraries (PHP, PostgreSQL,
 * APR, etc).  struct memcache_ctxt and its friends mcm_*() are used
 * to fulfill this goal.  Under most instances, programs, use of
 * mc_*() is sufficient, however there is nothing wrong with defining
 * your own memory context.
 *
 * mcMallocAtomic is used where applicable in the event that the
 * calling application makes use of a garbage collection mechanism
 * (ie, Boehm).  In non-GC'ed environments, this should be set to the
 * same things as mcMalloc.  When allocating a struct memcache_ctxt
 * object, it is absolutely necessary to allocate a new context and
 * assign it to call mcMemNewCtxt() instead of independently creating
 * a struct memcache_ctxt object (ie: "struct memcache_ctxt *ctxt;
 * ctxt = mcMemNewCtxt(...);" == good.  "struct memcache_ctxt ctxt;
 * bzero(ctxt, sizeof(struct memcache_ctxt));" == bad. */
struct memcache_ctxt {
  /* Memory context function pointers. */
  mcFreeFunc	mcFree;
  mcMallocFunc	mcMalloc;
  mcMallocFunc	mcMallocAtomic;
  mcReallocFunc	mcRealloc;

  /* Error handling system.  Users only need to worry about having
   * mcErrFunc().  All warnings, etc., go through this function.  See
   * struct mcm_errctxt for details on information passed to the
   * handler. */
  mcErrFunc mcErr;

  /* Key validation system.  Certain applications need to verify the
   * contents of keys and ensure that various values are contained
   * inside of keys.  If this function pointer is not null, before
   * keys are sent to the server, they will be passed to this function
   * pointer for testing/modification.  All modifications to the key
   * must be in place and can not change the memory location or the
   * length of the key. */
  mcKeyValidFunc mcKeyValid;

  /* Key hash function. */
  mcHashKeyFunc mcHashKey;

  /* Find Server function. */
  mcServerFindFunc mcServerFind;

  /* In non-fatal, normal operating conditions, it is plausble (indeed
   * likely) that certain operations are going to fail, but do so
   * wihin the bounds of normal operating levels for memcache(7).
   * Prime examples include performing an increment operation on a key
   * that doesn't exist.  Given that such cases are to be considered
   * normal, it is less than desirable to fall back to the error
   * handling system in memcache(3).  The following errnum value acts
   * to mimic the global errno(2) value, but on a per-context
   * basis. */
  u_int32_t errnum;

  /* Internal.  Pointer to the last command that was written out: the
   * state of this pointer is not guaranteed and its use is internal
   * to memcache(3).  Only used when a server dies and we need to pass
   * around the server's last command or other data. */
  struct memcache_buf *_rbuf;
  struct memcache_buf *_wbuf;
  u_int32_t _last_hash;

  /* Pointer to the context's error context/information. */
  struct memcache_err_ctxt *ectxt;

  /* Determines what error levels are ignored.  See mc_err_filter_*()
   * for the interface to this struct member.  Manual manipulation is
   * prohibited. */
  u_int32_t MCM_ERR_MASK;
};

struct memcache_server {
  /* A generic pointer not used by memcache(3), but can be used by
   * calling programs. */
  void *misc;

  /* The hostname of the server. */
  char *hostname;

  /* Port number of the host we're connecting to. */
  char *port;

  /* The file descriptor for this server */
  int fd;

  /* The timeout for this server */
  struct timeval tv;

  /* Is this particular server active or not?
   *
   * 'd' == Down	Last request was unsuccessful
   * 'n' == No host	The hostname doesn't exist
   * 't' == Try		Haven't connected to it yet, will attempt
   * 'u' == Up		Has been connected to successfully
   */
  char active;

  /* A cached copy of the looked up host. */
  struct addrinfo *hostinfo;

  /* The number of addresses in the cached copy.  If there is more
   * than one per DNS entry (discouraged), we establish a connection
   * to them all. */
  u_int32_t num_addrs;

#ifdef HAVE_SELECT
  /* Reduces the amount of user time required when reading data. */
  fd_set fds;
#endif

  /* read(2) buffer */
  struct memcache_buf *rbuf;

  /* write(2) buffer */
  struct memcache_buf *wbuf;

  u_int32_t _last_hash;

  /* Internal.  A cursor for where we are in the buffer.  This changes
   * every time we examine a bit of data in our buffer. */
  size_t soff;

  /* Internal.  A pointer to the start of the current line in the
   * buffer. */
  size_t startoff;

  /* Misc list bits */
  TAILQ_ENTRY(memcache_server) entries;
};


struct memcache_server_stats {
  pid_t pid;
  time_t uptime;
  time_t time;
  char *version;
  struct timeval rusage_user;
  struct timeval rusage_system;
  u_int32_t curr_items;
  u_int64_t total_items;
  u_int64_t bytes;
  u_int32_t curr_connections;
  u_int64_t total_connections;
  u_int32_t connection_structures;
  u_int64_t cmd_get;
#ifdef SEAN_HACKS
  u_int64_t cmd_refresh;
#endif
  u_int64_t cmd_set;
  u_int64_t get_hits;
  u_int64_t get_misses;
#ifdef SEAN_HACKS
  u_int64_t refresh_hits;
  u_int64_t refresh_misses;
#endif
  u_int64_t bytes_read;
  u_int64_t bytes_written;
  u_int64_t limit_maxbytes;
};


/* struct memcache.  Any of the bits that are commented as "Internal"
 * should not be twiddled with, ever.  The misc member can be used by
 * applications and is *never* touched/accessed by memcache(3).  Its
 * primary purpose is to aid in embedding memcache(3) in other
 * programming languages. */
struct memcache {
  /* A generic pointer not used by memcache(3), but can be used by
   * calling programs. */
  void *misc;

  /* The default timeout for all servers. */
  struct timeval tv;

  /* The number of servers in **servers. */
  u_int32_t num_servers;

  /* An array of usable memcache_servers. */
  struct memcache_server **servers;

  /* The complete list of servers. */
  TAILQ_HEAD(memcache_server_list, memcache_server) server_list;
};


struct memcache_res {
  /* A generic pointer not used by memcache(3), but can be used by
   * calling programs. */
  void *misc;

  char *key;		/* key */
  size_t len;		/* length of key */
  u_int32_t hash;	/* hash of the key */
  size_t bytes;		/* length of val */
  void *val;		/* the value */

  /* If size is zero (default), the memory for val is automatically
   * allocated using mcMalloc(3).  If size is zero, _flags has its
   * MC_RES_FREE_ON_DELETE bit set.
   *
   * If size is non-zero, memcache(3) assumes that the caller has set
   * val to an available portion of memory that is size bytes long.
   * memcache(3) will only populate val with as many bytes as are
   * specified by size (ie, it will trim the value in order to fit
   * into val). If size is non-zero, _flags has its
   * MC_RES_NO_FREE_ON_DELETE bit set by default. */
  size_t size;

  TAILQ_ENTRY(memcache_res) entries;

  /* This is the client supplied flags.  Please note, this flags is
   * very different than _flags (_flags is an internal bit and
   * shouldn't be read/changed, etc). */
  u_int16_t flags;

  /* If _flags has 0x01 set, val will be free(3)'ed on when this
   * struct is cleaned up via mc_res_free() or the request is cleaned
   * up via mc_req_free().
   *
   * If _flags has is 0x02 set, val will not be free(3)'ed when this
   * response or its parent request are cleaned up.
   *
   * Note: Use mc_res_free_on_delete() to set the "free on delete"
   * bits. */
  char _flags;
};

struct memcache_req {
  /* A generic pointer not used by memcache(3), but can be used by
   * calling programs. */
  void *misc;

  TAILQ_HEAD(memcache_res_list, memcache_res) query;
  TAILQ_HEAD(memcache_res_cb_list, memcache_res_cb) cb;
  u_int16_t num_keys;
};


/* Call back interface bits.  memcache(3) offers a callback
 * mechanism wherein many get requests can be lumped together into a
 * single get request.  After a response has been read from the
 * server, the callbacks are executed.
 *
 * Example:
 *
 * static void my_callback_func(MCM_CALLBACK_SIG);
 * static void
 * my_callback_func(MCM_CALLBACK_FUNC) {
 *   struct my_struct *ptr = (struct my_struct *)MCM_CALLBACK_PTR;
 *   struct memcache_ctxt *ctxt = MCM_CALLBACK_CTXT;
 *   struct memcache_res *res = MCM_CALLBACK_RES;
 *   ...
 * }
 *
 * and callbacks are registered like:
 *
 * struct memcache_req *req = mc_req_new();
 * struct memcache_res *res = mc_req_add(req, key, key_len);
 * mc_res_register_fetch_cb(req, res, my_callback_func, NULL);
 *
 * or, if you want to pass an optional void * pointer:
 *
 * struct my_struct *ptr;
 * struct memcache_res_cb *cb = mc_res_register_fetch_cb(req, res, my_callback_func, ptr);
 *
 * Then call mc_get() like normal whenever and your callback will be
 * executed.  Ex:
 *
 * mc_get(req);
 */

typedef void (*mcResCallback)(MCM_CALLBACK_FUNC);
struct memcache_res_cb {
  void *misc;
  const struct memcache_ctxt *ctxt;
  struct memcache_req *req;
  struct memcache_res *res;
  mcResCallback cb;
  TAILQ_ENTRY(memcache_res_cb) entries;
};


/* Adds a given key to the cache */
int			 mc_add(struct memcache *mc,
				char *key, const size_t key_len,
				const void *val, const size_t bytes,
				const time_t expire, const u_int16_t flags);

/* Gets the value from memcache and allocates the data for the caller.
 * It is the caller's responsibility to free the returned value.
 * mc_get() is the preferred interface, however. */
void			*mc_aget(struct memcache *mc, char *key, const size_t len);

/* Gets the value from memcache and allocates the data for the caller.
 * It is the caller's responsibility to free the returned value.  If
 * retlen is non-null, the size of the response will be set upon
 * return, or zero in the event of a failure.  mc_get() is the
 * preferred interface, however. */
void			*mc_aget2(struct memcache *mc, char *key, const size_t len, size_t *retlen);

#ifdef SEAN_HACKS
void			*mc_alisten(struct memcache *mc, char *key, const size_t len);

/* Gets the value from memcache and allocates the data for the caller.
 * It is the caller's responsibility to free the returned value.
 * mc_refresh() is the preferred interface, however. */
void			*mc_arefresh(struct memcache *mc, char *key, const size_t len);
#endif

/* Decrements a given key */
u_int32_t		 mc_decr(struct memcache *mc, char *key, const size_t key_len, const u_int32_t val);

/* Deletes a given key */
int			 mc_delete(struct memcache *mc, char *key, const size_t key_len, const time_t hold);

/* Returns true if the given error level was added to the filter */
int			 mc_err_filter_add(const u_int32_t err_mask);

/* Returns true if the given error level was removed from the filter */
int			 mc_err_filter_del(const u_int32_t err_mask);

/* Returns the current filter mask.  This interface has a questionable
 * future and may get removed or have its result set change from
 * release to release. */
u_int32_t		 mc_err_filter_get(void);

/* Returns true if the specified error level is being filtered. */
int			 mc_err_filter_test(const u_int32_t err_lvl);

/* Executes the error handler for testing */
void			 mc_err_test(void);

/* Flushes all keys on a given server */
int			 mc_flush(struct memcache *mc, struct memcache_server *ms);

/* Flushes all keys on all servers */
int			 mc_flush_all(struct memcache *mc);

/* cleans up a memcache object. */
void			 mc_free(struct memcache *mc);

/* mc_get() is the preferred method of accessing memcache.  It accepts
 * multiple keys and lets a user (should they so choose) perform
 * memory caching to reduce the number of mcMalloc(3) calls makes. */
void			 mc_get(struct memcache *mc, struct memcache_req *req);

/* Generates a hash value from a given key */
u_int32_t		 mc_hash(const struct memcache *mc, const char *key, const size_t len);

/* Generates a hash value from a given key (depreciated, use mc_hash())*/
u_int32_t		 mc_hash_key(const char *key, const size_t len);

/* Increments a given key */
u_int32_t		 mc_incr(struct memcache *mc, char *key, const size_t key_len, const u_int32_t val);

/* Allocates a new memcache object */
struct memcache	*mc_new(void);

#ifdef SEAN_HACKS
void			 mc_listen(struct memcache *mc, struct memcache_req *req);

/* mc_refresh() is the preferred method of accessing memcache.  It
 * accepts multiple keys and lets a user (should they so choose)
 * perform memory caching to reduce the number of mcMalloc(3) calls
 * makes.  mc_refresh() differs from mc_get() in that mc_refresh
 * updates the expiration time to be now + whatever the expiration for
 * the item was set to.  Sessions should use this as a way of noting
 * sessions expiring. */
void			 mc_refresh(struct memcache *mc, struct memcache_req *req);
#endif

/* Returns the release date for the library */
u_int32_t		 mc_reldate(void);

/* Replaces a given key to the cache */
int			 mc_replace(struct memcache *mc,
				    char *key, const size_t key_len,
				    const void *val, const size_t bytes,
				    const time_t expire, const u_int16_t flags);

/* Safely adds a key to a given request (the key is mc_strdup()'ed).
   See mc_req_add_ref() to avoid the mc_strdup(): note the warning in
   mc_req_add_ref() if you decide to use the other function. */
struct memcache_res	*mc_req_add(struct memcache_req *req, char *key, const size_t len);

/* Adds a key to a given request. Stores a pointer to key.  key can
   not be modified or free(3)'ed until the passed in request and the
   returning struct memcache_res object is done being used. */
struct memcache_res	*mc_req_add_ref(struct memcache_req *req, char *key, const size_t len);

/* Cleans up a given request and its subsequent responses.  If _flags
 * has the MC_RES_FREE_ON_DELETE bit set (default), it will clean up
 * the value too.  If _flags has MC_RES_NO_FREE_ON_DELETE set,
 * however, it is the caller's responsibility to free the value.  To
 * prevent double free(3) errors, if a value is free(3)'ed before
 * mc_req_free() is called, set val to NULL. */
void			 mc_req_free(struct memcache_req *req);

/* Allocates a new memcache request object. */
struct memcache_req	*mc_req_new(void);

/* Returns 1 if there has been an attempt by the library to fill the
 * struct's bits from a memcache server.  Returns 0 if there has been
 * no attempt to fill this struct's data. */
int			 mc_res_attempted(const struct memcache_res *res);

/* Tells the response object to free the allocated memory when it gets
 * cleaned up or to let the caller manage the memory. */
void			 mc_res_free_on_delete(struct memcache_res *res, const int free_on_delete);

/* Returns 1 if the given memcache_res struct contains data that was
 * found and if there has been an attempt at filling the data.  Return
 * 0 if no value was found for the key *or* there has been no attempt
 * at filling the data. */
int			 mc_res_found(const struct memcache_res *res);

/* Cleans up an individual response object.  Normally this is not
 * necessary as a call to mc_req_free() will clean up its response
 * objects. */
void			 mc_res_free(struct memcache_req *req, struct memcache_res *res);

/* Registers a callback with the request so that upon completion of a
 * fetch request, a callback gets executed. */
int			 mc_res_register_fetch_cb(struct memcache_req *req, struct memcache_res *res,
						  mcResCallback cb, void *misc);

/* Marks a given server as available again.  Does not reconnect to the
 * server, however. */
int			 mc_server_activate(struct memcache *mc, struct memcache_server *ms);

/* Mark all servers as available.  Does not connect to any servers,
 * but marks them as available. */
int			 mc_server_activate_all(struct memcache *mc);

/* Disconnects from a given server and marks it as down. */
void			 mc_server_deactivate(struct memcache *mc, struct memcache_server *ms);

/* Disconnects from a given server */
void			 mc_server_disconnect(struct memcache_server *ms);

/* Disconnects from all servers (leaves their active flag alone). */
void			 mc_server_disconnect_all(const struct memcache *mc);

/* When given a hash value, this function returns the appropriate
 * server to connect to in order to find the key. */
struct memcache_server	*mc_server_find(struct memcache *mc, const u_int32_t hash);

/* Adds a server to the list of available servers.  By default,
 * servers are assumed to be available.  Return codes:
 *
 * 0:	success
 * -1:	Unable to allocate a new server instance
 * -2:	Unable to strdup hostname
 * -3:	Unable to strdup port
 * -4:	Unable to Unable to resolve the host, server deactivated, but added to list
 * -5:	Unable to realloc(3) the server list, server list unchanged */
int			 mc_server_add(struct memcache *mc, const char *hostname, const char *port);
int			 mc_server_add2(struct memcache *mc,
					const char *hostname, const size_t hostname_len,
					const char *port, const size_t port_len);
int			 mc_server_add3(struct memcache *mc, struct memcache_server *ms);

/* Like the above, except hostport can be in the format:
 * "hostname:port" or just "hostname".  Ex: "127.0.0.1:11211" */
int			 mc_server_add4(struct memcache *mc, mc_const char *hostport);

/* Same as mc_server_add4(), except with a length for hostport */
int			 mc_server_add5(struct memcache *mc, mc_const char *hostport, const size_t hostlen);

/* Free's the space from a struct memcache_server.  Use mc_free(3)
 * instead: only use this function if you really know what you're
 * doing. */
void			 mc_server_free(struct memcache_server *ms);

/* Creates a new server struct */
struct memcache_server	*mc_server_new(void);


/* Cleans up a given stat's object */
void			 mc_server_stats_free(struct memcache_server_stats *s);

/* Gets a stats object from the given server.  It is the caller's
 * responsibility to cleanup the resulting object via
 * mc_server_stats_free(). */
struct memcache_server_stats	*mc_server_stats(struct memcache *mc, struct memcache_server *ms);

/* Set the timeout on a per server basis */
int			 mc_server_timeout(struct memcache_server *ms, const int sec, const int usec);

/* Sets a given key */
int			 mc_set(struct memcache *mc,
				char *key, const size_t key_len,
				const void *val, const size_t bytes,
				const time_t expire, const u_int16_t flags);

/* Creates a stats object for all available servers and returns the
 * cumulative stats.  Per host-specific data is generally the same as
 * the last server queried. */
struct memcache_server_stats	*mc_stats(struct memcache *mc);

/* memcache(3)'s strdup */
char			*mc_strdup(const char *str);

/* memcache(3)'s strnchr(3) */
char			*mc_strnchr(mc_const char *str, const int c, const size_t len);

/* memcache(3)'s strndup: returns a dup of str up to len bytes long,
 * and pads the string with a null character (ie: len + 1). */
char			*mc_strndup(const char *str, const size_t len);


/* Sets the default timeout for new servers. */
void			 mc_timeout(struct memcache *mc, const int sec, const int usec);

/* Returns a numeric version of the library */
u_int32_t		 mc_vernum(void);

/* Returns a string version of the library */
const char		*mc_version(void);



/* BEGIN memory management API functions and support for multiple
 * memory contexts.  Most users of memcache(3) should use the
 * functions prototyped above.  The below functions should be used by
 * advanced developers seeking a tad bit more control over their app's
 * use of memcache(3), authors of language extensions, or developers
 * who need to write modules that exist inside of a single process
 * with multiple memory allocation routines (ex: Apache and PHP). */


/* The following two functions are used to setup additional memory
 * allocations for programs that use memcache(3), but are not using
 * the standard system memory management routines (ex: PostgreSQL,
 * Ruby, etc.) */
int	mcMemSetup(mcFreeFunc freeFunc, mcMallocFunc mallocFunc,
		   mcMallocFunc mallocAtomicFunc, mcReallocFunc reallocFunc);
int	mcMemGet(mcFreeFunc *freeFunc, mcMallocFunc *mallocFunc,
		 mcMallocFunc *mallocAtomicFunc, mcReallocFunc *reallocFunc);

/* Returns a pointer to the global context. */
inline struct memcache_ctxt *mc_global_ctxt(void);

/* The next two functions are used to setup an error handler. */
int	mcErrSetup(mcErrFunc errFunc);
int	mcErrSetupCtxt(struct memcache_ctxt *ctxt, mcErrFunc errFunc);
int	mcErrGet(mcErrFunc *errFunc);


/* From here on out, the API assumes callers are providing a valid
 * memory context.  This allows multiple memory contexts to exist
 * inside the same process.  Very handy for PHP/Apache/APR authors, or
 * developers in similar situations.  For maximum portability and
 * embedability, use of the mcm_*() functions is *strongly*
 * encouraged. */

/* Creates a new memory context from scratch: should be sufficient for
 * most applications. */
struct memcache_ctxt	*mcMemNewCtxt(mcFreeFunc freeFunc, mcMallocFunc mallocFunc,
				      mcMallocFunc mallocAtomicFunc, mcReallocFunc reallocFunc);

/* Safely assigns the various function pointers to the passed in
 * memory context.  Only needed when an application needs to change
 * its memory allocation routines (not sure why this would ever need
 * to happen, to be honest). */
int                     mcMemSetupCtxt(struct memcache_ctxt *ctxt, mcFreeFunc freeFunc,
				       mcMallocFunc mallocFunc, mcMallocFunc mallocAtomicFunc,
				       mcReallocFunc reallocFunc);


/* Free's a given memcache context */
void			 mcMemFreeCtxt(struct memcache_ctxt *ctxt);

/* Functions from here to the bottom of the section behave identically
 * to the above functions, except they have one additional argument, a
 * struct memcache_ctxt pointer.  See above for documentation. */
int			 mcm_add(struct memcache_ctxt *ctxt, struct memcache *mc,
				 char *key, const size_t key_len,
				 const void *val, const size_t bytes,
				 const time_t expire, const u_int16_t flags);
void			*mcm_aget(struct memcache_ctxt *ctxt, struct memcache *mc,
				  char *key, const size_t len);
void			*mcm_aget2(struct memcache_ctxt *ctxt, struct memcache *mc,
				   char *key, const size_t len, size_t *retlen);
#ifdef SEAN_HACKS
void			*mcm_alisten(struct memcache_ctxt *ctxt, struct memcache *mc,
				     char *key, const size_t len);
void			*mcm_arefresh(struct memcache_ctxt *ctxt, struct memcache *mc,
				      char *key, const size_t len);
#endif
u_int32_t		 mcm_decr(struct memcache_ctxt *ctxt, struct memcache *mc,
				  char *key, const size_t key_len, const u_int32_t val);
int			 mcm_delete(struct memcache_ctxt *ctxt, struct memcache *mc,
				    char *key, const size_t key_len, const time_t hold);
void			 mcm_err(const struct memcache_ctxt *ctxt, const u_int32_t flags,
				 const char *funcname, const u_int32_t lineno, const u_int32_t errcode,
				 const char *msg, const u_int32_t msglen, const u_int32_t errlvl);
int			 mcm_err_filter_add(struct memcache_ctxt *ctxt, const u_int32_t err_mask);
int			 mcm_err_filter_del(struct memcache_ctxt *ctxt, const u_int32_t err_mask);
u_int32_t		 mcm_err_filter_get(const struct memcache_ctxt *ctxt);
int			 mcm_err_filter_test(const struct memcache_ctxt *ctxt, const u_int32_t err_lvl);
void			 mcm_err_test(const struct memcache_ctxt *ctxt);
int			 mcm_flush(struct memcache_ctxt *ctxt, struct memcache *mc,
				   struct memcache_server *ms);
int			 mcm_flush_all(struct memcache_ctxt *ctxt, struct memcache *mc);
void			 mcm_free(struct memcache_ctxt *ctxt, struct memcache *mc);
void			 mcm_get(struct memcache_ctxt *ctxt, struct memcache *mc, struct memcache_req *req);
u_int32_t		 mcm_hash(const struct memcache_ctxt *ctxt, const struct memcache *mc, const char *key, const size_t len);
u_int32_t		 mcm_hash_key(const struct memcache_ctxt *ctxt, const char *key, const size_t len);
u_int32_t		 mcm_incr(struct memcache_ctxt *ctxt, struct memcache *mc,
				  char *key, const size_t key_len, const u_int32_t val);
struct memcache		*mcm_new(struct memcache_ctxt *ctxt);
#ifdef SEAN_HACKS
void			 mcm_listen(struct memcache_ctxt *ctxt, struct memcache *mc,
				     struct memcache_req *req);
void			 mcm_refresh(struct memcache_ctxt *ctxt, struct memcache *mc,
				     struct memcache_req *req);
#endif
u_int32_t		 mcm_reldate(const struct memcache_ctxt *ctxt);
int			 mcm_replace(struct memcache_ctxt *ctxt, struct memcache *mc,
				     char *key, const size_t key_len,
				     const void *val, const size_t bytes,
				     const time_t expire, const u_int16_t flags);
struct memcache_res	*mcm_req_add(const struct memcache_ctxt *ctxt, struct memcache_req *req,
				     char *key, const size_t len);
struct memcache_res	*mcm_req_add_ref(const struct memcache_ctxt *ctxt, struct memcache_req *req,
					 char *key, const size_t len);
void			 mcm_req_free(const struct memcache_ctxt *ctxt, struct memcache_req *req);
struct memcache_req	*mcm_req_new(const struct memcache_ctxt *ctxt);
int			 mcm_res_attempted(const struct memcache_ctxt *ctxt, const struct memcache_res *res);
int			 mcm_res_found(const struct memcache_ctxt *ctxt, const struct memcache_res *res);
void			 mcm_res_free(const struct memcache_ctxt *ctxt, struct memcache_req *req,
				      struct memcache_res *res);
void			 mcm_res_free_on_delete(const struct memcache_ctxt *ctxt, struct memcache_res *res,
						const int free_on_delete);
int			 mcm_res_register_fetch_cb(struct memcache_ctxt *ctxt, struct memcache_req *req,
						   struct memcache_res *res, mcResCallback callback, void *misc);
int			 mcm_server_activate(const struct memcache_ctxt *ctxt, struct memcache *mc, struct memcache_server *ms);
int			 mcm_server_activate_all(const struct memcache_ctxt *ctxt, struct memcache *mc);
int			 mcm_server_add(struct memcache_ctxt *ctxt, struct memcache *mc,
					const char *hostname, const char *port);
int			 mcm_server_add2(struct memcache_ctxt *ctxt, struct memcache *mc,
					 const char *hostname, const size_t hostname_len,
					 const char *port, const size_t port_len);
int			 mcm_server_add3(struct memcache_ctxt *ctxt, struct memcache *mc,
					 struct memcache_server *ms);
int			 mcm_server_add4(struct memcache_ctxt *ctxt, struct memcache *mc,
					 mc_const char *hostport);
int			 mcm_server_add5(struct memcache_ctxt *ctxt, struct memcache *mc,
					 mc_const char *hostport, const size_t hostlen);
void			 mcm_server_deactivate(struct memcache_ctxt *ctxt, struct memcache *mc,
					       struct memcache_server *ms);
void			 mcm_server_disconnect(const struct memcache_ctxt *ctxt, struct memcache_server *ms);
void			 mcm_server_disconnect_all(const struct memcache_ctxt *ctxt, const struct memcache *mc);
struct memcache_server	*mcm_server_find(const struct memcache_ctxt *ctxt,
					 struct memcache *mc, const u_int32_t hash);
void			 mcm_server_free(struct memcache_ctxt *ctxt, struct memcache_server *ms);
struct memcache_server	*mcm_server_new(struct memcache_ctxt *ctxt);
void			 mcm_server_stats_free(const struct memcache_ctxt *ctxt, struct memcache_server_stats *s);
struct memcache_server_stats	*mcm_server_stats(struct memcache_ctxt *ctxt, struct memcache *mc, struct memcache_server *ms);
int			 mcm_server_timeout(const struct memcache_ctxt *ctxt, struct memcache_server *ms, const int sec, const int usec);
int			 mcm_set(struct memcache_ctxt *ctxt, struct memcache *mc,
				 char *key, const size_t key_len,
				 const void *val, const size_t bytes,
				 const time_t expire, const u_int16_t flags);
struct memcache_server_stats	*mcm_stats(struct memcache_ctxt *ctxt, struct memcache *mc);
char			*mcm_strdup(const struct memcache_ctxt *ctxt, const char *str);
char			*mcm_strnchr(const struct memcache_ctxt *ctxt, mc_const char *str, const int c, const size_t len);
char			*mcm_strndup(const struct memcache_ctxt *ctxt, const char *str, const size_t len);
char			*mcm_strnstr(const struct memcache_ctxt *ctxt, mc_const char *s, const char *find, size_t slen);
void			 mcm_timeout(const struct memcache_ctxt *ctxt, struct memcache *mc, const int sec, const int usec);
u_int32_t		 mcm_vernum(const struct memcache_ctxt *ctxt);
const char		*mcm_version(const struct memcache_ctxt *ctxt);
/* END memory management API functions */


/* BEGIN - Error handling convenience macros */
#define ERR_FLAG	0x1
#define WARN_FLAG	0x2
#define NO_ERRNO_FLAG	0x4
#define MCM_ERR(_code)			mcm_err(ctxt, ERR_FLAG, __FUNCTION__, __LINE__, _code, NULL, 0, 0)
#define MCM_ERR_MSG(_code, _msg)	mcm_err(ctxt, ERR_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), 0)
#define MCM_ERR_MSG_LVL(_code, _msg, _lvl)	mcm_err(ctxt, ERR_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), _lvl)
#define MCM_ERRX(_code)			mcm_err(ctxt, ERR_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, NULL, 0, 0)
#define MCM_ERRX_MSG_LVL(_code, _msg, _lvl)	mcm_err(ctxt, ERR_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), _lvl)
#define MCM_ERRX_MSG(_code, _msg)	mcm_err(ctxt, ERR_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), 0)
#define MCM_WARNX(_code, _msg)		mcm_err(ctxt, WARN_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), 0)
#define MCM_WARN_MSG(_code, _msg)	mcm_err(ctxt, WARN_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), 0)
#define MCM_WARN_MSGLEN(_code, _m, _l)	mcm_err(ctxt, WARN_FLAG, __FUNCTION__, __LINE__, _code, _m, _l, 0)
#define MCM_WARN_MSG_LVL(_code, _msg, _lvl)	mcm_err(ctxt, WARN_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), _lvl)
#define MCM_WARNX_MSG(_code, _msg)	mcm_err(ctxt, WARN_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, _msg, (_msg != NULL ? strlen(_msg) : 0), 0)
#define MCM_WARNX_MSGLEN(_code, _m, _l)	mcm_err(ctxt, WARN_FLAG|NO_ERRNO_FLAG, __FUNCTION__, __LINE__, _code, _m, _l, 0)
#define MCM_RET_CODE(_v)		(ctxt->ectxt->retcode != 0 ? ctxt->ectxt->retcode : _v)
/* END - Error handling convenience macros */


/* APIs that should be implemented: */

/* Resets all DNS entries */
void mc_server_reset_all_dns(struct memcache *mc);

/* Resets only one host's DNS cache */
void mc_server_reset_dns(struct memcache *mc, const char *hostname, const int port);

#ifdef TCP_NODELAY
/* Enable/disable TCP_NODELAY */
void mc_nodelay_enable(struct memcache *mc, const int enable);

/* Enable/disable TCP_NODELAY for a given server */
void mc_server_nodelay_enable(struct memcache_server *ms, const int enable);
#endif

/* Set the number of seconds you're willing to wait in total for a
 * response. ??? */

#ifdef __cplusplus
}
#endif

#endif