head 1.29; access; symbols LMTP2NNTP_1_4_1:1.28 LMTP2NNTP_1_4_0:1.28 SIO_0_9_3:1.28 SA_1_2_6:1.28 SA_1_2_5:1.28 SA_1_2_4:1.28 SA_1_2_3:1.28 LMTP2NNTP_1_3_0:1.27 LMTP2NNTP_1_3b2:1.27 SA_1_2_2:1.27 LMTP2NNTP_1_3b1:1.27 SA_1_2_1:1.27 LMTP2NNTP_1_3a3:1.27 LMTP2NNTP_1_3a2:1.27 LMTP2NNTP_1_3a1:1.27 SA_1_2_0:1.27 SA_1_1_0:1.26 SIO_0_9_2:1.26 SIO_0_9_1:1.26 LMTP2NNTP_1_2_0:1.26 LMTP2NNTP_1_2b4:1.26 LMTP2NNTP_1_2b3:1.26 LMTP2NNTP_1_2b2:1.26 LMTP2NNTP_1_2b1:1.24 LMTP2NNTP_1_2a8:1.24 SIO_0_9_0:1.24 LMTP2NNTP_1_2a7:1.24 SA_1_0_5:1.24 SA_1_0_4:1.23 SA_1_0_3:1.23 SA_1_0_2:1.21 SA_1_0_1:1.21 SA_1_0_0:1.21 SA_0_9_3:1.20 SA_0_9_2:1.16 LMTP2NNTP_1_2a6:1.16 LMTP2NNTP_1_2a5:1.16 SA_0_9_1:1.16 LMTP2NNTP_1_2a4:1.15 LMTP2NNTP_1_2a3:1.15 SA_0_9_0:1.15 LMTP2NNTP_1_2a1:1.12 LMTP2NNTP_1_1_1:1.12 LMTP2NNTP_1_1_0:1.12 LMTP2NNTP_1_1b4:1.12 LMTP2NNTP_1_1b3:1.12 LMTP2NNTP_1_1b2:1.9 LMTP2NNTP_1_1b1:1.9; locks; strict; comment @ * @; 1.29 date 2006.06.10.10.00.17; author rse; state Exp; branches; next 1.28; commitid JpcJR7gM5uNpwrAr; 1.28 date 2005.01.24.15.10.09; author rse; state Exp; branches; next 1.27; 1.27 date 2004.04.02.18.21.07; author rse; state Exp; branches; next 1.26; 1.26 date 2003.02.09.14.43.28; author rse; state Exp; branches; next 1.25; 1.25 date 2003.02.07.20.47.51; author rse; state Exp; branches; next 1.24; 1.24 date 2003.01.31.18.34.06; author rse; state Exp; branches; next 1.23; 1.23 date 2003.01.06.13.11.23; author rse; state Exp; branches; next 1.22; 1.22 date 2002.12.31.22.08.57; author rse; state Exp; branches; next 1.21; 1.21 date 2002.10.30.20.22.06; author rse; state Exp; branches; next 1.20; 1.20 date 2002.10.30.19.09.35; author rse; state Exp; branches; next 1.19; 1.19 date 2002.10.30.18.46.22; author rse; state Exp; branches; next 1.18; 1.18 date 2002.10.30.09.41.51; author rse; state Exp; branches; next 1.17; 1.17 date 2002.10.26.15.45.32; author rse; state Exp; branches; next 1.16; 1.16 date 2002.03.15.10.47.36; author rse; state Exp; branches; next 1.15; 1.15 date 2002.01.31.21.17.50; author rse; state Exp; branches; next 1.14; 1.14 date 2002.01.30.16.43.00; author rse; state Exp; branches; next 1.13; 1.13 date 2002.01.02.12.43.50; author rse; state Exp; branches; next 1.12; 1.12 date 2001.10.31.20.16.10; author rse; state Exp; branches; next 1.11; 1.11 date 2001.10.31.20.09.00; author rse; state Exp; branches; next 1.10; 1.10 date 2001.10.31.19.28.49; author rse; state Exp; branches; next 1.9; 1.9 date 2001.10.10.15.50.31; author rse; state Exp; branches; next 1.8; 1.8 date 2001.10.10.15.01.56; author rse; state Exp; branches; next 1.7; 1.7 date 2001.10.08.15.08.46; author rse; state Exp; branches; next 1.6; 1.6 date 2001.10.08.10.03.54; author rse; state Exp; branches; next 1.5; 1.5 date 2001.10.05.20.52.15; author rse; state Exp; branches; next 1.4; 1.4 date 2001.10.05.12.56.06; author rse; state Exp; branches; next 1.3; 1.3 date 2001.10.05.11.40.22; author rse; state Exp; branches; next 1.2; 1.2 date 2001.10.04.11.04.59; author rse; state Exp; branches; next 1.1; 1.1 date 2001.10.02.18.37.19; author rse; state Exp; branches; next ; desc @@ 1.29 log @Adjusted all copyright messages for year 2006 @ text @/* ** OSSP sa - Socket Abstraction ** Copyright (c) 2001-2006 Ralf S. Engelschall ** Copyright (c) 2001-2006 The OSSP Project ** Copyright (c) 2001-2005 Cable & Wireless ** ** This file is part of OSSP sa, a socket abstraction library which ** can be found at http://www.ossp.org/pkg/lib/sa/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** 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. ** ** sa_test.c: socket abstraction library test suite */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "ts.h" #include "sa.h" /* test: address import/export */ TS_TEST(test_saa_impexp) { sa_addr_t *saa; sa_rc_t rv; char *cp; int i; struct { char *in; sa_rc_t rv; char *out; char *out_alt; } table[] = { /* positive tests */ { "inet://0.0.0.0:0", SA_OK, "inet://0.0.0.0:0", NULL }, { "inet://127.0.0.1:514", SA_OK, "inet://127.0.0.1:514", NULL }, { "inet://localhost:syslog#udp", SA_OK, "inet://127.0.0.1:514", "inet://[::1]:514" }, { "inet://localhost:smtp", SA_OK, "inet://127.0.0.1:25", "inet://[::1]:25" }, { "unix:/tmp/socket", SA_OK, "unix:/tmp/socket", NULL }, /* negative tests */ { "inet:", SA_ERR_ARG, NULL, NULL }, { "inet://1.2.3.4.5:0", SA_ERR_ARG, NULL, NULL }, { "inet://just-hostname", SA_ERR_ARG, NULL, NULL }, { "unix:", SA_ERR_ARG, NULL, NULL } }; ts_test_check(TS_CTX, "sa_addr_create"); if ((rv = sa_addr_create(&saa)) != SA_OK) ts_test_fail(TS_CTX, "sa_addr_create -> %d[%s] (expected %d[%s])", rv, sa_error(rv), SA_OK, sa_error(SA_OK)); for (i = 0; i < (int)(sizeof(table)/sizeof(table[0])); i++) { ts_test_check(TS_CTX, "sa_addr_u2a(\"%s\")", table[i].in); if ((rv = sa_addr_u2a(saa, table[i].in)) != table[i].rv) ts_test_fail(TS_CTX, "sa_addr_a2u -> %d[%s] (expected %d[%s])", rv, sa_error(rv), table[i].rv, sa_error(table[i].rv)); ts_test_check(TS_CTX, "sa_addr_a2u"); if ((rv = sa_addr_a2u(saa, &cp)) != SA_OK) { ts_test_fail(TS_CTX, "sa_addr_u2a -> %d[%s] (expected %d[%s])", rv, sa_error(rv), SA_OK, sa_error(SA_OK)); continue; } if (table[i].rv == SA_OK) { if (table[i].out_alt != NULL) { if (strcmp(cp, table[i].out) != 0 && strcmp(cp, table[i].out_alt) != 0) ts_test_fail(TS_CTX, "sa_addr_a2u -> \"%s\" (expected \"%s\" or \"%s\")", cp, table[i].out, table[i].out_alt); } else { if (strcmp(cp, table[i].out) != 0) ts_test_fail(TS_CTX, "sa_addr_a2u -> \"%s\" (expected \"%s\")", cp, table[i].out); } } free(cp); } ts_test_check(TS_CTX, "sa_addr_destroy"); if ((rv = sa_addr_destroy(saa)) != SA_OK) ts_test_fail(TS_CTX, "sa_addr_destroy -> %d[%s] (expected %d[%s])", rv, sa_error(rv), SA_OK, sa_error(SA_OK)); } /* test: address matching */ TS_TEST(test_saa_match) { sa_addr_t *saa1; sa_addr_t *saa2; sa_rc_t rv; int i; struct { char *in; char *acl; int prefixlen; sa_rc_t rv; } table[] = { { "unix:/foo/bar", "unix:/foo/bar", -1, SA_OK }, { "unix:/foo/bar", "unix:/foo/bar", 0, SA_OK }, { "unix:/foo/bar", "unix:/foo", 4, SA_OK }, { "unix:/foo/bar", "unix:/foo/quux", 4, SA_OK }, { "unix:/foo/bar", "unix:/baz/quux", -1, SA_ERR_MTC }, { "inet://0.0.0.0:0", "inet://0.0.0.0:0", 0, SA_OK }, { "inet://127.0.0.1:514", "inet://127.0.0.1:514", -1, SA_OK }, { "inet://127.0.0.1:514", "inet://0.0.0.0:0", 0, SA_OK }, { "inet://127.0.0.1:514", "inet://12.34.56.78:9", 0, SA_OK }, { "inet://127.0.0.1:514", "inet://12.34.56.78:9", -1, SA_ERR_MTC }, { "inet://127.0.0.1:514", "inet://127.0.0.0:0", 24, SA_OK }, { "inet://127.0.0.1:514", "inet://127.0.0.0:0", 32, SA_ERR_MTC }, { "inet://141.1.23.20:25", "inet://141.1.23.40:25", 32, SA_ERR_MTC }, { "inet://141.1.23.20:25", "inet://141.1.23.40:25", 24, SA_OK } }; sa_addr_create(&saa1); sa_addr_create(&saa2); for (i = 0; i < (int)(sizeof(table)/sizeof(table[0])); i++) { if ((rv = sa_addr_u2a(saa1, table[i].in)) != SA_OK) continue; if ((rv = sa_addr_u2a(saa2, table[i].acl)) != SA_OK) continue; ts_test_check(TS_CTX, "sa_addr_match(\"%s\", \"%s\", %d)", table[i].in, table[i].acl, table[i].prefixlen); if ((rv = sa_addr_match(saa1, saa2, table[i].prefixlen)) != table[i].rv) ts_test_fail(TS_CTX, "sa_addr_match -> %d[%s] (expected %d[%s])", rv, sa_error(rv), table[i].rv, sa_error(table[i].rv)); } sa_addr_destroy(saa1); sa_addr_destroy(saa2); } #define ex(proc, cmd) \ do { \ sa_rc_t __rv; \ ts_test_check(TS_CTX, "%s: %s", #proc, #cmd); \ if ((__rv = (cmd)) != SA_OK) { \ if (__rv == SA_ERR_SYS) \ ts_test_fail(TS_CTX, "%s -> error: %s (rc=%d) (system: %s)", \ #cmd, sa_error(__rv), __rv, strerror(errno)); \ else \ ts_test_fail(TS_CTX, "%s -> error: %s (rc=%d)", \ #cmd, sa_error(__rv), __rv); \ } \ } while (0) /* test: client/server stream communication */ TS_TEST(test_sa_stream) { sa_t *sa_clt; sa_t *sa_srv; sa_addr_t *saa_srv; sa_addr_t *saa_clt; pid_t pid_srv; sa_t *sa_cld; sa_addr_t *saa_cld; char buf_srv[1024]; char buf_clt[1024]; size_t l; #define MSG_TCP_SRV_WELCOME "Welcome client\n" #define MSG_TCP_CLT_WELCOME "Welcome server\n" #define MSG_TCP_SRV_GOODBYE "Goodbye client\n" #define MSG_TCP_CLT_GOODBYE "Goodbye server\n" if ((pid_srv = fork()) == 0) { /* ** SERVER */ /* create server socket */ ex(SRV, sa_create(&sa_srv)); ex(SRV, sa_option(sa_srv, SA_OPTION_REUSEADDR, 1)); ex(SRV, sa_option(sa_srv, SA_OPTION_REUSEPORT, 1)); ex(SRV, sa_timeout(sa_srv, SA_TIMEOUT_ALL, 10, 0)); /* bind socket to local port */ ex(SRV, sa_addr_create(&saa_srv)); ex(SRV, sa_addr_u2a(saa_srv, "inet://127.0.0.1:12345#tcp")); ex(SRV, sa_bind(sa_srv, saa_srv)); ex(SRV, sa_addr_destroy(saa_srv)); /* receive client connection */ ex(SRV, sa_listen(sa_srv, 10)); ex(SRV, sa_accept(sa_srv, &saa_cld, &sa_cld)); /* communicate with client */ ex(SRV, sa_writef(sa_cld, "%s", MSG_TCP_SRV_WELCOME)); ex(SRV, sa_readln(sa_cld, buf_srv, sizeof(buf_srv), &l)); if (strcmp(buf_srv, MSG_TCP_CLT_WELCOME) != 0) ts_test_fail(TS_CTX, "server: got \"%s\", expected \"%s\"", buf_srv, MSG_TCP_CLT_WELCOME); ex(SRV, sa_writef(sa_cld, "%s", MSG_TCP_SRV_GOODBYE)); ex(SRV, sa_shutdown(sa_cld, "w")); ex(SRV, sa_readln(sa_cld, buf_srv, sizeof(buf_srv), &l)); if (strcmp(buf_srv, MSG_TCP_CLT_GOODBYE) != 0) ts_test_fail(TS_CTX, "server: got \"%s\", expected \"%s\"", buf_srv, MSG_TCP_CLT_GOODBYE); ex(SRV, sa_shutdown(sa_cld, "r")); /* destroy client connection */ ex(SRV, sa_destroy(sa_cld)); ex(SRV, sa_addr_destroy(saa_cld)); /* destroy server socket and die */ ex(SRV, sa_destroy(sa_srv)); exit(0); } else { /* ** CLIENT **/ sleep(2); /* create client socket */ ex(CLT, sa_create(&sa_clt)); ex(CLT, sa_timeout(sa_clt, SA_TIMEOUT_ALL, 10, 0)); /* connect to server */ ex(CLT, sa_addr_create(&saa_clt)); ex(CLT, sa_addr_u2a(saa_clt, "inet://127.0.0.1:12345#tcp")); ex(CLT, sa_connect(sa_clt, saa_clt)); ex(CLT, sa_addr_destroy(saa_clt)); /* communicate with server */ ex(CLT, sa_readln(sa_clt, buf_clt, sizeof(buf_clt), &l)); if (strcmp(buf_clt, MSG_TCP_SRV_WELCOME) != 0) ts_test_fail(TS_CTX, "client: got \"%s\", expected \"%s\"", buf_clt, MSG_TCP_SRV_WELCOME); ex(CLT, sa_writef(sa_clt, "%s", MSG_TCP_CLT_WELCOME)); ex(CLT, sa_readln(sa_clt, buf_clt, sizeof(buf_clt), &l)); if (strcmp(buf_clt, MSG_TCP_SRV_GOODBYE) != 0) ts_test_fail(TS_CTX, "client: got \"%s\", expected \"%s\"", buf_clt, MSG_TCP_SRV_GOODBYE); ex(CLT, sa_writef(sa_clt, "%s", MSG_TCP_CLT_GOODBYE)); ex(CLT, sa_shutdown(sa_clt, "rw")); /* destroy server connection and wait for server to exit */ ex(CLT, sa_destroy(sa_clt)); waitpid(pid_srv, NULL, 0); } } /* test: client/server datagram communication */ TS_TEST(test_sa_datagram) { sa_t *sa_clt; sa_t *sa_srv; sa_addr_t *saa_srv; sa_addr_t *saa_clt; pid_t pid_srv; char buf_srv[1024]; char buf_clt[1024]; size_t l; #define MSG_UDP_CLT_REQUEST "Who are you?\n" #define MSG_UDP_SRV_RESPONSE "I'm god\n" if ((pid_srv = fork()) == 0) { /* ** SERVER */ /* create server socket */ ex(SRV, sa_create(&sa_srv)); ex(SRV, sa_type(sa_srv, SA_TYPE_DATAGRAM)); ex(SRV, sa_option(sa_srv, SA_OPTION_REUSEADDR, 1)); ex(SRV, sa_option(sa_srv, SA_OPTION_REUSEPORT, 1)); ex(SRV, sa_timeout(sa_srv, SA_TIMEOUT_ALL, 10, 0)); /* bind socket to local port */ ex(SRV, sa_addr_create(&saa_srv)); ex(SRV, sa_addr_u2a(saa_srv, "inet://127.0.0.1:12345#udp")); ex(SRV, sa_bind(sa_srv, saa_srv)); ex(SRV, sa_addr_destroy(saa_srv)); /* communicate with client */ ex(SRV, sa_recv(sa_srv, &saa_clt, buf_srv, sizeof(buf_srv), &l)); if (strncmp(buf_srv, MSG_UDP_CLT_REQUEST, l) != 0) ts_test_fail(TS_CTX, "server: got \"%s\", expected \"%s\"", buf_srv, MSG_UDP_CLT_REQUEST); ex(SRV, sa_sendf(sa_srv, saa_clt, "%s", MSG_UDP_SRV_RESPONSE)); ex(SRV, sa_addr_destroy(saa_clt)); /* destroy server socket and die */ ex(SRV, sa_destroy(sa_srv)); exit(0); } else { /* ** CLIENT **/ sleep(2); /* create client socket */ ex(CLT, sa_create(&sa_clt)); ex(CLT, sa_type(sa_clt, SA_TYPE_DATAGRAM)); ex(CLT, sa_timeout(sa_clt, SA_TIMEOUT_ALL, 10, 0)); /* communicate with server */ ex(CLT, sa_addr_create(&saa_srv)); ex(CLT, sa_addr_u2a(saa_srv, "inet://127.0.0.1:12345#udp")); ex(CLT, sa_sendf(sa_clt, saa_srv, "%s", MSG_UDP_CLT_REQUEST)); ex(CLT, sa_addr_destroy(saa_srv)); ex(CLT, sa_recv(sa_clt, &saa_srv, buf_clt, sizeof(buf_clt), &l)); if (strncmp(buf_clt, MSG_UDP_SRV_RESPONSE, l) != 0) ts_test_fail(TS_CTX, "client: got \"%s\", expected \"%s\"", buf_clt, MSG_UDP_SRV_RESPONSE); ex(CLT, sa_addr_destroy(saa_srv)); /* destroy server connection and wait for server to exit */ ex(CLT, sa_destroy(sa_clt)); waitpid(pid_srv, NULL, 0); } } /* test: exception handling */ #ifdef WITH_EX #include "ex.h" TS_TEST(test_sa_ex) { sa_addr_t *saa; ex_t ex; int caught; ts_test_check(TS_CTX, "exception handling"); caught = 0; ex_try { sa_addr_create(&saa); sa_addr_u2a(saa, "inet:DUMMY"); sa_addr_destroy(saa); } ex_catch (ex) { if ((sa_rc_t)ex.ex_value != SA_ERR_ARG) ts_test_fail(TS_CTX, "unexpected exception: %d\n", (sa_rc_t)ex.ex_value); caught = 1; } if (!caught) ts_test_fail(TS_CTX, "expected exception not caught\n"); } #endif int main(int argc, char *argv[]) { ts_suite_t *ts; int n; ts = ts_suite_new("OSSP sa (Socket Abstraction)"); ts_suite_test(ts, test_saa_impexp, "socket address abstraction import/export"); ts_suite_test(ts, test_saa_match, "socket address abstraction matching"); ts_suite_test(ts, test_sa_stream, "socket abstraction stream communication"); ts_suite_test(ts, test_sa_datagram, "socket abstraction datagram communication"); #ifdef WITH_EX ts_suite_test(ts, test_sa_ex, "exception handling"); #endif n = ts_suite_run(ts); ts_suite_free(ts); return n; } @ 1.28 log @welcome 2005 in OSSP sa, too @ text @d3 2 a4 2 ** Copyright (c) 2001-2005 Ralf S. Engelschall ** Copyright (c) 2001-2005 The OSSP Project @ 1.27 log @Adjusted all copyright messages for new year 2004. @ text @d3 3 a5 3 ** Copyright (c) 2001-2004 Ralf S. Engelschall ** Copyright (c) 2001-2004 The OSSP Project ** Copyright (c) 2001-2004 Cable & Wireless @ 1.26 log @Fix memory leak in test suite (sa_test.c). (detected by valgrind, see http://developer.kde.org/~sewardj/) @ text @d3 3 a5 3 ** Copyright (c) 2001-2003 Ralf S. Engelschall ** Copyright (c) 2001-2003 The OSSP Project ** Copyright (c) 2001-2003 Cable & Wireless Deutschland @ 1.25 log @Add internal address resolving support via the new IEEE Std 1003.1g-2000 ("POSIX.1") getaddrinfo(3) API. This especially provides more portable IPv6 address resolving. @ text @d84 1 a84 1 if ((rv = sa_addr_a2u(saa, &cp)) != SA_OK) d87 2 d101 1 @ 1.24 log @Fixed test suite (sa_test.c): an sa_addr_t was destroyed too early and this way crashed the test suite. Submitted by: Brian T. Egleston @ text @d59 1 d62 5 a66 5 { "inet://0.0.0.0:0", SA_OK, "inet://0.0.0.0:0" }, { "inet://127.0.0.1:514", SA_OK, "inet://127.0.0.1:514" }, { "inet://localhost:syslog#udp", SA_OK, "inet://127.0.0.1:514" }, { "inet://localhost:smtp", SA_OK, "inet://127.0.0.1:25" }, { "unix:/tmp/socket", SA_OK, "unix:/tmp/socket" }, d68 4 a71 4 { "inet:", SA_ERR_ARG, NULL }, { "inet://1.2.3.4.5:0", SA_ERR_ARG, NULL }, { "inet://just-hostname", SA_ERR_ARG, NULL }, { "unix:", SA_ERR_ARG, NULL } d87 12 a98 4 if (table[i].rv == SA_OK) if (strcmp(cp, table[i].out) != 0) ts_test_fail(TS_CTX, "sa_addr_a2u -> \"%s\" (expected \"%s\")", cp, table[i].out); @ 1.23 log @- Adjusted all copyright messages for new year 2003. - Fixed generated owner in distribution tarball. - Prepare for 1.0.3 release @ text @d190 1 a191 1 ex(SRV, sa_bind(sa_srv, saa_srv)); d232 1 a233 1 ex(CLT, sa_connect(sa_clt, saa_clt)); d284 1 a285 1 ex(SRV, sa_bind(sa_srv, saa_srv)); @ 1.22 log @Fixed two compile-time warnings in sa_test.c @ text @d3 3 a5 3 ** Copyright (c) 2001-2002 Ralf S. Engelschall ** Copyright (c) 2001-2002 The OSSP Project ** Copyright (c) 2001-2002 Cable & Wireless Deutschland @ 1.21 log @API Cleanups: use politically correct use "extern" keyword in sa.h; use leading underscores for variables names in prototypes; move "raddr" argument to second position in sa_{send,recv,sendf}. @ text @d77 1 a77 1 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { d128 1 a128 1 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { @ 1.20 log @Added a function sa_sendf(3) which is a convience wrapper to sa_send(3) for sending formatted data. This is similar to what sa_writef(3) does for sa_write(3). The difference is just that sa_writef(3) does not need a temporary buffer (because can use the stream I/O write buffer) while sa_sendf(3) requires a temporary buffer for its operation. Nevertheless the temporary buffer is allocated only if the formatted data is large. For small formatted data a fast stack-based buffer is used for higher performance. @ text @d288 1 a288 1 ex(SRV, sa_recv(sa_srv, buf_srv, sizeof(buf_srv), &l, &saa_clt)); d315 1 a315 1 ex(CLT, sa_recv(sa_clt, buf_clt, sizeof(buf_clt), &l, &saa_srv)); @ 1.19 log @puhhh... finally finish test suite @ text @d292 1 a292 2 ex(SRV, sa_send(sa_srv, MSG_UDP_SRV_RESPONSE, strlen(MSG_UDP_SRV_RESPONSE), &l, saa_clt)); d313 1 a313 2 ex(CLT, sa_send(sa_clt, MSG_UDP_CLT_REQUEST, strlen(MSG_UDP_CLT_REQUEST), &l, saa_srv)); @ 1.18 log @first cut for more covering test suite: client/server test via TCP stream communication @ text @a156 5 #define MSG_SRV_WELCOME "Welcome client\n" #define MSG_CLT_WELCOME "Welcome server\n" #define MSG_SRV_GOODBYE "Goodbye client\n" #define MSG_CLT_GOODBYE "Goodbye server\n" d171 5 d198 1 a198 1 ex(SRV, sa_writef(sa_cld, "%s", MSG_SRV_WELCOME)); d200 1 a200 1 if (strcmp(buf_srv, MSG_CLT_WELCOME) != 0) d202 2 a203 2 buf_srv, MSG_CLT_WELCOME); ex(SRV, sa_writef(sa_cld, "%s", MSG_SRV_GOODBYE)); d206 1 a206 1 if (strcmp(buf_srv, MSG_CLT_GOODBYE) != 0) d208 1 a208 1 buf_srv, MSG_CLT_GOODBYE); d237 1 a237 1 if (strcmp(buf_clt, MSG_SRV_WELCOME) != 0) d239 2 a240 2 buf_clt, MSG_SRV_WELCOME); ex(CLT, sa_writef(sa_clt, "%s", MSG_CLT_WELCOME)); d242 1 a242 1 if (strcmp(buf_clt, MSG_SRV_GOODBYE) != 0) d244 2 a245 2 buf_clt, MSG_SRV_GOODBYE); ex(CLT, sa_writef(sa_clt, "%s", MSG_CLT_GOODBYE)); d257 70 a326 1 /* FIXME */ @ 1.17 log @strip trailing whitespaces @ text @d41 3 d143 19 d165 87 a251 1 /* FIXME */ @ 1.16 log @polishing for release @ text @d58 1 a58 1 { "inet://0.0.0.0:0", SA_OK, "inet://0.0.0.0:0" }, d60 1 a60 1 { "inet://localhost:syslog#udp", SA_OK, "inet://127.0.0.1:514" }, d72 1 a72 1 ts_test_fail(TS_CTX, "sa_addr_create -> %d[%s] (expected %d[%s])", d85 1 a85 1 ts_test_fail(TS_CTX, "sa_addr_a2u -> \"%s\" (expected \"%s\")", d90 1 a90 1 ts_test_fail(TS_CTX, "sa_addr_destroy -> %d[%s] (expected %d[%s])", d130 1 a130 1 ts_test_check(TS_CTX, "sa_addr_match(\"%s\", \"%s\", %d)", @ 1.15 log @fix name @ text @d2 1 a2 1 ** SA - OSSP Socket Abstraction Library d7 2 a8 2 ** This file is part of OSSP SA, a socket abstraction library which ** can be found at http://www.ossp.org/pkg/sa/. @ 1.14 log @add optional OSSP ex based exception handling support @ text @d183 1 a183 1 ts = ts_suite_new("OSSP SA (Socket Abstraction Library)"); @ 1.13 log @bump copyright year @ text @d31 4 d152 26 d188 3 @ 1.12 log @remember what we want to test @ text @d3 3 a5 3 ** Copyright (c) 2001 Ralf S. Engelschall ** Copyright (c) 2001 The OSSP Project ** Copyright (c) 2001 Cable & Wireless Deutschland @ 1.11 log @cleanup formatting @ text @d41 1 d90 1 d136 12 d154 4 a157 2 ts_suite_test(ts, test_saa_impexp, "socket address abstraction (import/export)"); ts_suite_test(ts, test_saa_match, "socket address abstraction (matching)"); @ 1.10 log @Rename test suite library name spaces in order to get rid of problems under Sun Solaris 2.x. @ text @d68 1 a68 1 rv, sa_error(rv), SA_OK, sa_error(SA_OK)); d73 1 a73 1 rv, sa_error(rv), table[i].rv, sa_error(table[i].rv)); d77 1 a77 1 rv, sa_error(rv), SA_OK, sa_error(SA_OK)); d80 2 a81 1 ts_test_fail(TS_CTX, "sa_addr_a2u -> \"%s\" (expected \"%s\")", cp, table[i].out); d86 1 a86 1 rv, sa_error(rv), SA_OK, sa_error(SA_OK)); d125 1 a125 1 table[i].in, table[i].acl, table[i].prefixlen); d128 1 a128 1 rv, sa_error(rv), table[i].rv, sa_error(table[i].rv)); @ 1.9 log @Create a real-life test suite for the socket address abstraction part. @ text @d41 1 a41 1 TST_FUNC(test_saa_impexp) d65 1 a65 1 tst_check(TST, "sa_addr_create"); d67 1 a67 1 tst_fail(TST, "sa_addr_create -> %d[%s] (expected %d[%s])", d70 1 a70 1 tst_check(TST, "sa_addr_u2a(\"%s\")", table[i].in); d72 1 a72 1 tst_fail(TST, "sa_addr_a2u -> %d[%s] (expected %d[%s])", d74 1 a74 1 tst_check(TST, "sa_addr_a2u"); d76 1 a76 1 tst_fail(TST, "sa_addr_u2a -> %d[%s] (expected %d[%s])", d80 1 a80 1 tst_fail(TST, "sa_addr_a2u -> \"%s\" (expected \"%s\")", cp, table[i].out); d82 1 a82 1 tst_check(tst, "sa_addr_destroy"); d84 1 a84 1 tst_fail(TST, "sa_addr_destroy -> %d[%s] (expected %d[%s])", d88 1 a88 1 TST_FUNC(test_saa_match) d123 1 a123 1 tst_check(TST, "sa_addr_match(\"%s\", \"%s\", %d)", d126 1 a126 1 tst_fail(TST, "sa_addr_match -> %d[%s] (expected %d[%s])", d135 1 a135 1 ts_t *ts; d138 5 a142 5 ts = ts_new("OSSP SA (Socket Abstraction Library)"); ts_test(ts, test_saa_impexp, "socket address abstraction (import/export)"); ts_test(ts, test_saa_match, "socket address abstraction (matching)"); n = ts_run(ts); ts_free(ts); @ 1.8 log @Implemented a new sub-library OSSP TS (Test Suite) and use this new beast for the first cut of an OSSP SA test suite. The TS library produces nice test suite reports like this one (for a failed test suite): | Test Suite: OSSP SA (Socket Abstraction Library) | __________________________________________________________________ | | Test: socket address abstraction .............................. OK | Test: socket abstraction .................................. FAILED | Ops, 1/1 checks failed! Detailed report follows: | Check: testerliX [sa_test.c:43] | Log: sorry [sa_test.c:44] | __________________________________________________________________ | | Test Summary: 2 tests (1 ok, 1 failed), 5 checks (4 ok, 1 failed) | Test Suite: FAILED (Test Suite Failed) Or this one (for a successfull test suite): | Test Suite: OSSP SA (Socket Abstraction Library) | __________________________________________________________________ | | Test: socket address abstraction .............................. OK | Test: socket abstraction ...................................... OK | __________________________________________________________________ | | Test Summary: 2 tests (2 ok, 0 failed), 5 checks (5 ok, 0 failed) | Test Suite: OK (Test Suite Successfully) @ text @d41 1 a41 5 TST_FUNC(test_sa) { } TST_FUNC(test_saa) d45 19 a63 2 char *cp1; char *cp2; d67 15 a81 13 tst_fail(tst, "rv=%d (%s)", rv, sa_error(rv)); tst_check(TST, "sa_addr_u2a"); cp1 = "inet://127.0.0.1:12345"; if ((rv = sa_addr_u2a(saa, cp1)) != SA_OK) tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv)); tst_check(TST, "sa_addr_a2u"); if ((rv = sa_addr_a2u(saa, &cp2)) != SA_OK) tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv)); if (strcmp(cp1, cp2) != 0) tst_fail(TST, "import \"%s\" <-> export \"%s\"", cp1, cp2); d84 47 a130 1 tst_fail(TST, "rv=%d (%s)", rv, sa_error(rv)); d139 2 a140 2 ts_test(ts, test_saa, "socket address abstraction"); ts_test(ts, test_sa, "socket abstraction"); @ 1.7 log @log line number @ text @d38 1 d41 3 a43 2 #define DIE_MARK \ __FILE__, __LINE__ d45 1 a45 1 static void die(const char *file, int line, char *fmt, ...) d47 23 a69 8 va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%d:ERROR: ", file, line); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); exit(1); d72 1 a72 1 int main(int argc, char *argv[]) d74 1 a74 12 sa_addr_t *ra; sa_addr_t *la; sa_t *sa; char caBuf[1024]; int nBuf; char caTime[15+1]; time_t now; struct tm *tm; struct utsname uts; char *cp; char caTag[32+1]; char *cpHost; d77 6 a82 52 /* create remote address */ if (sa_addr_create(&ra) != SA_OK) die(DIE_MARK, "sa_addr_create (ra)"); if (sa_addr_u2a(ra, "inet://141.1.129.1:514") != SA_OK) die(DIE_MARK, "sa_addr_u2a (ra)"); /* create local address */ if (sa_addr_create(&la) != SA_OK) die(DIE_MARK, "sa_addr_create (la)"); if (sa_addr_u2a(la, "inet://0.0.0.0:0") != SA_OK) die(DIE_MARK, "sa_addr_u2a (la)"); /* create datagram socket */ if (sa_create(&sa) != SA_OK) die(DIE_MARK, "sa_create"); if (sa_type(sa, SA_TYPE_DATAGRAM) != SA_OK) die(DIE_MARK, "sa_type"); /* bind socket to local address */ if (sa_bind(sa, la) != SA_OK) die(DIE_MARK, "sa_bind"); /* RFC3164: The BSD syslog Protocol; C. Lonvick; August 2001. */ now = time(NULL); tm = localtime(&now); strftime(caTime, sizeof(caTime), "%b %e %H:%M:%S", tm); if (uname(&uts) == -1) die(DIE_MARK, "uname"); cpHost = strdup(uts.nodename); if ((cp = strchr(cpHost, '.')) != NULL) *cp = '\0'; strcpy(caTag, "progname[12]: "); if (strlen(caTag) > 32) caTag[32] = '\0'; sprintf(caBuf, "<16>%s %s %s[%ld]: %s", caTime, cpHost, argv[0], (long)getpid(), "test for Internet Datagram socket"); fprintf(stderr, "Send to syslog: \"%s\"\n", caBuf); /* send message to syslogd(8) */ nBuf = strlen(caBuf); if (sa_send(sa, caBuf, nBuf, (size_t *)&n, ra) != SA_OK) die(DIE_MARK, "sa_writeto"); /* destroy socket and address objects */ if (sa_destroy(sa) != SA_OK) die(DIE_MARK, "sa_destroy"); if (sa_addr_destroy(la) != SA_OK) die(DIE_MARK, "sa_addr_destroy (la)"); if (sa_addr_destroy(ra) != SA_OK) die(DIE_MARK, "sa_addr_destroy (ra)"); return 0; @ 1.6 log @Various cleanups @ text @d40 4 a43 1 static void die(char *fmt, ...) d48 1 a48 1 fprintf(stderr, "test:ERROR: "); d73 1 a73 1 die("sa_addr_create (ra)"); d75 1 a75 1 die("sa_addr_u2a (ra)"); d79 1 a79 1 die("sa_addr_create (la)"); d81 1 a81 1 die("sa_addr_u2a (la)"); d85 1 a85 1 die("sa_create"); d87 1 a87 1 die("sa_type"); d91 1 a91 1 die("sa_bind"); d98 1 a98 1 die("uname"); d112 1 a112 1 die("sa_writeto"); d116 1 a116 1 die("sa_destroy"); d118 1 a118 1 die("sa_addr_destroy (la)"); d120 1 a120 1 die("sa_addr_destroy (ra)"); @ 1.5 log @Woohhhooo: Second major revamp of Socket Abstraction (SA) library. This time is gets really close to a 100% clean and polished library. @ text @d1 29 @ 1.4 log @simplify test @ text @d79 1 a79 1 if (sa_writeto(sa, caBuf, nBuf, (size_t *)&n, ra) != SA_OK) @ 1.3 log @Major revamp of SA library in order to support Unix Domain sockets. - "{tcp,udp}://host:port" addresses are now "inet://host:port" addresses - "unix:/path/to/socket" is the address for Unix Domain sockets - sa_type() was introduced which sets socket type to stream or datagram @ text @a5 1 #include d7 1 d65 5 a69 7 if (uname(&uts) == 0) { cpHost = strdup(uts.nodename); if ((cp = strchr(cpHost, '.')) != NULL) *cp = '\0'; } else cpHost = strdup("0.0.0.0"); /* FIXME */ d73 5 a77 2 sprintf(caBuf, "<%d>%s %s %s%s", LOG_MAIL|LOG_EMERG, caTime, cpHost, caTag, "test"); fprintf(stderr, "%s\n", caBuf); @ 1.2 log @reduce warnings @ text @a10 2 /* see RFC3164 */ d39 13 a51 4 if (sa_u2a(&ra, "udp://%s:514", argv[1]) != SA_OK) die("sa_u2a ra"); if (sa_u2a(&la, "udp://0.0.0.0:0") != SA_OK) die("sa_u2a la"); d54 4 a61 1 a64 1 a71 1 d75 1 a75 2 sprintf(caBuf, "<%d>%s %s %s%s", LOG_MAIL|LOG_EMERG, caTime, cpHost, caTag, argv[2]); d80 2 d84 5 a88 2 free(ra); free(la); @ 1.1 log @Upgrade ad-hoc build environment to standard OSSP build environment. @ text @a34 1 char caHost; d71 1 a71 1 if (sa_writeto(sa, caBuf, nBuf, &n, ra) != SA_OK) @