+
+static int
+grr_sprintf_alloc (char **str, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = grr_sprintf_alloc_va (str, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+/* ripped more or less straight out of PRINTF(3) */
+static int
+grr_sprintf_alloc_va (char **str, const char *fmt, va_list ap)
+{
+ char *new_str;
+ /* Guess we need no more than 100 bytes. */
+ int n, size = 100;
+
+ if ((*str = malloc (size)) == NULL)
+ return -1;
+ while (1) {
+ /* Try to print in the allocated space. */
+ n = vsnprintf (*str, size, fmt, ap);
+ /* If that worked, return the size. */
+ if (n > -1 && n < size)
+ return n;
+ /* Else try again with more space. */
+ if (n > -1) /* glibc 2.1 */
+ size = n+1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+ new_str = realloc(*str, size);
+ if (new_str == NULL) {
+ free(*str);
+ *str = NULL;
+ return -1;
+ }
+ *str = new_str;
+ }
+}