|
Packit |
209cc3 |
#include <stdio.h>
|
|
Packit |
209cc3 |
#include <stdlib.h>
|
|
Packit |
209cc3 |
#include <stdarg.h>
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
#include "portability.h"
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* vasprintf() and asprintf() for platforms with a C99-compliant
|
|
Packit |
209cc3 |
* snprintf() - so that, if you format into a 1-byte buffer, it
|
|
Packit |
209cc3 |
* will return how many characters it would have produced had
|
|
Packit |
209cc3 |
* it been given an infinite-sized buffer.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
int
|
|
Packit |
209cc3 |
pcap_vasprintf(char **strp, const char *format, va_list args)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
char buf;
|
|
Packit |
209cc3 |
int len;
|
|
Packit |
209cc3 |
size_t str_size;
|
|
Packit |
209cc3 |
char *str;
|
|
Packit |
209cc3 |
int ret;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* XXX - the C99 standard says, in section 7.19.6.5 "Thes
|
|
Packit |
209cc3 |
* nprintf function":
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* The snprintf function is equivalent to fprintf, except that
|
|
Packit |
209cc3 |
* the output is written into an array (specified by argument s)
|
|
Packit |
209cc3 |
* rather than to a stream. If n is zero, nothing is written,
|
|
Packit |
209cc3 |
* and s may be a null pointer. Otherwise, output characters
|
|
Packit |
209cc3 |
* beyond the n-1st are discarded rather than being written
|
|
Packit |
209cc3 |
* to the array, and a null character is written at the end
|
|
Packit |
209cc3 |
* of the characters actually written into the array.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* ...
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* The snprintf function returns the number of characters that
|
|
Packit |
209cc3 |
* would have been written had n been sufficiently large, not
|
|
Packit |
209cc3 |
* counting the terminating null character, or a negative value
|
|
Packit |
209cc3 |
* if an encoding error occurred. Thus, the null-terminated
|
|
Packit |
209cc3 |
* output has been completely written if and only if the returned
|
|
Packit |
209cc3 |
* value is nonnegative and less than n.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* That doesn't make it entirely clear whether, if a null buffer
|
|
Packit |
209cc3 |
* pointer and a zero count are passed, it will return the number
|
|
Packit |
209cc3 |
* of characters that would have been written had a buffer been
|
|
Packit |
209cc3 |
* passed.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* And, even if C99 *does*, in fact, say it has to work, it
|
|
Packit |
209cc3 |
* doesn't work in Solaris 8, for example - it returns -1 for
|
|
Packit |
209cc3 |
* NULL/0, but returns the correct character count for a 1-byte
|
|
Packit |
209cc3 |
* buffer.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* So we pass a one-character pointer in order to find out how
|
|
Packit |
209cc3 |
* many characters this format and those arguments will need
|
|
Packit |
209cc3 |
* without actually generating any more of those characters
|
|
Packit |
209cc3 |
* than we need.
|
|
Packit |
209cc3 |
*
|
|
Packit |
209cc3 |
* (The fact that it might happen to work with GNU libc or with
|
|
Packit |
209cc3 |
* various BSD libcs is completely uninteresting, as those tend
|
|
Packit |
209cc3 |
* to have asprintf() already and thus don't even *need* this
|
|
Packit |
209cc3 |
* code; this is for use in those UN*Xes that *don't* have
|
|
Packit |
209cc3 |
* asprintf().)
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
len = vsnprintf(&buf, sizeof buf, format, args);
|
|
Packit |
209cc3 |
if (len == -1) {
|
|
Packit |
209cc3 |
*strp = NULL;
|
|
Packit |
209cc3 |
return (-1);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
str_size = len + 1;
|
|
Packit |
209cc3 |
str = malloc(str_size);
|
|
Packit |
209cc3 |
if (str == NULL) {
|
|
Packit |
209cc3 |
*strp = NULL;
|
|
Packit |
209cc3 |
return (-1);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
ret = vsnprintf(str, str_size, format, args);
|
|
Packit |
209cc3 |
if (ret == -1) {
|
|
Packit |
209cc3 |
free(str);
|
|
Packit |
209cc3 |
*strp = NULL;
|
|
Packit |
209cc3 |
return (-1);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
*strp = str;
|
|
Packit |
209cc3 |
/*
|
|
Packit |
209cc3 |
* vsnprintf() shouldn't truncate the string, as we have
|
|
Packit |
209cc3 |
* allocated a buffer large enough to hold the string, so its
|
|
Packit |
209cc3 |
* return value should be the number of characters written.
|
|
Packit |
209cc3 |
*/
|
|
Packit |
209cc3 |
return (ret);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
int
|
|
Packit |
209cc3 |
pcap_asprintf(char **strp, const char *format, ...)
|
|
Packit |
209cc3 |
{
|
|
Packit |
209cc3 |
va_list args;
|
|
Packit |
209cc3 |
int ret;
|
|
Packit |
209cc3 |
|
|
Packit |
209cc3 |
va_start(args, format);
|
|
Packit |
209cc3 |
ret = pcap_vasprintf(strp, format, args);
|
|
Packit |
209cc3 |
va_end(args);
|
|
Packit |
209cc3 |
return (ret);
|
|
Packit |
209cc3 |
}
|
|
Packit |
209cc3 |
|