From 91097d7d32a033142c382a843d3caeb9396bd820 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 19 Oct 2004 17:20:15 +0000 Subject: [PATCH] return the number of elements copied from address to ascii conversion func --- src/libCom/osi/osiSock.c | 133 +++++++++++++++++++++------------------ src/libCom/osi/osiSock.h | 46 +++++++++----- 2 files changed, 105 insertions(+), 74 deletions(-) diff --git a/src/libCom/osi/osiSock.c b/src/libCom/osi/osiSock.c index c3a939001..a077ec0e9 100644 --- a/src/libCom/osi/osiSock.c +++ b/src/libCom/osi/osiSock.c @@ -22,13 +22,11 @@ #define epicsExportSharedSymbols #include "epicsAssert.h" #include "epicsSignal.h" +#include "epicsStdio.h" #include "osiSock.h" #define nDigitsDottedIP 4u -#define maxChunkDigit 3u -#define maxDottedIPDigit ( ( nDigitsDottedIP - 1 ) + nDigitsDottedIP*maxChunkDigit ) #define chunkSize 8u -#define maxPortDigits 5u #define makeMask(NBITS) ( ( 1u << ( (unsigned) NBITS) ) - 1u ) @@ -63,23 +61,30 @@ int epicsShareAPI sockAddrAreIdentical * sockAddrToA() * (convert socket address to ASCII host name) */ -void epicsShareAPI sockAddrToA - ( const struct sockaddr *paddr, char *pBuf, unsigned bufSize ) +unsigned epicsShareAPI sockAddrToA ( + const struct sockaddr * paddr, char * pBuf, unsigned bufSize ) { - if (bufSize<1) { - return; + if ( bufSize < 1 ) { + return 0; } - if (paddr->sa_family!=AF_INET) { - strncpy (pBuf, "", bufSize-1); - /* - * force null termination - */ - pBuf[bufSize-1] = '\0'; + if ( paddr->sa_family != AF_INET ) { + static const char * pErrStr = ""; + unsigned len = strlen ( pErrStr ); + if ( len < bufSize ) { + strcpy ( pBuf, pErrStr ); + return len; + } + else { + strncpy ( pBuf, "", bufSize-1 ); + pBuf[bufSize-1] = '\0'; + return bufSize-1; + } } else { - const struct sockaddr_in *paddr_in = ( const struct sockaddr_in * ) paddr; - ipAddrToA ( paddr_in, pBuf, bufSize ); + const struct sockaddr_in * paddr_in = + (const struct sockaddr_in *) paddr; + return ipAddrToA ( paddr_in, pBuf, bufSize ); } } @@ -87,32 +92,33 @@ void epicsShareAPI sockAddrToA * ipAddrToA() * (convert IP address to ASCII host name) */ -void epicsShareAPI ipAddrToA - ( const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ) +unsigned epicsShareAPI ipAddrToA ( + const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ) { - unsigned len; - - len = ipAddrToHostName ( &paddr->sin_addr, pBuf, bufSize ); + unsigned len = ipAddrToHostName ( + & paddr->sin_addr, pBuf, bufSize ); if ( len == 0 ) { - ipAddrToDottedIP ( paddr, pBuf, bufSize ); + len = ipAddrToDottedIP ( paddr, pBuf, bufSize ); } else { - assert ( len < bufSize ); - bufSize -= len; - - /* - * allow space for the port number - */ - if ( bufSize > maxPortDigits + 1 ) { - sprintf ( &pBuf[len], ":%hu", ntohs (paddr->sin_port) ); - } + unsigned reducedSize = bufSize - len; + int status = epicsSnprintf ( + &pBuf[len], reducedSize, ":%hu", + ntohs (paddr->sin_port) ); + if ( status > 0 ) { + unsigned portSize = (unsigned) status; + if ( portSize < reducedSize ) { + len += portSize; + } + } } + return len; } /* * sockAddrToDottedIP () */ -void epicsShareAPI sockAddrToDottedIP +unsigned epicsShareAPI sockAddrToDottedIP ( const struct sockaddr *paddr, char *pBuf, unsigned bufSize ) { if ( paddr->sa_family != AF_INET ) { @@ -131,40 +137,47 @@ void epicsShareAPI sockAddrToDottedIP /* * ipAddrToDottedIP () */ -void epicsShareAPI ipAddrToDottedIP - ( const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ) +unsigned epicsShareAPI ipAddrToDottedIP ( + const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ) { - if ( bufSize > maxDottedIPDigit ) { - unsigned chunk[nDigitsDottedIP]; - unsigned addr = ntohl ( paddr->sin_addr.s_addr ); - unsigned i; - unsigned len; + static const char * pErrStr = ""; + unsigned chunk[nDigitsDottedIP]; + unsigned addr = ntohl ( paddr->sin_addr.s_addr ); + unsigned strLen; + unsigned i; + int status; - for ( i = 0; i < nDigitsDottedIP; i++ ) { - chunk[i] = addr & makeMask ( chunkSize ); - addr >>= chunkSize; + if ( bufSize == 0u ) { + return 0u; + } + + for ( i = 0; i < nDigitsDottedIP; i++ ) { + chunk[i] = addr & makeMask ( chunkSize ); + addr >>= chunkSize; + } + + /* + * inet_ntoa() isnt used because it isnt thread safe + * (and the replacements are not standardized) + */ + status = epicsSnprintf ( pBuf, bufSize, "%u.%u.%u.%u:%hu", + chunk[3], chunk[2], chunk[1], chunk[0], + ntohs ( paddr->sin_port ) ); + if ( status > 0 ) { + strLen = ( unsigned ) status; + if ( strLen > bufSize - 1 ) { + return strLen; } - - /* - * inet_ntoa() isnt used because it isnt thread safe - * (and the replacements are not standardized) - */ - len = (unsigned) sprintf ( pBuf, "%u.%u.%u.%u", - chunk[3], chunk[2], chunk[1], chunk[0] ); - - assert ( len < bufSize ); - bufSize -= len; - - /* - * allow space for the port number - */ - if ( bufSize > maxPortDigits + 1 ) { - sprintf ( &pBuf[len], ":%hu", ntohs ( paddr->sin_port ) ); - } + } + strLen = strlen ( pErrStr ); + if ( strLen < bufSize ) { + strcpy ( pBuf, pErrStr ); + return strLen; } else { - strncpy ( pBuf, "", bufSize ); - pBuf[bufSize-1] = '\0'; + strncpy ( pBuf, pErrStr, bufSize ); + pBuf[bufSize-1] = '\0'; + return bufSize - 1u; } } diff --git a/src/libCom/osi/osiSock.h b/src/libCom/osi/osiSock.h index 90d36165e..1855ad41a 100644 --- a/src/libCom/osi/osiSock.h +++ b/src/libCom/osi/osiSock.h @@ -59,44 +59,62 @@ epicsShareFunc enum epicsSocketSystemCallInterruptMechanismQueryInfo /* * convert socket address to ASCII in this order * 1) look for matching host name and typically add trailing IP port - * 2) convert to raw ascii address (typically this is a + * 2) failing that, convert to raw ascii address (typically this is a * dotted IP address with trailing port) + * 3) failing that, writes "" into pBuf + * + * returns the number of character elements stored in buffer not + * including the null termination, but always writes at least a + * null ternminater in the string (if bufSize >= 1) */ -epicsShareFunc void epicsShareAPI sockAddrToA - (const struct sockaddr *paddr, char *pBuf, unsigned bufSize); +epicsShareFunc unsigned epicsShareAPI sockAddrToA ( + const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); /* * convert IP address to ASCII in this order * 1) look for matching host name and add trailing port * 2) convert to raw dotted IP address with trailing port + * + * returns the number of character elements stored in buffer not + * including the null termination, but always writes at least a + * null ternminater in the string (if bufSize >= 1) */ -epicsShareFunc void epicsShareAPI ipAddrToA - (const struct sockaddr_in *pInetAddr, char *pBuf, unsigned bufSize); +epicsShareFunc unsigned epicsShareAPI ipAddrToA ( + const struct sockaddr_in * pInetAddr, char * pBuf, unsigned bufSize ); /* * sockAddrToDottedIP () * typically convert to raw dotted IP address with trailing port + * + * returns the number of character elements stored in buffer not + * including the null termination, but always writes at least a + * null ternminater in the string (if bufSize >= 1) */ -epicsShareFunc void epicsShareAPI sockAddrToDottedIP - ( const struct sockaddr *paddr, char *pBuf, unsigned bufSize ); +epicsShareFunc unsigned epicsShareAPI sockAddrToDottedIP ( + const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); /* * ipAddrToDottedIP () * convert to raw dotted IP address with trailing port + * + * returns the number of character elements stored in buffer not + * including the null termination, but always writes at least a + * null ternminater in the string (if bufSize >= 1) */ -epicsShareFunc void epicsShareAPI ipAddrToDottedIP - ( const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ); +epicsShareFunc unsigned epicsShareAPI ipAddrToDottedIP ( + const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ); /* * convert inet address to a host name string * - * returns the number of bytes stored in buffer not counting the terminating - * null character, or zero on failure + * returns the number of character elements stored in buffer not + * including the null termination. This will be zero if a matching + * host name cant be found. * * there are many OS specific implementation stubs for this routine */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize); +epicsShareFunc unsigned epicsShareAPI ipAddrToHostName ( + const struct in_addr * pAddr, char * pBuf, unsigned bufSize ); /* * attempt to convert ASCII string to an IP address in this order @@ -105,7 +123,7 @@ epicsShareFunc unsigned epicsShareAPI ipAddrToHostName * 3) look for valid host name with optional port */ epicsShareFunc int epicsShareAPI aToIPAddr - (const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP); + ( const char * pAddrString, unsigned short defaultPort, struct sockaddr_in * pIP); /* * attempt to convert ASCII host name string with optional port to an IP address