From b6414381b96e41a26b9150cc44e36a839084f673 Mon Sep 17 00:00:00 2001 From: Stefan Ritt Date: Wed, 28 Jul 2004 12:52:30 +0000 Subject: [PATCH] Added int_vasprintf from Recai Oktas SVN revision: 988 --- src/elogd.c | 123 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/src/elogd.c b/src/elogd.c index 032f512d..93737417 100755 --- a/src/elogd.c +++ b/src/elogd.c @@ -6,6 +6,9 @@ Contents: Web server program for Electronic Logbook ELOG $Log$ + Revision 1.409 2004/07/28 12:52:30 midas + Added int_vasprintf from Recai Oktas + Revision 1.408 2004/07/28 12:00:38 midas Fixed bug with invalid sizeof(list) @@ -733,7 +736,104 @@ char *stristr(const char *str, const char *pattern) /*----------------------- Message handling -------------------------*/ -#ifdef OS_UNIX +/* Have vasprintf? (seems that only libc6 based Linux has this) */ +#ifdef __linux__ +# define HAVE_VASPRINTF +#endif + +#ifndef HAVE_VASPRINTF +/* vasprintf implementation taken (and adapted) from GNU libiberty */ + +static int int_vasprintf(char **result, const char *format, va_list args) +{ + const char *p = format; + /* Add one to make sure that it is never zero, which might cause malloc + to return NULL. */ + int total_width = strlen(format) + 1; + va_list ap; + +#ifdef va_copy + va_copy(ap, args); +#else + memcpy(&ap, &args, sizeof(va_list)); +#endif + + while (*p != '\0') { + if (*p++ == '%') { + while (strchr("-+ #0", *p)) + ++p; + if (*p == '*') { + ++p; + total_width += abs(va_arg(ap, int)); + } else + total_width += strtoul(p, (char **) &p, 10); + if (*p == '.') { + ++p; + if (*p == '*') { + ++p; + total_width += abs(va_arg(ap, int)); + } else + total_width += strtoul(p, (char **) &p, 10); + } + while (strchr("hlL", *p)) + ++p; + /* + * Should be big enough for any format specifier + * except %s and floats. + */ + total_width += 30; + switch (*p) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + (void) va_arg(ap, int); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + (void) va_arg(ap, double); + /* + * Since an ieee double can have an exponent of 307, we'll + * make the buffer wide enough to cover the gross case. + */ + total_width += 307; + break; + case 's': + total_width += strlen(va_arg(ap, char *)); + break; + case 'p': + case 'n': + (void) va_arg(ap, char *); + break; + } + p++; + } + } +#ifdef va_copy + va_end(ap); +#endif + *result = (char *) malloc(total_width); + if (*result != NULL) + return vsprintf(*result, format, args); + else + return -1; +} + +#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) +int vasprintf(char **result, const char *format, _BSD_VA_LIST_ args) +#else +int vasprintf(char **result, const char *format, va_list args) +#endif +{ + return int_vasprintf(result, format, args); +} +#endif /* ! HAVE_VASPRINTF */ /* Safe replacement for vasprintf (adapted code from Samba) */ int xvasprintf(char **ptr, const char *format, va_list ap) @@ -776,23 +876,6 @@ void eprintf(const char *format, ...) free(msg); } -#else /* OS_UNIX */ - -/* Driver for printf_handler, drop-in replacement for printf */ -void eprintf(const char *format, ...) -{ - va_list ap; - char msg[10000]; - - va_start(ap, format); - vsprintf(msg, format, ap); - va_end(ap); - - (*printf_handler) (msg); -} - -#endif - /* Driver for fputs_handler, drop-in replacement for fputs(buf, fd) */ void efputs(const char *buf) { @@ -850,7 +933,7 @@ void fputs_stderr(const char *buf) fputs(buf, stderr); } -/* Redirect all messages handled with eprintf/efputs +/* Redirect all messages handled with eprintf/efputs to syslog (Unix) or event log (Windows) */ void redirect_to_syslog(void) { @@ -19984,7 +20067,7 @@ int read_password(char *pwd, int size) } while (1); str[n] = 0; - + strlcpy(pwd, str, size); return n; }