summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pw/Makefile5
-rw-r--r--pw/sbuf/subr_prf.c1310
-rw-r--r--pw/sbuf/subr_sbuf.c950
-rw-r--r--pw/sbuf/sys/sbuf.h123
4 files changed, 1 insertions, 2387 deletions
diff --git a/pw/Makefile b/pw/Makefile
index 776d231..f13d1e3 100644
--- a/pw/Makefile
+++ b/pw/Makefile
@@ -24,9 +24,6 @@ SRC := pw_utils.c \
cpdir.c \
strtonum.c
-SBUFSRC := sbuf/subr_sbuf.c \
- sbuf/subr_prf.c
-
LIBUTILSRC := libutil/_secure_path.c \
libutil/gr_util.c \
libutil/flopen.c \
@@ -45,7 +42,7 @@ pw: $(SRC:%.c=%.o) $(LIBUTILSRC:%.c=%.o) $(SBUFSRC:%.c=%.o) ent.xml
$(LDID) -Sent.xml $@
%.o: %.c
- $(CC) $(CFLAGS) -c -o $@ $< -I. -Isbuf -Ilibutil
+ $(CC) $(CFLAGS) -c -o $@ $< -I. -Ilibutil
install-pw: pw pw.8 pw.conf.5
$(GINSTALL) -Dm755 pw $(DESTDIR)/$(PREFIX)/sbin/pw
diff --git a/pw/sbuf/subr_prf.c b/pw/sbuf/subr_prf.c
deleted file mode 100644
index de4ff4f..0000000
--- a/pw/sbuf/subr_prf.c
+++ /dev/null
@@ -1,1310 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1986, 1988, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifdef _KERNEL
-#include "opt_ddb.h"
-#include "opt_printf.h"
-#endif /* _KERNEL */
-
-#include <sys/param.h>
-#ifdef _KERNEL
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/kdb.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-#include <sys/kernel.h>
-#include <sys/msgbuf.h>
-#include <sys/malloc.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/stddef.h>
-#include <sys/sysctl.h>
-#include <sys/tty.h>
-#include <sys/syslog.h>
-#include <sys/cons.h>
-#include <sys/uio.h>
-#else /* !_KERNEL */
-#include <errno.h>
-#endif
-#include <ctype.h>
-#include <sys/sbuf.h>
-
-#ifdef DDB
-#include <ddb/ddb.h>
-#endif
-
-/*
- * Note that stdarg.h and the ANSI style va_start macro is used for both
- * ANSI and traditional C compilers.
- */
-#ifdef _KERNEL
-#include <machine/stdarg.h>
-#else
-#include <stdarg.h>
-#endif
-
-/*
- * This is needed for sbuf_putbuf() when compiled into userland. Due to the
- * shared nature of this file, it's the only place to put it.
- */
-#ifndef _KERNEL
-#include <stdio.h>
-#endif
-
-#ifdef _KERNEL
-
-#define TOCONS 0x01
-#define TOTTY 0x02
-#define TOLOG 0x04
-
-/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
-#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
-
-struct putchar_arg {
- int flags;
- int pri;
- struct tty *tty;
- char *p_bufr;
- size_t n_bufr;
- char *p_next;
- size_t remain;
-};
-
-struct snprintf_arg {
- char *str;
- size_t remain;
-};
-
-extern int log_open;
-
-static void msglogchar(int c, int pri);
-static void msglogstr(char *str, int pri, int filter_cr);
-static void putchar(int ch, void *arg);
-static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
-static void snprintf_func(int ch, void *arg);
-
-static bool msgbufmapped; /* Set when safe to use msgbuf */
-int msgbuftrigger;
-struct msgbuf *msgbufp;
-
-#ifndef BOOT_TAG_SZ
-#define BOOT_TAG_SZ 32
-#endif
-#ifndef BOOT_TAG
-/* Tag used to mark the start of a boot in dmesg */
-#define BOOT_TAG "---<<BOOT>>---"
-#endif
-
-static char current_boot_tag[BOOT_TAG_SZ + 1] = BOOT_TAG;
-SYSCTL_STRING(_kern, OID_AUTO, boot_tag, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
- current_boot_tag, 0, "Tag added to dmesg at start of boot");
-
-static int log_console_output = 1;
-SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RWTUN,
- &log_console_output, 0, "Duplicate console output to the syslog");
-
-/*
- * See the comment in log_console() below for more explanation of this.
- */
-static int log_console_add_linefeed;
-SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RWTUN,
- &log_console_add_linefeed, 0, "log_console() adds extra newlines");
-
-static int always_console_output;
-SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RWTUN,
- &always_console_output, 0, "Always output to console despite TIOCCONS");
-
-/*
- * Warn that a system table is full.
- */
-void
-tablefull(const char *tab)
-{
-
- log(LOG_ERR, "%s: table is full\n", tab);
-}
-
-/*
- * Uprintf prints to the controlling terminal for the current process.
- */
-int
-uprintf(const char *fmt, ...)
-{
- va_list ap;
- struct putchar_arg pca;
- struct proc *p;
- struct thread *td;
- int retval;
-
- td = curthread;
- if (TD_IS_IDLETHREAD(td))
- return (0);
-
- if (td->td_proc == initproc) {
- /* Produce output when we fail to load /sbin/init: */
- va_start(ap, fmt);
- retval = vprintf(fmt, ap);
- va_end(ap);
- return (retval);
- }
-
- sx_slock(&proctree_lock);
- p = td->td_proc;
- PROC_LOCK(p);
- if ((p->p_flag & P_CONTROLT) == 0) {
- PROC_UNLOCK(p);
- sx_sunlock(&proctree_lock);
- return (0);
- }
- SESS_LOCK(p->p_session);
- pca.tty = p->p_session->s_ttyp;
- SESS_UNLOCK(p->p_session);
- PROC_UNLOCK(p);
- if (pca.tty == NULL) {
- sx_sunlock(&proctree_lock);
- return (0);
- }
- pca.flags = TOTTY;
- pca.p_bufr = NULL;
- va_start(ap, fmt);
- tty_lock(pca.tty);
- sx_sunlock(&proctree_lock);
- retval = kvprintf(fmt, putchar, &pca, 10, ap);
- tty_unlock(pca.tty);
- va_end(ap);
- return (retval);
-}
-
-/*
- * tprintf and vtprintf print on the controlling terminal associated with the
- * given session, possibly to the log as well.
- */
-void
-tprintf(struct proc *p, int pri, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vtprintf(p, pri, fmt, ap);
- va_end(ap);
-}
-
-void
-vtprintf(struct proc *p, int pri, const char *fmt, va_list ap)
-{
- struct tty *tp = NULL;
- int flags = 0;
- struct putchar_arg pca;
- struct session *sess = NULL;
-
- sx_slock(&proctree_lock);
- if (pri != -1)
- flags |= TOLOG;
- if (p != NULL) {
- PROC_LOCK(p);
- if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
- sess = p->p_session;
- sess_hold(sess);
- PROC_UNLOCK(p);
- tp = sess->s_ttyp;
- if (tp != NULL && tty_checkoutq(tp))
- flags |= TOTTY;
- else
- tp = NULL;
- } else
- PROC_UNLOCK(p);
- }
- pca.pri = pri;
- pca.tty = tp;
- pca.flags = flags;
- pca.p_bufr = NULL;
- if (pca.tty != NULL)
- tty_lock(pca.tty);
- sx_sunlock(&proctree_lock);
- kvprintf(fmt, putchar, &pca, 10, ap);
- if (pca.tty != NULL)
- tty_unlock(pca.tty);
- if (sess != NULL)
- sess_release(sess);
- msgbuftrigger = 1;
-}
-
-static int
-_vprintf(int level, int flags, const char *fmt, va_list ap)
-{
- struct putchar_arg pca;
- int retval;
-#ifdef PRINTF_BUFR_SIZE
- char bufr[PRINTF_BUFR_SIZE];
-#endif
-
- TSENTER();
- pca.tty = NULL;
- pca.pri = level;
- pca.flags = flags;
-#ifdef PRINTF_BUFR_SIZE
- pca.p_bufr = bufr;
- pca.p_next = pca.p_bufr;
- pca.n_bufr = sizeof(bufr);
- pca.remain = sizeof(bufr);
- *pca.p_next = '\0';
-#else
- /* Don't buffer console output. */
- pca.p_bufr = NULL;
-#endif
-
- retval = kvprintf(fmt, putchar, &pca, 10, ap);
-
-#ifdef PRINTF_BUFR_SIZE
- /* Write any buffered console/log output: */
- if (*pca.p_bufr != '\0') {
- if (pca.flags & TOLOG)
- msglogstr(pca.p_bufr, level, /*filter_cr*/1);
-
- if (pca.flags & TOCONS)
- cnputs(pca.p_bufr);
- }
-#endif
-
- TSEXIT();
- return (retval);
-}
-
-/*
- * Log writes to the log buffer, and guarantees not to sleep (so can be
- * called by interrupt routines). If there is no process reading the
- * log yet, it writes to the console also.
- */
-void
-log(int level, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vlog(level, fmt, ap);
- va_end(ap);
-}
-
-void
-vlog(int level, const char *fmt, va_list ap)
-{
-
- (void)_vprintf(level, log_open ? TOLOG : TOCONS | TOLOG, fmt, ap);
- msgbuftrigger = 1;
-}
-
-#define CONSCHUNK 128
-
-void
-log_console(struct uio *uio)
-{
- int c, error, nl;
- char *consbuffer;
- int pri;
-
- if (!log_console_output)
- return;
-
- pri = LOG_INFO | LOG_CONSOLE;
- uio = cloneuio(uio);
- consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK);
-
- nl = 0;
- while (uio->uio_resid > 0) {
- c = imin(uio->uio_resid, CONSCHUNK - 1);
- error = uiomove(consbuffer, c, uio);
- if (error != 0)
- break;
- /* Make sure we're NUL-terminated */
- consbuffer[c] = '\0';
- if (consbuffer[c - 1] == '\n')
- nl = 1;
- else
- nl = 0;
- msglogstr(consbuffer, pri, /*filter_cr*/ 1);
- }
- /*
- * The previous behavior in log_console() is preserved when
- * log_console_add_linefeed is non-zero. For that behavior, if an
- * individual console write came in that was not terminated with a
- * line feed, it would add a line feed.
- *
- * This results in different data in the message buffer than
- * appears on the system console (which doesn't add extra line feed
- * characters).
- *
- * A number of programs and rc scripts write a line feed, or a period
- * and a line feed when they have completed their operation. On
- * the console, this looks seamless, but when displayed with
- * 'dmesg -a', you wind up with output that looks like this:
- *
- * Updating motd:
- * .
- *
- * On the console, it looks like this:
- * Updating motd:.
- *
- * We could add logic to detect that situation, or just not insert
- * the extra newlines. Set the kern.log_console_add_linefeed
- * sysctl/tunable variable to get the old behavior.
- */
- if (!nl && log_console_add_linefeed) {
- consbuffer[0] = '\n';
- consbuffer[1] = '\0';
- msglogstr(consbuffer, pri, /*filter_cr*/ 1);
- }
- msgbuftrigger = 1;
- free(uio, M_IOV);
- free(consbuffer, M_TEMP);
-}
-
-int
-printf(const char *fmt, ...)
-{
- va_list ap;
- int retval;
-
- va_start(ap, fmt);
- retval = vprintf(fmt, ap);
- va_end(ap);
-
- return (retval);
-}
-
-int
-vprintf(const char *fmt, va_list ap)
-{
- int retval;
-
- retval = _vprintf(-1, TOCONS | TOLOG, fmt, ap);
-
- if (!KERNEL_PANICKED())
- msgbuftrigger = 1;
-
- return (retval);
-}
-
-static void
-prf_putbuf(char *bufr, int flags, int pri)
-{
-
- if (flags & TOLOG)
- msglogstr(bufr, pri, /*filter_cr*/1);
-
- if (flags & TOCONS) {
- if ((!KERNEL_PANICKED()) && (constty != NULL))
- msgbuf_addstr(&consmsgbuf, -1,
- bufr, /*filter_cr*/ 0);
-
- if ((constty == NULL) ||(always_console_output))
- cnputs(bufr);
- }
-}
-
-static void
-putbuf(int c, struct putchar_arg *ap)
-{
- /* Check if no console output buffer was provided. */
- if (ap->p_bufr == NULL) {
- /* Output direct to the console. */
- if (ap->flags & TOCONS)
- cnputc(c);
-
- if (ap->flags & TOLOG)
- msglogchar(c, ap->pri);
- } else {
- /* Buffer the character: */
- *ap->p_next++ = c;
- ap->remain--;
-
- /* Always leave the buffer zero terminated. */
- *ap->p_next = '\0';
-
- /* Check if the buffer needs to be flushed. */
- if (ap->remain == 2 || c == '\n') {
- prf_putbuf(ap->p_bufr, ap->flags, ap->pri);
-
- ap->p_next = ap->p_bufr;
- ap->remain = ap->n_bufr;
- *ap->p_next = '\0';
- }
-
- /*
- * Since we fill the buffer up one character at a time,
- * this should not happen. We should always catch it when
- * ap->remain == 2 (if not sooner due to a newline), flush
- * the buffer and move on. One way this could happen is
- * if someone sets PRINTF_BUFR_SIZE to 1 or something
- * similarly silly.
- */
- KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd",
- ap->remain));
- }
-}
-
-/*
- * Print a character on console or users terminal. If destination is
- * the console then the last bunch of characters are saved in msgbuf for
- * inspection later.
- */
-static void
-putchar(int c, void *arg)
-{
- struct putchar_arg *ap = (struct putchar_arg*) arg;
- struct tty *tp = ap->tty;
- int flags = ap->flags;
-
- /* Don't use the tty code after a panic or while in ddb. */
- if (kdb_active) {
- if (c != '\0')
- cnputc(c);
- return;
- }
-
- if ((flags & TOTTY) && tp != NULL && !KERNEL_PANICKED())
- tty_putchar(tp, c);
-
- if ((flags & (TOCONS | TOLOG)) && c != '\0')
- putbuf(c, ap);
-}
-
-/*
- * Scaled down version of sprintf(3).
- */
-int
-sprintf(char *buf, const char *cfmt, ...)
-{
- int retval;
- va_list ap;
-
- va_start(ap, cfmt);
- retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
- buf[retval] = '\0';
- va_end(ap);
- return (retval);
-}
-
-/*
- * Scaled down version of vsprintf(3).
- */
-int
-vsprintf(char *buf, const char *cfmt, va_list ap)
-{
- int retval;
-
- retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
- buf[retval] = '\0';
- return (retval);
-}
-
-/*
- * Scaled down version of snprintf(3).
- */
-int
-snprintf(char *str, size_t size, const char *format, ...)
-{
- int retval;
- va_list ap;
-
- va_start(ap, format);
- retval = vsnprintf(str, size, format, ap);
- va_end(ap);
- return(retval);
-}
-
-/*
- * Scaled down version of vsnprintf(3).
- */
-int
-vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
- struct snprintf_arg info;
- int retval;
-
- info.str = str;
- info.remain = size;
- retval = kvprintf(format, snprintf_func, &info, 10, ap);
- if (info.remain >= 1)
- *info.str++ = '\0';
- return (retval);
-}
-
-/*
- * Kernel version which takes radix argument vsnprintf(3).
- */
-int
-vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
-{
- struct snprintf_arg info;
- int retval;
-
- info.str = str;
- info.remain = size;
- retval = kvprintf(format, snprintf_func, &info, radix, ap);
- if (info.remain >= 1)
- *info.str++ = '\0';
- return (retval);
-}
-
-static void
-snprintf_func(int ch, void *arg)
-{
- struct snprintf_arg *const info = arg;
-
- if (info->remain >= 2) {
- *info->str++ = ch;
- info->remain--;
- }
-}
-
-/*
- * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
- * order; return an optional length and a pointer to the last character
- * written in the buffer (i.e., the first character of the string).
- * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
- */
-static char *
-ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
-{
- char *p, c;
-
- p = nbuf;
- *p = '\0';
- do {
- c = hex2ascii(num % base);
- *++p = upper ? toupper(c) : c;
- } while (num /= base);
- if (lenp)
- *lenp = p - nbuf;
- return (p);
-}
-
-/*
- * Scaled down version of printf(3).
- *
- * Two additional formats:
- *
- * The format %b is supported to decode error registers.
- * Its usage is:
- *
- * printf("reg=%b\n", regval, "<base><arg>*");
- *
- * where <base> is the output base expressed as a control character, e.g.
- * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
- * the first of which gives the bit number to be inspected (origin 1), and
- * the next characters (up to a control character, i.e. a character <= 32),
- * give the name of the register. Thus:
- *
- * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE");
- *
- * would produce output:
- *
- * reg=3<BITTWO,BITONE>
- *
- * XXX: %D -- Hexdump, takes pointer and separator string:
- * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
- * ("%*D", len, ptr, " " -> XX XX XX XX ...
- */
-int
-kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
-{
-#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
- char nbuf[MAXNBUF];
- char *d;
- const char *p, *percent, *q;
- u_char *up;
- int ch, n;
- uintmax_t num;
- int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
- int cflag, hflag, jflag, tflag, zflag;
- int bconv, dwidth, upper;
- char padc;
- int stop = 0, retval = 0;
-
- num = 0;
- q = NULL;
- if (!func)
- d = (char *) arg;
- else
- d = NULL;
-
- if (fmt == NULL)
- fmt = "(fmt null)\n";
-
- if (radix < 2 || radix > 36)
- radix = 10;
-
- for (;;) {
- padc = ' ';
- width = 0;
- while ((ch = (u_char)*fmt++) != '%' || stop) {
- if (ch == '\0')
- return (retval);
- PCHAR(ch);
- }
- percent = fmt - 1;
- qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
- sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0;
- cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
-reswitch: switch (ch = (u_char)*fmt++) {
- case '.':
- dot = 1;
- goto reswitch;
- case '#':
- sharpflag = 1;
- goto reswitch;
- case '+':
- sign = 1;
- goto reswitch;
- case '-':
- ladjust = 1;
- goto reswitch;
- case '%':
- PCHAR(ch);
- break;
- case '*':
- if (!dot) {
- width = va_arg(ap, int);
- if (width < 0) {
- ladjust = !ladjust;
- width = -width;
- }
- } else {
- dwidth = va_arg(ap, int);
- }
- goto reswitch;
- case '0':
- if (!dot) {
- padc = '0';
- goto reswitch;
- }
- /* FALLTHROUGH */
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- for (n = 0;; ++fmt) {
- n = n * 10 + ch - '0';
- ch = *fmt;
- if (ch < '0' || ch > '9')
- break;
- }
- if (dot)
- dwidth = n;
- else
- width = n;
- goto reswitch;
- case 'b':
- ladjust = 1;
- bconv = 1;
- goto handle_nosign;
- case 'c':
- width -= 1;
-
- if (!ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- PCHAR(va_arg(ap, int));
- if (ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- break;
- case 'D':
- up = va_arg(ap, u_char *);
- p = va_arg(ap, char *);
- if (!width)
- width = 16;
- while(width--) {
- PCHAR(hex2ascii(*up >> 4));
- PCHAR(hex2ascii(*up & 0x0f));
- up++;
- if (width)
- for (q=p;*q;q++)
- PCHAR(*q);
- }
- break;
- case 'd':
- case 'i':
- base = 10;
- sign = 1;
- goto handle_sign;
- case 'h':
- if (hflag) {
- hflag = 0;
- cflag = 1;
- } else
- hflag = 1;
- goto reswitch;
- case 'j':
- jflag = 1;
- goto reswitch;
- case 'l':
- if (lflag) {
- lflag = 0;
- qflag = 1;
- } else
- lflag = 1;
- goto reswitch;
- case 'n':
- /*
- * We do not support %n in kernel, but consume the
- * argument.
- */
- if (jflag)
- (void)va_arg(ap, intmax_t *);
- else if (qflag)
- (void)va_arg(ap, quad_t *);
- else if (lflag)
- (void)va_arg(ap, long *);
- else if (zflag)
- (void)va_arg(ap, size_t *);
- else if (hflag)
- (void)va_arg(ap, short *);
- else if (cflag)
- (void)va_arg(ap, char *);
- else
- (void)va_arg(ap, int *);
- break;
- case 'o':
- base = 8;
- goto handle_nosign;
- case 'p':
- base = 16;
- sharpflag = (width == 0);
- sign = 0;
- num = (uintptr_t)va_arg(ap, void *);
- goto number;
- case 'q':
- qflag = 1;
- goto reswitch;
- case 'r':
- base = radix;
- if (sign)
- goto handle_sign;
- goto handle_nosign;
- case 's':
- p = va_arg(ap, char *);
- if (p == NULL)
- p = "(null)";
- if (!dot)
- n = strlen (p);
- else
- for (n = 0; n < dwidth && p[n]; n++)
- continue;
-
- width -= n;
-
- if (!ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- while (n--)
- PCHAR(*p++);
- if (ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- break;
- case 't':
- tflag = 1;
- goto reswitch;
- case 'u':
- base = 10;
- goto handle_nosign;
- case 'X':
- upper = 1;
- /* FALLTHROUGH */
- case 'x':
- base = 16;
- goto handle_nosign;
- case 'y':
- base = 16;
- sign = 1;
- goto handle_sign;
- case 'z':
- zflag = 1;
- goto reswitch;
-handle_nosign:
- sign = 0;
- if (jflag)
- num = va_arg(ap, uintmax_t);
- else if (qflag)
- num = va_arg(ap, u_quad_t);
- else if (tflag)
- num = va_arg(ap, ptrdiff_t);
- else if (lflag)
- num = va_arg(ap, u_long);
- else if (zflag)
- num = va_arg(ap, size_t);
- else if (hflag)
- num = (u_short)va_arg(ap, int);
- else if (cflag)
- num = (u_char)va_arg(ap, int);
- else
- num = va_arg(ap, u_int);
- if (bconv) {
- q = va_arg(ap, char *);
- base = *q++;
- }
- goto number;
-handle_sign:
- if (jflag)
- num = va_arg(ap, intmax_t);
- else if (qflag)
- num = va_arg(ap, quad_t);
- else if (tflag)
- num = va_arg(ap, ptrdiff_t);
- else if (lflag)
- num = va_arg(ap, long);
- else if (zflag)
- num = va_arg(ap, ssize_t);
- else if (hflag)
- num = (short)va_arg(ap, int);
- else if (cflag)
- num = (char)va_arg(ap, int);
- else
- num = va_arg(ap, int);
-number:
- if (sign && (intmax_t)num < 0) {
- neg = 1;
- num = -(intmax_t)num;
- }
- p = ksprintn(nbuf, num, base, &n, upper);
- tmp = 0;
- if (sharpflag && num != 0) {
- if (base == 8)
- tmp++;
- else if (base == 16)
- tmp += 2;
- }
- if (neg)
- tmp++;
-
- if (!ladjust && padc == '0')
- dwidth = width - tmp;
- width -= tmp + imax(dwidth, n);
- dwidth -= n;
- if (!ladjust)
- while (width-- > 0)
- PCHAR(' ');
- if (neg)
- PCHAR('-');
- if (sharpflag && num != 0) {
- if (base == 8) {
- PCHAR('0');
- } else if (base == 16) {
- PCHAR('0');
- PCHAR('x');
- }
- }
- while (dwidth-- > 0)
- PCHAR('0');
-
- while (*p)
- PCHAR(*p--);
-
- if (bconv && num != 0) {
- /* %b conversion flag format. */
- tmp = retval;
- while (*q) {
- n = *q++;
- if (num & (1 << (n - 1))) {
- PCHAR(retval != tmp ?
- ',' : '<');
- for (; (n = *q) > ' '; ++q)
- PCHAR(n);
- } else
- for (; *q > ' '; ++q)
- continue;
- }
- if (retval != tmp) {
- PCHAR('>');
- width -= retval - tmp;
- }
- }
-
- if (ladjust)
- while (width-- > 0)
- PCHAR(' ');
-
- break;
- default:
- while (percent < fmt)
- PCHAR(*percent++);
- /*
- * Since we ignore a formatting argument it is no
- * longer safe to obey the remaining formatting
- * arguments as the arguments will no longer match
- * the format specs.
- */
- stop = 1;
- break;
- }
- }
-#undef PCHAR
-}
-
-/*
- * Put character in log buffer with a particular priority.
- */
-static void
-msglogchar(int c, int pri)
-{
- static int lastpri = -1;
- static int dangling;
- char nbuf[MAXNBUF];
- char *p;
-
- if (!msgbufmapped)
- return;
- if (c == '\0' || c == '\r')
- return;
- if (pri != -1 && pri != lastpri) {
- if (dangling) {
- msgbuf_addchar(msgbufp, '\n');
- dangling = 0;
- }
- msgbuf_addchar(msgbufp, '<');
- for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
- msgbuf_addchar(msgbufp, *p--);
- msgbuf_addchar(msgbufp, '>');
- lastpri = pri;
- }
- msgbuf_addchar(msgbufp, c);
- if (c == '\n') {
- dangling = 0;
- lastpri = -1;
- } else {
- dangling = 1;
- }
-}
-
-static void
-msglogstr(char *str, int pri, int filter_cr)
-{
- if (!msgbufmapped)
- return;
-
- msgbuf_addstr(msgbufp, pri, str, filter_cr);
-}
-
-void
-msgbufinit(void *ptr, int size)
-{
- char *cp;
- static struct msgbuf *oldp = NULL;
- bool print_boot_tag;
-
- size -= sizeof(*msgbufp);
- cp = (char *)ptr;
- print_boot_tag = !msgbufmapped;
- /* Attempt to fetch kern.boot_tag tunable on first mapping */
- if (!msgbufmapped)
- TUNABLE_STR_FETCH("kern.boot_tag", current_boot_tag,
- sizeof(current_boot_tag));
- msgbufp = (struct msgbuf *)(cp + size);
- msgbuf_reinit(msgbufp, cp, size);
- if (msgbufmapped && oldp != msgbufp)
- msgbuf_copy(oldp, msgbufp);
- msgbufmapped = true;
- if (print_boot_tag && *current_boot_tag != '\0')
- printf("%s\n", current_boot_tag);
- oldp = msgbufp;
-}
-
-/* Sysctls for accessing/clearing the msgbuf */
-static int
-sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
-{
- char buf[128];
- u_int seq;
- int error, len;
-
- error = priv_check(req->td, PRIV_MSGBUF);
- if (error)
- return (error);
-
- /* Read the whole buffer, one chunk at a time. */
- mtx_lock(&msgbuf_lock);
- msgbuf_peekbytes(msgbufp, NULL, 0, &seq);
- for (;;) {
- len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq);
- mtx_unlock(&msgbuf_lock);
- if (len == 0)
- return (SYSCTL_OUT(req, "", 1)); /* add nulterm */
-
- error = sysctl_handle_opaque(oidp, buf, len, req);
- if (error)
- return (error);
-
- mtx_lock(&msgbuf_lock);
- }
-}
-
-SYSCTL_PROC(_kern, OID_AUTO, msgbuf,
- CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
-
-static int msgbuf_clearflag;
-
-static int
-sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
-{
- int error;
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
- if (!error && req->newptr) {
- mtx_lock(&msgbuf_lock);
- msgbuf_clear(msgbufp);
- mtx_unlock(&msgbuf_lock);
- msgbuf_clearflag = 0;
- }
- return (error);
-}
-
-SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE,
- &msgbuf_clearflag, 0, sysctl_kern_msgbuf_clear, "I",
- "Clear kernel message buffer");
-
-#ifdef DDB
-
-DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
-{
- int i, j;
-
- if (!msgbufmapped) {
- db_printf("msgbuf not mapped yet\n");
- return;
- }
- db_printf("msgbufp = %p\n", msgbufp);
- db_printf("magic = %x, size = %d, r= %u, w = %u, ptr = %p, cksum= %u\n",
- msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_rseq,
- msgbufp->msg_wseq, msgbufp->msg_ptr, msgbufp->msg_cksum);
- for (i = 0; i < msgbufp->msg_size && !db_pager_quit; i++) {
- j = MSGBUF_SEQ_TO_POS(msgbufp, i + msgbufp->msg_rseq);
- db_printf("%c", msgbufp->msg_ptr[j]);
- }
- db_printf("\n");
-}
-
-#endif /* DDB */
-
-void
-hexdump(const void *ptr, int length, const char *hdr, int flags)
-{
- int i, j, k;
- int cols;
- const unsigned char *cp;
- char delim;
-
- if ((flags & HD_DELIM_MASK) != 0)
- delim = (flags & HD_DELIM_MASK) >> 8;
- else
- delim = ' ';
-
- if ((flags & HD_COLUMN_MASK) != 0)
- cols = flags & HD_COLUMN_MASK;
- else
- cols = 16;
-
- cp = ptr;
- for (i = 0; i < length; i+= cols) {
- if (hdr != NULL)
- printf("%s", hdr);
-
- if ((flags & HD_OMIT_COUNT) == 0)
- printf("%04x ", i);
-
- if ((flags & HD_OMIT_HEX) == 0) {
- for (j = 0; j < cols; j++) {
- k = i + j;
- if (k < length)
- printf("%c%02x", delim, cp[k]);
- else
- printf(" ");
- }
- }
-
- if ((flags & HD_OMIT_CHARS) == 0) {
- printf(" |");
- for (j = 0; j < cols; j++) {
- k = i + j;
- if (k >= length)
- printf(" ");
- else if (cp[k] >= ' ' && cp[k] <= '~')
- printf("%c", cp[k]);
- else
- printf(".");
- }
- printf("|");
- }
- printf("\n");
- }
-}
-#endif /* _KERNEL */
-
-void
-sbuf_hexdump(struct sbuf *sb, const void *ptr, int length, const char *hdr,
- int flags)
-{
- int i, j, k;
- int cols;
- const unsigned char *cp;
- char delim;
-
- if ((flags & HD_DELIM_MASK) != 0)
- delim = (flags & HD_DELIM_MASK) >> 8;
- else
- delim = ' ';
-
- if ((flags & HD_COLUMN_MASK) != 0)
- cols = flags & HD_COLUMN_MASK;
- else
- cols = 16;
-
- cp = ptr;
- for (i = 0; i < length; i+= cols) {
- if (hdr != NULL)
- sbuf_printf(sb, "%s", hdr);
-
- if ((flags & HD_OMIT_COUNT) == 0)
- sbuf_printf(sb, "%04x ", i);
-
- if ((flags & HD_OMIT_HEX) == 0) {
- for (j = 0; j < cols; j++) {
- k = i + j;
- if (k < length)
- sbuf_printf(sb, "%c%02x", delim, cp[k]);
- else
- sbuf_printf(sb, " ");
- }
- }
-
- if ((flags & HD_OMIT_CHARS) == 0) {
- sbuf_printf(sb, " |");
- for (j = 0; j < cols; j++) {
- k = i + j;
- if (k >= length)
- sbuf_printf(sb, " ");
- else if (cp[k] >= ' ' && cp[k] <= '~')
- sbuf_printf(sb, "%c", cp[k]);
- else
- sbuf_printf(sb, ".");
- }
- sbuf_printf(sb, "|");
- }
- sbuf_printf(sb, "\n");
- }
-}
-
-#ifdef _KERNEL
-void
-counted_warning(unsigned *counter, const char *msg)
-{
- struct thread *td;
- unsigned c;
-
- for (;;) {
- c = *counter;
- if (c == 0)
- break;
- if (atomic_cmpset_int(counter, c, c - 1)) {
- td = curthread;
- log(LOG_INFO, "pid %d (%s) %s%s\n",
- td->td_proc->p_pid, td->td_name, msg,
- c > 1 ? "" : " - not logging anymore");
- break;
- }
- }
-}
-#endif
-
-#ifdef _KERNEL
-void
-sbuf_putbuf(struct sbuf *sb)
-{
-
- prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1);
-}
-#else
-void
-sbuf_putbuf(struct sbuf *sb)
-{
-
- printf("%s", sbuf_data(sb));
-}
-#endif
-
-int
-sbuf_printf_drain(void *arg, const char *data, int len)
-{
- size_t *retvalptr;
- int r;
-#ifdef _KERNEL
- char *dataptr;
- char oldchr;
-
- /*
- * This is allowed as an extra byte is always resvered for
- * terminating NUL byte. Save and restore the byte because
- * we might be flushing a record, and there may be valid
- * data after the buffer.
- */
- oldchr = data[len];
- dataptr = __DECONST(char *, data);
- dataptr[len] = '\0';
-
- prf_putbuf(dataptr, TOLOG | TOCONS, -1);
- r = len;
-
- dataptr[len] = oldchr;
-
-#else /* !_KERNEL */
-
- r = printf("%.*s", len, data);
- if (r < 0)
- return (-errno);
-
-#endif
-
- retvalptr = arg;
- if (retvalptr != NULL)
- *retvalptr += r;
-
- return (r);
-}
diff --git a/pw/sbuf/subr_sbuf.c b/pw/sbuf/subr_sbuf.c
deleted file mode 100644
index 5588bae..0000000
--- a/pw/sbuf/subr_sbuf.c
+++ /dev/null
@@ -1,950 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2000-2008 Poul-Henning Kamp
- * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-
-#ifdef _KERNEL
-#include <sys/ctype.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/malloc.h>
-#include <sys/systm.h>
-#include <sys/uio.h>
-#include <machine/stdarg.h>
-#else /* _KERNEL */
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif /* _KERNEL */
-
-#include <sys/sbuf.h>
-
-#ifdef _KERNEL
-static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
-#define SBMALLOC(size, flags) malloc(size, M_SBUF, (flags) | M_ZERO)
-#define SBFREE(buf) free(buf, M_SBUF)
-#else /* _KERNEL */
-#define KASSERT(e, m)
-#define SBMALLOC(size, flags) calloc(1, size)
-#define SBFREE(buf) free(buf)
-#endif /* _KERNEL */
-
-/*
- * Predicates
- */
-#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
-#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT)
-#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
-#define SBUF_ISDRAINATEOL(s) ((s)->s_flags & SBUF_DRAINATEOL)
-#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
-#define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1))
-#define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND)
-#define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION)
-#define SBUF_NULINCLUDED(s) ((s)->s_flags & SBUF_INCLUDENUL)
-#define SBUF_ISDRAINTOEOR(s) ((s)->s_flags & SBUF_DRAINTOEOR)
-#define SBUF_DODRAINTOEOR(s) (SBUF_ISSECTION(s) && SBUF_ISDRAINTOEOR(s))
-#define SBUF_MALLOCFLAG(s) \
- (((s)->s_flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK)
-
-/*
- * Set / clear flags
- */
-#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
-#define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0)
-
-#define SBUF_MINSIZE 2 /* Min is 1 byte + nulterm. */
-#define SBUF_MINEXTENDSIZE 16 /* Should be power of 2. */
-
-#ifdef PAGE_SIZE
-#define SBUF_MAXEXTENDSIZE PAGE_SIZE
-#define SBUF_MAXEXTENDINCR PAGE_SIZE
-#else
-#define SBUF_MAXEXTENDSIZE 4096
-#define SBUF_MAXEXTENDINCR 4096
-#endif
-
-/*
- * Debugging support
- */
-#if defined(_KERNEL) && defined(INVARIANTS)
-
-static void
-_assert_sbuf_integrity(const char *fun, struct sbuf *s)
-{
-
- KASSERT(s != NULL,
- ("%s called with a NULL sbuf pointer", fun));
- KASSERT(s->s_buf != NULL,
- ("%s called with uninitialized or corrupt sbuf", fun));
- if (SBUF_ISFINISHED(s) && SBUF_NULINCLUDED(s)) {
- KASSERT(s->s_len <= s->s_size,
- ("wrote past end of sbuf (%jd >= %jd)",
- (intmax_t)s->s_len, (intmax_t)s->s_size));
- } else {
- KASSERT(s->s_len < s->s_size,
- ("wrote past end of sbuf (%jd >= %jd)",
- (intmax_t)s->s_len, (intmax_t)s->s_size));
- }
-}
-
-static void
-_assert_sbuf_state(const char *fun, struct sbuf *s, int state)
-{
-
- KASSERT((s->s_flags & SBUF_FINISHED) == state,
- ("%s called with %sfinished or corrupt sbuf", fun,
- (state ? "un" : "")));
-}
-
-#define assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s))
-#define assert_sbuf_state(s, i) _assert_sbuf_state(__func__, (s), (i))
-
-#else /* _KERNEL && INVARIANTS */
-
-#define assert_sbuf_integrity(s) do { } while (0)
-#define assert_sbuf_state(s, i) do { } while (0)
-
-#endif /* _KERNEL && INVARIANTS */
-
-#ifdef CTASSERT
-CTASSERT(powerof2(SBUF_MAXEXTENDSIZE));
-CTASSERT(powerof2(SBUF_MAXEXTENDINCR));
-#endif
-
-static int
-sbuf_extendsize(int size)
-{
- int newsize;
-
- if (size < (int)SBUF_MAXEXTENDSIZE) {
- newsize = SBUF_MINEXTENDSIZE;
- while (newsize < size)
- newsize *= 2;
- } else {
- newsize = roundup(size, SBUF_MAXEXTENDINCR);
- }
- KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
- return (newsize);
-}
-
-/*
- * Extend an sbuf.
- */
-static int
-sbuf_extend(struct sbuf *s, int addlen)
-{
- char *newbuf;
- int newsize;
-
- if (!SBUF_CANEXTEND(s))
- return (-1);
- newsize = sbuf_extendsize(s->s_size + addlen);
- newbuf = SBMALLOC(newsize, SBUF_MALLOCFLAG(s));
- if (newbuf == NULL)
- return (-1);
- memcpy(newbuf, s->s_buf, s->s_size);
- if (SBUF_ISDYNAMIC(s))
- SBFREE(s->s_buf);
- else
- SBUF_SETFLAG(s, SBUF_DYNAMIC);
- s->s_buf = newbuf;
- s->s_size = newsize;
- return (0);
-}
-
-/*
- * Initialize an sbuf.
- * If buf is non-NULL, it points to a static or already-allocated string
- * big enough to hold at least length characters.
- */
-struct sbuf *
-sbuf_new(struct sbuf *s, char *buf, int length, int flags)
-{
-
- KASSERT(length >= 0,
- ("attempt to create an sbuf of negative length (%d)", length));
- KASSERT((flags & ~SBUF_USRFLAGMSK) == 0,
- ("%s called with invalid flags", __func__));
- KASSERT((flags & SBUF_AUTOEXTEND) || length >= SBUF_MINSIZE,
- ("sbuf buffer %d smaller than minimum %d bytes", length,
- SBUF_MINSIZE));
-
- flags &= SBUF_USRFLAGMSK;
-
- /*
- * Allocate 'DYNSTRUCT' sbuf from the heap, if NULL 's' was provided.
- */
- if (s == NULL) {
- s = SBMALLOC(sizeof(*s),
- (flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK);
- if (s == NULL)
- goto out;
- SBUF_SETFLAG(s, SBUF_DYNSTRUCT);
- } else {
- /*
- * DYNSTRUCT SBMALLOC sbufs are allocated with M_ZERO, but
- * user-provided sbuf objects must be initialized.
- */
- memset(s, 0, sizeof(*s));
- }
-
- s->s_flags |= flags;
- s->s_size = length;
- s->s_buf = buf;
- /*
- * Never-written sbufs do not need \n termination.
- */
- SBUF_SETFLAG(s, SBUF_DRAINATEOL);
-
- /*
- * Allocate DYNAMIC, i.e., heap data buffer backing the sbuf, if no
- * buffer was provided.
- */
- if (s->s_buf == NULL) {
- if (SBUF_CANEXTEND(s))
- s->s_size = sbuf_extendsize(s->s_size);
- s->s_buf = SBMALLOC(s->s_size, SBUF_MALLOCFLAG(s));
- if (s->s_buf == NULL)
- goto out;
- SBUF_SETFLAG(s, SBUF_DYNAMIC);
- }
-
-out:
- if (s != NULL && s->s_buf == NULL) {
- if (SBUF_ISDYNSTRUCT(s))
- SBFREE(s);
- s = NULL;
- }
- return (s);
-}
-
-#ifdef _KERNEL
-/*
- * Create an sbuf with uio data
- */
-struct sbuf *
-sbuf_uionew(struct sbuf *s, struct uio *uio, int *error)
-{
-
- KASSERT(uio != NULL,
- ("%s called with NULL uio pointer", __func__));
- KASSERT(error != NULL,
- ("%s called with NULL error pointer", __func__));
-
- s = sbuf_new(s, NULL, uio->uio_resid + 1, 0);
- if (s == NULL) {
- *error = ENOMEM;
- return (NULL);
- }
- *error = uiomove(s->s_buf, uio->uio_resid, uio);
- if (*error != 0) {
- sbuf_delete(s);
- return (NULL);
- }
- s->s_len = s->s_size - 1;
- if (SBUF_ISSECTION(s))
- s->s_sect_len = s->s_size - 1;
- *error = 0;
- return (s);
-}
-#endif
-
-int
-sbuf_get_flags(struct sbuf *s)
-{
-
- return (s->s_flags & SBUF_USRFLAGMSK);
-}
-
-void
-sbuf_clear_flags(struct sbuf *s, int flags)
-{
-
- s->s_flags &= ~(flags & SBUF_USRFLAGMSK);
-}
-
-void
-sbuf_set_flags(struct sbuf *s, int flags)
-{
-
- s->s_flags |= (flags & SBUF_USRFLAGMSK);
-}
-
-/*
- * Clear an sbuf and reset its position.
- */
-void
-sbuf_clear(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- /* don't care if it's finished or not */
- KASSERT(s->s_drain_func == NULL,
- ("%s makes no sense on sbuf %p with drain", __func__, s));
-
- SBUF_CLEARFLAG(s, SBUF_FINISHED);
- s->s_error = 0;
- s->s_len = 0;
- s->s_rec_off = 0;
- s->s_sect_len = 0;
-}
-
-/*
- * Set the sbuf's end position to an arbitrary value.
- * Effectively truncates the sbuf at the new position.
- */
-int
-sbuf_setpos(struct sbuf *s, ssize_t pos)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- KASSERT(pos >= 0,
- ("attempt to seek to a negative position (%jd)", (intmax_t)pos));
- KASSERT(pos < s->s_size,
- ("attempt to seek past end of sbuf (%jd >= %jd)",
- (intmax_t)pos, (intmax_t)s->s_size));
- KASSERT(!SBUF_ISSECTION(s),
- ("attempt to seek when in a section"));
-
- if (pos < 0 || pos > s->s_len)
- return (-1);
- s->s_len = pos;
- return (0);
-}
-
-/*
- * Drain into a counter. Counts amount of data without producing output.
- * Useful for cases like sysctl, where user may first request only size.
- * This allows to avoid pointless allocation/freeing of large buffers.
- */
-int
-sbuf_count_drain(void *arg, const char *data __unused, int len)
-{
- size_t *sizep;
-
- sizep = (size_t *)arg;
- *sizep += len;
- return (len);
-}
-
-/*
- * Set up a drain function and argument on an sbuf to flush data to
- * when the sbuf buffer overflows.
- */
-void
-sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
-{
-
- assert_sbuf_state(s, 0);
- assert_sbuf_integrity(s);
- KASSERT(func == s->s_drain_func || s->s_len == 0,
- ("Cannot change drain to %p on non-empty sbuf %p", func, s));
- s->s_drain_func = func;
- s->s_drain_arg = ctx;
-}
-
-/*
- * Call the drain and process the return.
- */
-static int
-sbuf_drain(struct sbuf *s)
-{
- int len;
-
- KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
- KASSERT(s->s_error == 0, ("Called %s with error on %p", __func__, s));
-
- if (SBUF_DODRAINTOEOR(s) && s->s_rec_off == 0)
- return (s->s_error = EDEADLK);
- len = s->s_drain_func(s->s_drain_arg, s->s_buf,
- SBUF_DODRAINTOEOR(s) ? s->s_rec_off : s->s_len);
- if (len <= 0) {
- s->s_error = len ? -len : EDEADLK;
- return (s->s_error);
- }
- KASSERT(len > 0 && len <= s->s_len,
- ("Bad drain amount %d for sbuf %p", len, s));
- s->s_len -= len;
- s->s_rec_off -= len;
- /*
- * Fast path for the expected case where all the data was
- * drained.
- */
- if (s->s_len == 0) {
- /*
- * When the s_buf is entirely drained, we need to remember if
- * the last character was a '\n' or not for
- * sbuf_nl_terminate().
- */
- if (s->s_buf[len - 1] == '\n')
- SBUF_SETFLAG(s, SBUF_DRAINATEOL);
- else
- SBUF_CLEARFLAG(s, SBUF_DRAINATEOL);
- return (0);
- }
- /*
- * Move the remaining characters to the beginning of the
- * string.
- */
- memmove(s->s_buf, s->s_buf + len, s->s_len);
- return (0);
-}
-
-/*
- * Append bytes to an sbuf. This is the core function for appending
- * to an sbuf and is the main place that deals with extending the
- * buffer and marking overflow.
- */
-static void
-sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
-{
- size_t n;
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- if (s->s_error != 0)
- return;
- while (len > 0) {
- if (SBUF_FREESPACE(s) <= 0) {
- /*
- * If there is a drain, use it, otherwise extend the
- * buffer.
- */
- if (s->s_drain_func != NULL)
- (void)sbuf_drain(s);
- else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
- < 0)
- s->s_error = ENOMEM;
- if (s->s_error != 0)
- return;
- }
- n = SBUF_FREESPACE(s);
- if (len < n)
- n = len;
- memcpy(&s->s_buf[s->s_len], buf, n);
- s->s_len += n;
- if (SBUF_ISSECTION(s))
- s->s_sect_len += n;
- len -= n;
- buf += n;
- }
-}
-
-static void
-sbuf_put_byte(struct sbuf *s, char c)
-{
-
- sbuf_put_bytes(s, &c, 1);
-}
-
-/*
- * Append a byte string to an sbuf.
- */
-int
-sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
-{
-
- sbuf_put_bytes(s, buf, len);
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-
-#ifdef _KERNEL
-/*
- * Copy a byte string from userland into an sbuf.
- */
-int
-sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
- KASSERT(s->s_drain_func == NULL,
- ("Nonsensical copyin to sbuf %p with a drain", s));
-
- if (s->s_error != 0)
- return (-1);
- if (len == 0)
- return (0);
- if (len > SBUF_FREESPACE(s)) {
- sbuf_extend(s, len - SBUF_FREESPACE(s));
- if (SBUF_FREESPACE(s) < len)
- len = SBUF_FREESPACE(s);
- }
- if (copyin(uaddr, s->s_buf + s->s_len, len) != 0)
- return (-1);
- s->s_len += len;
-
- return (0);
-}
-#endif
-
-/*
- * Copy a byte string into an sbuf.
- */
-int
-sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- sbuf_clear(s);
- return (sbuf_bcat(s, buf, len));
-}
-
-/*
- * Append a string to an sbuf.
- */
-int
-sbuf_cat(struct sbuf *s, const char *str)
-{
- size_t n;
-
- n = strlen(str);
- sbuf_put_bytes(s, str, n);
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-
-#ifdef _KERNEL
-/*
- * Append a string from userland to an sbuf.
- */
-int
-sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
-{
- size_t done;
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
- KASSERT(s->s_drain_func == NULL,
- ("Nonsensical copyin to sbuf %p with a drain", s));
-
- if (s->s_error != 0)
- return (-1);
-
- if (len == 0)
- len = SBUF_FREESPACE(s); /* XXX return 0? */
- if (len > SBUF_FREESPACE(s)) {
- sbuf_extend(s, len);
- if (SBUF_FREESPACE(s) < len)
- len = SBUF_FREESPACE(s);
- }
- switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
- case ENAMETOOLONG:
- s->s_error = ENOMEM;
- /* fall through */
- case 0:
- s->s_len += done - 1;
- if (SBUF_ISSECTION(s))
- s->s_sect_len += done - 1;
- break;
- default:
- return (-1); /* XXX */
- }
-
- return (done);
-}
-#endif
-
-/*
- * Copy a string into an sbuf.
- */
-int
-sbuf_cpy(struct sbuf *s, const char *str)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- sbuf_clear(s);
- return (sbuf_cat(s, str));
-}
-
-/*
- * Format the given argument list and append the resulting string to an sbuf.
- */
-#ifdef _KERNEL
-
-/*
- * Append a non-NUL character to an sbuf. This prototype signature is
- * suitable for use with kvprintf(9).
- */
-static void
-sbuf_putc_func(int c, void *arg)
-{
-
- if (c != '\0')
- sbuf_put_byte(arg, c);
-}
-
-int
-sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- KASSERT(fmt != NULL,
- ("%s called with a NULL format string", __func__));
-
- (void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-#else /* !_KERNEL */
-int
-sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
-{
- va_list ap_copy;
- int error, len;
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- KASSERT(fmt != NULL,
- ("%s called with a NULL format string", __func__));
-
- if (s->s_error != 0)
- return (-1);
-
- /*
- * For the moment, there is no way to get vsnprintf(3) to hand
- * back a character at a time, to push everything into
- * sbuf_putc_func() as was done for the kernel.
- *
- * In userspace, while drains are useful, there's generally
- * not a problem attempting to malloc(3) on out of space. So
- * expand a userland sbuf if there is not enough room for the
- * data produced by sbuf_[v]printf(3).
- */
-
- error = 0;
- do {
- va_copy(ap_copy, ap);
- len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1,
- fmt, ap_copy);
- if (len < 0) {
- s->s_error = errno;
- return (-1);
- }
- va_end(ap_copy);
-
- if (SBUF_FREESPACE(s) >= len)
- break;
- /* Cannot print with the current available space. */
- if (s->s_drain_func != NULL && s->s_len > 0)
- error = sbuf_drain(s); /* sbuf_drain() sets s_error. */
- else if (sbuf_extend(s, len - SBUF_FREESPACE(s)) != 0)
- s->s_error = error = ENOMEM;
- } while (error == 0);
-
- /*
- * s->s_len is the length of the string, without the terminating nul.
- * When updating s->s_len, we must subtract 1 from the length that
- * we passed into vsnprintf() because that length includes the
- * terminating nul.
- *
- * vsnprintf() returns the amount that would have been copied,
- * given sufficient space, so don't over-increment s_len.
- */
- if (SBUF_FREESPACE(s) < len)
- len = SBUF_FREESPACE(s);
- s->s_len += len;
- if (SBUF_ISSECTION(s))
- s->s_sect_len += len;
-
- KASSERT(s->s_len < s->s_size,
- ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
-
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-#endif /* _KERNEL */
-
-/*
- * Format the given arguments and append the resulting string to an sbuf.
- */
-int
-sbuf_printf(struct sbuf *s, const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- va_start(ap, fmt);
- result = sbuf_vprintf(s, fmt, ap);
- va_end(ap);
- return (result);
-}
-
-/*
- * Append a character to an sbuf.
- */
-int
-sbuf_putc(struct sbuf *s, int c)
-{
-
- sbuf_put_byte(s, c);
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-
-/*
- * Append a trailing newline to a non-empty sbuf, if one is not already
- * present. Handles sbufs with drain functions correctly.
- */
-int
-sbuf_nl_terminate(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- /*
- * If the s_buf isn't empty, the last byte is simply s_buf[s_len - 1].
- *
- * If the s_buf is empty because a drain function drained it, we
- * remember if the last byte was a \n with the SBUF_DRAINATEOL flag in
- * sbuf_drain().
- *
- * In either case, we only append a \n if the previous character was
- * something else.
- */
- if (s->s_len == 0) {
- if (!SBUF_ISDRAINATEOL(s))
- sbuf_put_byte(s, '\n');
- } else if (s->s_buf[s->s_len - 1] != '\n')
- sbuf_put_byte(s, '\n');
-
- if (s->s_error != 0)
- return (-1);
- return (0);
-}
-
-/*
- * Trim whitespace characters from end of an sbuf.
- */
-int
-sbuf_trim(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
- KASSERT(s->s_drain_func == NULL,
- ("%s makes no sense on sbuf %p with drain", __func__, s));
-
- if (s->s_error != 0)
- return (-1);
-
- while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) {
- --s->s_len;
- if (SBUF_ISSECTION(s))
- s->s_sect_len--;
- }
-
- return (0);
-}
-
-/*
- * Check if an sbuf has an error.
- */
-int
-sbuf_error(const struct sbuf *s)
-{
-
- return (s->s_error);
-}
-
-/*
- * Finish off an sbuf.
- */
-int
-sbuf_finish(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- s->s_buf[s->s_len] = '\0';
- if (SBUF_NULINCLUDED(s))
- s->s_len++;
- if (s->s_drain_func != NULL) {
- while (s->s_len > 0 && s->s_error == 0)
- s->s_error = sbuf_drain(s);
- }
- SBUF_SETFLAG(s, SBUF_FINISHED);
-#ifdef _KERNEL
- return (s->s_error);
-#else
- if (s->s_error != 0) {
- errno = s->s_error;
- return (-1);
- }
- return (0);
-#endif
-}
-
-/*
- * Return a pointer to the sbuf data.
- */
-char *
-sbuf_data(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, SBUF_FINISHED);
- KASSERT(s->s_drain_func == NULL,
- ("%s makes no sense on sbuf %p with drain", __func__, s));
-
- return (s->s_buf);
-}
-
-/*
- * Return the length of the sbuf data.
- */
-ssize_t
-sbuf_len(struct sbuf *s)
-{
-
- assert_sbuf_integrity(s);
- /* don't care if it's finished or not */
- KASSERT(s->s_drain_func == NULL,
- ("%s makes no sense on sbuf %p with drain", __func__, s));
-
- if (s->s_error != 0)
- return (-1);
-
- /* If finished, nulterm is already in len, else add one. */
- if (SBUF_NULINCLUDED(s) && !SBUF_ISFINISHED(s))
- return (s->s_len + 1);
- return (s->s_len);
-}
-
-/*
- * Clear an sbuf, free its buffer if necessary.
- */
-void
-sbuf_delete(struct sbuf *s)
-{
- int isdyn;
-
- assert_sbuf_integrity(s);
- /* don't care if it's finished or not */
-
- if (SBUF_ISDYNAMIC(s))
- SBFREE(s->s_buf);
- isdyn = SBUF_ISDYNSTRUCT(s);
- memset(s, 0, sizeof(*s));
- if (isdyn)
- SBFREE(s);
-}
-
-/*
- * Check if an sbuf has been finished.
- */
-int
-sbuf_done(const struct sbuf *s)
-{
-
- return (SBUF_ISFINISHED(s));
-}
-
-/*
- * Start a section.
- */
-void
-sbuf_start_section(struct sbuf *s, ssize_t *old_lenp)
-{
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
-
- if (!SBUF_ISSECTION(s)) {
- KASSERT(s->s_sect_len == 0,
- ("s_sect_len != 0 when starting a section"));
- if (old_lenp != NULL)
- *old_lenp = -1;
- s->s_rec_off = s->s_len;
- SBUF_SETFLAG(s, SBUF_INSECTION);
- } else {
- KASSERT(old_lenp != NULL,
- ("s_sect_len should be saved when starting a subsection"));
- *old_lenp = s->s_sect_len;
- s->s_sect_len = 0;
- }
-}
-
-/*
- * End the section padding to the specified length with the specified
- * character.
- */
-ssize_t
-sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c)
-{
- ssize_t len;
-
- assert_sbuf_integrity(s);
- assert_sbuf_state(s, 0);
- KASSERT(SBUF_ISSECTION(s),
- ("attempt to end a section when not in a section"));
-
- if (pad > 1) {
- len = roundup(s->s_sect_len, pad) - s->s_sect_len;
- for (; s->s_error == 0 && len > 0; len--)
- sbuf_put_byte(s, c);
- }
- len = s->s_sect_len;
- if (old_len == -1) {
- s->s_rec_off = s->s_sect_len = 0;
- SBUF_CLEARFLAG(s, SBUF_INSECTION);
- } else {
- s->s_sect_len += old_len;
- }
- if (s->s_error != 0)
- return (-1);
- return (len);
-}
diff --git a/pw/sbuf/sys/sbuf.h b/pw/sbuf/sys/sbuf.h
deleted file mode 100644
index f2cd679..0000000
--- a/pw/sbuf/sys/sbuf.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2000-2008 Poul-Henning Kamp
- * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS_SBUF_H_
-#define _SYS_SBUF_H_
-
-#include <sys/_types.h>
-
-typedef __builtin_va_list __va_list;
-
-struct sbuf;
-typedef int (sbuf_drain_func)(void *, const char *, int);
-
-/*
- * Structure definition
- */
-struct sbuf {
- char *s_buf; /* storage buffer */
- sbuf_drain_func *s_drain_func; /* drain function */
- void *s_drain_arg; /* user-supplied drain argument */
- int s_error; /* current error code */
- ssize_t s_size; /* size of storage buffer */
- ssize_t s_len; /* current length of string */
-#define SBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */
-#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
-#define SBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */
-#define SBUF_DRAINTOEOR 0x00000004 /* use section 0 as drain EOR marker */
-#define SBUF_NOWAIT 0x00000008 /* Extend with non-blocking malloc */
-#define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
-#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
-#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
-#define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */
-#define SBUF_INSECTION 0x00100000 /* set by sbuf_start_section() */
-#define SBUF_DRAINATEOL 0x00200000 /* drained contents ended in \n */
- int s_flags; /* flags */
- ssize_t s_sect_len; /* current length of section */
- ssize_t s_rec_off; /* current record start offset */
-};
-
-#ifndef HD_COLUMN_MASK
-#define HD_COLUMN_MASK 0xff
-#define HD_DELIM_MASK 0xff00
-#define HD_OMIT_COUNT (1 << 16)
-#define HD_OMIT_HEX (1 << 17)
-#define HD_OMIT_CHARS (1 << 18)
-#endif /* HD_COLUMN_MASK */
-
-__BEGIN_DECLS
-/*
- * API functions
- */
-struct sbuf *sbuf_new(struct sbuf *, char *, int, int);
-#define sbuf_new_auto() \
- sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND)
-int sbuf_get_flags(struct sbuf *);
-void sbuf_clear_flags(struct sbuf *, int);
-void sbuf_set_flags(struct sbuf *, int);
-void sbuf_clear(struct sbuf *);
-int sbuf_setpos(struct sbuf *, ssize_t);
-int sbuf_bcat(struct sbuf *, const void *, size_t);
-int sbuf_bcpy(struct sbuf *, const void *, size_t);
-int sbuf_cat(struct sbuf *, const char *);
-int sbuf_cpy(struct sbuf *, const char *);
-int sbuf_printf(struct sbuf *, const char *, ...)
- __printflike(2, 3);
-int sbuf_vprintf(struct sbuf *, const char *, __va_list)
- __printflike(2, 0);
-int sbuf_nl_terminate(struct sbuf *);
-int sbuf_putc(struct sbuf *, int);
-void sbuf_set_drain(struct sbuf *, sbuf_drain_func *, void *);
-int sbuf_trim(struct sbuf *);
-int sbuf_error(const struct sbuf *);
-int sbuf_finish(struct sbuf *);
-char *sbuf_data(struct sbuf *);
-ssize_t sbuf_len(struct sbuf *);
-int sbuf_done(const struct sbuf *);
-void sbuf_delete(struct sbuf *);
-void sbuf_start_section(struct sbuf *, ssize_t *);
-ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
-void sbuf_hexdump(struct sbuf *, const void *, int, const char *,
- int);
-int sbuf_count_drain(void *arg, const char *data, int len);
-int sbuf_printf_drain(void *arg, const char *data, int len);
-void sbuf_putbuf(struct sbuf *);
-
-#ifdef _KERNEL
-struct uio;
-struct sbuf *sbuf_uionew(struct sbuf *, struct uio *, int *);
-int sbuf_bcopyin(struct sbuf *, const void *, size_t);
-int sbuf_copyin(struct sbuf *, const void *, size_t);
-#endif
-__END_DECLS
-
-#endif