--- sa.c 2001/10/02 13:27:44 1.1
+++ sa.c 2001/10/03 19:40:31 1.2
@@ -129,39 +129,66 @@
#error "neither inet_ntop nor inet_ntoa available"
#endif
-/* make sure vsnprintf() exists */
-#if defined(HAVE_VSNPRINTF)
-#define sa_vsnprintf vsnprintf
-#elif defined(HAVE_VSPRINTF)
-static int sa_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
+/* minimal vsnprintf(3) */
+static int sa_mvsnprintf(char *buffer, size_t bufsize, const char *format, va_list ap)
{
- int rv;
-
- rv = vsprintf(str, fmt, ap);
- if (rv > size) {
- fprintf(stderr, "ERROR: vsprintf(3) buffer overflow!\n");
- abort();
+ char *bufptr;
+ char *bufend;
+ char ibuf[((sizeof(int)*8)/3)+10]; /* (available bits) x log_10(2) + safety */
+ char *cp;
+ char c;
+ int d;
+ int n;
+
+ bufptr = buffer;
+ bufend = buffer + bufsize - 1;
+ while ((c = *format++) != '\0' && bufptr < bufend) {
+ if (c == '%') {
+ c = *format++;
+ if (c == '%')
+ *bufptr++ = c;
+ else if (c == 'c')
+ *bufptr++ = (char)va_arg(ap, int);
+ else if (c == 's') {
+ if ((cp = (char *)va_arg(ap, char *)) == NULL)
+ cp = "(null)";
+ n = strlen(cp);
+ if ((bufptr + n) > bufend)
+ n = bufend - bufptr;
+ memcpy(bufptr, cp, n);
+ bufptr += n;
+ }
+ else if (c == 'd') {
+ d = (int)va_arg(ap, int);
+ sprintf(ibuf, "%d", d);
+ n = strlen(ibuf);
+ memcpy(bufptr, ibuf, n);
+ bufptr += n;
+ }
+ else {
+ *bufptr++ = '%';
+ if (bufptr < bufend)
+ *bufptr++ = c;
+ }
+ }
+ else
+ *bufptr++ = c;
}
+ *bufptr = '\0';
+ return (bufptr - buffer);
}
-#else
-#error "neither vsnprintf nor vsprintf available"
-#endif
-/* make sure snprintf() exists */
-#if defined(HAVE_SNPRINTF)
-#define sa_snprintf snprintf
-#else
-static int sa_snprintf(char *str, size_t size, const char *fmt, ...)
+/* minimal snprintf(3) */
+static int sa_msnprintf(char *buffer, size_t bufsize, const char *format, ...)
{
+ int chars;
va_list ap;
- int rv;
- va_start(ap, fmt);
- rv = sa_vsnprintf(str, size, fmt, ap);
+ va_start(ap, format);
+ chars = sa_mvsnprintf(buffer, bufsize, format, ap);
va_end(ap);
- return rv;
+ return chars;
}
-#endif
sa_rc_t sa_u2a(sa_addr_t **saa, const char *uri, ...)
{
@@ -192,7 +219,7 @@
/* on-the-fly create or just take over URI */
va_start(ap, uri);
- sa_vsnprintf(uribuf, sizeof(uribuf), uri, ap);
+ sa_mvsnprintf(uribuf, sizeof(uribuf), uri, ap);
va_end(ap);
/* parse URI into protocol, host and port parts */
@@ -369,7 +396,7 @@
#endif
else
return SA_ERR_ARG;
- sa_snprintf(uribuf, sizeof(uribuf), "%s://%s:%d", pe->p_name, caHost, nPort);
+ sa_msnprintf(uribuf, sizeof(uribuf), "%s://%s:%d", pe->p_name, caHost, nPort);
*uri = strdup(uribuf);
return SA_OK;
}
@@ -490,6 +517,28 @@
return SA_OK;
}
+sa_rc_t sa_getoption(sa_t *sa, int optname, void *optval, socklen_t *optlen)
+{
+ if (sa == NULL)
+ return SA_ERR_ARG;
+ if (sa->sSocket == -1)
+ return SA_ERR_USE;
+ if (getsockopt(sa->sSocket, SOL_SOCKET, optname, optval, optlen) == -1)
+ return SA_ERR_SYS;
+ return SA_OK;
+}
+
+sa_rc_t sa_setoption(sa_t *sa, int optname, const void *optval, socklen_t optlen)
+{
+ if (sa == NULL)
+ return SA_ERR_ARG;
+ if (sa->sSocket == -1)
+ return SA_ERR_USE;
+ if (setsockopt(sa->sSocket, SOL_SOCKET, optname, optval, optlen) == -1)
+ return SA_ERR_SYS;
+ return SA_OK;
+}
+
sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr)
{
sa_rc_t rv;
@@ -905,7 +954,7 @@
return SA_OK;
}
-sa_rc_t sa_printf(sa_t *sa, const char *cpFmt, ...)
+sa_rc_t sa_writef(sa_t *sa, const char *cpFmt, ...)
{
va_list ap;
size_t n;
@@ -914,7 +963,7 @@
if (sa == NULL)
return SA_ERR_ARG;
va_start(ap, cpFmt);
- n = sa_vsnprintf(caBuf, sizeof(caBuf), cpFmt, ap);
+ n = sa_mvsnprintf(caBuf, sizeof(caBuf), cpFmt, ap);
sa_write(sa, caBuf, n, &n);
va_end(ap);
return SA_OK;
|