Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- 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; Index: ossp-pkg/sa/sa.h RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.h,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/sa/sa.h,v' 2>/dev/null --- sa.h 2001/10/02 14:12:27 1.2 +++ sa.h 2001/10/03 19:40:31 1.3 @@ -105,6 +105,8 @@ /* parameter operations */ sa_rc_t sa_timeout (sa_t *sa, long sec, long usec); sa_rc_t sa_buffers (sa_t *sa, size_t rsize, size_t wsize); +sa_rc_t sa_getoption(sa_t *sa, int optname, void *optval, socklen_t *optlen); +sa_rc_t sa_setoption(sa_t *sa, int optname, const void *optval, socklen_t optlen); /* connection operations */ sa_rc_t sa_bind (sa_t *sa, sa_addr_t *laddr); @@ -122,7 +124,7 @@ sa_rc_t sa_readline (sa_t *sa, char *buf, size_t buflen, size_t *bufdone); sa_rc_t sa_write (sa_t *sa, const char *buf, size_t buflen, size_t *bufdone); sa_rc_t sa_writeto (sa_t *sa, const char *buf, size_t buflen, size_t *bufdone, sa_addr_t *raddr); -sa_rc_t sa_printf (sa_t *sa, const char *fmt, ...); +sa_rc_t sa_writef (sa_t *sa, const char *fmt, ...); sa_rc_t sa_flush (sa_t *sa); #endif /* __SA_H__ */