Index: ossp-pkg/l2/README RCS File: /v/ossp/cvs/ossp-pkg/l2/README,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/l2/README,v' 2>/dev/null --- README 2002/07/30 19:12:30 1.8 +++ README 2002/10/11 16:00:48 1.9 @@ -5,7 +5,7 @@ |_____|_____| OSSP l2 -- Logging Library - Version 0.9.0 (30-Jul-2002) + Version 0.9.1 (11-Oct-2002) ABSTRACT Index: ossp-pkg/l2/configure.ac RCS File: /v/ossp/cvs/ossp-pkg/l2/configure.ac,v rcsdiff -q -kk '-r1.23' '-r1.24' -u '/v/ossp/cvs/ossp-pkg/l2/configure.ac,v' 2>/dev/null --- configure.ac 2002/07/30 19:08:24 1.23 +++ configure.ac 2002/10/11 16:00:48 1.24 @@ -44,8 +44,8 @@ AC_CHECK_MAINTAINER AC_CONFIGURE_LIBTOOL -AC_CHECK_BISON(BISON, 1.30, [1.3[[0-9]]|1.[[4-9]]]) -AC_CHECK_FLEX(FLEX, 2.5.10, [2.5.1[[0-9]]|2.[[6-9]].*]) +AC_CHECK_BISON(BISON, 1.30, [1.3[[0-9]]|1.[[4-9]][[0-9]]]) +AC_CHECK_FLEX(FLEX, 2.5.10, [2.5.1[[0-9]]|2.5.[[2-9]][[0-9]]|2.[[6-9]].*]) AC_CHECK_LIB(nsl, gethostname) if test ".`echo $LIBS | grep nsl`" = . ;then Index: ossp-pkg/l2/devtool.conf RCS File: /v/ossp/cvs/ossp-pkg/l2/devtool.conf,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/l2/devtool.conf,v' 2>/dev/null --- devtool.conf 2002/07/30 19:12:30 1.6 +++ devtool.conf 2002/10/11 16:00:48 1.7 @@ -5,7 +5,7 @@ %autogen @autogen shtool 1.6.1 "1.6.*" all @autogen libtool 1.4.2 "1.4*" - @autogen autoconf 2.53 "2.5[3-9]*" + @autogen autoconf 2.54 "2.5[4-9]*" %autoclean @autoclean shtool Index: ossp-pkg/l2/l2_ut_sa.ac RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.ac,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.ac,v' 2>/dev/null --- l2_ut_sa.ac 2002/03/14 15:29:23 1.5 +++ l2_ut_sa.ac 2002/10/11 16:00:48 1.6 @@ -1,11 +1,11 @@ dnl ## -dnl ## SA - OSSP Socket Abstraction Library -dnl ## Copyright (c) 2001 Ralf S. Engelschall -dnl ## Copyright (c) 2001 The OSSP Project -dnl ## Copyright (c) 2001 Cable & Wireless Deutschland +dnl ## OSSP sa - Socket Abstraction +dnl ## Copyright (c) 2001-2002 Ralf S. Engelschall +dnl ## Copyright (c) 2001-2002 The OSSP Project +dnl ## Copyright (c) 2001-2002 Cable & Wireless Deutschland dnl ## -dnl ## This file is part of OSSP SA, a socket abstraction library which -dnl ## can be found at http://www.ossp.org/pkg/sa/. +dnl ## This file is part of OSSP sa, a socket abstraction library which +dnl ## can be found at http://www.ossp.org/pkg/lib/sa/. dnl ## dnl ## Permission to use, copy, modify, and distribute this software for dnl ## any purpose with or without fee is hereby granted, provided that @@ -72,7 +72,7 @@ AC_CHECK_HEADERS(string.h sys/types.h sys/socket.h netdb.h netinet/in.h) # check for system functions - AC_CHECK_FUNCS(inet_aton inet_pton inet_ntoa inet_ntop snprintf) + AC_CHECK_FUNCS(inet_addr inet_aton inet_pton inet_ntoa inet_ntop snprintf) dnl # check for network/socket size type SA_CHECK_TYPEDEF(socklen_t, sys/socket.h) Index: ossp-pkg/l2/l2_ut_sa.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.c,v rcsdiff -q -kk '-r1.17' '-r1.18' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.c,v' 2>/dev/null --- l2_ut_sa.c 2001/10/31 21:26:11 1.17 +++ l2_ut_sa.c 2002/10/11 16:00:48 1.18 @@ -1,11 +1,11 @@ /* -** SA - OSSP Socket Abstraction Library -** Copyright (c) 2001 Ralf S. Engelschall -** Copyright (c) 2001 The OSSP Project -** Copyright (c) 2001 Cable & Wireless Deutschland +** OSSP sa - Socket Abstraction +** Copyright (c) 2001-2002 Ralf S. Engelschall +** Copyright (c) 2001-2002 The OSSP Project +** Copyright (c) 2001-2002 Cable & Wireless Deutschland ** -** This file is part of OSSP SA, a socket abstraction library which -** can be found at http://www.ossp.org/pkg/sa/. +** 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 @@ -45,12 +45,25 @@ #include /* for "struct timeval" */ #include /* for "struct sockaddr_un" */ #include /* for "struct sockaddr_in[6]" */ -#include /* for "AF_XXX" and "SOCK_XXX" */ +#include /* for "PF_XXX", "AF_XXX" and "SOCK_XXX" */ #include /* for "inet_XtoX" */ /* include own API header */ #include "l2_ut_sa.h" +/* unique library identifier */ +const char sa_id[] = "OSSP sa"; + +/* support for OSSP ex based exception throwing */ +#ifdef WITH_EX +#include "ex.h" +#define SA_RC(rv) \ + ( (rv) != SA_OK && (ex_catching && !ex_shielding) \ + ? (ex_throw(sa_id, NULL, (rv)), (rv)) : (rv) ) +#else +#define SA_RC(rv) (rv) +#endif /* WITH_EX */ + /* boolean values */ #ifndef FALSE #define FALSE (0) @@ -64,6 +77,17 @@ #define AF_LOCAL AF_UNIX #endif +/* backward compatibility for PF_XXX (still unused) */ +#if !defined(PF_LOCAL) && defined(AF_LOCAL) +#define PF_LOCAL AF_LOCAL +#endif +#if !defined(PF_INET) && defined(AF_INET) +#define PF_INET AF_INET +#endif +#if !defined(PF_INET6) && defined(AF_INET6) +#define PF_INET6 AF_INET6 +#endif + /* backward compatibility for ssize_t */ #if defined(HAVE_CONFIG_H) && !defined(HAVE_SSIZE_T) #define ssize_t long @@ -130,14 +154,14 @@ do { \ (sa)->scSysCall.sc_##fn.fptr.any = (void (*)())(ptr); \ (sa)->scSysCall.sc_##fn.fctx = (ctx); \ - } while(0) + } while (0) /* system call structure assignment macro */ #define SA_SC_COPY(sa1, sa2, fn) \ do { \ (sa1)->scSysCall.sc_##fn.fptr.any = (sa2)->scSysCall.sc_##fn.fptr.any; \ (sa1)->scSysCall.sc_##fn.fctx = (sa2)->scSysCall.sc_##fn.fctx; \ - } while(0) + } while (0) /* system call function call macros */ #define SA_SC_CALL_0(sa, fn) \ @@ -214,10 +238,17 @@ struct in_addr in_val; if (family == AF_INET) { +#if defined(HAVE_INET_ATON) /* at least for IPv4 we can rely on the old inet_aton(3) and for IPv6 inet_pton(3) would exist anyway */ if (inet_aton(strptr, &in_val) == 0) return 0; +#elif defined(HAVE_INET_ADDR) + /* at least for IPv4 try to rely on the even older inet_addr(3) */ + memset(&in_val, '\0', sizeof(in_val)); + if ((in_val.s_addr = inet_addr(strptr)) == ((in_addr_t)-1)) + return 0; +#endif memcpy(addrptr, &in_val, sizeof(struct in_addr)); return 1; } @@ -232,14 +263,14 @@ #ifdef HAVE_INET_NTOP return inet_ntop(family, src, dst, size); #else - struct in_addr in_val; char *cp; int n; if (family == AF_INET) { +#ifdef HAVE_INET_NTOA /* at least for IPv4 we can rely on the old inet_ntoa(3) and for IPv6 inet_ntop(3) would exist anyway */ - if ((cp = inet_ntoa(src)) == NULL) + if ((cp = inet_ntoa(*((struct in_addr *)src))) == NULL) return NULL; n = strlen(cp); if (n > size-1) @@ -247,6 +278,7 @@ memcpy(dst, cp, n); dst[n] = '\0'; return dst; +#endif } errno = EAFNOSUPPORT; return NULL; @@ -356,13 +388,13 @@ else { /* perform real output */ ctx.bufptr = buffer; - ctx.buflen = bufsize - 1; + ctx.buflen = bufsize; n = sa_mvxprintf(sa_mvsnprintf_cb, &ctx, format, ap); + if (n != -1 && ctx.buflen == 0) + n = -1; + if (n != -1) + *(ctx.bufptr) = '\0'; } - if (n != -1 && ctx.buflen == 0) - n = -1; - if (n != -1) - *(ctx.bufptr) = '\0'; return n; } @@ -387,11 +419,11 @@ /* argument sanity check(s) */ if (saap == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* allocate and initialize new address object */ if ((saa = (sa_addr_t *)malloc(sizeof(sa_addr_t))) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); saa->nFamily = 0; saa->saBuf = NULL; saa->slBuf = 0; @@ -407,7 +439,7 @@ { /* argument sanity check(s) */ if (saa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* free address objects and sub-object(s) */ if (saa->saBuf != NULL) @@ -436,7 +468,7 @@ char *cpHost; char *cpPort; char *cpProto; - int nPort; + unsigned int nPort; const char *cpPath; char uribuf[1024]; char *cp; @@ -445,7 +477,7 @@ /* argument sanity check(s) */ if (saa == NULL || uri == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* on-the-fly create or just take over URI */ va_start(ap, uri); @@ -472,12 +504,12 @@ /* fill-in socket address structure */ n = strlen(cpPath); if (n == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); if ((n+1) > sizeof(un.sun_path)) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); if (cpPath[0] != '/') { if (getcwd(un.sun_path, sizeof(un.sun_path)-(n+1)) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); cp = un.sun_path + strlen(un.sun_path); } else @@ -497,22 +529,22 @@ if (cpHost[0] == '[') { /* IPv6 address (see RFC2732) */ #ifndef AF_INET6 - return SA_ERR_IMP; + return SA_RC(SA_ERR_IMP); #else bIPv6 = TRUE; cpHost++; if ((cp = strchr(cpHost, ']')) == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); *cp++ = '\0'; if (*cp != ':') - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); cp++; #endif } else { /* IPv4 address or hostname */ if ((cp = strrchr(cpHost, ':')) == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); *cp++ = '\0'; } cpPort = cp; @@ -532,10 +564,10 @@ } } if (bNumeric) - nPort = atoi(cpPort); + nPort = (unsigned int)atoi(cpPort); else { if ((se = getservbyname(cpPort, cpProto)) == NULL) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); nPort = ntohs(se->s_port); } @@ -585,19 +617,19 @@ } #endif else - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); } else - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); } else - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* fill-in result address structure */ if (saa->saBuf != NULL) free(saa->saBuf); if ((saa->saBuf = (struct sockaddr *)malloc(sl)) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); memcpy(saa->saBuf, sa, sl); saa->slBuf = sl; saa->nFamily = sf; @@ -610,7 +642,7 @@ { /* argument sanity check(s) */ if (saa == NULL || sabuf == NULL || salen == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* make sure we import only supported addresses */ if (!( sabuf->sa_family == AF_LOCAL @@ -619,13 +651,13 @@ || sabuf->sa_family == AF_INET6 #endif )) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* create result address structure */ if (saa->saBuf != NULL) free(saa->saBuf); if ((saa->saBuf = (struct sockaddr *)malloc(salen)) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); memcpy(saa->saBuf, sabuf, salen); saa->slBuf = salen; @@ -645,11 +677,11 @@ struct sockaddr_in6 *sa6; #endif char caHost[512]; - int nPort; + unsigned int nPort; /* argument sanity check(s) */ if (saa == NULL || uri == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* export object contents */ if (saa->nFamily == AF_LOCAL) { @@ -680,7 +712,7 @@ } #endif else - return SA_ERR_INT; + return SA_RC(SA_ERR_INT); /* pass result to caller */ *uri = strdup(uribuf); @@ -693,11 +725,11 @@ { /* argument sanity check(s) */ if (saa == NULL || sabuf == NULL || salen == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* export underlying address structure */ if ((*sabuf = (struct sockaddr *)malloc(saa->slBuf)) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); memmove(*sabuf, saa->saBuf, saa->slBuf); *salen = saa->slBuf; @@ -715,10 +747,12 @@ int i; const unsigned char *ucp0; #endif + unsigned int np1, np2; + int bMatchPort; /* argument sanity check(s) */ - if (saa1 == NULL || saa2 == NULL || prefixlen < -1) - return SA_ERR_ARG; + if (saa1 == NULL || saa2 == NULL) + return SA_RC(SA_ERR_ARG); /* short circuiting for wildcard matching */ if (prefixlen == 0) @@ -726,18 +760,20 @@ /* determine address representation pointer and size */ if (saa1->nFamily == AF_LOCAL) { + np1 = 0; + np2 = 0; ucp1 = (const unsigned char *)(((struct sockaddr_un *)saa1->saBuf)->sun_path); ucp2 = (const unsigned char *)(((struct sockaddr_un *)saa2->saBuf)->sun_path); l1 = strlen(((struct sockaddr_un *)saa1->saBuf)->sun_path) * 8; l2 = strlen(((struct sockaddr_un *)saa2->saBuf)->sun_path) * 8; - if (prefixlen == -1) { + if (prefixlen < 0) { if (l1 != l2) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); nBits = l1; } else { if (l1 < prefixlen || l2 < prefixlen) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); nBits = prefixlen; } } @@ -747,12 +783,16 @@ /* special case of comparing a regular IPv4 address (1.2.3.4) with an "IPv4-mapped IPv6 address" (::ffff:1.2.3.4). For details see RFC 2373. */ if (saa1->nFamily == AF_INET6) { + np1 = (unsigned int)(((struct sockaddr_in6 *)saa1->saBuf)->sin6_port); + np2 = (unsigned int)(((struct sockaddr_in *)saa2->saBuf)->sin_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr); ucp0 = ucp1; ucp1 += 12; } else { + np1 = (unsigned int)(((struct sockaddr_in *)saa1->saBuf)->sin_port); + np2 = (unsigned int)(((struct sockaddr_in6 *)saa2->saBuf)->sin6_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr); ucp0 = ucp2; @@ -760,34 +800,42 @@ } for (i = 0; i < 10; i++) if (ucp0[i] != 0x00) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); if (!(ucp0[10] == 0xFF && ucp0[11] == 0xFF)) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); nBits = 32; } #endif else if (saa1->nFamily == AF_INET) { + np1 = (unsigned int)(((struct sockaddr_in *)saa1->saBuf)->sin_port); + np2 = (unsigned int)(((struct sockaddr_in *)saa2->saBuf)->sin_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr); nBits = 32; } #ifdef AF_INET6 else if (saa1->nFamily == AF_INET6) { + np1 = (unsigned int)(((struct sockaddr_in6 *)saa1->saBuf)->sin6_port); + np2 = (unsigned int)(((struct sockaddr_in6 *)saa2->saBuf)->sin6_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr); nBits = 128; -#endif } +#endif else - return SA_ERR_INT; + return SA_RC(SA_ERR_INT); /* make sure we do not compare than possible */ - if (prefixlen > nBits) - return SA_ERR_ARG; + if (prefixlen > (nBits+1)) + return SA_RC(SA_ERR_ARG); - /* support equal matching (= all bits) */ - if (prefixlen == -1) + /* support equal matching (= all bits plus optionally port) */ + bMatchPort = FALSE; + if (prefixlen < 0) { + if (prefixlen < -1) + bMatchPort = TRUE; prefixlen = nBits; + } /* perform address representation comparison (assumption guaranteed by API: network byte order is used) */ @@ -795,15 +843,21 @@ nBits = (prefixlen % 8); if (nBytes > 0) { if (memcmp(ucp1, ucp2, nBytes) != 0) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); } if (nBits > 0) { uc1 = ucp1[nBytes]; uc2 = ucp2[nBytes]; mask = (0xFF << (8-nBits)) & 0xFF; if ((uc1 & mask) != (uc2 & mask)) - return SA_ERR_MTC; + return SA_RC(SA_ERR_MTC); } + + /* optionally perform additional port matching */ + if (bMatchPort) + if (np1 != np2) + return SA_RC(SA_ERR_MTC); + return SA_OK; } @@ -814,15 +868,15 @@ if (sa->fdSocket != -1) { if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) { if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_RCVTIMEO, - &sa->tvTimeout[SA_TIMEOUT_READ], - sizeof(sa->tvTimeout[SA_TIMEOUT_READ])) < 0) - return SA_ERR_SYS; + (const void *)(&sa->tvTimeout[SA_TIMEOUT_READ]), + (socklen_t)(sizeof(sa->tvTimeout[SA_TIMEOUT_READ]))) < 0) + return SA_RC(SA_ERR_SYS); } if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) { if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_SNDTIMEO, - &sa->tvTimeout[SA_TIMEOUT_WRITE], - sizeof(sa->tvTimeout[SA_TIMEOUT_WRITE])) < 0) - return SA_ERR_SYS; + (const void *)(&sa->tvTimeout[SA_TIMEOUT_WRITE]), + (socklen_t)(sizeof(sa->tvTimeout[SA_TIMEOUT_WRITE]))) < 0) + return SA_RC(SA_ERR_SYS); } } #endif @@ -834,16 +888,17 @@ { int nType; int nProto; +#if !(defined(IPPROTO_TCP) && defined(IPPROTO_UDP)) struct protoent *pe; - char *cpProto; +#endif /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* only perform operation if socket still does not exist */ if (sa->fdSocket != -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* determine socket type */ if (sa->eType == SA_TYPE_STREAM) @@ -851,7 +906,7 @@ else if (sa->eType == SA_TYPE_DATAGRAM) nType = SOCK_DGRAM; else - return SA_ERR_INT; + return SA_RC(SA_ERR_INT); /* determine socket protocol */ if (nFamily == AF_LOCAL) @@ -861,22 +916,31 @@ #else else if (nFamily == AF_INET) { #endif +#if defined(IPPROTO_TCP) && defined(IPPROTO_UDP) + if (nType == SOCK_STREAM) + nProto = IPPROTO_TCP; + else if (nType == SOCK_DGRAM) + nProto = IPPROTO_UDP; + else + return SA_RC(SA_ERR_INT); +#else if (nType == SOCK_STREAM) - cpProto = "tcp"; + pe = getprotobyname("tcp"); else if (nType == SOCK_DGRAM) - cpProto = "udp"; + pe = getprotobyname("udp"); else - return SA_ERR_INT; - if ((pe = getprotobyname(cpProto)) == NULL) - return SA_ERR_SYS; + return SA_RC(SA_ERR_INT); + if (pe == NULL) + return SA_RC(SA_ERR_SYS); nProto = pe->p_proto; +#endif } else - return SA_ERR_INT; + return SA_RC(SA_ERR_INT); /* create the underlying socket */ if ((sa->fdSocket = socket(nFamily, nType, nProto)) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* optionally set kernel timeouts */ sa_socket_settimeouts(sa); @@ -889,11 +953,11 @@ { /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* check context */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* close socket */ close(sa->fdSocket); @@ -910,11 +974,11 @@ /* argument sanity check(s) */ if (sap == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* allocate and initialize socket object */ if ((sa = (sa_t *)malloc(sizeof(sa_t))) == NULL) - return SA_ERR_MEM; + return SA_RC(SA_ERR_MEM); /* init object attributes */ sa->eType = SA_TYPE_STREAM; @@ -952,7 +1016,7 @@ { /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* kill underlying socket */ sa_socket_kill(sa); @@ -972,9 +1036,9 @@ { /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); if (!(type == SA_TYPE_STREAM || type == SA_TYPE_DATAGRAM)) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* kill underlying socket if type changes */ if (sa->eType != type) @@ -993,7 +1057,7 @@ /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); if (id == SA_TIMEOUT_ALL) { for (i = 0; i < (sizeof(sa->tvTimeout)/sizeof(sa->tvTimeout[0])); i++) { @@ -1019,19 +1083,19 @@ /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); if (id == SA_BUFFER_READ) { /* configure read/incoming buffer */ if (sa->nReadLen > size) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); if (size > 0) { if (sa->cpReadBuf == NULL) cp = (char *)malloc(size); else cp = (char *)realloc(sa->cpReadBuf, size); if (cp == NULL) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); sa->cpReadBuf = cp; sa->nReadSize = size; } @@ -1045,14 +1109,14 @@ else if (id == SA_BUFFER_WRITE) { /* configure write/outgoing buffer */ if (sa->nWriteLen > size) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); if (size > 0) { if (sa->cpWriteBuf == NULL) cp = (char *)malloc(size); else cp = (char *)realloc(sa->cpWriteBuf, size); if (cp == NULL) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); sa->cpWriteBuf = cp; sa->nWriteSize = size; } @@ -1063,7 +1127,8 @@ sa->nWriteSize = 0; } } - return SA_ERR_ARG; + else + return SA_RC(SA_ERR_ARG); return SA_OK; } @@ -1076,7 +1141,7 @@ /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* process option */ rv = SA_OK; @@ -1091,17 +1156,60 @@ break; } if (setsockopt(sa->fdSocket, IPPROTO_TCP, TCP_NODELAY, - (void *)&mode, sizeof(mode)) < 0) + (const void *)&mode, (socklen_t)sizeof(mode)) < 0) rv = SA_ERR_SYS; #else rv = SA_ERR_IMP; #endif break; } + case SA_OPTION_LINGER: { +#if defined(SO_LINGER) + struct linger *linger = (struct linger *)va_arg(ap, void *); + if (sa->fdSocket == -1) { + rv = SA_ERR_USE; + break; + } + if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_LINGER, + (const void *)linger, (socklen_t)sizeof(struct linger)) < 0) + rv = SA_ERR_SYS; +#else + rv = SA_ERR_IMP; +#endif + break; + } + case SA_OPTION_REUSEADDR: +#ifdef SA_OPTION_REUSEPORT + case SA_OPTION_REUSEPORT: +#endif + { + /* enable/disable reusability of binding to address or port */ + int mode = ((int)va_arg(ap, int) ? 1 : 0); + int flag; + if (sa->fdSocket == -1) { + rv = SA_ERR_USE; + break; + } + switch (id) { + case SA_OPTION_REUSEADDR: flag = SO_REUSEADDR; break; +#ifdef SA_OPTION_REUSEPORT + case SA_OPTION_REUSEPORT: flag = SO_REUSEPORT; break; +#endif + default: flag = 0; break; + } + if (setsockopt(sa->fdSocket, SOL_SOCKET, flag, + (const void *)&mode, (socklen_t)sizeof(mode)) < 0) + rv = SA_ERR_SYS; + break; + } case SA_OPTION_NONBLOCK: { /* enable/disable non-blocking I/O mode */ int flags; int mode = (int)va_arg(ap, int); + if (sa->fdSocket == -1) { + rv = SA_ERR_USE; + break; + } if ((flags = fcntl(sa->fdSocket, F_GETFL, 0)) < 0) { rv = SA_ERR_SYS; break; @@ -1120,31 +1228,32 @@ } va_end(ap); - return rv; + return SA_RC(rv); } /* override system call */ sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx) { + sa_rc_t rv; + + /* argument sanity check(s) */ if (sa == NULL || fptr == NULL) - return SA_ERR_ARG; - if (id == SA_SYSCALL_CONNECT) - SA_SC_ASSIGN(sa, connect, fptr, fctx); - else if (id == SA_SYSCALL_ACCEPT) - SA_SC_ASSIGN(sa, accept, fptr, fctx); - else if (id == SA_SYSCALL_SELECT) - SA_SC_ASSIGN(sa, select, fptr, fctx); - else if (id == SA_SYSCALL_READ) - SA_SC_ASSIGN(sa, read, fptr, fctx); - else if (id == SA_SYSCALL_WRITE) - SA_SC_ASSIGN(sa, write, fptr, fctx); - else if (id == SA_SYSCALL_RECVFROM) - SA_SC_ASSIGN(sa, recvfrom, fptr, fctx); - else if (id == SA_SYSCALL_SENDTO) - SA_SC_ASSIGN(sa, sendto, fptr, fctx); - else - return SA_ERR_ARG; - return SA_OK; + return SA_RC(SA_ERR_ARG); + + /* assign system call */ + rv = SA_OK; + switch (id) { + case SA_SYSCALL_CONNECT: SA_SC_ASSIGN(sa, connect, fptr, fctx); break; + case SA_SYSCALL_ACCEPT: SA_SC_ASSIGN(sa, accept, fptr, fctx); break; + case SA_SYSCALL_SELECT: SA_SC_ASSIGN(sa, select, fptr, fctx); break; + case SA_SYSCALL_READ: SA_SC_ASSIGN(sa, read, fptr, fctx); break; + case SA_SYSCALL_WRITE: SA_SC_ASSIGN(sa, write, fptr, fctx); break; + case SA_SYSCALL_RECVFROM: SA_SC_ASSIGN(sa, recvfrom, fptr, fctx); break; + case SA_SYSCALL_SENDTO: SA_SC_ASSIGN(sa, sendto, fptr, fctx); break; + default: rv = SA_ERR_ARG; + } + + return SA_RC(rv); } /* bind socket to a local address */ @@ -1155,12 +1264,12 @@ /* argument sanity check(s) */ if (sa == NULL || laddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* lazy creation of underlying socket */ if (sa->fdSocket == -1) if ((rv = sa_socket_init(sa, laddr->nFamily)) != SA_OK) - return rv; + return SA_RC(rv); /* remove a possibly existing old Unix Domain socket on filesystem */ if (laddr->nFamily == AF_LOCAL) { @@ -1170,7 +1279,7 @@ /* perform bind operation on underlying socket */ if (bind(sa->fdSocket, laddr->saBuf, laddr->slBuf) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); return SA_OK; } @@ -1185,16 +1294,16 @@ /* argument sanity check(s) */ if (sa == NULL || raddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* connecting is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* lazy creation of underlying socket */ if (sa->fdSocket == -1) if ((rv = sa_socket_init(sa, raddr->nFamily)) != SA_OK) - return rv; + return SA_RC(rv); rv = SA_OK; if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) { @@ -1246,7 +1355,7 @@ /* fetch pending error */ len = sizeof(error); - if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, &error, &len) < 0) + if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0) error = errno; done: @@ -1262,7 +1371,7 @@ rv = SA_ERR_SYS; } } - return rv; + return SA_RC(rv); } /* listen on socket for connections */ @@ -1270,19 +1379,19 @@ { /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* listening is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least sa_bind() has to be already performed */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* perform listen operation on underlying socket */ if (listen(sa->fdSocket, backlog) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); return SA_OK; } @@ -1306,15 +1415,15 @@ /* argument sanity check(s) */ if (sa == NULL || caddr == NULL || csa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* accepting connections is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least sa_listen() has to be already performed */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* if timeout is enabled, perform a smart-blocking wait */ if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_ACCEPT])) { @@ -1325,28 +1434,28 @@ &sa->tvTimeout[SA_TIMEOUT_ACCEPT]); } while (n == -1 && errno == EINTR); if (n == 0) - return SA_ERR_TMT; + return SA_RC(SA_ERR_TMT); if (n <= 0) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); } /* perform accept operation on underlying socket */ sa_len = sizeof(sa_buf); if ((s = SA_SC_CALL_3(sa, accept, sa->fdSocket, (struct sockaddr *)&sa_buf, &sa_len)) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* create result address object */ if ((rv = sa_addr_create(caddr)) != SA_OK) - return rv; + return SA_RC(rv); if ((rv = sa_addr_s2a(*caddr, (struct sockaddr *)&sa_buf, sa_len)) != SA_OK) { sa_addr_destroy(*caddr); - return rv; + return SA_RC(rv); } /* create result socket object */ if ((rv = sa_create(csa)) != SA_OK) { sa_addr_destroy(*caddr); - return rv; + return SA_RC(rv); } /* fill-in child socket */ @@ -1384,27 +1493,27 @@ /* argument sanity check(s) */ if (sa == NULL || raddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* peers exist only for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least sa_connect() or sa_accept() has to be already performed */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* determine remote address of underlying socket */ sa_len = sizeof(sa_buf); if (getpeername(sa->fdSocket, (struct sockaddr *)&sa_buf, &sa_len) < 0) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* create result address object */ if ((rv = sa_addr_create(raddr)) != SA_OK) - return rv; + return SA_RC(rv); if ((rv = sa_addr_s2a(*raddr, (struct sockaddr *)&sa_buf, sa_len)) != SA_OK) { sa_addr_destroy(*raddr); - return rv; + return SA_RC(rv); } return SA_OK; @@ -1424,23 +1533,23 @@ /* argument sanity check(s) */ if (sa == NULL || laddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* at least sa_bind() has to be already performed */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* determine local address of underlying socket */ sa_len = sizeof(sa_buf); if (getsockname(sa->fdSocket, (struct sockaddr *)&sa_buf, &sa_len) < 0) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* create result address object */ if ((rv = sa_addr_create(laddr)) != SA_OK) - return rv; + return SA_RC(rv); if ((rv = sa_addr_s2a(*laddr, (struct sockaddr *)&sa_buf, sa_len)) != SA_OK) { sa_addr_destroy(*laddr); - return rv; + return SA_RC(rv); } return SA_OK; @@ -1451,11 +1560,11 @@ { /* argument sanity check(s) */ if (sa == NULL || fd == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* if still no socket exists, say this explicitly */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* pass socket to caller */ *fd = sa->fdSocket; @@ -1506,19 +1615,19 @@ { int n; sa_rc_t rv; - size_t res; + int res; /* argument sanity check(s) */ if (sa == NULL || cpBuf == NULL || nBufReq == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* reading is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* perform read operation */ rv = SA_OK; @@ -1537,7 +1646,7 @@ else { /* user-space buffered I/O */ res = 0; - while (1) { + for (;;) { if (nBufReq <= sa->nReadLen) { /* buffer holds enough data, so just use this */ memmove(cpBuf, sa->cpReadBuf, nBufReq); @@ -1592,9 +1701,9 @@ /* pass number of actually read bytes to caller */ if (nBufRes != NULL) - *nBufRes = res; + *nBufRes = (size_t)res; - return rv; + return SA_RC(rv); } /* read data from socket until [CR]LF (convinience function) */ @@ -1607,15 +1716,15 @@ /* argument sanity check(s) */ if (sa == NULL || cpBuf == NULL || nBufReq == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* reading is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* we just perform a plain sa_read() per character, because if buffers are enabled, this is not as stupid as it looks at the first @@ -1639,7 +1748,7 @@ if (nBufRes != NULL) *nBufRes = res; - return rv; + return SA_RC(rv); } /* internal raw write operation */ @@ -1683,21 +1792,21 @@ /* write data to socket */ sa_rc_t sa_write(sa_t *sa, const char *cpBuf, size_t nBufReq, size_t *nBufRes) { - size_t n; - size_t res; + int n; + int res; sa_rc_t rv; /* argument sanity check(s) */ if (sa == NULL || cpBuf == NULL || nBufReq == 0) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* writing is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); rv = SA_OK; if (sa->nWriteSize == 0) { @@ -1740,9 +1849,9 @@ /* pass number of actually written bytes to caller */ if (nBufRes != NULL) - *nBufRes = res; + *nBufRes = (size_t)res; - return rv; + return SA_RC(rv); } /* output callback function context for sa_writef() */ @@ -1771,15 +1880,15 @@ /* argument sanity check(s) */ if (sa == NULL || cpFmt == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* writing is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* format string into temporary buffer */ va_start(ap, cpFmt); @@ -1794,20 +1903,20 @@ /* flush write/outgoing I/O buffer */ sa_rc_t sa_flush(sa_t *sa) { - size_t n; + int n; sa_rc_t rv; /* argument sanity check(s) */ if (sa == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* flushing is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* try to flush buffer */ rv = SA_OK; @@ -1825,7 +1934,7 @@ } sa->nWriteLen = 0; } - return rv; + return SA_RC(rv); } /* shutdown a socket connection */ @@ -1835,15 +1944,15 @@ /* argument sanity check(s) */ if (sa == NULL || flags == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* shutdown is only possible for stream communication */ if (sa->eType != SA_TYPE_STREAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a connection has to exist */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* determine flags for shutdown(2) */ how = 0; @@ -1854,11 +1963,11 @@ else if (strcmp(flags, "rw") == 0) how = SHUT_RDWR; else - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* perform shutdown operation on underlying socket */ if (shutdown(sa->fdSocket, how) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); return SA_OK; } @@ -1879,15 +1988,15 @@ /* argument sanity check(s) */ if (sa == NULL || buf == NULL || buflen == 0 || raddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* receiving is only possible for datagram communication */ if (sa->eType != SA_TYPE_DATAGRAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* at least a sa_bind() has to be performed */ if (sa->fdSocket == -1) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* if timeout is enabled, perform explicit/smart blocking instead of implicitly/hard blocking in the recvfrom(2) system call */ @@ -1901,14 +2010,14 @@ if (n == 0) errno = ETIMEDOUT; if (n <= 0) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); } /* perform receive operation on underlying socket */ sa_len = sizeof(sa_buf); if ((n = SA_SC_CALL_6(sa, recvfrom, sa->fdSocket, buf, buflen, 0, (struct sockaddr *)&sa_buf, &sa_len)) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* create result address object */ if ((rv = sa_addr_create(raddr)) != SA_OK) @@ -1934,11 +2043,11 @@ /* argument sanity check(s) */ if (sa == NULL || buf == NULL || buflen == 0 || raddr == NULL) - return SA_ERR_ARG; + return SA_RC(SA_ERR_ARG); /* sending is only possible for datagram communication */ if (sa->eType != SA_TYPE_DATAGRAM) - return SA_ERR_USE; + return SA_RC(SA_ERR_USE); /* lazy creation of underlying socket */ if (sa->fdSocket == -1) @@ -1957,12 +2066,12 @@ if (n == 0) errno = ETIMEDOUT; if (n <= 0) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); } /* perform send operation on underlying socket */ if ((n = SA_SC_CALL_6(sa, sendto, sa->fdSocket, buf, buflen, 0, raddr->saBuf, raddr->slBuf)) == -1) - return SA_ERR_SYS; + return SA_RC(SA_ERR_SYS); /* pass actual number of sent bytes to caller */ if (bufdone != NULL) Index: ossp-pkg/l2/l2_ut_sa.h RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.h,v rcsdiff -q -kk '-r1.13' '-r1.14' -u '/v/ossp/cvs/ossp-pkg/l2/l2_ut_sa.h,v' 2>/dev/null --- l2_ut_sa.h 2001/11/30 09:51:09 1.13 +++ l2_ut_sa.h 2002/10/11 16:00:48 1.14 @@ -1,11 +1,11 @@ /* -** SA - OSSP Socket Abstraction Library -** Copyright (c) 2001 Ralf S. Engelschall -** Copyright (c) 2001 The OSSP Project -** Copyright (c) 2001 Cable & Wireless Deutschland +** OSSP sa - Socket Abstraction +** Copyright (c) 2001-2002 Ralf S. Engelschall +** Copyright (c) 2001-2002 The OSSP Project +** Copyright (c) 2001-2002 Cable & Wireless Deutschland ** -** This file is part of OSSP SA, a socket abstraction library which -** can be found at http://www.ossp.org/pkg/sa/. +** 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 @@ -43,7 +43,7 @@ /* fallback for POSIX socklen_t */ #if defined(HAVE_CONFIG_H) && !defined(HAVE_SOCKLEN_T) -#define socklen_t int +typedef int socklen_t; #endif /* embedding support */ @@ -138,6 +138,9 @@ /* list of options */ typedef enum { SA_OPTION_NAGLE, + SA_OPTION_LINGER, + SA_OPTION_REUSEADDR, + SA_OPTION_REUSEPORT, SA_OPTION_NONBLOCK } sa_option_t; @@ -152,6 +155,9 @@ SA_SYSCALL_SENDTO } sa_syscall_t; +/* unique library identifier */ +extern const char sa_id[]; + /* address object operations */ sa_rc_t sa_addr_create (sa_addr_t **saa); sa_rc_t sa_addr_destroy (sa_addr_t *saa); Index: ossp-pkg/l2/l2_version.c RCS File: /v/ossp/cvs/ossp-pkg/l2/l2_version.c,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/l2/l2_version.c,v' 2>/dev/null --- l2_version.c 2002/07/30 19:08:25 1.5 +++ l2_version.c 2002/10/11 16:00:48 1.6 @@ -8,7 +8,7 @@ #ifndef _L2_VERSION_C_ #define _L2_VERSION_C_ -#define L2_VERSION 0x009200 +#define L2_VERSION 0x009201 typedef struct { const int v_hex; @@ -32,13 +32,13 @@ #undef _L2_VERSION_C_AS_HEADER_ l2_version_t l2_version = { - 0x009200, - "0.9.0", - "0.9.0 (30-Jul-2002)", - "This is OSSP l2, Version 0.9.0 (30-Jul-2002)", - "OSSP l2 0.9.0 (30-Jul-2002)", - "OSSP l2/0.9.0", - "@(#)OSSP l2 0.9.0 (30-Jul-2002)", + 0x009201, + "0.9.1", + "0.9.1 (11-Oct-2002)", + "This is OSSP l2, Version 0.9.1 (11-Oct-2002)", + "OSSP l2 0.9.1 (11-Oct-2002)", + "OSSP l2/0.9.1", + "@(#)OSSP l2 0.9.1 (11-Oct-2002)", "$Id$" };