]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ntp/libntp/xsbprintf.c
Update ntpd to 4.2.8p13 to fix authenticated denial of service.
[FreeBSD/FreeBSD.git] / contrib / ntp / libntp / xsbprintf.c
1 /*
2  * xsbprintf.c - string buffer formatting helpers
3  *
4  * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
5  * The contents of 'html/copyright.html' apply.
6  */
7
8 #include <config.h>
9 #include <sys/types.h>
10
11 #include "ntp_stdlib.h"
12
13 /* eXtended Varlist String Buffer printf
14  *
15  * Formats via 'vsnprintf' into a string buffer, with some semantic
16  * specialties:
17  *
18  * - The start of the buffer pointer is updated according to the number
19  *   of characters written.
20  * - If the buffer is insufficient to format the number of charactes,
21  *   the partial result will be be discarded, and zero is returned to
22  *   indicate nothing was written to the buffer.
23  * - On successful formatting, the return code is the return value of
24  *   the inner call to 'vsnprintf()'.
25  * - If there is any error, the state of the buffer will not be
26  *   changed. (Bytes in the buffer might be smashed, but the buffer
27  *   position does not change, and the NUL marker stays in place at the
28  *   current buffer position.)
29  * - If '(*ppbuf - pend) <= 0' (or ppbuf is NULL), fail with EINVAL.
30  */
31 int
32 xvsbprintf(
33         char       **ppbuf,     /* pointer to buffer pointer (I/O) */
34         char * const pend,      /* buffer end (I)                  */
35         char const  *pfmt,      /* printf-like format string       */
36         va_list      va         /* formatting args for above       */
37         )
38 {
39         char *pbuf = (ppbuf) ? *ppbuf : NULL;
40         int   rc   = -1;
41         if (pbuf && (pend - pbuf > 0)) {
42                 size_t blen = (size_t)(pend - pbuf);
43                 rc = vsnprintf(pbuf, blen, pfmt, va);
44                 if (rc > 0) {
45                     if ((size_t)rc >= blen)
46                         rc = 0;
47                     pbuf += rc;
48                 }
49                 *pbuf = '\0'; /* fear of bad vsnprintf */
50                 *ppbuf = pbuf;
51         } else {
52                 errno = EINVAL;
53         }
54         return rc;
55 }
56
57 /* variadic wrapper around the buffer string formatter */
58 int
59 xsbprintf(
60         char       **ppbuf,     /* pointer to buffer pointer (I/O) */
61         char * const pend,      /* buffer end (I)                  */
62         char const  *pfmt,      /* printf-like format string       */
63         ...                     /* formatting args for above       */
64         )
65 {
66         va_list va;
67         int     rc;
68         
69         va_start(va, pfmt);
70         rc = xvsbprintf(ppbuf, pend, pfmt, va);
71         va_end(va);
72         return rc;
73 }
74
75 /* that's all folks! */