Index: libevent/evhttp.h =================================================================== --- libevent/evhttp.h (revision 454) +++ libevent/evhttp.h (working copy) @@ -28,6 +28,7 @@ #define _EVHTTP_H_ #include +#include #ifdef __cplusplus extern "C" { Index: libevent/http.c =================================================================== --- libevent/http.c (revision 454) +++ libevent/http.c (working copy) @@ -71,12 +71,13 @@ #undef timeout_pending #undef timeout_initialized -#include "strlcpy-internal.h" -#include "event.h" -#include "evhttp.h" -#include "evutil.h" +#include +#include +#include +#include #include "log.h" #include "http-internal.h" +#include "strlcpy-internal.h" #ifndef HAVE_GETADDRINFO struct addrinfo { Index: libevent/event_tagging.c =================================================================== --- libevent/event_tagging.c (revision 454) +++ libevent/event_tagging.c (working copy) @@ -55,7 +55,8 @@ #endif #include -#include "event.h" +#include +#include #include "log.h" int decode_int(uint32_t *pnumber, struct evbuffer *evbuf); Index: libevent/event_rpcgen.py =================================================================== --- libevent/event_rpcgen.py (revision 454) +++ libevent/event_rpcgen.py (working copy) @@ -1335,7 +1335,8 @@ '#include \n' '#include \n' '#include \n' - '#include \n\n' ) + '#include \n\n' + '#include \n\n' ) for statement in cppdirect: pre += '%s\n' % statement Index: libevent/test/regress_rpc.c =================================================================== --- libevent/test/regress_rpc.c (revision 454) +++ libevent/test/regress_rpc.c (working copy) @@ -564,8 +564,82 @@ } void +rpc_test(void) +{ + struct msg *msg, *msg2; + struct kill *attack; + struct run *run; + struct evbuffer *tmp = evbuffer_new(); + struct timeval tv_start, tv_end; + int i; + + fprintf(stdout, "Testing RPC: "); + + msg = msg_new(); + EVTAG_ASSIGN(msg, from_name, "niels"); + EVTAG_ASSIGN(msg, to_name, "phoenix"); + + if (EVTAG_GET(msg, attack, &attack) == -1) { + fprintf(stderr, "Failed to set kill message.\n"); + exit(1); + } + + EVTAG_ASSIGN(attack, weapon, "feather"); + EVTAG_ASSIGN(attack, action, "tickle"); + + gettimeofday(&tv_start, NULL); + for (i = 0; i < 1000; ++i) { + run = EVTAG_ADD(msg, run); + if (run == NULL) { + fprintf(stderr, "Failed to add run message.\n"); + exit(1); + } + EVTAG_ASSIGN(run, how, "very fast but with some data in it"); + } + + if (msg_complete(msg) == -1) { + fprintf(stderr, "Failed to make complete message.\n"); + exit(1); + } + + evtag_marshal_msg(tmp, 0, msg); + + msg2 = msg_new(); + if (evtag_unmarshal_msg(tmp, 0, msg2) == -1) { + fprintf(stderr, "Failed to unmarshal message.\n"); + exit(1); + } + + gettimeofday(&tv_end, NULL); + timersub(&tv_end, &tv_start, &tv_end); + fprintf(stderr, "(%.1f us/add) ", + (float)tv_end.tv_sec/(float)i * 1000000.0 + + tv_end.tv_usec / (float)i); + + if (!EVTAG_HAS(msg2, from_name) || + !EVTAG_HAS(msg2, to_name) || + !EVTAG_HAS(msg2, attack)) { + fprintf(stderr, "Missing data structures.\n"); + exit(1); + } + + if (EVTAG_LEN(msg2, run) != i) { + fprintf(stderr, "Wrong number of run messages.\n"); + exit(1); + } + + msg_free(msg); + msg_free(msg2); + + evbuffer_free(tmp); + + fprintf(stdout, "OK\n"); +} + +void rpc_suite(void) { + rpc_test(); rpc_basic_test(); rpc_basic_message(); rpc_basic_client(); Index: libevent/test/regress.h =================================================================== --- libevent/test/regress.h (revision 454) +++ libevent/test/regress.h (working copy) @@ -31,13 +31,27 @@ extern "C" { #endif +#ifdef HAVE_EVENT_HTTP void http_suite(void); void http_basic_test(void); void rpc_suite(void); +#endif +#ifdef HAVE_EVENT_DNS void dns_suite(void); - +#endif + +#ifdef HAVE_EVENT_BEVENTS +void buffer_suite(void); +#endif + +int setup_test(char *); +int cleanup_test(void); + +extern int test_ok; +extern int pair[2]; + #ifdef __cplusplus } #endif Index: libevent/test/regress_buffer.c =================================================================== --- libevent/test/regress_buffer.c (revision 0) +++ libevent/test/regress_buffer.c (revision 0) @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2003, 2004 Niels Provos + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifdef WIN32 +#include +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#ifndef WIN32 +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "event-internal.h" +#include "log.h" +#include "regress.h" +#include "regress.gen.h" + +void +test_evbuffer(void) { + + struct evbuffer *evb = evbuffer_new(); + setup_test("Testing Evbuffer: "); + + evbuffer_add_printf(evb, "%s/%d", "hello", 1); + + if (EVBUFFER_LENGTH(evb) == 7 && + strcmp((char*)EVBUFFER_DATA(evb), "hello/1") == 0) + test_ok = 1; + + evbuffer_free(evb); + + cleanup_test(); +} + +void +test_evbuffer_find(void) +{ + u_char* p; + char* test1 = "1234567890\r\n"; + char* test2 = "1234567890\r"; +#define EVBUFFER_INITIAL_LENGTH 256 + char test3[EVBUFFER_INITIAL_LENGTH]; + unsigned int i; + struct evbuffer * buf = evbuffer_new(); + + /* make sure evbuffer_find doesn't match past the end of the buffer */ + fprintf(stdout, "Testing evbuffer_find 1: "); + evbuffer_add(buf, (u_char*)test1, strlen(test1)); + evbuffer_drain(buf, strlen(test1)); + evbuffer_add(buf, (u_char*)test2, strlen(test2)); + p = evbuffer_find(buf, (u_char*)"\r\n", 2); + if (p == NULL) { + fprintf(stdout, "OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* + * drain the buffer and do another find; in r309 this would + * read past the allocated buffer causing a valgrind error. + */ + fprintf(stdout, "Testing evbuffer_find 2: "); + evbuffer_drain(buf, strlen(test2)); + for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i) + test3[i] = 'a'; + test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x'; + evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH); + p = evbuffer_find(buf, (u_char *)"xy", 2); + if (p == NULL) { + printf("OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + /* simple test for match at end of allocated buffer */ + fprintf(stdout, "Testing evbuffer_find 3: "); + p = evbuffer_find(buf, (u_char *)"ax", 2); + if (p != NULL && strncmp((char*)p, "ax", 2) == 0) { + printf("OK\n"); + } else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + evbuffer_free(buf); +} + +void +readcb(struct bufferevent *bev, void *arg) +{ + if (EVBUFFER_LENGTH(bev->input) == 8333) { + bufferevent_disable(bev, EV_READ); + test_ok++; + } +} + +void +writecb(struct bufferevent *bev, void *arg) +{ + if (EVBUFFER_LENGTH(bev->output) == 0) + test_ok++; +} + +void +errorcb(struct bufferevent *bev, short what, void *arg) +{ + test_ok = -2; +} + +void +test_bufferevent(void) +{ + struct bufferevent *bev1, *bev2; + char buffer[8333]; + int i; + + setup_test("Bufferevent: "); + + bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL); + bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL); + + bufferevent_disable(bev1, EV_READ); + bufferevent_enable(bev2, EV_READ); + + for (i = 0; i < sizeof(buffer); i++) + buffer[i] = i; + + bufferevent_write(bev1, buffer, sizeof(buffer)); + + event_dispatch(); + + bufferevent_free(bev1); + bufferevent_free(bev2); + + if (test_ok != 2) + test_ok = 0; + + cleanup_test(); +} + +int decode_int(uint32_t *pnumber, struct evbuffer *evbuf); + +#define TEST_MAX_INT 6 + +void +evtag_int_test(void) +{ + struct evbuffer *tmp = evbuffer_new(); + uint32_t integers[TEST_MAX_INT] = { + 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 + }; + uint32_t integer; + int i; + + for (i = 0; i < TEST_MAX_INT; i++) { + int oldlen, newlen; + oldlen = EVBUFFER_LENGTH(tmp); + encode_int(tmp, integers[i]); + newlen = EVBUFFER_LENGTH(tmp); + fprintf(stdout, "\t\tencoded 0x%08x with %d bytes\n", + integers[i], newlen - oldlen); + } + + for (i = 0; i < TEST_MAX_INT; i++) { + if (decode_int(&integer, tmp) == -1) { + fprintf(stderr, "decode %d failed", i); + exit(1); + } + if (integer != integers[i]) { + fprintf(stderr, "got %x, wanted %x", + integer, integers[i]); + exit(1); + } + } + + if (EVBUFFER_LENGTH(tmp) != 0) { + fprintf(stderr, "trailing data"); + exit(1); + } + evbuffer_free(tmp); + + fprintf(stdout, "\t%s: OK\n", __func__); +} + +void +evtag_fuzz(void) +{ + u_char buffer[4096]; + struct evbuffer *tmp = evbuffer_new(); + struct timeval tv; + int i, j; + + int not_failed = 0; + for (j = 0; j < 100; j++) { + for (i = 0; i < sizeof(buffer); i++) + buffer[i] = rand(); + evbuffer_drain(tmp, -1); + evbuffer_add(tmp, buffer, sizeof(buffer)); + + if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) + not_failed++; + } + + /* The majority of decodes should fail */ + if (not_failed >= 10) { + fprintf(stderr, "evtag_unmarshal should have failed"); + exit(1); + } + + /* Now insert some corruption into the tag length field */ + evbuffer_drain(tmp, -1); + timerclear(&tv); + tv.tv_sec = 1; + evtag_marshal_timeval(tmp, 0, &tv); + evbuffer_add(tmp, buffer, sizeof(buffer)); + + EVBUFFER_DATA(tmp)[1] = 0xff; + if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) { + fprintf(stderr, "evtag_unmarshal_timeval should have failed"); + exit(1); + } + + evbuffer_free(tmp); + + fprintf(stdout, "\t%s: OK\n", __func__); +} + +void +evtag_test(void) +{ + fprintf(stdout, "Testing Tagging:\n"); + + evtag_init(); + evtag_int_test(); + evtag_fuzz(); + + fprintf(stdout, "OK\n"); +} + +void +buffer_suite(void) +{ + test_evbuffer(); + test_evbuffer_find(); + + test_bufferevent(); + + evtag_test(); +} Index: libevent/test/Makefile.am =================================================================== --- libevent/test/Makefile.am (revision 454) +++ libevent/test/Makefile.am (working copy) @@ -12,9 +12,23 @@ test_eof_SOURCES = test-eof.c test_weof_SOURCES = test-weof.c test_time_SOURCES = test-time.c -regress_SOURCES = regress.c regress.h regress_http.c regress_dns.c \ - regress_rpc.c \ - regress.gen.c regress.gen.h +if BUILD_EVENT_HTTP +REGRESS_HTTP_SRC = regress_http.c +REGRESS_RPC_SRC = regress_rpc.c regress.gen.c regress.gen.h +endif +if BUILD_EVENT_DNS +REGRESS_DNS_SRC = regress_dns.c +endif +if BUILD_EVENT_BEVENTS +REGRESS_BEVENTS_SRC = regress_buffer.c +endif + +regress_SOURCES = \ + $(REGRESS_HTTP_SRC) \ + $(REGRESS_RPC_SRC) \ + $(REGRESS_DNS_SRC) \ + $(REGRESS_BEVENTS_SRC) \ + regress.c regress.h bench_SOURCES = bench.c regress.gen.c regress.gen.h: regress.rpc Index: libevent/test/regress.c =================================================================== --- libevent/test/regress.c (revision 454) +++ libevent/test/regress.c (working copy) @@ -54,13 +54,12 @@ #include #include -#include "event.h" -#include "evutil.h" +#include +#include #include "event-internal.h" #include "log.h" #include "regress.h" -#include "regress.gen.h" int pair[2]; int test_ok; @@ -583,131 +582,6 @@ cleanup_test(); } -void -test_evbuffer(void) { - - struct evbuffer *evb = evbuffer_new(); - setup_test("Testing Evbuffer: "); - - evbuffer_add_printf(evb, "%s/%d", "hello", 1); - - if (EVBUFFER_LENGTH(evb) == 7 && - strcmp((char*)EVBUFFER_DATA(evb), "hello/1") == 0) - test_ok = 1; - - evbuffer_free(evb); - - cleanup_test(); -} - -void -test_evbuffer_find(void) -{ - u_char* p; - char* test1 = "1234567890\r\n"; - char* test2 = "1234567890\r"; -#define EVBUFFER_INITIAL_LENGTH 256 - char test3[EVBUFFER_INITIAL_LENGTH]; - unsigned int i; - struct evbuffer * buf = evbuffer_new(); - - /* make sure evbuffer_find doesn't match past the end of the buffer */ - fprintf(stdout, "Testing evbuffer_find 1: "); - evbuffer_add(buf, (u_char*)test1, strlen(test1)); - evbuffer_drain(buf, strlen(test1)); - evbuffer_add(buf, (u_char*)test2, strlen(test2)); - p = evbuffer_find(buf, (u_char*)"\r\n", 2); - if (p == NULL) { - fprintf(stdout, "OK\n"); - } else { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - /* - * drain the buffer and do another find; in r309 this would - * read past the allocated buffer causing a valgrind error. - */ - fprintf(stdout, "Testing evbuffer_find 2: "); - evbuffer_drain(buf, strlen(test2)); - for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i) - test3[i] = 'a'; - test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x'; - evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH); - p = evbuffer_find(buf, (u_char *)"xy", 2); - if (p == NULL) { - printf("OK\n"); - } else { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - /* simple test for match at end of allocated buffer */ - fprintf(stdout, "Testing evbuffer_find 3: "); - p = evbuffer_find(buf, (u_char *)"ax", 2); - if (p != NULL && strncmp((char*)p, "ax", 2) == 0) { - printf("OK\n"); - } else { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - evbuffer_free(buf); -} - -void -readcb(struct bufferevent *bev, void *arg) -{ - if (EVBUFFER_LENGTH(bev->input) == 8333) { - bufferevent_disable(bev, EV_READ); - test_ok++; - } -} - -void -writecb(struct bufferevent *bev, void *arg) -{ - if (EVBUFFER_LENGTH(bev->output) == 0) - test_ok++; -} - -void -errorcb(struct bufferevent *bev, short what, void *arg) -{ - test_ok = -2; -} - -void -test_bufferevent(void) -{ - struct bufferevent *bev1, *bev2; - char buffer[8333]; - int i; - - setup_test("Bufferevent: "); - - bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL); - bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL); - - bufferevent_disable(bev1, EV_READ); - bufferevent_enable(bev2, EV_READ); - - for (i = 0; i < sizeof(buffer); i++) - buffer[i] = i; - - bufferevent_write(bev1, buffer, sizeof(buffer)); - - event_dispatch(); - - bufferevent_free(bev1); - bufferevent_free(bev2); - - if (test_ok != 2) - test_ok = 0; - - cleanup_test(); -} - struct test_pri_event { struct event ev; int count; @@ -816,8 +690,6 @@ cleanup_test(); } -int decode_int(uint32_t *pnumber, struct evbuffer *evbuf); - void read_once_cb(int fd, short event, void *arg) { @@ -861,176 +733,6 @@ cleanup_test(); } -#define TEST_MAX_INT 6 - -void -evtag_int_test(void) -{ - struct evbuffer *tmp = evbuffer_new(); - uint32_t integers[TEST_MAX_INT] = { - 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 - }; - uint32_t integer; - int i; - - for (i = 0; i < TEST_MAX_INT; i++) { - int oldlen, newlen; - oldlen = EVBUFFER_LENGTH(tmp); - encode_int(tmp, integers[i]); - newlen = EVBUFFER_LENGTH(tmp); - fprintf(stdout, "\t\tencoded 0x%08x with %d bytes\n", - integers[i], newlen - oldlen); - } - - for (i = 0; i < TEST_MAX_INT; i++) { - if (decode_int(&integer, tmp) == -1) { - fprintf(stderr, "decode %d failed", i); - exit(1); - } - if (integer != integers[i]) { - fprintf(stderr, "got %x, wanted %x", - integer, integers[i]); - exit(1); - } - } - - if (EVBUFFER_LENGTH(tmp) != 0) { - fprintf(stderr, "trailing data"); - exit(1); - } - evbuffer_free(tmp); - - fprintf(stdout, "\t%s: OK\n", __func__); -} - -void -evtag_fuzz(void) -{ - u_char buffer[4096]; - struct evbuffer *tmp = evbuffer_new(); - struct timeval tv; - int i, j; - - int not_failed = 0; - for (j = 0; j < 100; j++) { - for (i = 0; i < sizeof(buffer); i++) - buffer[i] = rand(); - evbuffer_drain(tmp, -1); - evbuffer_add(tmp, buffer, sizeof(buffer)); - - if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) - not_failed++; - } - - /* The majority of decodes should fail */ - if (not_failed >= 10) { - fprintf(stderr, "evtag_unmarshal should have failed"); - exit(1); - } - - /* Now insert some corruption into the tag length field */ - evbuffer_drain(tmp, -1); - timerclear(&tv); - tv.tv_sec = 1; - evtag_marshal_timeval(tmp, 0, &tv); - evbuffer_add(tmp, buffer, sizeof(buffer)); - - EVBUFFER_DATA(tmp)[1] = 0xff; - if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) { - fprintf(stderr, "evtag_unmarshal_timeval should have failed"); - exit(1); - } - - evbuffer_free(tmp); - - fprintf(stdout, "\t%s: OK\n", __func__); -} - -void -evtag_test(void) -{ - fprintf(stdout, "Testing Tagging:\n"); - - evtag_init(); - evtag_int_test(); - evtag_fuzz(); - - fprintf(stdout, "OK\n"); -} - -void -rpc_test(void) -{ - struct msg *msg, *msg2; - struct kill *attack; - struct run *run; - struct evbuffer *tmp = evbuffer_new(); - struct timeval tv_start, tv_end; - int i; - - fprintf(stdout, "Testing RPC: "); - - msg = msg_new(); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "phoenix"); - - if (EVTAG_GET(msg, attack, &attack) == -1) { - fprintf(stderr, "Failed to set kill message.\n"); - exit(1); - } - - EVTAG_ASSIGN(attack, weapon, "feather"); - EVTAG_ASSIGN(attack, action, "tickle"); - - gettimeofday(&tv_start, NULL); - for (i = 0; i < 1000; ++i) { - run = EVTAG_ADD(msg, run); - if (run == NULL) { - fprintf(stderr, "Failed to add run message.\n"); - exit(1); - } - EVTAG_ASSIGN(run, how, "very fast but with some data in it"); - } - - if (msg_complete(msg) == -1) { - fprintf(stderr, "Failed to make complete message.\n"); - exit(1); - } - - evtag_marshal_msg(tmp, 0, msg); - - msg2 = msg_new(); - if (evtag_unmarshal_msg(tmp, 0, msg2) == -1) { - fprintf(stderr, "Failed to unmarshal message.\n"); - exit(1); - } - - gettimeofday(&tv_end, NULL); - timersub(&tv_end, &tv_start, &tv_end); - fprintf(stderr, "(%.1f us/add) ", - (float)tv_end.tv_sec/(float)i * 1000000.0 + - tv_end.tv_usec / (float)i); - - if (!EVTAG_HAS(msg2, from_name) || - !EVTAG_HAS(msg2, to_name) || - !EVTAG_HAS(msg2, attack)) { - fprintf(stderr, "Missing data structures.\n"); - exit(1); - } - - if (EVTAG_LEN(msg2, run) != i) { - fprintf(stderr, "Wrong number of run messages.\n"); - exit(1); - } - - msg_free(msg); - msg_free(msg2); - - evbuffer_free(tmp); - - fprintf(stdout, "OK\n"); -} - int main (int argc, char **argv) { @@ -1054,17 +756,6 @@ test_priorities(2); test_priorities(3); - test_evbuffer(); - test_evbuffer_find(); - - test_bufferevent(); - - http_suite(); - - rpc_suite(); - - dns_suite(); - test_simpleread(); test_simplewrite(); @@ -1086,10 +777,20 @@ test_want_only_once(); - evtag_test(); +#ifdef HAVE_EVENT_DNS + dns_suite(); +#endif - rpc_test(); +#ifdef HAVE_EVENT_BEVENTS + buffer_suite(); +#endif +#ifdef HAVE_EVENT_HTTP + http_suite(); + + rpc_suite(); +#endif + #ifndef WIN32 test_signal_dealloc(); test_signal_pipeloss(); Index: libevent/evbuffer.c =================================================================== --- libevent/evbuffer.c (revision 454) +++ libevent/evbuffer.c (working copy) @@ -43,7 +43,8 @@ #include #endif -#include "event.h" +#include +#include /* prototypes */ Index: libevent/configure.in =================================================================== --- libevent/configure.in (revision 454) +++ libevent/configure.in (working copy) @@ -12,6 +12,14 @@ fi dnl Checks for programs. +AC_DEFUN([AC_PROG_F77], [:]) +AC_DEFUN([AC_PROG_FC], [:]) +AC_DEFUN([AC_PROG_CXX], [:]) +AC_DEFUN([AC_PROG_CXXCPP], [:]) +AC_DEFUN([AC_PROG_OBJC], [:]) +AC_DEFUN([AC_PROG_OBJCCPP], [:]) +AC_DEFUN([AC_LIBTOOL_CXX], [:]) +AC_DEFUN([AC_LIBTOOL_F77], [:]) AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S @@ -30,10 +38,21 @@ AC_SUBST(LIBTOOL_DEPS) dnl Check for optional stuff -AC_ARG_WITH(rtsig, - [ --with-rtsig compile with support for real time signals (experimental)], - [usertsig=yes], [usertsig=no]) +AC_DEFUN([ARG_ENABLE], + [AC_ARG_ENABLE([$1], + [AS_HELP_STRING([--enable-$1], [build with support for $3 @<:@default=$2@:>@])], + [use[]$1=$enableval], [use[]$1=$2])]) +AC_DEFUN([ARG_WITH], + [AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1], [build with support for $3 @<:@default=$2@:>@])], + [use[]$1=$enableval], [use[]$1=$2])]) + +ARG_ENABLE([dns], [yes], [dns layer]) +ARG_ENABLE([http], [yes], [http layer]) +ARG_ENABLE([bevents], [yes], [buffer events]) +ARG_WITH([rtsig], [no], [real time signals (experimental)]) + dnl Checks for libraries. AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(resolv, inet_aton) @@ -127,8 +146,17 @@ bwin32=false; AC_MSG_RESULT(no), ) -AM_CONDITIONAL(BUILD_WIN32, test x$bwin32 = xtrue) +AC_DEFUN([BUILD_CHECK], + [ AM_CONDITIONAL(BUILD_[]$1, test x$[]$2 = x[]$3) + if test x$[]$2 = x[]$3; then + AC_DEFINE(HAVE_[]$1, 1, [Define if $4]) + fi ]) +BUILD_CHECK([WIN32], [bwin32], [true], [win32 support is enabled]) +BUILD_CHECK([EVENT_DNS], [usedns], [yes], [dns support is enabled]) +BUILD_CHECK([EVENT_HTTP], [usehttp], [yes], [http support is enabled]) +BUILD_CHECK([EVENT_BEVENTS], [usebevents], [yes], [buffer events support is enabled]) + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE Index: libevent/buffer.c =================================================================== --- libevent/buffer.c (revision 454) +++ libevent/buffer.c (working copy) @@ -61,7 +61,8 @@ #include #endif -#include "event.h" +#include +#include struct evbuffer * evbuffer_new(void) Index: libevent/evbuffer.h =================================================================== --- libevent/evbuffer.h (revision 0) +++ libevent/evbuffer.h (revision 0) @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2000-2004 Niels Provos + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ +#ifndef _EVBUFFER_H_ +#define _EVBUFFER_H_ + +/** @file evbuffer.h + + Basic support for dealing with buffer events, marshalling data, etc. + + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* These functions deal with buffering input and output */ + +struct evbuffer { + u_char *buffer; + u_char *orig_buffer; + + size_t misalign; + size_t totallen; + size_t off; + + void (*cb)(struct evbuffer *, size_t, size_t, void *); + void *cbarg; +}; + +/* Just for error reporting - use other constants otherwise */ +#define EVBUFFER_READ 0x01 +#define EVBUFFER_WRITE 0x02 +#define EVBUFFER_EOF 0x10 +#define EVBUFFER_ERROR 0x20 +#define EVBUFFER_TIMEOUT 0x40 + +struct bufferevent; +typedef void (*evbuffercb)(struct bufferevent *, void *); +typedef void (*everrorcb)(struct bufferevent *, short what, void *); + +struct event_watermark { + size_t low; + size_t high; +}; + +struct bufferevent { + struct event ev_read; + struct event ev_write; + + struct evbuffer *input; + struct evbuffer *output; + + struct event_watermark wm_read; + struct event_watermark wm_write; + + evbuffercb readcb; + evbuffercb writecb; + everrorcb errorcb; + void *cbarg; + + int timeout_read; /* in seconds */ + int timeout_write; /* in seconds */ + + short enabled; /* events that are currently enabled */ +}; + + +/** + Create a new bufferevent. + + libevent provides an abstraction on top of the regular event callbacks. + This abstraction is called a buffered event. A buffered event provides + input and output buffers that get filled and drained automatically. The + user of a buffered event no longer deals directly with the I/O, but + instead is reading from input and writing to output buffers. + + Once initialized, the bufferevent structure can be used repeatedly with + bufferevent_enable() and bufferevent_disable(). + + When read enabled the bufferevent will try to read from the file descriptor + and call the read callback. The write callback is executed whenever the + output buffer is drained below the write low watermark, which is 0 by + default. + + If multiple bases are in use, bufferevent_base_set() must be called before + enabling the bufferevent for the first time. + + @param fd the file descriptor from which data is read and written to. + This file descriptor is not allowed to be a pipe(2). + @param readcb callback to invoke when there is data to be read, or NULL if + no callback is desired + @param writecb callback to invoke when the file descriptor is ready for + writing, or NULL if no callback is desired + @param errorcb callback to invoke when there is an error on the file + descriptor + @param cbarg an argument that will be supplied to each of the callbacks + (readcb, writecb, and errorcb) + @return a pointer to a newly allocated bufferevent struct, or NULL if an + error occurred + @see bufferevent_base_set(), bufferevent_free() + */ +struct bufferevent *bufferevent_new(int fd, + evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); + + +/** + Assign a bufferevent to a specific event_base. + + @param base an event_base returned by event_init() + @param bufev a bufferevent struct returned by bufferevent_new() + @return 0 if successful, or -1 if an error occurred + @see bufferevent_new() + */ +int bufferevent_base_set(struct event_base *base, struct bufferevent *bufev); + + +/** + Assign a priority to a bufferevent. + + @param bufev a bufferevent struct + @param pri the priority to be assigned + @return 0 if successful, or -1 if an error occurred + */ +int bufferevent_priority_set(struct bufferevent *bufev, int pri); + + +/** + Deallocate the storage associated with a bufferevent structure. + + @param bufev the bufferevent structure to be freed. + */ +void bufferevent_free(struct bufferevent *bufev); + + +/** + Write data to a bufferevent buffer. + + The bufferevent_write() function can be used to write data to the file + descriptor. The data is appended to the output buffer and written to the + descriptor automatically as it becomes available for writing. + + @param bufev the bufferevent to be written to + @param data a pointer to the data to be written + @param size the length of the data, in bytes + @return 0 if successful, or -1 if an error occurred + @see bufferevent_write_buffer() + */ +int bufferevent_write(struct bufferevent *bufev, void *data, size_t size); + + +/** + Write data from an evbuffer to a bufferevent buffer. + + @param bufev the bufferevent to be written to + @param buf the evbuffer to be written + @return 0 if successful, or -1 if an error occurred + @see bufferevent_write() + */ +int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); + + +/** + Read data from a bufferevent buffer. + + The bufferevent_read() function is used to read data from the input buffer. + + @param bufev the bufferevent to be read from + @param data pointer to a buffer that will store the data + @param size the size of the data buffer, in bytes + @return the amount of data read, in bytes. + */ +size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); + +/** + Enable a bufferevent. + + @param bufev the bufferevent to be enabled + @param event any combination of EV_READ | EV_WRITE. + @return 0 if successful, or -1 if an error occurred + @see bufferevent_disable() + */ +int bufferevent_enable(struct bufferevent *bufev, short event); + + +/** + Disable a bufferevent. + + @param bufev the bufferevent to be disabled + @param event any combination of EV_READ | EV_WRITE. + @return 0 if successful, or -1 if an error occurred + @see bufferevent_enable() + */ +int bufferevent_disable(struct bufferevent *bufev, short event); + + +/** + Set the read and write timeout for a buffered event. + + @param bufev the bufferevent to be modified + @param timeout_read the read timeout + @param timeout_write the write timeout + */ +void bufferevent_settimeout(struct bufferevent *bufev, + int timeout_read, int timeout_write); + + +#define EVBUFFER_LENGTH(x) (x)->off +#define EVBUFFER_DATA(x) (x)->buffer +#define EVBUFFER_INPUT(x) (x)->input +#define EVBUFFER_OUTPUT(x) (x)->output + + +/** + Allocate storage for a new evbuffer. + + @return a pointer to a newly allocated evbuffer struct, or NULL if an error + occurred + */ +struct evbuffer *evbuffer_new(void); + + +/** + Deallocate storage for an evbuffer. + + @param pointer to the evbuffer to be freed + */ +void evbuffer_free(struct evbuffer *); + + +/** + Expands the available space in an event buffer. + + Expands the available space in the event buffer to at least datlen + + @param buf the event buffer to be expanded + @param datlen the new minimum length requirement + @return 0 if successful, or -1 if an error occurred +*/ +int evbuffer_expand(struct evbuffer *, size_t); + + +/** + Append data to the end of an evbuffer. + + @param buf the event buffer to be appended to + @param data pointer to the beginning of the data buffer + @param datlen the number of bytes to be copied from the data buffer + */ +int evbuffer_add(struct evbuffer *, const void *, size_t); + + + +/** + Read data from an event buffer and drain the bytes read. + + @param buf the event buffer to be read from + @param data the destination buffer to store the result + @param datlen the maximum size of the destination buffer + @return the number of bytes read + */ +int evbuffer_remove(struct evbuffer *, void *, size_t); + + +/** + * Read a single line from an event buffer. + * + * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. + * The returned buffer needs to be freed by the caller. + * + * @param buffer the evbuffer to read from + * @return pointer to a single line, or NULL if an error occurred + */ +char *evbuffer_readline(struct evbuffer *); + + +/** + Move data from one evbuffer into another evbuffer. + + This is a destructive add. The data from one buffer moves into + the other buffer. The destination buffer is expanded as needed. + + @param outbuf the output buffer + @param inbuf the input buffer + @return 0 if successful, or -1 if an error occurred + */ +int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); + + +/** + Append a formatted string to the end of an evbuffer. + + @param buf the evbuffer that will be appended to + @param fmt a format string + @param ... arguments that will be passed to printf(3) + @return 0 if successful, or -1 if an error occurred + */ +int evbuffer_add_printf(struct evbuffer *, const char *fmt, ...); + + +/** + Append a va_list formatted string to the end of an evbuffer. + + @param buf the evbuffer that will be appended to + @param fmt a format string + @param ap a varargs va_list argument array that will be passed to vprintf(3) + @return 0 if successful, or -1 if an error occurred + */ +int evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap); + + +/** + Remove a specified number of bytes data from the beginning of an evbuffer. + + @param buf the evbuffer to be drained + @param len the number of bytes to drain from the beginning of the buffer + @return 0 if successful, or -1 if an error occurred + */ +void evbuffer_drain(struct evbuffer *, size_t); + + +/** + Write the contents of an evbuffer to a file descriptor. + + The evbuffer will be drained after the bytes have been successfully written. + + @param buffer the evbuffer to be written and drained + @param fd the file descriptor to be written to + @return the number of bytes written, or -1 if an error occurred + @see evbuffer_read() + */ +int evbuffer_write(struct evbuffer *, int); + + +/** + Read from a file descriptor and store the result in an evbuffer. + + @param buf the evbuffer to store the result + @param fd the file descriptor to read from + @param howmuch the number of bytes to be read + @return the number of bytes read, or -1 if an error occurred + @see evbuffer_write() + */ +int evbuffer_read(struct evbuffer *, int, int); + + +/** + Find a string within an evbuffer. + + @param buffer the evbuffer to be searched + @param what the string to be searched for + @param len the length of the search string + @return a pointer to the beginning of the search string, or NULL if the search failed. + */ +u_char *evbuffer_find(struct evbuffer *, const u_char *, size_t); + +/** + Set a callback to invoke when the evbuffer is modified. + + @param buffer the evbuffer to be monitored + @param cb the callback function to invoke when the evbuffer is modified + @param cbarg an argument to be provided to the callback function + */ +void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *); + +/* + * Marshaling tagged data - We assume that all tags are inserted in their + * numeric order - so that unknown tags will always be higher than the + * known ones - and we can just ignore the end of an event buffer. + */ + +void evtag_init(void); + +void evtag_marshal(struct evbuffer *evbuf, uint8_t tag, const void *data, + uint32_t len); + +/** + Encode an integer and store it in an evbuffer. + + We encode integer's by nibbles; the first nibble contains the number + of significant nibbles - 1; this allows us to encode up to 64-bit + integers. This function is byte-order independent. + + @param evbuf evbuffer to store the encoded number + @param number a 32-bit integer + */ +void encode_int(struct evbuffer *evbuf, uint32_t number); + +void evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer); + +void evtag_marshal_string(struct evbuffer *buf, uint8_t tag, + const char *string); + +void evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag, + struct timeval *tv); + +void evtag_test(void); + +int evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst); +int evtag_peek(struct evbuffer *evbuf, uint8_t *ptag); +int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength); +int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength); +int evtag_consume(struct evbuffer *evbuf); + +int evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag, + uint32_t *pinteger); + +int evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data, + size_t len); + +int evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag, + char **pstring); + +int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag, + struct timeval *ptv); + +#ifdef __cplusplus +} +#endif + +#endif /* _EVBUFFER_H_ */ Index: libevent/event.h =================================================================== --- libevent/event.h (revision 454) +++ libevent/event.h (working copy) @@ -633,407 +633,6 @@ */ int event_priority_set(struct event *, int); - -/* These functions deal with buffering input and output */ - -struct evbuffer { - u_char *buffer; - u_char *orig_buffer; - - size_t misalign; - size_t totallen; - size_t off; - - void (*cb)(struct evbuffer *, size_t, size_t, void *); - void *cbarg; -}; - -/* Just for error reporting - use other constants otherwise */ -#define EVBUFFER_READ 0x01 -#define EVBUFFER_WRITE 0x02 -#define EVBUFFER_EOF 0x10 -#define EVBUFFER_ERROR 0x20 -#define EVBUFFER_TIMEOUT 0x40 - -struct bufferevent; -typedef void (*evbuffercb)(struct bufferevent *, void *); -typedef void (*everrorcb)(struct bufferevent *, short what, void *); - -struct event_watermark { - size_t low; - size_t high; -}; - -struct bufferevent { - struct event ev_read; - struct event ev_write; - - struct evbuffer *input; - struct evbuffer *output; - - struct event_watermark wm_read; - struct event_watermark wm_write; - - evbuffercb readcb; - evbuffercb writecb; - everrorcb errorcb; - void *cbarg; - - int timeout_read; /* in seconds */ - int timeout_write; /* in seconds */ - - short enabled; /* events that are currently enabled */ -}; - - -/** - Create a new bufferevent. - - libevent provides an abstraction on top of the regular event callbacks. - This abstraction is called a buffered event. A buffered event provides - input and output buffers that get filled and drained automatically. The - user of a buffered event no longer deals directly with the I/O, but - instead is reading from input and writing to output buffers. - - Once initialized, the bufferevent structure can be used repeatedly with - bufferevent_enable() and bufferevent_disable(). - - When read enabled the bufferevent will try to read from the file descriptor - and call the read callback. The write callback is executed whenever the - output buffer is drained below the write low watermark, which is 0 by - default. - - If multiple bases are in use, bufferevent_base_set() must be called before - enabling the bufferevent for the first time. - - @param fd the file descriptor from which data is read and written to. - This file descriptor is not allowed to be a pipe(2). - @param readcb callback to invoke when there is data to be read, or NULL if - no callback is desired - @param writecb callback to invoke when the file descriptor is ready for - writing, or NULL if no callback is desired - @param errorcb callback to invoke when there is an error on the file - descriptor - @param cbarg an argument that will be supplied to each of the callbacks - (readcb, writecb, and errorcb) - @return a pointer to a newly allocated bufferevent struct, or NULL if an - error occurred - @see bufferevent_base_set(), bufferevent_free() - */ -struct bufferevent *bufferevent_new(int fd, - evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); - - -/** - Assign a bufferevent to a specific event_base. - - @param base an event_base returned by event_init() - @param bufev a bufferevent struct returned by bufferevent_new() - @return 0 if successful, or -1 if an error occurred - @see bufferevent_new() - */ -int bufferevent_base_set(struct event_base *base, struct bufferevent *bufev); - - -/** - Assign a priority to a bufferevent. - - @param bufev a bufferevent struct - @param pri the priority to be assigned - @return 0 if successful, or -1 if an error occurred - */ -int bufferevent_priority_set(struct bufferevent *bufev, int pri); - - -/** - Deallocate the storage associated with a bufferevent structure. - - @param bufev the bufferevent structure to be freed. - */ -void bufferevent_free(struct bufferevent *bufev); - - -/** - Write data to a bufferevent buffer. - - The bufferevent_write() function can be used to write data to the file - descriptor. The data is appended to the output buffer and written to the - descriptor automatically as it becomes available for writing. - - @param bufev the bufferevent to be written to - @param data a pointer to the data to be written - @param size the length of the data, in bytes - @return 0 if successful, or -1 if an error occurred - @see bufferevent_write_buffer() - */ -int bufferevent_write(struct bufferevent *bufev, void *data, size_t size); - - -/** - Write data from an evbuffer to a bufferevent buffer. - - @param bufev the bufferevent to be written to - @param buf the evbuffer to be written - @return 0 if successful, or -1 if an error occurred - @see bufferevent_write() - */ -int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); - - -/** - Read data from a bufferevent buffer. - - The bufferevent_read() function is used to read data from the input buffer. - - @param bufev the bufferevent to be read from - @param data pointer to a buffer that will store the data - @param size the size of the data buffer, in bytes - @return the amount of data read, in bytes. - */ -size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); - -/** - Enable a bufferevent. - - @param bufev the bufferevent to be enabled - @param event any combination of EV_READ | EV_WRITE. - @return 0 if successful, or -1 if an error occurred - @see bufferevent_disable() - */ -int bufferevent_enable(struct bufferevent *bufev, short event); - - -/** - Disable a bufferevent. - - @param bufev the bufferevent to be disabled - @param event any combination of EV_READ | EV_WRITE. - @return 0 if successful, or -1 if an error occurred - @see bufferevent_enable() - */ -int bufferevent_disable(struct bufferevent *bufev, short event); - - -/** - Set the read and write timeout for a buffered event. - - @param bufev the bufferevent to be modified - @param timeout_read the read timeout - @param timeout_write the write timeout - */ -void bufferevent_settimeout(struct bufferevent *bufev, - int timeout_read, int timeout_write); - - -#define EVBUFFER_LENGTH(x) (x)->off -#define EVBUFFER_DATA(x) (x)->buffer -#define EVBUFFER_INPUT(x) (x)->input -#define EVBUFFER_OUTPUT(x) (x)->output - - -/** - Allocate storage for a new evbuffer. - - @return a pointer to a newly allocated evbuffer struct, or NULL if an error - occurred - */ -struct evbuffer *evbuffer_new(void); - - -/** - Deallocate storage for an evbuffer. - - @param pointer to the evbuffer to be freed - */ -void evbuffer_free(struct evbuffer *); - - -/** - Expands the available space in an event buffer. - - Expands the available space in the event buffer to at least datlen - - @param buf the event buffer to be expanded - @param datlen the new minimum length requirement - @return 0 if successful, or -1 if an error occurred -*/ -int evbuffer_expand(struct evbuffer *, size_t); - - -/** - Append data to the end of an evbuffer. - - @param buf the event buffer to be appended to - @param data pointer to the beginning of the data buffer - @param datlen the number of bytes to be copied from the data buffer - */ -int evbuffer_add(struct evbuffer *, const void *, size_t); - - - -/** - Read data from an event buffer and drain the bytes read. - - @param buf the event buffer to be read from - @param data the destination buffer to store the result - @param datlen the maximum size of the destination buffer - @return the number of bytes read - */ -int evbuffer_remove(struct evbuffer *, void *, size_t); - - -/** - * Read a single line from an event buffer. - * - * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. - * The returned buffer needs to be freed by the caller. - * - * @param buffer the evbuffer to read from - * @return pointer to a single line, or NULL if an error occurred - */ -char *evbuffer_readline(struct evbuffer *); - - -/** - Move data from one evbuffer into another evbuffer. - - This is a destructive add. The data from one buffer moves into - the other buffer. The destination buffer is expanded as needed. - - @param outbuf the output buffer - @param inbuf the input buffer - @return 0 if successful, or -1 if an error occurred - */ -int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); - - -/** - Append a formatted string to the end of an evbuffer. - - @param buf the evbuffer that will be appended to - @param fmt a format string - @param ... arguments that will be passed to printf(3) - @return 0 if successful, or -1 if an error occurred - */ -int evbuffer_add_printf(struct evbuffer *, const char *fmt, ...); - - -/** - Append a va_list formatted string to the end of an evbuffer. - - @param buf the evbuffer that will be appended to - @param fmt a format string - @param ap a varargs va_list argument array that will be passed to vprintf(3) - @return 0 if successful, or -1 if an error occurred - */ -int evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap); - - -/** - Remove a specified number of bytes data from the beginning of an evbuffer. - - @param buf the evbuffer to be drained - @param len the number of bytes to drain from the beginning of the buffer - @return 0 if successful, or -1 if an error occurred - */ -void evbuffer_drain(struct evbuffer *, size_t); - - -/** - Write the contents of an evbuffer to a file descriptor. - - The evbuffer will be drained after the bytes have been successfully written. - - @param buffer the evbuffer to be written and drained - @param fd the file descriptor to be written to - @return the number of bytes written, or -1 if an error occurred - @see evbuffer_read() - */ -int evbuffer_write(struct evbuffer *, int); - - -/** - Read from a file descriptor and store the result in an evbuffer. - - @param buf the evbuffer to store the result - @param fd the file descriptor to read from - @param howmuch the number of bytes to be read - @return the number of bytes read, or -1 if an error occurred - @see evbuffer_write() - */ -int evbuffer_read(struct evbuffer *, int, int); - - -/** - Find a string within an evbuffer. - - @param buffer the evbuffer to be searched - @param what the string to be searched for - @param len the length of the search string - @return a pointer to the beginning of the search string, or NULL if the search failed. - */ -u_char *evbuffer_find(struct evbuffer *, const u_char *, size_t); - -/** - Set a callback to invoke when the evbuffer is modified. - - @param buffer the evbuffer to be monitored - @param cb the callback function to invoke when the evbuffer is modified - @param cbarg an argument to be provided to the callback function - */ -void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *); - -/* - * Marshaling tagged data - We assume that all tags are inserted in their - * numeric order - so that unknown tags will always be higher than the - * known ones - and we can just ignore the end of an event buffer. - */ - -void evtag_init(void); - -void evtag_marshal(struct evbuffer *evbuf, uint8_t tag, const void *data, - uint32_t len); - -/** - Encode an integer and store it in an evbuffer. - - We encode integer's by nibbles; the first nibble contains the number - of significant nibbles - 1; this allows us to encode up to 64-bit - integers. This function is byte-order independent. - - @param evbuf evbuffer to store the encoded number - @param number a 32-bit integer - */ -void encode_int(struct evbuffer *evbuf, uint32_t number); - -void evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer); - -void evtag_marshal_string(struct evbuffer *buf, uint8_t tag, - const char *string); - -void evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag, - struct timeval *tv); - -void evtag_test(void); - -int evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst); -int evtag_peek(struct evbuffer *evbuf, uint8_t *ptag); -int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength); -int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength); -int evtag_consume(struct evbuffer *evbuf); - -int evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag, - uint32_t *pinteger); - -int evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data, - size_t len); - -int evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag, - char **pstring); - -int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag, - struct timeval *ptv); - #ifdef __cplusplus } #endif Index: libevent/Makefile.am =================================================================== --- libevent/Makefile.am (revision 454) +++ libevent/Makefile.am (working copy) @@ -4,7 +4,7 @@ bin_SCRIPTS = event_rpcgen.py EXTRA_DIST = acconfig.h event.h event-internal.h log.h evsignal.h evdns.3 \ - evrpc.h evrpc-internal.h \ + evrpc.h evrpc-internal.h evbuffer.h \ event.3 \ kqueue.c epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c \ evport.c devpoll.c event_rpcgen.py \ @@ -39,16 +39,44 @@ endif -libevent_la_SOURCES = event.c buffer.c evbuffer.c log.c event_tagging.c \ - http.c evhttp.h http-internal.h evdns.c evdns.h evrpc.c evutil.c \ - strlcpy.c \ - strlcpy-internal.h evrpc.h evrpc-internal.h strlcpy-internal.h \ - $(SYS_SRC) +if BUILD_EVENT_HTTP +HTTP_SRC = http.c evrpc.c +HTTP_INCLUDES = evhttp.h evrpc.h +HTTP_INCLUDES_INT = http-internal.h evrpc-internal.h +endif + +if BUILD_EVENT_DNS +DNS_SRC = evdns.c +DNS_INCLUDES = evdns.h +endif + +if BUILD_EVENT_BEVENTS +BEVENTS_SRC = buffer.c evbuffer.c event_tagging.c +BEVENTS_INCLUDES = +endif + +EVENT_SRC = event.c log.c evutil.c strlcpy.c +EVENT_INCLUDES = event.h +EVENT_INCLUDES_INT = event-internal.h strlcpy-internal.h evutil.h + +include_HEADERS = \ + $(HTTP_INCLUDES) \ + $(DNS_INCLUDES) \ + $(BEVENTS_INCLUDES) \ + $(EVENT_INCLUDES) + +libevent_la_SOURCES = \ + $(HTTP_SRC) \ + $(DNS_SRC) \ + $(BEVENTS_SRC) \ + $(SYS_SRC) \ + $(EVENT_SRC) \ + $(EVENT_INCLUDES_INT) \ + $(HTTP_INCLUDES_INT) \ + $(include_HEADERS) libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS) libevent_la_LDFLAGS = -release @VERSION@ -version-info 1:3:0 -include_HEADERS = event.h evhttp.h evdns.h evrpc.h evutil.h - INCLUDES = -I$(srcdir)/compat $(SYS_INCLUDES) man_MANS = event.3 evdns.3