summaryrefslogtreecommitdiffstats
path: root/src/util/support/k5buf.c
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2008-10-28 22:03:35 +0000
committerGreg Hudson <ghudson@mit.edu>2008-10-28 22:03:35 +0000
commit88cd11e1087decfebf0fd87e5243dab9efc9c686 (patch)
treece245e9c6298934b486d3cfa92557304639efaa6 /src/util/support/k5buf.c
parent886967fbb7889a6a2654b5256bb9bb442382ccde (diff)
downloadkrb5-88cd11e1087decfebf0fd87e5243dab9efc9c686.tar.gz
krb5-88cd11e1087decfebf0fd87e5243dab9efc9c686.tar.xz
krb5-88cd11e1087decfebf0fd87e5243dab9efc9c686.zip
In the k5buf module, add a function to append formatted data to a
buffer. ticket: 6200 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20932 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util/support/k5buf.c')
-rw-r--r--src/util/support/k5buf.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index 747490280..23fb20365 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -115,6 +115,71 @@ void krb5int_buf_add_len(struct k5buf *buf, const char *data, size_t len)
buf->data[buf->len] = '\0';
}
+void krb5int_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+ size_t remaining;
+ char *tmp;
+
+ if (buf->buftype == ERROR)
+ return;
+ remaining = buf->space - buf->len;
+
+ if (buf->buftype == FIXED) {
+ /* Format the data directly into the fixed buffer. */
+ va_start(ap, fmt);
+ r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ va_end(ap);
+ if (SNPRINTF_OVERFLOW(r, remaining))
+ buf->buftype = ERROR;
+ else
+ buf->len += (unsigned int) r;
+ return;
+ }
+
+ /* Optimistically format the data directly into the dynamic buffer. */
+ assert(buf->buftype == DYNAMIC);
+ va_start(ap, fmt);
+ r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ va_end(ap);
+ if (!SNPRINTF_OVERFLOW(r, remaining)) {
+ buf->len += (unsigned int) r;
+ return;
+ }
+
+ if (r >= 0) {
+ /* snprintf correctly told us how much space is required. */
+ if (!ensure_space(buf, r))
+ return;
+ remaining = buf->space - buf->len;
+ va_start(ap, fmt);
+ r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
+ va_end(ap);
+ if (SNPRINTF_OVERFLOW(r, remaining)) /* Shouldn't ever happen. */
+ buf->buftype = ERROR;
+ else
+ buf->len += (unsigned int) r;
+ return;
+ }
+
+ /* It's a pre-C99 snprintf implementation, or something else went
+ wrong. Fall back to asprintf. */
+ va_start(ap, fmt);
+ r = vasprintf(&tmp, fmt, ap);
+ va_end(ap);
+ if (r < 0) {
+ buf->buftype = ERROR;
+ return;
+ }
+ if (ensure_space(buf, r)) {
+ /* Copy the temporary string into buf, including terminator. */
+ memcpy(buf->data + buf->len, tmp, r + 1);
+ buf->len += r;
+ }
+ free(tmp);
+}
+
void krb5int_buf_truncate(struct k5buf *buf, size_t len)
{
if (buf->buftype == ERROR)