Compare commits

...

28 Commits
0.8.7 ... 0.9.1

Author SHA1 Message Date
Guillem Jover
1ca09c18f7 Release libbsd 0.9.1 2018-05-22 16:07:42 +02:00
Guillem Jover
e4e15ed286 Fix strnvis() and strnunvis() NetBSD ABI break
The NetBSD implementations have different prototypes to the ones coming
from OpenBSD, which will break builds, and have caused segfaults at
run-time. We provide now both interfaces with different prototypes as
different version nodes allow selecting them at compile-time, defaulting
for now to the OpenBSD one to avoid build-time breakage, while emitting
a compile-time warning. Later on, in 0.10.0, we will be switching the
compile-time default to the NetBSD version.

Ref: http://gnats.netbsd.org/44977
Fixes: https://bugs.debian.org/899282
2018-05-22 16:07:42 +02:00
Guillem Jover
bf697b900c Add symbol redirection support
We need this to be able to select different version symbols at
compile-time.
2018-05-22 15:45:37 +02:00
Guillem Jover
f1966385b3 Fix COPYING file format
We cannot refer to a License short-name if that is not on its own
License paragraph. Split several other common License fields into
their own paragraphs to avoid this problem in the future.
2018-05-22 13:47:05 +02:00
Guillem Jover
e007233cf0 Release libbsd 0.9.0 2018-05-21 04:48:32 +02:00
Guillem Jover
3cabf46bb0 Deprecate fgetwln()
This function has the same problems as fgetln() which is already marked
as deprecated.
2018-05-21 04:48:32 +02:00
Guillem Jover
6eebc1f264 Fix typo in fgetln() linker warning 2018-05-21 04:48:32 +02:00
Guillem Jover
a1730c1063 Add Windows support for getentropy() and arc4random()
Import from OpenBSD.
2018-05-21 04:48:32 +02:00
Guillem Jover
6f68c93076 Switch strtonum() implementation from strtoll() to strtoi()
Import from NetBSD.
2018-05-21 04:48:32 +02:00
Guillem Jover
e13b1a337a Import strtoi() and strtou() functions from NetBSD 2018-05-21 04:47:28 +02:00
Guillem Jover
ef5faeb575 Update few RCS keyword contents to match BSD originals
This will slightly reduce the delta, and makes it easier to compare the
sources.
2018-05-21 04:47:28 +02:00
Guillem Jover
2d7de186e9 Update vis/unvis modules from NetBSD 2018-05-21 04:47:28 +02:00
Guillem Jover
3efad64155 Update readpassphrase() from OpenBSD 2018-05-21 04:47:28 +02:00
Guillem Jover
a6f407ab0d Update heapsort() from OpenBSD 2018-05-21 04:47:28 +02:00
Guillem Jover
21edbb4f22 Update fmtcheck() from NetBSD 2018-05-21 04:47:28 +02:00
Guillem Jover
e3979d1a7c Update humanize_number() from FreeBSD
Implements HN_IEC_PREFIXES.
2018-05-21 04:47:28 +02:00
Guillem Jover
facbddb652 Update pidfile module from FreeBSD
Use EINVAL instead of EDOOFUS. Add a missing synopsis for
pidfile_fileno() in the man page. Move the definition of struct pidfh
from libutil.h into pidfile.c following upstream change.
2018-05-21 04:47:28 +02:00
Guillem Jover
3d88c999b4 Update arc4random() headers from OpenBSD
Split Linux support into its own header separate from the generic Unix
to fix a Linux-specific issue with clone(). Reset rsp to NULL on failure.
2018-05-21 04:47:28 +02:00
Guillem Jover
e42381dc51 Update getentropy() code from OpenBSD
Includes changes to handle the Linux syscall blocking when there is not
enough entropy during boot, by switching it to non-blocking mode and
falling back to the alternative implementations. Man page URL reference
fixes. Build fixes for Mac OS X.

Fixes: https://bugs.debian.org/898088
2018-05-21 04:47:28 +02:00
Guillem Jover
993828d84e Add flopenat() function from FreeBSD 2018-05-21 03:49:26 +02:00
Guillem Jover
30b4d50754 Add __arraycount() macro from NetBSD 2018-05-21 03:36:44 +02:00
Baruch Siach
f6ed7c278b Fix build for openrisc with uClibc
uClibc defines EM_OR1K instead of EM_OPENRISC for the OpenRISC ELF
e_machine ID. Use EM_OR1K when EM_OPENRISC is not defined.

This fixes the following build failure:

In file included from nlist.c:44:0:
nlist.c: In function ‘__elf_is_okay__’:
local-elf.h:224:23: error: ‘EM_OPENRISC’ undeclared (first use in this function)
 #define ELF_TARG_MACH EM_OPENRISC
                       ^
nlist.c:77:26: note: in expansion of macro ‘ELF_TARG_MACH’
   if (ehdr->e_machine == ELF_TARG_MACH &&
                          ^

Signed-off-by: Guillem Jover <guillem@hadrons.org>
2018-04-04 02:29:15 +02:00
Guillem Jover
1f8a3f7bcc Fix function declaration protection for glibc already providing them
On non-glibc based systems we cannot unconditionally use the
__GLIBC_PREREQ macro as it gets expanded before evaluation. Instead,
if it is undefined, define it to 0.

We should also always declare these functions on non-glibc based
systems. And on systems with a new enough glibc, which provides these
functions, we should still provide the declarations if _GNU_SOURCE
is *not* defined.

Reported-by: Jörg Krause <joerg.krause@embedded.rocks>
2018-03-13 02:28:53 +01:00
Guillem Jover
b20272f5a9 Remove <features.h> inclusion from <bsd/libutil.h>
This is a non-portable header, and we should not assume it is present.
Let the first system header pull it in if needed.
2018-03-13 02:28:53 +01:00
Guillem Jover
11ec8f1e5d Handle systems missing <sys/cdefs.h>
This is a non-portable header, and we cannot expect it to be provided by
the system libc (e.g. musl). We just need and rely on declaration that
we have defined ourselves in our own <bsd/sys/cdefs.h>. So we switch to
only ever assume that.

Fixes: https://bugs.freedesktop.org/105281
2018-03-13 02:28:53 +01:00
Guillem Jover
5ba8c5bab0 progname: Port to Windows
Define the directory separator depending on the system targetted.

Reported-by: Progyan Bhattacharya <progyanb@acm.org>
2018-03-06 01:10:14 +01:00
Guillem Jover
0093ca2b0e Handle SPARC V8+ on Sun Studio compiler 2018-03-05 00:02:34 +01:00
James Clarke
0b65d43963 Add support for ELF machine EM_SPARC32PLUS
32-bit SPARC on V8+ uses a different ELF machine type.

Fixes: https://bugs.gentoo.org/634550
Signed-off-by: Guillem Jover <guillem@hadrons.org>
2018-03-04 23:49:25 +01:00
64 changed files with 3652 additions and 1008 deletions

206
COPYING
View File

@@ -3,7 +3,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files:
*
Copyright:
Copyright © 2004-2006, 2008-2017 Guillem Jover <guillem@hadrons.org>
Copyright © 2004-2006, 2008-2018 Guillem Jover <guillem@hadrons.org>
License: BSD-3-clause
Files:
@@ -110,6 +110,8 @@ Files:
man/setmode.3bsd
man/strmode.3bsd
man/strnstr.3bsd
man/strtoi.3bsd
man/strtou.3bsd
man/unvis.3bsd
man/vis.3bsd
man/wcslcpy.3bsd
@@ -121,8 +123,9 @@ Files:
src/setmode.c
src/strmode.c
src/strnstr.c
src/strtoi.c
src/strtou.c
src/unvis.c
src/vis.c
Copyright:
Copyright © 1980, 1982, 1986, 1989-1994
The Regents of the University of California. All rights reserved.
@@ -153,29 +156,16 @@ Copyright:
Co. or Unix System Laboratories, Inc. and are reproduced herein with
the permission of UNIX System Laboratories, Inc.
License: BSD-3-clause-Regents
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.
Files:
src/vis.c
Copyright:
Copyright © 1989, 1993
The Regents of the University of California. All rights reserved.
.
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.
Copyright © 1999, 2005 The NetBSD Foundation, Inc.
All rights reserved.
License: BSD-3-clause-Regents and BSD-2-clause-NetBSD
Files:
include/bsd/libutil.h
@@ -184,30 +174,7 @@ Copyright:
All rights reserved.
Copyright © 2002 Networks Associates Technology, Inc.
All rights reserved.
License: BSD-3-clause-Peter-Wemm
Redistribution and use in source and binary forms, with or without
modification, is 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. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
.
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.
License: BSD-3-clause-author
Files:
man/timeradd.3bsd
@@ -271,8 +238,11 @@ Files:
src/fmtcheck.c
src/humanize_number.c
src/stringlist.c
src/strtonum.c
Copyright:
Copyright © 1994, 1997-2000, 2002, 2008, 2010 The NetBSD Foundation, Inc.
Copyright © 1994, 1997-2000, 2002, 2008, 2010, 2014
The NetBSD Foundation, Inc.
Copyright © 2013 John-Mark Gurney <jmg@FreeBSD.org>
All rights reserved.
.
Some code was contributed to The NetBSD Foundation by Allen Briggs.
@@ -293,26 +263,6 @@ Copyright:
Some code is derived from software contributed to The NetBSD Foundation
by Jukka Ruohonen.
License: BSD-2-clause-NetBSD
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.
.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
Files:
include/bsd/sys/endian.h
@@ -367,7 +317,7 @@ License: BSD-2-clause
Files:
src/flopen.c
Copyright:
Copyright © 2007 Dag-Erling Coïdan Smørgrav
Copyright © 2007-2009 Dag-Erling Coïdan Smørgrav
All rights reserved.
License: BSD-2-clause-verbatim
Redistribution and use in source and binary forms, with or without
@@ -403,25 +353,6 @@ Copyright:
Copyright © 2002 Niels Provos <provos@citi.umich.edu>
All rights reserved.
License: BSD-2-clause-author
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.
.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
Files:
include/bsd/readpassphrase.h
@@ -429,9 +360,11 @@ Files:
man/strlcpy.3bsd
man/strtonum.3bsd
src/arc4random.c
src/arc4random_linux.h
src/arc4random_openbsd.h
src/arc4random_uniform.c
src/arc4random_unix.h
src/arc4random_win.h
src/closefrom.c
src/getentropy_aix.c
src/getentropy_bsd.c
@@ -440,11 +373,11 @@ Files:
src/getentropy_linux.c
src/getentropy_osx.c
src/getentropy_solaris.c
src/getentropy_win.c
src/readpassphrase.c
src/reallocarray.c
src/strlcat.c
src/strlcpy.c
src/strtonum.c
Copyright:
Copyright © 2004 Ted Unangst and Todd Miller
All rights reserved.
@@ -549,6 +482,56 @@ License: Beerware
can do whatever you want with this stuff. If we meet some day, and you think
this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
License: BSD-3-clause-Regents
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.
License: BSD-3-clause-author
Redistribution and use in source and binary forms, with or without
modification, is 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. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
.
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.
License: BSD-3-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -572,6 +555,49 @@ License: BSD-3-clause
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: BSD-2-clause-NetBSD
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.
.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
License: BSD-2-clause-author
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.
.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
License: BSD-2-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View File

@@ -12,8 +12,8 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])],
[AC_SUBST([AM_DEFAULT_VERBOSITY], [1])])
LIBBSD_ABI_MAJOR=0
LIBBSD_ABI_MINOR=8
LIBBSD_ABI_PATCH=7
LIBBSD_ABI_MINOR=9
LIBBSD_ABI_PATCH=1
LIBBSD_ABI="$LIBBSD_ABI_MAJOR:$LIBBSD_ABI_MINOR:$LIBBSD_ABI_PATCH"
AC_SUBST([LIBBSD_ABI])

View File

@@ -13,6 +13,7 @@ nobase_include_HEADERS = \
bsd/bsd.h \
bsd/err.h \
bsd/getopt.h \
bsd/inttypes.h \
bsd/libutil.h \
bsd/md5.h \
bsd/nlist.h \

49
include/bsd/inttypes.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* Copyright © 2018 Guillem Jover <guillem@hadrons.org>
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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 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.
*/
#ifdef LIBBSD_OVERLAY
#include_next <inttypes.h>
#else
#include <inttypes.h>
#endif
#ifndef LIBBSD_INTTYPES_H
#define LIBBSD_INTTYPES_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
__BEGIN_DECLS
intmax_t strtoi(const char *__restrict nptr, char **__restrict endptr,
int base, intmax_t lo, intmax_t hi, int *rstatus);
uintmax_t strtou(const char *__restrict nptr, char **__restrict endptr,
int base, uintmax_t lo, uintmax_t hi, int *rstatus);
__END_DECLS
#endif

View File

@@ -39,19 +39,16 @@
#ifndef LIBBSD_LIBUTIL_H
#define LIBBSD_LIBUTIL_H
#include <features.h>
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
/* for pidfile.c */
struct pidfh {
int pf_fd;
char *pf_path;
dev_t pf_dev;
ino_t pf_ino;
};
struct pidfh;
__BEGIN_DECLS
int humanize_number(char *buf, size_t len, int64_t bytes,
@@ -59,8 +56,10 @@ int humanize_number(char *buf, size_t len, int64_t bytes,
int expand_number(const char *_buf, uint64_t *_num);
int flopen(const char *_path, int _flags, ...);
int flopenat(int dirfd, const char *path, int flags, ...);
struct pidfh *pidfile_open(const char *path, mode_t mode, pid_t *pidptr);
int pidfile_fileno(const struct pidfh *pfh);
int pidfile_write(struct pidfh *pfh);
int pidfile_close(struct pidfh *pfh);
int pidfile_remove(struct pidfh *pfh);
@@ -68,12 +67,14 @@ int pidfile_remove(struct pidfh *pfh);
char *fparseln(FILE *, size_t *, size_t *, const char[3], int);
__END_DECLS
/* humanize_number(3) */
/* Values for humanize_number(3)'s flags parameter. */
#define HN_DECIMAL 0x01
#define HN_NOSPACE 0x02
#define HN_B 0x04
#define HN_DIVISOR_1000 0x08
#define HN_IEC_PREFIXES 0x10
/* Values for humanize_number(3)'s scale parameter. */
#define HN_GETSCALE 0x10
#define HN_AUTOSCALE 0x20

View File

@@ -27,7 +27,11 @@ typedef struct MD5Context {
uint8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */
} MD5_CTX;
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
__BEGIN_DECLS

View File

@@ -27,7 +27,11 @@
#ifndef LIBBSD_NLIST_H
#define LIBBSD_NLIST_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
struct nlist {
union {

View File

@@ -31,7 +31,11 @@
#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
__BEGIN_DECLS

View File

@@ -42,7 +42,11 @@
#ifndef LIBBSD_STDLIB_H
#define LIBBSD_STDLIB_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/stat.h>
#include <stdint.h>
@@ -67,7 +71,8 @@ int sradixsort(const unsigned char **base, int nmemb,
const unsigned char *table, unsigned endbyte);
void *reallocf(void *ptr, size_t size);
#if defined(_GNU_SOURCE) && defined(__GLIBC__) && !__GLIBC_PREREQ(2, 26)
#if !defined(__GLIBC__) || \
(defined(__GLIBC__) && (!__GLIBC_PREREQ(2, 26) || !defined(_GNU_SOURCE)))
void *reallocarray(void *ptr, size_t nmemb, size_t size);
#endif

View File

@@ -33,7 +33,11 @@
#ifndef LIBBSD_STRING_H
#define LIBBSD_STRING_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
__BEGIN_DECLS
@@ -42,7 +46,8 @@ size_t strlcat(char *dst, const char *src, size_t siz);
char *strnstr(const char *str, const char *find, size_t str_len);
void strmode(mode_t mode, char *str);
#if defined(_GNU_SOURCE) && defined(__GLIBC__) && !__GLIBC_PREREQ(2, 25)
#if !defined(__GLIBC__) || \
(defined(__GLIBC__) && (!__GLIBC_PREREQ(2, 25) || !defined(_GNU_SOURCE)))
void explicit_bzero(void *buf, size_t len);
#endif
__END_DECLS

View File

@@ -31,7 +31,12 @@
#ifndef LIBBSD_STRINGLIST_H
#define LIBBSD_STRINGLIST_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
/*

View File

@@ -58,6 +58,14 @@
#endif
#endif
/*
* On non-glibc based systems, we cannot unconditionally use the
* __GLIBC_PREREQ macro as it gets expanded before evaluation.
*/
#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(maj, min) 0
#endif
/*
* Some kFreeBSD headers expect those macros to be set for sanity checks.
*/
@@ -68,6 +76,9 @@
#define _SYS_CDEFS_H
#endif
#define LIBBSD_CONCAT(x, y) x ## y
#define LIBBSD_STRING(x) #x
#ifdef __GNUC__
#define LIBBSD_GCC_VERSION (__GNUC__ << 8 | __GNUC_MINOR__)
#else
@@ -82,6 +93,12 @@
#define LIBBSD_DEPRECATED(x)
#endif
#if LIBBSD_GCC_VERSION >= 0x0200
#define LIBBSD_REDIRECT(name, proto, alias) name proto __asm__(LIBBSD_ASMNAME(#alias))
#endif
#define LIBBSD_ASMNAME(cname) LIBBSD_ASMNAME_PREFIX(__USER_LABEL_PREFIX__, cname)
#define LIBBSD_ASMNAME_PREFIX(prefix, cname) LIBBSD_STRING(prefix) cname
#ifndef __dead2
# if LIBBSD_GCC_VERSION >= 0x0207
# define __dead2 __attribute__((__noreturn__))
@@ -147,6 +164,12 @@
# define __bounded__(x, y, z)
#endif
/*
* Return the number of elements in a statically-allocated array,
* __x.
*/
#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
/*
* We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
* require it.

View File

@@ -33,7 +33,11 @@
#ifndef LIBBSD_SYS_QUEUE_H
#define LIBBSD_SYS_QUEUE_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
/*
* This file defines four types of data structures: singly-linked lists,

View File

@@ -30,7 +30,11 @@
#ifndef LIBBSD_SYS_TREE_H
#define LIBBSD_SYS_TREE_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
/*
* This file defines data structures for different types of trees:

View File

@@ -41,7 +41,11 @@
#ifndef LIBBSD_TIMECONV_H
#define LIBBSD_TIMECONV_H
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <stdint.h>
#include <time.h>

View File

@@ -1,3 +1,5 @@
/* $NetBSD: vis.h,v 1.25 2017/04/23 01:57:36 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -27,7 +29,6 @@
* SUCH DAMAGE.
*
* @(#)vis.h 8.1 (Berkeley) 6/2/93
* $FreeBSD: src/include/vis.h,v 1.11 2003/10/30 10:40:49 phk Exp $
*/
#ifndef LIBBSD_VIS_H
@@ -38,25 +39,34 @@
/*
* to select alternate encoding format
*/
#define VIS_OCTAL 0x01 /* use octal \ddd format */
#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */
#define VIS_OCTAL 0x0001 /* use octal \ddd format */
#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropriate */
/*
* to alter set of characters encoded (default is to encode all
* non-graphic except space, tab, and newline).
*/
#define VIS_SP 0x04 /* also encode space */
#define VIS_TAB 0x08 /* also encode tab */
#define VIS_NL 0x10 /* also encode newline */
#define VIS_SP 0x0004 /* also encode space */
#define VIS_TAB 0x0008 /* also encode tab */
#define VIS_NL 0x0010 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */
#define VIS_DQ 0x8000 /* also encode double quotes */
/*
* other
*/
#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
#define VIS_GLOB 0x100 /* encode glob(3) magics */
#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */
#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */
#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */
#define VIS_MIMESTYLE 0x0100 /* mime-style escape = HEX HEX */
#define VIS_HTTP1866 0x0200 /* http-style &#num; or &string; */
#define VIS_NOESCAPE 0x0400 /* don't decode `\' */
#define _VIS_END 0x0800 /* for unvis */
#define VIS_GLOB 0x1000 /* encode glob(3) magic characters */
#define VIS_SHELL 0x2000 /* encode shell special characters [not glob] */
#define VIS_META (VIS_WHITE | VIS_GLOB | VIS_SHELL)
#define VIS_NOLOCALE 0x4000 /* encode using the C locale */
/*
* unvis return codes
@@ -70,18 +80,73 @@
/*
* unvis flags
*/
#define UNVIS_END 1 /* no more characters */
#define UNVIS_END _VIS_END /* no more characters */
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
/*
* NetBSD added an strnvis and unfortunately made it incompatible with the
* existing one in OpenBSD and Freedesktop's libbsd (the former having existed
* for over ten years). Despite this incompatibility being reported during
* development (see http://gnats.netbsd.org/44977) they still shipped it.
* Even more unfortunately FreeBSD and later MacOS picked up this incompatible
* implementation.
*
* Provide both implementations and default for now on the historical one to
* avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
* Define LIBBSD_NETBSD_VIS to switch to the NetBSD one now.
*/
#ifndef LIBBSD_NETBSD_VIS
#warning "NetBSD added incompatible strnvis() and strnunvis(), please see <bsd/vis.h> for more detils."
#endif
__BEGIN_DECLS
char *vis(char *, int, int, int);
char *nvis(char *, size_t, int, int, int);
char *svis(char *, int, int, int, const char *);
char *snvis(char *, size_t, int, int, int, const char *);
int strvis(char *, const char *, int);
int strvisx(char *, const char *, size_t, int);
int stravis(char **, const char *, int);
#ifdef LIBBSD_NETBSD_VIS
/* NetBSD prototype. */
int LIBBSD_REDIRECT(strnvis, (char *, size_t, const char *, int),
strnvis_netbsd);
#else
/* OpenBSD prototype (current default). */
int strnvis(char *, const char *, size_t, int);
#endif
int strsvis(char *, const char *, int, const char *);
int strsnvis(char *, size_t, const char *, int, const char *);
int strvisx(char *, const char *, size_t, int);
int strnvisx(char *, size_t, const char *, size_t, int);
int strenvisx(char *, size_t, const char *, size_t, int, int *);
int strsvisx(char *, const char *, size_t, int, const char *);
int strsnvisx(char *, size_t, const char *, size_t, int, const char *);
int strsenvisx(char *, size_t, const char *, size_t , int, const char *,
int *);
int strunvis(char *, const char *);
int strunvisx(char *, const char *, int);
#ifdef LIBBSD_NETBSD_VIS
/* NetBSD prototype. */
int LIBBSD_REDIRECT(strnunvis, (char *, size_t, const char *),
strnunvis_netbsd);
#else
/* OpenBSD prototype (current default). */
ssize_t strnunvis(char *, const char *, size_t);
#endif
int strunvisx(char *, const char *, int);
int strnunvisx(char *, size_t, const char *, int);
int unvis(char *, int, int *, int);
__END_DECLS

View File

@@ -40,7 +40,11 @@
#define LIBBSD_WCHAR_H
#include <stddef.h>
#ifdef LIBBSD_OVERLAY
#include <sys/cdefs.h>
#else
#include <bsd/sys/cdefs.h>
#endif
#include <sys/types.h>
__BEGIN_DECLS

View File

@@ -212,7 +212,9 @@ dist_man_MANS = \
strnstr.3bsd \
strnunvis.3bsd \
strnvis.3bsd \
strtoi.3bsd \
strtonum.3bsd \
strtou.3bsd \
strunvis.3bsd \
strvis.3bsd \
strvisx.3bsd \

View File

@@ -25,12 +25,13 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 6, 2009
.Dd July 28, 2017
.Dt FLOPEN 3bsd
.Os
.Sh NAME
.Nm flopen
.Nd reliably open and lock a file
.Nm flopen ,
.Nm flopenat
.Nd "Reliably open and lock a file"
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
@@ -44,6 +45,10 @@ for include usage.)
.Fn flopen "const char *path" "int flags"
.Ft int
.Fn flopen "const char *path" "int flags" "mode_t mode"
.Ft int
.Fn flopenat "int fd" "const char *path" "int flags"
.Ft int
.Fn flopenat "int fd" "const char *path" "int flags" "mode_t mode"
.Sh DESCRIPTION
The
.Fn flopen
@@ -53,7 +58,7 @@ It is essentially equivalent with calling
with the same parameters followed by
.Fn flock
with an
.Va operation
.Fa operation
argument of
.Dv LOCK_EX ,
except that
@@ -65,7 +70,7 @@ files, mailboxes and other kinds of files which are used for
synchronization between processes.
.Pp
If
.Va flags
.Fa flags
includes
.Dv O_NONBLOCK
and the file is already locked,
@@ -78,11 +83,32 @@ to
As with
.Fn open ,
the additional
.Va mode
.Fa mode
argument is required if
.Va flags
.Fa flags
includes
.Dv O_CREAT .
.Pp
The
.Fn flopenat
function is equivalent to the
.Fn flopen
function except in the case where the
.Fa path
specifies a relative path.
In this case the file to be opened is determined relative to the directory
associated with the file descriptor
.Fa fd
instead of the current working directory.
If
.Fn flopenat
is passed the special value
.Dv AT_FDCWD
in the
.Fa fd
parameter, the current working directory is used
and the behavior is identical to a call to
.Fn flopen .
.Sh RETURN VALUES
If successful,
.Fn flopen
@@ -102,4 +128,4 @@ and
The
.Nm
function and this manual page were written by
.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org .
.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .

View File

@@ -1,3 +1,5 @@
.\" $NetBSD: fmtcheck.3,v 1.8 2014/06/14 08:18:24 apb Exp $
.\"
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
@@ -24,15 +26,12 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fmtcheck.3,v 1.9 2004/07/02 23:52:10 ru Exp $
.Dd October 16, 2002
.Os
.Dd June 14, 2014
.Dt FMTCHECK 3bsd
.Os
.Sh NAME
.Nm fmtcheck
.Nd sanitizes user-supplied
.Xr printf 3 Ns -style
format string
.Nd sanitizes user-supplied printf(3)-style format string
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
@@ -45,8 +44,8 @@ for include usage.)
.Fn fmtcheck "const char *fmt_suspect" "const char *fmt_default"
.Sh DESCRIPTION
The
.Fn fmtcheck
scans
.Nm
function scans
.Fa fmt_suspect
and
.Fa fmt_default
@@ -60,55 +59,45 @@ is a valid format string.
.Pp
The
.Xr printf 3
family of functions cannot verify the types of arguments that they are
family of functions can not verify the types of arguments that they are
passed at run-time.
In some cases, like
.Xr catgets 3 ,
it is useful or necessary to use a user-supplied format string with no
guarantee that the format string matches the specified arguments.
guarantee that the format string matches the specified parameters.
.Pp
The
.Fn fmtcheck
was designed to be used in these cases, as in:
.Nm
function was designed to be used in these cases, as in:
.Bd -literal -offset indent
printf(fmtcheck(user_format, standard_format), arg1, arg2);
.Ed
.Pp
In the check, field widths, fillers, precisions, etc.\& are ignored (unless
In the check, field widths, fillers, precisions, etc. are ignored (unless
the field width or precision is an asterisk
.Ql *
instead of a digit string).
Also, any text other than the format specifiers
is completely ignored.
Also, any text other than the format specifiers is completely ignored.
.Pp
Note that the formats may be quite different as long as they accept the
same parameters.
For example, "%ld %o %30s %#llx %-10.*e %n" is
compatible with "This number %lu %d%% and string %s has %qd numbers
and %.*g floats (%n)."
However, "%o" is not equivalent to "%lx" because
the first requires an integer and the second requires a long,
and "%p" is not equivalent to "%lu" because
the first requires a pointer and the second requires a long.
.Sh RETURN VALUES
If
.Fa fmt_suspect
is a valid format and consumes the same argument types as
.Fa fmt_default ,
then the
.Fn fmtcheck
will return
.Nm
function will return
.Fa fmt_suspect .
Otherwise, it will return
.Fa fmt_default .
.Sh SECURITY CONSIDERATIONS
Note that the formats may be quite different as long as they accept the
same arguments.
For example,
.Qq Li "%p %o %30s %#llx %-10.*e %n"
is compatible with
.Qq Li "This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)" .
However,
.Qq Li %o
is not equivalent to
.Qq Li %lx
because
the first requires an integer and the second requires a long.
.Sh SEE ALSO
.Xr printf 3
.Sh BUGS
The
.Fn fmtcheck
function does not understand all of the conversions that
.Xr printf 3
does.

View File

@@ -1,6 +1,6 @@
.\" libbsd man page
.\"
.\" Copyright © 2017 Gullem Jover <guillem@hadrons.org>
.\" Copyright © 2017-2018 Gullem Jover <guillem@hadrons.org>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -24,7 +24,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 31 2017
.Dd May 21 2018
.Dt LIBBSD 7
.Os
.Sh NAME
@@ -94,6 +94,7 @@ be prefixed with
.It In bitstring.h
.It In err.h
.It In getopt.h
.It In inttypes.h
.It In libutil.h
.It In md5.h
.It In netinet/ip_icmp.h
@@ -142,6 +143,17 @@ Use
.Fn getline 3
instead, which is available in many systems and required by
.St -p1003.1-2008 .
.It Fn fgetwln
Unportable, requires assistance from the stdio layer.
An implementation has to choose between leaking buffers or being reentrant
for a limited amount of streams (this implementation chose the latter with
a limit of 32).
Use
.Fn fgetwc 3
instead, which is available in many systems and required by
.St -isoC-99
and
.St -p1003.1-2001 .
.It Fn funopen
Unportable, requires assistance from the stdio layer or some hook framework.
On GNU systems the
@@ -214,7 +226,9 @@ This function is provided by
.Xr strlcpy 3bsd ,
.Xr strmode 3bsd ,
.Xr strnstr 3bsd ,
.Xr strtoi 3bsd ,
.Xr strtonum 3bsd ,
.Xr strtou 3bsd ,
.Xr timeradd 3bsd ,
.Xr timeval 3bsd ,
.Xr tree 3bsd ,

View File

@@ -24,15 +24,16 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 20, 2008
.Dd February 8, 2012
.Dt PIDFILE 3bsd
.Os
.Sh NAME
.Nm pidfile_open ,
.Nm pidfile_write ,
.Nm pidfile_close ,
.Nm pidfile_remove
.Nd library for PID files handling
.Nm pidfile_remove ,
.Nm pidfile_fileno
.Nd "library for PID files handling"
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
@@ -49,6 +50,8 @@ for include usage.)
.Fn pidfile_close "struct pidfh *pfh"
.Ft int
.Fn pidfile_remove "struct pidfh *pfh"
.Ft int
.Fn pidfile_fileno "struct pidfh *pfh"
.Sh DESCRIPTION
The
.Nm pidfile
@@ -62,11 +65,14 @@ The
function opens (or creates) a file specified by the
.Fa path
argument and locks it.
If a file can not be locked, a PID of an already running daemon is returned in
the
If
.Fa pidptr
argument (if it is not
.Dv NULL ) .
argument is not
.Dv NULL
and file can not be locked, the function will use it to store a PID of an
already running daemon or
.Li -1
in case daemon did not write its PID yet.
The function does not write process' PID into the file here, so it can be
used before
.Fn fork Ns ing
@@ -77,10 +83,16 @@ argument is
.Dv NULL ,
.Pa /var/run/ Ns Ao Va progname Ac Ns Pa .pid
file will be used.
The
.Fn pidfile_open
function sets the O_CLOEXEC close-on-exec flag when opening the pidfile.
.Pp
The
.Fn pidfile_write
function writes process' PID into a previously opened file.
The file is truncated before write, so calling the
.Fn pidfile_write
function multiple times is supported.
.Pp
The
.Fn pidfile_close
@@ -92,6 +104,10 @@ to start a child process.
The
.Fn pidfile_remove
function closes and removes a pidfile.
.Pp
The
.Fn pidfile_fileno
function returns the file descriptor for the open pidfile.
.Sh RETURN VALUES
The
.Fn pidfile_open
@@ -105,15 +121,27 @@ If an error occurs,
will be set.
.Pp
.Rv -std pidfile_write pidfile_close pidfile_remove
.Pp
The
.Fn pidfile_fileno
function returns the low-level file descriptor.
It returns
.Li -1
and sets
.Va errno
if a NULL
.Vt pidfh
is specified, or if the pidfile is no longer open.
.Sh EXAMPLES
The following example shows in which order these functions should be used.
Note that it is safe to pass
.Dv NULL
to
.Fn pidfile_write ,
.Fn pidfile_remove
and
.Fn pidfile_remove ,
.Fn pidfile_close
and
.Fn pidfile_fileno
functions.
.Bd -literal
struct pidfh *pfh;
@@ -127,6 +155,11 @@ if (pfh == NULL) {
}
/* If we cannot create pidfile from other reasons, only warn. */
warn("Cannot open or create pidfile");
/*
* Even though pfh is NULL we can continue, as the other pidfile_*
* function can handle such situation by doing nothing except setting
* errno to EINVAL.
*/
}
if (daemon(0, 0) == \-1) {
@@ -165,16 +198,18 @@ function will fail if:
.It Bq Er EEXIST
Some process already holds the lock on the given pidfile, meaning that a
daemon is already running.
If
.Fa pidptr
argument is not
.Dv NULL
the function will use it to store a PID of an already running daemon or
.Li -1
in case daemon did not write its PID yet.
.It Bq Er ENAMETOOLONG
Specified pidfile's name is too long.
.It Bq Er EINVAL
Some process already holds the lock on the given pidfile, but PID read
from there is invalid.
.It Bq Er EAGAIN
Some process already holds the lock on the given pidfile, but the file
is truncated.
Most likely, the existing daemon is writing new PID into
the file.
.El
.Pp
The
@@ -242,6 +277,16 @@ and
system calls and the
.Xr flopen 3bsd
library function.
.Pp
The
.Fn pidfile_fileno
function will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
Improper function use.
Probably called not from the process which used
.Fn pidfile_open .
.El
.Sh SEE ALSO
.Xr open 2 ,
.Xr daemon 3 ,
@@ -251,7 +296,7 @@ library function.
The
.Nm pidfile
functionality is based on ideas from
.An John-Mark Gurney Aq jmg@FreeBSD.org .
.An John-Mark Gurney Aq Mt jmg@FreeBSD.org .
.Pp
The code and manual page was written by
.An Pawel Jakub Dawidek Aq pjd@FreeBSD.org .
.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org .

View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: readpassphrase.3,v 1.16 2005/07/22 03:16:58 jaredy Exp $
.\" $OpenBSD: readpassphrase.3,v 1.20 2014/03/06 23:03:18 millert Exp $
.\"
.\" Copyright (c) 2000, 2002 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@@ -18,7 +18,7 @@
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\"
.Dd $Mdocdate: May 31 2007 $
.Dd $Mdocdate: March 6 2014 $
.Dt READPASSPHRASE 3bsd
.Os
.Sh NAME
@@ -55,9 +55,11 @@ Up to
Any additional
characters and the terminating newline (or return) character are discarded.
.Pp
.Fn readpassphrase
takes the following optional
.Fa flags :
The
.Fa flags
argument is the bitwise
.Tn OR
of zero or more of the following values:
.Bd -literal -offset indent
RPP_ECHO_OFF turn off echo (default behavior)
RPP_ECHO_ON leave echo on
@@ -65,7 +67,7 @@ RPP_REQUIRE_TTY fail if there is no tty
RPP_FORCELOWER force input to lower case
RPP_FORCEUPPER force input to upper case
RPP_SEVENBIT strip the high bit from input
RPP_STDIN force read of passphrase from stdin
RPP_STDIN read passphrase from stdin; ignore prompt
.Ed
.Pp
The calling process should zero the passphrase as soon as possible to
@@ -100,7 +102,7 @@ if (compare(transform(passbuf), epass) != 0)
\&...
memset(passbuf, 0, sizeof(passbuf));
explicit_bzero(passbuf, sizeof(passbuf));
.Ed
.Sh ERRORS
.Bl -tag -width Er

238
man/strtoi.3bsd Normal file
View File

@@ -0,0 +1,238 @@
.\" $NetBSD: strtoi.3,v 1.7 2017/07/03 21:32:50 wiz Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Chris Torek and the American National Standards Committee X3,
.\" on Information Processing Systems.
.\"
.\" 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.
.\"
.\" from: @(#)strtol.3 8.1 (Berkeley) 6/4/93
.\"
.\" Created by Kamil Rytarowski, based on ID:
.\" NetBSD: strtol.3,v 1.31 2015/03/11 09:57:35 wiz Exp
.\"
.Dd November 13, 2015
.Dt STRTOI 3bsd
.Os
.Sh NAME
.Nm strtoi
.Nd convert string value to an intmax_t integer
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
.Sh SYNOPSIS
.In inttypes.h
(See
.Xr libbsd 7
for include usage.)
.Ft intmax_t
.Fo strtoi
.Fa "const char * restrict nptr"
.Fa "char ** restrict endptr"
.Fa "int base"
.Fa "intmax_t lo"
.Fa "intmax_t hi"
.Fa "int *rstatus"
.Fc
.Sh DESCRIPTION
The
.Fn strtoi
function
converts the string in
.Fa nptr
to an
.Ft intmax_t
value.
The
.Fn strtoi
function uses internally
.Xr strtoimax 3
and ensures that the result is always in the range [
.Fa lo ..
.Fa hi
].
In adddition it always places
.Dv 0
on success or a conversion status in the
.Fa rstatus
argument, avoiding the
.Dv errno
gymnastics the other functions require.
The
.Fa rstatus
argument can be
.Dv NULL
if conversion status is to be ignored.
.Pp
The string may begin with an arbitrary amount of white space
(as determined by
.Xr isspace 3 )
followed by a single optional
.Ql +
or
.Ql -
sign.
If
.Fa base
is zero or 16,
the string may then include a
.Ql 0x
or
.Ql 0X
prefix,
and the number will be read in base 16; otherwise,
.\" if the
.\" .Fa base
.\" is zero or 2,
.\" the string may then include a
.\" .Ql 0b
.\" or
.\" .Ql 0B
.\" prefix,
.\" and the number will be read in base 2; otherwise,
a zero
.Fa base
is taken as 10 (decimal) unless the next character is
.Ql 0 ,
in which case it is taken as 8 (octal).
.Pp
The remainder of the string is converted to a
.Em intmax_t
value in the obvious manner,
stopping at the first character which is not a valid digit
in the given base.
(In bases above 10, the letter
.Ql A
in either upper or lower case
represents 10,
.Ql B
represents 11, and so forth, with
.Ql Z
representing 35.)
.Pp
If
.Fa endptr
is non-nil,
.Fn strtoi
stores the address of the first invalid character in
.Fa *endptr .
If there were no digits at all, however,
.Fn strtoi
stores the original value of
.Fa nptr
in
.Fa *endptr .
(Thus, if
.Fa *nptr
is not
.Ql \e0
but
.Fa **endptr
is
.Ql \e0
on return, the entire string was valid.)
.Sh RETURN VALUES
The
.Fn strtoi
function
always returns the closest value in the range specified by
the
.Fa lo
and
.Fa hi
arguments.
.Pp
The
.Va errno
value is guaranteed to be left unchanged.
.Pp
Errors are stored as the conversion status in the
.Fa rstatus
argument.
.Sh EXAMPLES
The following example will always return a number in
.Dv [1..99]
range no matter what the input is, and warn if the conversion failed.
.Bd -literal -offset indent
int e;
intmax_t lval = strtoi(buf, NULL, 0, 1, 99, &e);
if (e)
warnc(e, "conversion of `%s' to a number failed, using %jd",
buf, lval);
.Ed
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er ECANCELED
The string did not contain any characters that were converted.
.It Bq Er EINVAL
The
.Ar base
is not between 2 and 36 and does not contain the special value 0.
.It Bq Er ENOTSUP
The string contained non-numeric characters that did not get converted.
In this case,
.Fa endptr
points to the first unconverted character.
.It Bq Er ERANGE
The given string was out of range; the value converted has been clamped;
or the range given was invalid, i.e.
.Fa lo
>
.Fa hi .
.El
.Sh SEE ALSO
.Xr atof 3 ,
.Xr atoi 3 ,
.Xr atol 3 ,
.Xr atoll 3 ,
.Xr strtod 3 ,
.Xr strtoimax 3 ,
.Xr strtol 3 ,
.Xr strtoll 3 ,
.Xr strtou 3bsd ,
.Xr strtoul 3 ,
.Xr strtoull 3 ,
.Xr strtoumax 3
.Sh STANDARDS
The
.Fn strtoi
function is a
.Nx
extension.
.Sh HISTORY
The
.Fn strtoi
function first appeared in
.Nx 7 .
.Ox
introduced the
.Fn strtonum 3bsd
function for the same purpose, but the interface makes it impossible to
properly differentiate illegal returns.
.Sh BUGS
Ignores the current locale.

View File

@@ -1,3 +1,6 @@
.\" $NetBSD: strtonum.3,v 1.2 2015/01/19 11:47:41 wiz Exp $
.\" $OpenBSD: strtonum.3,v 1.17 2013/08/14 06:32:28 jmc Exp $
.\"
.\" Copyright (c) 2004 Ted Unangst
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -12,10 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\" $OpenBSD: strtonum.3,v 1.12 2005/10/26 11:37:58 jmc Exp $
.\" $FreeBSD$
.\"
.Dd April 29, 2004
.Dd January 18, 2015
.Dt STRTONUM 3bsd
.Os
.Sh NAME
@@ -45,14 +45,6 @@ function converts the string in
to a
.Vt "long long"
value.
The
.Fn strtonum
function was designed to facilitate safe, robust programming
and overcome the shortcomings of the
.Xr atoi 3
and
.Xr strtol 3
family of interfaces.
.Pp
The string may begin with an arbitrary amount of whitespace
(as determined by
@@ -112,15 +104,13 @@ The above example will guarantee that the value of iterations is between
1 and 64 (inclusive).
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er EINVAL
The given string did not consist solely of digit characters; or
.Ar minval
was larger than
.Ar maxval .
.It Bq Er ERANGE
The given string was out of range.
.It Bq Er EINVAL
The given string did not consist solely of digit characters.
.It Bq Er EINVAL
The supplied
.Fa minval
was larger than
.Fa maxval .
.El
.Pp
If an error occurs,
@@ -142,21 +132,58 @@ The string did not consist solely of digit characters.
.Xr atoll 3 ,
.Xr sscanf 3 ,
.Xr strtod 3 ,
.Xr strtoi 3bsd ,
.Xr strtol 3 ,
.Xr strtoul 3
.Xr strtoll 3 ,
.Xr strtou 3bsd ,
.Xr strtoul 3 ,
.Xr strtoull 3
.Sh STANDARDS
The
.Fn strtonum
function is a
.Bx
is an
.Ox
extension.
The existing alternatives, such as
.Xr atoi 3
and
.Xr strtol 3 ,
are either impossible or difficult to use safely.
.Sh HISTORY
The
.Fn strtonum
function first appeared in
.Ox 3.6 .
.Fn strtonum
was redesigned in
.Nx 8
as
.Fn strtoi 3bsd
and
.Fn strtou 3bsd .
.Sh CAVEATS
The
.Fn strtonum
function was designed to facilitate safe,
robust programming and overcome the shortcomings of the
.Xr atoi 3
and
.Xr strtol 3
family of interfaces, however there are problems with the
.Fn strtonum
API:
.Bl -dash
.It
will return 0 on failure; 0 might not be in range, so that necessitates
an error check even if you want to avoid it
.It
does not differentiate 'illegal' returns, so we can't tell the
difference between partial and no conversions
.It
returns english strings
.It
can't set the base, or find where the conversion ended
.It
hardcodes long long integer type
.El
To overcome the shortcomings of
.Fn strtonum
.Nx
provides
.Fn strtou 3bsd
and
.Fn strtoi 3bsd .

238
man/strtou.3bsd Normal file
View File

@@ -0,0 +1,238 @@
.\" $NetBSD: strtou.3,v 1.7 2017/07/03 21:32:50 wiz Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Chris Torek and the American National Standards Committee X3,
.\" on Information Processing Systems.
.\"
.\" 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.
.\"
.\" from: @(#)strtoul.3 8.1 (Berkeley) 6/4/93
.\"
.\" Created by Kamil Rytarowski, based on ID:
.\" NetBSD: strtoul.3,v 1.29 2015/03/10 13:00:58 christos Exp
.\"
.Dd November 13, 2015
.Dt STRTOU 3bsd
.Os
.Sh NAME
.Nm strtou
.Nd convert a string to an uintmax_t integer
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
.Sh SYNOPSIS
.In inttypes.h
(See
.Xr libbsd 7
for include usage.)
.Ft uintmax_t
.Fo strtou
.Fa "const char * restrict nptr"
.Fa "char ** restrict endptr"
.Fa "int base"
.Fa "uintmax_t lo"
.Fa "uintmax_t hi"
.Fa "int *rstatus"
.Fc
.Sh DESCRIPTION
The
.Fn strtou
function converts the string in
.Fa nptr
to an
.Ft uintmax_t
value.
The
.Fn strtou
function uses internally
.Xr strtoumax 3
and ensures that the result is always in the range [
.Fa lo ..
.Fa hi
].
In adddition it always places
.Dv 0
on success or a conversion status in the
.Fa rstatus
argument, avoiding the
.Dv errno
gymnastics the other functions require.
The
.Fa rstatus
argument can be
.Dv NULL
if conversion status is to be ignored.
.Pp
The string may begin with an arbitrary amount of white space
(as determined by
.Xr isspace 3 )
followed by a single optional
.Ql +
or
.Ql -
sign.
If
.Fa base
is zero or 16,
the string may then include a
.Ql 0x
or
.Ql 0X
prefix,
and the number will be read in base 16; otherwise,
.\" if the
.\" .Fa base
.\" is zero or 2,
.\" the string may then include a
.\" .Ql 0b
.\" or
.\" .Ql 0B
.\" prefix,
.\" and the number will be read in base 2; otherwise,
a zero
.Fa base
is taken as 10 (decimal) unless the next character is
.Ql 0 ,
in which case it is taken as 8 (octal).
.Pp
The remainder of the string is converted to an
.Em uintmax_t
value in the obvious manner,
stopping at the end of the string
or at the first character that does not produce a valid digit
in the given base.
(In bases above 10, the letter
.Ql A
in either upper or lower case
represents 10,
.Ql B
represents 11, and so forth, with
.Ql Z
representing 35.)
.Pp
If
.Fa endptr
is non-nil,
.Fn strtou
stores the address of the first invalid character in
.Fa *endptr .
If there were no digits at all, however,
.Fn strtou
stores the original value of
.Fa nptr
in
.Fa *endptr .
(Thus, if
.Fa *nptr
is not
.Ql \e0
but
.Fa **endptr
is
.Ql \e0
on return, the entire string was valid.)
.Sh RETURN VALUES
The
.Fn strtou
function
always returns the closest value in the range specified by
the
.Fa lo
and
.Fa hi
arguments.
.Pp
The
.Va errno
value is guaranteed to be left unchanged.
.Pp
Errors are stored as the conversion status in the
.Fa rstatus
argument.
.Sh EXAMPLES
The following example will always return a number in
.Dv [1..99]
range no matter what the input is, and warn if the conversion failed.
.Bd -literal -offset indent
int e;
uintmax_t lval = strtou(buf, NULL, 0, 1, 99, &e);
if (e)
warnc(e, "conversion of `%s' to a number failed, using %ju",
buf, lval);
.Ed
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er ECANCELED
The string did not contain any characters that were converted.
.It Bq Er EINVAL
The
.Ar base
is not between 2 and 36 and does not contain the special value 0.
.It Bq Er ENOTSUP
The string contained non-numeric characters that did not get converted.
In this case,
.Fa endptr
points to the first unconverted character.
.It Bq Er ERANGE
The given string was out of range; the value converted has been clamped; or
the range given was invalid, i.e.
.Fa lo
>
.Fa hi .
.El
.Sh SEE ALSO
.Xr atof 3 ,
.Xr atoi 3 ,
.Xr atol 3 ,
.Xr atoll 3 ,
.Xr strtod 3 ,
.Xr strtoi 3bsd ,
.Xr strtoimax 3 ,
.Xr strtol 3 ,
.Xr strtoll 3 ,
.Xr strtoul 3 ,
.Xr strtoull 3 ,
.Xr strtoumax 3
.Sh STANDARDS
The
.Fn strtou
function is a
.Nx
extension.
.Sh HISTORY
The
.Fn strtou
function first appeared in
.Nx 7 .
.Ox
introduced the
.Fn strtonum 3bsd
function for the same purpose, but the interface makes it impossible to
properly differentiate illegal returns.
.Sh BUGS
Ignores the current locale.

View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: unvis.3,v 1.15 2005/07/22 03:16:58 jaredy Exp $
.\" $NetBSD: unvis.3,v 1.29 2017/10/24 19:14:55 abhinav Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,13 +27,17 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd $Mdocdate: May 31 2007 $
.\" @(#)unvis.3 8.2 (Berkeley) 12/11/93
.\"
.Dd March 12, 2011
.Dt UNVIS 3bsd
.Os
.Sh NAME
.Nm unvis ,
.Nm strunvis ,
.Nm strnunvis
.Nm strnunvis ,
.Nm strunvisx ,
.Nm strnunvisx
.Nd decode a visual representation of characters
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
@@ -44,88 +48,91 @@
.Xr libbsd 7
for include usage.)
.Ft int
.Fn unvis "char *cp" "char c" "int *astate" "int flag"
.Fn unvis "char *cp" "int c" "int *astate" "int flag"
.Ft int
.Fn strunvis "char *dst" "char *src"
.Ft ssize_t
.Fn strnunvis "char *dst" "char *src" "size_t size"
.Fn strunvis "char *dst" "const char *src"
.Ft int
.Fn strnunvis "char *dst" "size_t dlen" "const char *src"
.Ft int
.Fn strunvisx "char *dst" "const char *src" "int flag"
.Ft int
.Fn strnunvisx "char *dst" "size_t dlen" "const char *src" "int flag"
.Sh DESCRIPTION
The
.Fn unvis ,
.Fn strunvis
and
.Fn strnunvis
functions are used to decode a visual representation of characters,
as produced by the
.Fn strunvisx
functions
are used to decode a visual representation of characters, as produced
by the
.Xr vis 3bsd
function, back into the original form.
function, back into
the original form.
.Pp
The
.Fn unvis
is called with successive characters in
.Fa c
until a valid
sequence is recognized, at which time the decoded character is
available at the character pointed to by
.Fa cp .
function is called with successive characters in
.Ar c
until a valid sequence is recognized, at which time the decoded
character is available at the character pointed to by
.Ar cp .
.Pp
The
.Fn strunvis
decodes the characters pointed to by
.Fa src
function decodes the characters pointed to by
.Ar src
into the buffer pointed to by
.Fa dst .
.Pp
.Fn strnunvis
decodes the characters pointed to by
.Fa src
into the buffer pointed to by
.Fa dst ,
writing a maximum of
.Fa size
bytes.
.Ar dst .
The
.Fn strunvis
function simply copies
.Fa src
.Ar src
to
.Fa dst ,
.Ar dst ,
decoding any escape sequences along the way,
and returns the number of characters placed into
.Fa dst ,
.Ar dst ,
or \-1 if an
invalid escape sequence was detected.
The size of
.Fa dst
should be
equal to the size of
.Fa src
.Ar dst
should be equal to the size of
.Ar src
(that is, no expansion takes place during decoding).
.Pp
The
.Fn strunvisx
function does the same as the
.Fn strunvis
terminates the destination string with a trailing NUL byte;
.Fn strnunvis
does so if
.Fa size
is larger than 0.
function,
but it allows you to add a flag that specifies the style the string
.Ar src
is encoded with.
Currently, the supported flags are:
.Dv VIS_HTTPSTYLE
and
.Dv VIS_MIMESTYLE .
.Pp
The
.Fn unvis
function implements a state machine that can be used to decode an arbitrary
stream of bytes.
function implements a state machine that can be used to decode an
arbitrary stream of bytes.
All state associated with the bytes being decoded is stored outside the
.Fn unvis
function (that is, a pointer to the state is passed in), so
calls decoding different streams can be freely intermixed.
To start decoding a stream of bytes, first initialize an integer
to zero.
To start decoding a stream of bytes, first initialize an integer to zero.
Call
.Fn unvis
with each successive byte, along with a pointer
to this integer, and a pointer to a destination character.
.Sh RETURN VALUES
The
.Fn unvis
function has several return codes that must be handled properly.
They are:
.Bl -tag -width UNVIS_VALIDPUSH
.It Li \&0 (zero)
.It Li \&0 No (zero)
Another character is necessary; nothing has been recognized yet.
.It Dv UNVIS_VALID
A valid character has been recognized and is available at the location
@@ -140,30 +147,41 @@ however, the character currently passed in should be passed in again.
A valid sequence was detected, but no character was produced.
This return code is necessary to indicate a logical break between characters.
.It Dv UNVIS_SYNBAD
An invalid escape sequence was detected, or the decoder is in an
unknown state.
An invalid escape sequence was detected, or the decoder is in an unknown state.
The decoder is placed into the starting state.
.El
.Pp
When all bytes in the stream have been processed, call
.Fn unvis
one more time with
.Fa flag
set to
one more time with flag set to
.Dv UNVIS_END
to extract any remaining character (the character passed in is ignored).
.Pp
The
.Fn strunvis
function returns the number of bytes written (not counting
the trailing NUL byte) or \-1 if an error occurred.
.Fa flag
argument is also used to specify the encoding style of the source.
If set to
.Dv VIS_HTTPSTYLE
or
.Dv VIS_HTTP1808 ,
.Fn unvis
will decode URI strings as specified in RFC 1808.
If set to
.Dv VIS_HTTP1866 ,
.Fn unvis
will decode entity references and numeric character references
as specified in RFC 1866.
If set to
.Dv VIS_MIMESTYLE ,
.Fn unvis
will decode MIME Quoted-Printable strings as specified in RFC 2045.
If set to
.Dv VIS_NOESCAPE ,
.Fn unvis
will not decode
.Ql \e
quoted characters.
.Pp
The
.Fn strnunvis
function returns the number of bytes (not counting the trailing NUL byte)
that would be needed to fully convert the input string, or \-1 if an
error occurred.
.Sh EXAMPLES
The following code fragment illustrates a proper use of
.Fn unvis .
.Bd -literal -offset indent
@@ -177,25 +195,72 @@ again:
case UNVIS_NOCHAR:
break;
case UNVIS_VALID:
(void) putchar(out);
(void)putchar(out);
break;
case UNVIS_VALIDPUSH:
(void) putchar(out);
(void)putchar(out);
goto again;
case UNVIS_SYNBAD:
(void)fprintf(stderr, "bad sequence!\en");
exit(1);
errx(EXIT_FAILURE, "Bad character sequence!");
}
}
if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID)
(void) putchar(out);
if (unvis(&out, '\e0', &state, UNVIS_END) == UNVIS_VALID)
(void)putchar(out);
.Ed
.Sh ERRORS
The functions
.Fn strunvis ,
.Fn strnunvis ,
.Fn strunvisx ,
and
.Fn strnunvisx
will return \-1 on error and set
.Va errno
to:
.Bl -tag -width Er
.It Bq Er EINVAL
An invalid escape sequence was detected, or the decoder is in an unknown state.
.El
.Pp
In addition the functions
.Fn strnunvis
and
.Fn strnunvisx
will can also set
.Va errno
on error to:
.Bl -tag -width Er
.It Bq Er ENOSPC
Not enough space to perform the conversion.
.El
.Sh SEE ALSO
.Xr unvis 1 ,
.Xr vis 1 ,
.Xr vis 3bsd
.Rs
.%A R. Fielding
.%T Relative Uniform Resource Locators
.%O RFC1808
.Re
.Sh HISTORY
The
.Fn unvis
function first appeared in
function
first appeared in
.Bx 4.4 .
The
.Fn strnunvis
and
.Fn strnunvisx
functions appeared in
.Nx 6.0 .
.Sh BUGS
The names
.Dv VIS_HTTP1808
and
.Dv VIS_HTTP1866
are wrong.
Percent-encoding was defined in RFC 1738, the original RFC for URL.
RFC 1866 defines HTML 2.0, an application of SGML, from which it
inherits concepts of numeric character references and entity
references.

View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: vis.3,v 1.23 2005/08/28 19:51:27 millert Exp $
.\" $NetBSD: vis.3,v 1.49 2017/08/05 20:22:29 wiz Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,53 +27,87 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd $Mdocdate: May 31 2007 $
.\" @(#)vis.3 8.1 (Berkeley) 6/9/93
.\"
.Dd April 22, 2017
.Dt VIS 3bsd
.Os
.Sh NAME
.Nm vis ,
.Nm nvis ,
.Nm strvis ,
.Nm stravis ,
.Nm strnvis ,
.Nm strvisx
.Nm strvisx ,
.Nm strnvisx ,
.Nm strenvisx ,
.Nm svis ,
.Nm snvis ,
.Nm strsvis ,
.Nm strsnvis ,
.Nm strsvisx ,
.Nm strsnvisx ,
.Nm strsenvisx
.Nd visually encode characters
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
.Lb libbsd
.Sh SYNOPSIS
.In stdlib.h
.In vis.h
(See
.Xr libbsd 7
for include usage.)
.Ft char *
.Fn vis "char *dst" "int c" "int flag" "int nextc"
.Ft char *
.Fn nvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc"
.Ft int
.Fn strvis "char *dst" "const char *src" "int flag"
.Ft int
.Fn strnvis "char *dst" "const char *src" "size_t size" "int flag"
.Fn stravis "char **dst" "const char *src" "int flag"
.Ft int
.Fn strnvis "char *dst" "size_t dlen" "const char *src" "int flag"
.Ft int
.Fn strvisx "char *dst" "const char *src" "size_t len" "int flag"
.Ft int
.Fn strnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag"
.Ft int
.Fn strenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "int *cerr_ptr"
.Ft char *
.Fn svis "char *dst" "int c" "int flag" "int nextc" "const char *extra"
.Ft char *
.Fn snvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc" "const char *extra"
.Ft int
.Fn strsvis "char *dst" "const char *src" "int flag" "const char *extra"
.Ft int
.Fn strsnvis "char *dst" "size_t dlen" "const char *src" "int flag" "const char *extra"
.Ft int
.Fn strsvisx "char *dst" "const char *src" "size_t len" "int flag" "const char *extra"
.Ft int
.Fn strsnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra"
.Ft int
.Fn strsenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra" "int *cerr_ptr"
.Sh DESCRIPTION
The
.Fn vis
function copies into
function
copies into
.Fa dst
a string which represents the character
.Fa c .
If
.Fa c
needs no encoding, it is copied in unaltered.
The string is NUL terminated and a pointer to the end of the string is
The string is null terminated, and a pointer to the end of the string is
returned.
The maximum length of any encoding is four
characters (not including the trailing NUL);
bytes (not including the trailing
.Dv NUL ) ;
thus, when
encoding a set of characters into a buffer, the size of the buffer should
be four times the number of characters encoded, plus one for the trailing
NUL.
The
.Fa flag
parameter is used for altering the default range of
be four times the number of bytes encoded, plus one for the trailing
.Dv NUL .
The flag parameter is used for altering the default range of
characters considered for encoding and for altering the visual
representation.
The additional character,
@@ -84,9 +118,11 @@ encoding format (explained below).
.Pp
The
.Fn strvis ,
.Fn strnvis
.Fn stravis ,
.Fn strnvis ,
.Fn strvisx ,
and
.Fn strvisx
.Fn strnvisx
functions copy into
.Fa dst
a visual representation of
@@ -94,89 +130,153 @@ the string
.Fa src .
The
.Fn strvis
function encodes characters from
.Fa src
up to the first NUL.
The
and
.Fn strnvis
function encodes characters from
functions encode characters from
.Fa src
up to the first NUL or the end of
.Fa dst ,
as indicated by
.Fa size .
up to the
first
.Dv NUL .
The
.Fn strvisx
function encodes exactly
and
.Fn strnvisx
functions encode exactly
.Fa len
characters from
.Fa src
(this
is useful for encoding a block of data that may contain NULs).
All three forms NUL terminate
.Fa dst ,
except for
.Fn strnvis
when
.Fa size
is zero, in which case
.Fa dst
is not touched.
For
.Fn strvis
and
.Fn strvisx ,
the size of
is useful for encoding a block of data that may contain
.Dv NUL Ns 's ) .
Both forms
.Dv NUL
terminate
.Fa dst .
The size of
.Fa dst
must be four times the number
of characters encoded from
of bytes encoded from
.Fa src
(plus one for the NUL).
.Fn strvis
(plus one for the
.Dv NUL ) .
Both
forms return the number of characters in
.Fa dst
(not including the trailing
.Dv NUL ) .
The
.Fn stravis
function allocates space dynamically to hold the string.
The
.Dq Nm n
versions of the functions also take an additional argument
.Fa dlen
that indicates the length of the
.Fa dst
buffer.
If
.Fa dlen
is not large enough to fit the converted string then the
.Fn strnvis
and
.Fn strvisx
return the number of characters in
.Fa dst
(not including the trailing NUL).
.Fn strnvis
returns the length that
.Fa dst
would become if it were of unlimited size (similar to
.Xr snprintf 3
or
.Xr strlcpy 3bsd ) .
This can be used to detect truncation but it also means that
the return value of
.Fn strnvis
must not be used without checking it against
.Fa size .
.Fn strnvisx
functions return \-1 and set
.Va errno
to
.Dv ENOSPC .
The
.Fn strenvisx
function takes an additional argument,
.Fa cerr_ptr ,
that is used to pass in and out a multibyte conversion error flag.
This is useful when processing single characters at a time when
it is possible that the locale may be set to something other
than the locale of the characters in the input data.
.Pp
The functions
.Fn svis ,
.Fn snvis ,
.Fn strsvis ,
.Fn strsnvis ,
.Fn strsvisx ,
.Fn strsnvisx ,
and
.Fn strsenvisx
correspond to
.Fn vis ,
.Fn nvis ,
.Fn strvis ,
.Fn strnvis ,
.Fn strvisx ,
.Fn strnvisx ,
and
.Fn strenvisx
but have an additional argument
.Fa extra ,
pointing to a
.Dv NUL
terminated list of characters.
These characters will be copied encoded or backslash-escaped into
.Fa dst .
These functions are useful e.g. to remove the special meaning
of certain characters to shells.
.Pp
The encoding is a unique, invertible representation composed entirely of
graphic characters; it can be decoded back into the original form using
the
.Xr unvis 3bsd
or
.Xr unvis 3bsd ,
.Xr strunvis 3bsd
or
.Xr strnunvis 3bsd
functions.
.Pp
There are two parameters that can be controlled: the range of
characters that are encoded, and the type
of representation used.
By default, all non-graphic characters
except space, tab, and newline are encoded
(see
characters that are encoded (applies only to
.Fn vis ,
.Fn nvis ,
.Fn strvis ,
.Fn strnvis ,
.Fn strvisx ,
and
.Fn strnvisx ) ,
and the type of representation used.
By default, all non-graphic characters,
except space, tab, and newline are encoded (see
.Xr isgraph 3 ) .
The following flags
alter this:
.Bl -tag -width VIS_WHITEX
.It Dv VIS_DQ
Also encode double quotes
.It Dv VIS_GLOB
Also encode magic characters recognized by
.Xr glob 3
.Pf ( Ql * ,
Also encode the magic characters
.Ql ( * ,
.Ql \&? ,
.Ql \&[ )
.Ql \&[ ,
and
.Ql # .
.Ql # )
recognized by
.Xr glob 3 .
.It Dv VIS_SHELL
Also encode the meta characters used by shells (in addition to the glob
characters):
.Ql ( ' ,
.Ql ` ,
.Ql \&" ,
.Ql \&; ,
.Ql & ,
.Ql < ,
.Ql > ,
.Ql \&( ,
.Ql \&) ,
.Ql \&| ,
.Ql \&] ,
.Ql \e ,
.Ql $ ,
.Ql \&! ,
.Ql \&^ ,
and
.Ql ~ ) .
.It Dv VIS_SP
Also encode space.
.It Dv VIS_TAB
@@ -185,34 +285,56 @@ Also encode tab.
Also encode newline.
.It Dv VIS_WHITE
Synonym for
.Dv VIS_SP
\&|
.Dv VIS_TAB
\&|
.Dv VIS_NL .
.Dv VIS_SP | VIS_TAB | VIS_NL .
.It Dv VIS_META
Synonym for
.Dv VIS_WHITE | VIS_GLOB | VIS_SHELL .
.It Dv VIS_SAFE
Only encode
.Dq unsafe
characters.
These are control characters which may cause common terminals to perform
Unsafe means control characters which may cause common terminals to perform
unexpected functions.
Currently this form allows space,
tab, newline, backspace, bell, and return -- in addition
to all graphic characters -- unencoded.
Currently this form allows space, tab, newline, backspace, bell, and
return \(em in addition to all graphic characters \(em unencoded.
.El
.Pp
There are three forms of encoding.
All forms use the backslash
(The above flags have no effect for
.Fn svis ,
.Fn snvis ,
.Fn strsvis ,
.Fn strsnvis ,
.Fn strsvisx ,
and
.Fn strsnvisx .
When using these functions, place all graphic characters to be
encoded in an array pointed to by
.Fa extra .
In general, the backslash character should be included in this array, see the
warning on the use of the
.Dv VIS_NOSLASH
flag below).
.Pp
There are six forms of encoding.
All forms use the backslash character
.Ql \e
character to introduce a special
sequence; two backslashes are used to represent a real backslash.
to introduce a special
sequence; two backslashes are used to represent a real backslash,
except
.Dv VIS_HTTPSTYLE
that uses
.Ql % ,
or
.Dv VIS_MIMESTYLE
that uses
.Ql = .
These are the visual formats:
.Bl -tag -width VIS_CSTYLE
.It (default)
Use an
.Ql M
to represent meta characters (characters with the 8th
bit set), and use a caret
bit set), and use caret
.Ql ^
to represent control characters (see
.Xr iscntrl 3 ) .
@@ -256,27 +378,27 @@ space.
.It Dv \e240
Represents Meta-space.
.El
.Pp
.It Dv VIS_CSTYLE
Use C-style backslash sequences to represent standard non-printable
characters.
The following sequences are used to represent the indicated characters:
.Bd -unfilled -offset indent
.Li \ea Tn - BEL No (007)
.Li \eb Tn - BS No (010)
.Li \ef Tn - NP No (014)
.Li \en Tn - NL No (012)
.Li \er Tn - CR No (015)
.Li \es Tn - SP No (040)
.Li \et Tn - HT No (011)
.Li \ev Tn - VT No (013)
.Li \e0 Tn - NUL No (000)
.Li \ea Tn \(em BEL No (007)
.Li \eb Tn \(em BS No (010)
.Li \ef Tn \(em NP No (014)
.Li \en Tn \(em NL No (012)
.Li \er Tn \(em CR No (015)
.Li \es Tn \(em SP No (040)
.Li \et Tn \(em HT No (011)
.Li \ev Tn \(em VT No (013)
.Li \e0 Tn \(em NUL No (000)
.Ed
.Pp
When using this format, the
.Fa nextc
parameter is looked at to determine
if a NUL character can be encoded as
parameter is looked at to determine if a
.Dv NUL
character can be encoded as
.Ql \e0
instead of
.Ql \e000 .
@@ -284,13 +406,36 @@ If
.Fa nextc
is an octal digit, the latter representation is used to
avoid ambiguity.
.Pp
Non-printable characters without C-style
backslash sequences use the default representation.
.It Dv VIS_OCTAL
Use a three digit octal sequence.
The form is
.Ql \eddd
where
.Ar d
.Em d
represents an octal digit.
.It Dv VIS_CSTYLE \&| Dv VIS_OCTAL
Same as
.Dv VIS_CSTYLE
except that non-printable characters without C-style
backslash sequences use a three digit octal sequence.
.It Dv VIS_HTTPSTYLE
Use URI encoding as described in RFC 1738.
The form is
.Ql %xx
where
.Em x
represents a lower case hexadecimal digit.
.It Dv VIS_MIMESTYLE
Use MIME Quoted-Printable encoding as described in RFC 2045, only don't
break lines and don't handle CRLF.
The form is
.Ql =XX
where
.Em X
represents an upper case hexadecimal digit.
.El
.Pp
There is one additional flag,
@@ -304,21 +449,112 @@ meta characters as
.Ql M-C ) .
With this flag set, the encoding is
ambiguous and non-invertible.
.Sh MULTIBYTE CHARACTER SUPPORT
These functions support multibyte character input.
The encoding conversion is influenced by the setting of the
.Ev LC_CTYPE
environment variable which defines the set of characters
that can be copied without encoding.
.Pp
If
.Dv VIS_NOLOCALE
is set, processing is done assuming the C locale and overriding
any other environment settings.
.Pp
When 8-bit data is present in the input,
.Ev LC_CTYPE
must be set to the correct locale or to the C locale.
If the locales of the data and the conversion are mismatched,
multibyte character recognition may fail and encoding will be performed
byte-by-byte instead.
.Pp
As noted above,
.Fa dst
must be four times the number of bytes processed from
.Fa src .
But note that each multibyte character can be up to
.Dv MB_LEN_MAX
bytes
.\" (see
.\" .Xr multibyte 3 )
so in terms of multibyte characters,
.Fa dst
must be four times
.Dv MB_LEN_MAX
times the number of characters processed from
.Fa src .
.Sh ENVIRONMENT
.Bl -tag -width ".Ev LC_CTYPE"
.It Ev LC_CTYPE
Specify the locale of the input data.
Set to C if the input data locale is unknown.
.El
.Sh ERRORS
The functions
.Fn nvis
and
.Fn snvis
will return
.Dv NULL
and the functions
.Fn strnvis ,
.Fn strnvisx ,
.Fn strsnvis ,
and
.Fn strsnvisx ,
will return \-1 when the
.Fa dlen
destination buffer size is not enough to perform the conversion while
setting
.Va errno
to:
.Bl -tag -width ".Bq Er ENOSPC"
.It Bq Er ENOSPC
The destination buffer size is not large enough to perform the conversion.
.El
.Sh SEE ALSO
.Xr unvis 1 ,
.Xr vis 1 ,
.Xr snprintf 3 ,
.Xr strlcpy 3bsd ,
.Xr glob 3 ,
.\" .Xr multibyte 3 ,
.Xr unvis 3bsd
.Rs
.%A T. Berners-Lee
.%T Uniform Resource Locators (URL)
.%O "RFC 1738"
.Re
.Rs
.%T "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies"
.%O "RFC 2045"
.Re
.Sh HISTORY
The
.Fn vis ,
.Fn strvis
.Fn strvis ,
and
.Fn strvisx
functions first appeared in
.Bx 4.4 .
The
.Fn strnvis
function first appeared in
.Ox 2.9 .
.Fn svis ,
.Fn strsvis ,
and
.Fn strsvisx
functions appeared in
.Nx 1.5 .
The buffer size limited versions of the functions
.Po Fn nvis ,
.Fn strnvis ,
.Fn strnvisx ,
.Fn snvis ,
.Fn strsnvis ,
and
.Fn strsnvisx Pc
appeared in
.Nx 6.0
and
.Fx 9.2 .
Multibyte character support was added in
.Nx 7.0
and
.Fx 9.2 .

View File

@@ -16,6 +16,7 @@ libbsd_la_included_sources = \
getentropy_linux.c \
getentropy_osx.c \
getentropy_solaris.c \
getentropy_win.c \
$(nil)
EXTRA_DIST = \
@@ -60,9 +61,11 @@ libbsd_la_LDFLAGS = \
libbsd_la_SOURCES = \
arc4random.c \
arc4random.h \
arc4random_unix.h \
arc4random_linux.h \
arc4random_openbsd.h \
arc4random_uniform.c \
arc4random_unix.h \
arc4random_win.h \
bsd_getopt.c \
chacha_private.h \
closefrom.c \
@@ -103,7 +106,9 @@ libbsd_la_SOURCES = \
stringlist.c \
strmode.c \
strnstr.c \
strtoi.c \
strtonum.c \
strtou.c \
timeconv.c \
unvis.c \
vis.c \

View File

@@ -34,6 +34,10 @@ getentropy(void *buf, size_t len);
#if defined(__OpenBSD__)
#include "arc4random_openbsd.h"
#elif defined(__linux__)
#include "arc4random_linux.h"
#elif defined(_WIN32)
#include "arc4random_win.h"
#else
#include "arc4random_unix.h"
#endif

88
src/arc4random_linux.h Normal file
View File

@@ -0,0 +1,88 @@
/* $OpenBSD: arc4random_linux.h,v 1.11 2016/06/30 12:19:51 bcook Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Stub functions for portability.
*/
#include <sys/mman.h>
#include <pthread.h>
#include <signal.h>
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx)
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
#ifdef __GLIBC__
extern void *__dso_handle;
extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
#else
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
#endif
static inline void
_getentropy_fail(void)
{
raise(SIGKILL);
}
static volatile sig_atomic_t _rs_forked;
static inline void
_rs_forkhandler(void)
{
_rs_forked = 1;
}
static inline void
_rs_forkdetect(void)
{
static pid_t _rs_pid = 0;
pid_t pid = getpid();
/* XXX unusual calls to clone() can bypass checks */
if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
_rs_pid = pid;
_rs_forked = 0;
if (rs)
memset(rs, 0, sizeof(*rs));
}
}
static inline int
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
return (-1);
if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
munmap(*rsp, sizeof(**rsp));
*rsp = NULL;
return (-1);
}
_ARC4_ATFORK(_rs_forkhandler);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: arc4random_linux.h,v 1.8 2014/08/13 06:04:10 deraadt Exp $ */
/* $OpenBSD: arc4random_freebsd.h,v 1.4 2016/06/30 12:19:51 bcook Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -84,6 +84,7 @@ _rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
munmap(*rsp, sizeof(**rsp));
*rsp = NULL;
return (-1);
}

78
src/arc4random_win.h Normal file
View File

@@ -0,0 +1,78 @@
/* $OpenBSD: arc4random_win.h,v 1.6 2016/06/30 12:17:29 bcook Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Stub functions for portability.
*/
#include <windows.h>
static volatile HANDLE arc4random_mtx = NULL;
/*
* Initialize the mutex on the first lock attempt. On collision, each thread
* will attempt to allocate a mutex and compare-and-swap it into place as the
* global mutex. On failure to swap in the global mutex, the mutex is closed.
*/
#define _ARC4_LOCK() { \
if (!arc4random_mtx) { \
HANDLE p = CreateMutex(NULL, FALSE, NULL); \
if (InterlockedCompareExchangePointer((void **)&arc4random_mtx, (void *)p, NULL)) \
CloseHandle(p); \
} \
WaitForSingleObject(arc4random_mtx, INFINITE); \
} \
#define _ARC4_UNLOCK() ReleaseMutex(arc4random_mtx)
static inline void
_getentropy_fail(void)
{
TerminateProcess(GetCurrentProcess(), 0);
}
static inline int
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
*rsp = VirtualAlloc(NULL, sizeof(**rsp),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (*rsp == NULL)
return (-1);
*rsxp = VirtualAlloc(NULL, sizeof(**rsxp),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (*rsxp == NULL) {
VirtualFree(*rsp, 0, MEM_RELEASE);
*rsp = NULL;
return (-1);
}
return (0);
}
static inline void
_rs_forkhandler(void)
{
}
static inline void
_rs_forkdetect(void)
{
}

View File

@@ -4,7 +4,7 @@ D. J. Bernstein
Public domain.
*/
/* $OpenBSD$ */
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
typedef unsigned char u8;
typedef unsigned int u32;

View File

@@ -76,7 +76,7 @@ fgetln(FILE *stream, size_t *len)
}
}
libbsd_link_warning(fgetln,
"This functions cannot be safely ported, use getline(3) "
"This function cannot be safely ported, use getline(3) "
"instead, as it is supported by GNU and POSIX.1-2008.")
#else
#error "Function fgetln() needs to be ported."

View File

@@ -30,6 +30,8 @@
#include <stdio.h>
#include <wchar.h>
#include "local-link.h"
struct filewbuf {
FILE *fp;
wchar_t *wbuf;
@@ -85,3 +87,6 @@ fgetwln(FILE *stream, size_t *lenp)
*lenp = wused;
return wused ? fb->wbuf : NULL;
}
libbsd_link_warning(fgetwln,
"This function cannot be safely ported, use fgetwc(3) "
"instead, as it is supported by C99 and POSIX.1-2001.")

View File

@@ -1,5 +1,7 @@
/*-
* Copyright (c) 2007 Dag-Erling Coïdan Smørgrav
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2007-2009 Dag-Erling Coïdan Smørgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,13 +32,21 @@
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <unistd.h>
#include <libutil.h>
int
flopen(const char *path, int flags, ...)
/*
* Reliably open and lock a file.
*
* Please do not modify this code without first reading the revision history
* and discussing your changes with <des@freebsd.org>. Don't be fooled by the
* code's apparent simplicity; there would be no need for this function if it
* was easy to get right.
*/
static int
vflopenat(int dirfd, const char *path, int flags, va_list ap)
{
int fd, operation, serrno, trunc;
struct stat sb, fsb;
@@ -48,11 +58,7 @@ flopen(const char *path, int flags, ...)
mode = 0;
if (flags & O_CREAT) {
va_list ap;
va_start(ap, flags);
mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
va_end(ap);
}
operation = LOCK_EX;
@@ -63,7 +69,7 @@ flopen(const char *path, int flags, ...)
flags &= ~O_TRUNC;
for (;;) {
if ((fd = open(path, flags, mode)) == -1)
if ((fd = openat(dirfd, path, flags, mode)) == -1)
/* non-existent or no access */
return (-1);
if (flock(fd, operation) == -1) {
@@ -73,7 +79,7 @@ flopen(const char *path, int flags, ...)
errno = serrno;
return (-1);
}
if (stat(path, &sb) == -1) {
if (fstatat(dirfd, path, &sb, 0) == -1) {
/* disappeared from under our feet */
(void)close(fd);
continue;
@@ -98,6 +104,42 @@ flopen(const char *path, int flags, ...)
errno = serrno;
return (-1);
}
/*
* The following change is provided as a specific example to
* avoid.
*/
#if 0
if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
serrno = errno;
(void)close(fd);
errno = serrno;
return (-1);
}
#endif
return (fd);
}
}
int
flopen(const char *path, int flags, ...)
{
va_list ap;
int ret;
va_start(ap, flags);
ret = vflopenat(AT_FDCWD, path, flags, ap);
va_end(ap);
return (ret);
}
int
flopenat(int dirfd, const char *path, int flags, ...)
{
va_list ap;
int ret;
va_start(ap, flags);
ret = vflopenat(dirfd, path, flags, ap);
va_end(ap);
return (ret);
}

View File

@@ -1,3 +1,5 @@
/* $NetBSD: fmtcheck.c,v 1.16 2017/12/13 06:43:45 rin Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -24,9 +26,6 @@
* 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.
*
* from NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp
* from FreeBSD: fmtcheck.c,v 1.8 2005/03/21 08:00:55 das Exp
*/
#include <sys/cdefs.h>
@@ -35,27 +34,33 @@
#include <string.h>
#include <ctype.h>
/* __weak_reference(__fmtcheck, fmtcheck); */
#ifdef __weak_alias
__weak_alias(fmtcheck,__fmtcheck)
#endif
enum __e_fmtcheck_types {
FMTCHECK_START,
FMTCHECK_SHORT,
FMTCHECK_INT,
FMTCHECK_WINTT,
FMTCHECK_LONG,
FMTCHECK_QUAD,
FMTCHECK_INTMAXT,
FMTCHECK_PTRDIFFT,
FMTCHECK_SIZET,
FMTCHECK_POINTER,
FMTCHECK_CHARPOINTER,
FMTCHECK_SHORTPOINTER,
FMTCHECK_INTPOINTER,
FMTCHECK_LONGPOINTER,
FMTCHECK_QUADPOINTER,
FMTCHECK_INTMAXTPOINTER,
FMTCHECK_PTRDIFFTPOINTER,
FMTCHECK_SIZETPOINTER,
#ifndef NO_FLOATING_POINT
FMTCHECK_DOUBLE,
FMTCHECK_LONGDOUBLE,
#endif
FMTCHECK_STRING,
FMTCHECK_WSTRING,
FMTCHECK_WIDTH,
FMTCHECK_PRECISION,
FMTCHECK_DONE,
@@ -63,6 +68,18 @@ enum __e_fmtcheck_types {
};
typedef enum __e_fmtcheck_types EFT;
enum e_modifier {
MOD_NONE,
MOD_CHAR,
MOD_SHORT,
MOD_LONG,
MOD_QUAD,
MOD_INTMAXT,
MOD_LONGDOUBLE,
MOD_PTRDIFFT,
MOD_SIZET,
};
#define RETURN(pf,f,r) do { \
*(pf) = (f); \
return r; \
@@ -71,103 +88,168 @@ typedef enum __e_fmtcheck_types EFT;
static EFT
get_next_format_from_precision(const char **pf)
{
int sh, lg, quad, longdouble, ptrdifft, sizet;
enum e_modifier modifier;
const char *f;
sh = lg = quad = longdouble = ptrdifft = sizet = 0;
f = *pf;
switch (*f) {
case 'h':
f++;
sh = 1;
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
if (*f == 'h') {
f++;
modifier = MOD_CHAR;
} else {
modifier = MOD_SHORT;
}
break;
case 'j':
f++;
modifier = MOD_INTMAXT;
break;
case 'l':
f++;
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
if (*f == 'l') {
f++;
quad = 1;
modifier = MOD_QUAD;
} else {
lg = 1;
modifier = MOD_LONG;
}
break;
case 'q':
f++;
quad = 1;
modifier = MOD_QUAD;
break;
case 't':
f++;
ptrdifft = 1;
modifier = MOD_PTRDIFFT;
break;
case 'z':
f++;
sizet = 1;
modifier = MOD_SIZET;
break;
case 'L':
f++;
longdouble = 1;
modifier = MOD_LONGDOUBLE;
break;
#ifdef WIN32
case 'I':
f++;
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
if (*f == '3' && f[1] == '2') {
f += 2;
modifier = MOD_NONE;
} else if (*f == '6' && f[1] == '4') {
f += 2;
modifier = MOD_QUAD;
}
else {
#ifdef _WIN64
modifier = MOD_QUAD;
#else
modifier = MOD_NONE;
#endif
}
break;
#endif
default:
modifier = MOD_NONE;
break;
}
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
if (strchr("diouxX", *f)) {
if (longdouble)
RETURN(pf,f,FMTCHECK_UNKNOWN);
if (lg)
switch (modifier) {
case MOD_LONG:
RETURN(pf,f,FMTCHECK_LONG);
if (quad)
case MOD_QUAD:
RETURN(pf,f,FMTCHECK_QUAD);
if (ptrdifft)
case MOD_INTMAXT:
RETURN(pf,f,FMTCHECK_INTMAXT);
case MOD_PTRDIFFT:
RETURN(pf,f,FMTCHECK_PTRDIFFT);
if (sizet)
case MOD_SIZET:
RETURN(pf,f,FMTCHECK_SIZET);
case MOD_CHAR:
case MOD_SHORT:
case MOD_NONE:
RETURN(pf,f,FMTCHECK_INT);
default:
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
}
if (*f == 'n') {
if (longdouble)
RETURN(pf,f,FMTCHECK_UNKNOWN);
if (sh)
switch (modifier) {
case MOD_CHAR:
RETURN(pf,f,FMTCHECK_CHARPOINTER);
case MOD_SHORT:
RETURN(pf,f,FMTCHECK_SHORTPOINTER);
if (lg)
case MOD_LONG:
RETURN(pf,f,FMTCHECK_LONGPOINTER);
if (quad)
case MOD_QUAD:
RETURN(pf,f,FMTCHECK_QUADPOINTER);
if (ptrdifft)
case MOD_INTMAXT:
RETURN(pf,f,FMTCHECK_INTMAXTPOINTER);
case MOD_PTRDIFFT:
RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
if (sizet)
case MOD_SIZET:
RETURN(pf,f,FMTCHECK_SIZETPOINTER);
case MOD_NONE:
RETURN(pf,f,FMTCHECK_INTPOINTER);
default:
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
}
if (strchr("DOU", *f)) {
if (sh + lg + quad + longdouble + ptrdifft + sizet)
if (modifier != MOD_NONE)
RETURN(pf,f,FMTCHECK_UNKNOWN);
RETURN(pf,f,FMTCHECK_LONG);
}
#ifndef NO_FLOATING_POINT
if (strchr("aAeEfFgG", *f)) {
if (longdouble)
switch (modifier) {
case MOD_LONGDOUBLE:
RETURN(pf,f,FMTCHECK_LONGDOUBLE);
if (sh + lg + quad + ptrdifft + sizet)
RETURN(pf,f,FMTCHECK_UNKNOWN);
case MOD_LONG:
case MOD_NONE:
RETURN(pf,f,FMTCHECK_DOUBLE);
}
#endif
if (*f == 'c') {
if (sh + lg + quad + longdouble + ptrdifft + sizet)
default:
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
}
if (*f == 'c') {
switch (modifier) {
case MOD_LONG:
RETURN(pf,f,FMTCHECK_WINTT);
case MOD_NONE:
RETURN(pf,f,FMTCHECK_INT);
default:
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
}
if (*f == 'C') {
if (modifier != MOD_NONE)
RETURN(pf,f,FMTCHECK_UNKNOWN);
RETURN(pf,f,FMTCHECK_WINTT);
}
if (*f == 's') {
if (sh + lg + quad + longdouble + ptrdifft + sizet)
RETURN(pf,f,FMTCHECK_UNKNOWN);
switch (modifier) {
case MOD_LONG:
RETURN(pf,f,FMTCHECK_WSTRING);
case MOD_NONE:
RETURN(pf,f,FMTCHECK_STRING);
default:
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
}
if (*f == 'S') {
if (modifier != MOD_NONE)
RETURN(pf,f,FMTCHECK_UNKNOWN);
RETURN(pf,f,FMTCHECK_WSTRING);
}
if (*f == 'p') {
if (sh + lg + quad + longdouble + ptrdifft + sizet)
if (modifier != MOD_NONE)
RETURN(pf,f,FMTCHECK_UNKNOWN);
RETURN(pf,f,FMTCHECK_LONG);
RETURN(pf,f,FMTCHECK_POINTER);
}
RETURN(pf,f,FMTCHECK_UNKNOWN);
/*NOTREACHED*/
@@ -185,7 +267,7 @@ get_next_format_from_width(const char **pf)
RETURN(pf,f,FMTCHECK_PRECISION);
}
/* eat any precision (empty is allowed) */
while (isdigit(*f)) f++;
while (isdigit((unsigned char)*f)) f++;
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
}
RETURN(pf,f,get_next_format_from_precision(pf));
@@ -229,7 +311,7 @@ get_next_format(const char **pf, EFT eft)
RETURN(pf,f,FMTCHECK_WIDTH);
}
/* eat any width */
while (isdigit(*f)) f++;
while (isdigit((unsigned char)*f)) f++;
if (!*f) {
RETURN(pf,f,FMTCHECK_UNKNOWN);
}
@@ -238,7 +320,7 @@ get_next_format(const char **pf, EFT eft)
/*NOTREACHED*/
}
__const char *
const char *
fmtcheck(const char *f1, const char *f2)
{
const char *f1p, *f2p;

View File

@@ -40,6 +40,8 @@
#include "getentropy_aix.c"
#elif defined(__hpux)
#include "getentropy_hpux.c"
#elif defined(_WIN32)
#include "getentropy_win.c"
#else
#error "No getentropy hooks defined for this platform."
#endif

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_aix.c,v 1.3 2015/08/25 17:26:43 deraadt Exp $ */
/* $OpenBSD: getentropy_aix.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2015 Michael Felt <aixtools@gmail.com>
@@ -18,7 +18,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
/*
* -lperfstat is needed for the psuedo entropy data

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_freebsd.c,v 1.1 2014/11/03 06:23:30 bcook Exp $ */
/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
@@ -17,7 +17,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#include <sys/types.h>

View File

@@ -17,7 +17,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#include <sys/types.h>

View File

@@ -17,7 +17,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#define _POSIX_C_SOURCE 199309L
@@ -110,7 +110,7 @@ getentropy(void *buf, size_t len)
* - Do the best under the circumstances....
*
* This code path exists to bring light to the issue that Hurd
* does not provide a failsafe API for entropy collection.
* still does not provide a failsafe API for entropy collection.
*
* We hope this demonstrates that Hurd should either get a
* sysctl ABI, or consider providing a new failsafe API which

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_linux.c,v 1.40 2015/08/25 17:26:43 deraadt Exp $ */
/* $OpenBSD: getentropy_linux.c,v 1.45 2018/03/13 22:53:28 bcook Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -17,7 +17,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#define _POSIX_C_SOURCE 199309L
@@ -75,7 +75,7 @@
int getentropy(void *buf, size_t len);
static int gotdata(char *buf, size_t len);
#ifdef SYS_getrandom
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
static int getentropy_getrandom(void *buf, size_t len);
#endif
static int getentropy_urandom(void *buf, size_t len);
@@ -95,15 +95,18 @@ getentropy(void *buf, size_t len)
return (-1);
}
#ifdef SYS_getrandom
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
/*
* Try descriptor-less getrandom()
* Try descriptor-less getrandom(), in non-blocking mode.
*
* The design of Linux getrandom is broken. It has an
* uninitialized phase coupled with blocking behaviour, which
* is unacceptable from within a library at boot time without
* possible recovery. See http://bugs.python.org/issue26839#msg267745
*/
ret = getentropy_getrandom(buf, len);
if (ret != -1)
return (ret);
if (errno != ENOSYS)
return (-1);
#endif
/*
@@ -121,7 +124,7 @@ getentropy(void *buf, size_t len)
* Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
* sysctl is a failsafe API, so it guarantees a result. This
* should work inside a chroot, or when file descriptors are
* exhuasted.
* exhausted.
*
* However this can fail if the Linux kernel removes support
* for sysctl. Starting in 2007, there have been efforts to
@@ -157,7 +160,7 @@ getentropy(void *buf, size_t len)
* - Do the best under the circumstances....
*
* This code path exists to bring light to the issue that Linux
* does not provide a failsafe API for entropy collection.
* still does not provide a failsafe API for entropy collection.
*
* We hope this demonstrates that Linux should either retain their
* sysctl ABI, or consider providing a new failsafe API which
@@ -191,7 +194,7 @@ gotdata(char *buf, size_t len)
return (0);
}
#ifdef SYS_getrandom
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
static int
getentropy_getrandom(void *buf, size_t len)
{
@@ -200,7 +203,7 @@ getentropy_getrandom(void *buf, size_t len)
if (len > 256)
return (-1);
do {
ret = syscall(SYS_getrandom, buf, len, 0);
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
} while (ret == -1 && errno == EINTR);
if (ret != (int)len)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_osx.c,v 1.8 2014/07/21 20:19:47 guenther Exp $ */
/* $OpenBSD: getentropy_osx.c,v 1.11 2016/09/03 15:24:09 bcook Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -17,9 +17,10 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#include <TargetConditionals.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -45,14 +46,18 @@
#include <mach/mach_time.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#if TARGET_OS_OSX
#include <sys/socketvar.h>
#include <sys/vmmeter.h>
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#if TARGET_OS_OSX
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_var.h>
#include <netinet/udp_var.h>
#endif
#include <CommonCrypto/CommonDigest.h>
#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
@@ -207,9 +212,11 @@ nodevrandom:
return (-1);
}
#if TARGET_OS_OSX
static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
#endif
static int kmib[] = { CTL_KERN, KERN_USRSTACK };
static int hwmib[] = { CTL_HW, HW_USERMEM };
@@ -229,9 +236,11 @@ getentropy_fallback(void *buf, size_t len)
pid_t pid;
size_t i, ii, m;
char *p;
#if TARGET_OS_OSX
struct tcpstat tcpstat;
struct udpstat udpstat;
struct ipstat ipstat;
#endif
uint64_t mach_time;
unsigned int idata;
void *addr;
@@ -266,6 +275,7 @@ getentropy_fallback(void *buf, size_t len)
HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
&idata, &ii, NULL, 0) == -1, idata);
#if TARGET_OS_OSX
ii = sizeof(tcpstat);
HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
&tcpstat, &ii, NULL, 0) == -1, tcpstat);
@@ -277,6 +287,7 @@ getentropy_fallback(void *buf, size_t len)
ii = sizeof(ipstat);
HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
&ipstat, &ii, NULL, 0) == -1, ipstat);
#endif
HX((pid = getpid()) == -1, pid);
HX((pid = getsid(pid)) == -1, pid);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_solaris.c,v 1.10 2015/08/25 17:26:43 deraadt Exp $ */
/* $OpenBSD: getentropy_solaris.c,v 1.12 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -17,7 +17,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
* http://man.openbsd.org/getentropy.2
*/
#include <sys/types.h>

59
src/getentropy_win.c Normal file
View File

@@ -0,0 +1,59 @@
/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
* Copyright (c) 2014, Bob Beck <beck@obtuse.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include <windows.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <wincrypt.h>
#include <process.h>
int getentropy(void *buf, size_t len);
/*
* On Windows, CryptGenRandom is supposed to be a well-seeded
* cryptographically strong random number generator.
*/
int
getentropy(void *buf, size_t len)
{
HCRYPTPROV provider;
if (len > 256) {
errno = EIO;
return (-1);
}
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT) == 0)
goto fail;
if (CryptGenRandom(provider, len, buf) == 0) {
CryptReleaseContext(provider, 0);
goto fail;
}
CryptReleaseContext(provider, 0);
return (0);
fail:
errno = EIO;
return (-1);
}

View File

@@ -1,3 +1,4 @@
/* $OpenBSD: heapsort.c,v 1.11 2017/05/20 12:48:56 millert Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -64,7 +65,7 @@
* Build the list into a heap, where a heap is defined such that for
* the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
*
* There two cases. If j == nmemb, select largest of Ki and Kj. If
* There are two cases. If j == nmemb, select largest of Ki and Kj. If
* j < nmemb, select largest of Ki, Kj and Kj+1.
*/
#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
@@ -86,12 +87,12 @@
* Select the top of the heap and 'heapify'. Since by far the most expensive
* action is the call to the compar function, a considerable optimization
* in the average case can be achieved due to the fact that k, the displaced
* elememt, is usually quite small, so it would be preferable to first
* element, is usually quite small, so it would be preferable to first
* heapify, always maintaining the invariant that the larger child is copied
* over its parent's record.
*
* Then, starting from the *bottom* of the heap, finding k's correct place,
* again maintianing the invariant. As a result of the invariant no element
* again maintaining the invariant. As a result of the invariant no element
* is 'lost' when k is assigned its correct place in the heap.
*
* The time savings from this optimization are on the order of 15-20% for the

View File

@@ -1,7 +1,10 @@
/* $NetBSD: humanize_number.c,v 1.14 2008/04/28 20:22:59 martin Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
* Copyright 2013 John-Mark Gurney <jmg@FreeBSD.org>
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -31,6 +34,7 @@
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
@@ -39,58 +43,81 @@
#include <locale.h>
#include <libutil.h>
static const int maxscale = 6;
int
humanize_number(char *buf, size_t len, int64_t bytes,
humanize_number(char *buf, size_t len, int64_t quotient,
const char *suffix, int scale, int flags)
{
const char *prefixes, *sep;
int b, i, r, maxscale, s1, s2, sign;
int i, r, remainder, s1, s2, sign;
int divisordeccut;
int64_t divisor, max;
size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
assert(scale >= 0);
if (flags & HN_DIVISOR_1000) {
/* SI for decimal multiplies */
divisor = 1000;
if (flags & HN_B)
prefixes = "B\0k\0M\0G\0T\0P\0E";
else
prefixes = "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
* binary multiplies
* XXX IEC 60027-2 recommends Ki, Mi, Gi...
*/
divisor = 1024;
if (flags & HN_B)
prefixes = "B\0K\0M\0G\0T\0P\0E";
else
prefixes = "\0\0K\0M\0G\0T\0P\0E";
}
#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
maxscale = 7;
if (scale >= maxscale &&
(scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
return (-1);
if (buf == NULL || suffix == NULL)
return (-1);
/* Since so many callers don't check -1, NUL terminate the buffer */
if (len > 0)
buf[0] = '\0';
if (bytes < 0) {
/* validate args */
if (buf == NULL || suffix == NULL)
return (-1);
if (scale < 0)
return (-1);
else if (scale > maxscale &&
((scale & ~(HN_AUTOSCALE|HN_GETSCALE)) != 0))
return (-1);
if ((flags & HN_DIVISOR_1000) && (flags & HN_IEC_PREFIXES))
return (-1);
/* setup parameters */
remainder = 0;
if (flags & HN_IEC_PREFIXES) {
baselen = 2;
/*
* Use the prefixes for power of two recommended by
* the International Electrotechnical Commission
* (IEC) in IEC 80000-3 (i.e. Ki, Mi, Gi...).
*
* HN_IEC_PREFIXES implies a divisor of 1024 here
* (use of HN_DIVISOR_1000 would have triggered
* an assertion earlier).
*/
divisor = 1024;
divisordeccut = 973; /* ceil(.95 * 1024) */
if (flags & HN_B)
prefixes = "B\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
else
prefixes = "\0\0\0Ki\0Mi\0Gi\0Ti\0Pi\0Ei";
} else {
baselen = 1;
if (flags & HN_DIVISOR_1000) {
divisor = 1000;
divisordeccut = 950;
if (flags & HN_B)
prefixes = "B\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
else
prefixes = "\0\0\0k\0\0M\0\0G\0\0T\0\0P\0\0E";
} else {
divisor = 1024;
divisordeccut = 973; /* ceil(.95 * 1024) */
if (flags & HN_B)
prefixes = "B\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E";
else
prefixes = "\0\0\0K\0\0M\0\0G\0\0T\0\0P\0\0E";
}
}
#define SCALE2PREFIX(scale) (&prefixes[(scale) * 3])
if (quotient < 0) {
sign = -1;
bytes *= -100;
baselen = 3; /* sign, digit, prefix */
quotient = -quotient;
baselen += 2; /* sign, digit */
} else {
sign = 1;
bytes *= 100;
baselen = 2; /* digit, prefix */
baselen += 1; /* digit */
}
if (flags & HN_NOSPACE)
sep = "";
@@ -106,7 +133,7 @@ humanize_number(char *buf, size_t len, int64_t bytes,
if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
/* See if there is additional columns can be used. */
for (max = 100, i = len - baselen; i-- > 0;)
for (max = 1, i = len - baselen; i-- > 0;)
max *= 10;
/*
@@ -114,29 +141,39 @@ humanize_number(char *buf, size_t len, int64_t bytes,
* If there will be an overflow by the rounding below,
* divide once more.
*/
for (i = 0; bytes >= max - 50 && i < maxscale; i++)
bytes /= divisor;
for (i = 0;
(quotient >= max || (quotient == max - 1 &&
(remainder >= divisordeccut || remainder >=
divisor / 2))) && i < maxscale; i++) {
remainder = quotient % divisor;
quotient /= divisor;
}
if (scale & HN_GETSCALE)
return (i);
} else
for (i = 0; i < scale && i < maxscale; i++)
bytes /= divisor;
} else {
for (i = 0; i < scale && i < maxscale; i++) {
remainder = quotient % divisor;
quotient /= divisor;
}
}
/* If a value <= 9.9 after rounding and ... */
if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
/* baselen + \0 + .N */
if (len < baselen + 1 + 2)
return (-1);
b = ((int)bytes + 5) / 10;
s1 = b / 10;
s2 = b % 10;
/*
* XXX - should we make sure there is enough space for the decimal
* place and if not, don't do HN_DECIMAL?
*/
if (((quotient == 9 && remainder < divisordeccut) || quotient < 9) &&
i > 0 && flags & HN_DECIMAL) {
s1 = (int)quotient + ((remainder * 10 + divisor / 2) /
divisor / 10);
s2 = ((remainder * 10 + divisor / 2) / divisor) % 10;
r = snprintf(buf, len, "%d%s%d%s%s%s",
sign * s1, localeconv()->decimal_point, s2,
sep, SCALE2PREFIX(i), suffix);
} else
r = snprintf(buf, len, "%" PRId64 "%s%s%s",
sign * ((bytes + 50) / 100),
sign * (quotient + (remainder + divisor / 2) / divisor),
sep, SCALE2PREFIX(i), suffix);
return (r);

View File

@@ -139,3 +139,32 @@ LIBBSD_0.7 {
LIBBSD_0.8 {
explicit_bzero;
} LIBBSD_0.7;
LIBBSD_0.9 {
flopenat;
pidfile_fileno;
strtoi;
strtou;
nvis;
snvis;
stravis;
strenvisx;
strnunvisx;
strsenvisx;
strsnvis;
strsnvisx;
strsvis;
strsvisx;
svis;
} LIBBSD_0.8;
LIBBSD_0.9.1 {
/* The strnvis() and strnunvis() symbols changed prototype to match
* the NetBSD implementation. Provided as versioned nodes in 0.9.1, and
* exposed here explicitly so that we can redirect at compile-time. */
strnvis_netbsd;
strnunvis_netbsd;
} LIBBSD_0.9;

View File

@@ -186,7 +186,11 @@
#define ELF_TARG_MACH EM_SPARCV9
#define ELF_TARG_CLASS ELFCLASS64
#else
#if defined(__sparc_v9__) || defined(__sparcv9)
#define ELF_TARG_MACH EM_SPARC32PLUS
#else
#define ELF_TARG_MACH EM_SPARC
#endif
#define ELF_TARG_CLASS ELFCLASS32
#endif
#define ELF_TARG_DATA ELFDATA2MSB
@@ -221,7 +225,11 @@
#elif defined(__or1k__)
#if defined(EM_OPENRISC)
#define ELF_TARG_MACH EM_OPENRISC
#else
#define ELF_TARG_MACH EM_OR1K
#endif
#define ELF_TARG_CLASS ELFCLASS32
#define ELF_TARG_DATA ELFDATA2MSB

View File

@@ -29,20 +29,27 @@
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
struct pidfh {
int pf_fd;
char *pf_path;
dev_t pf_dev;
ino_t pf_ino;
};
static int _pidfile_remove(struct pidfh *pfh, int freeit);
static int
pidfile_verify(struct pidfh *pfh)
pidfile_verify(const struct pidfh *pfh)
{
struct stat sb;
@@ -114,25 +121,33 @@ pidfile_open(const char *path, mode_t mode, pid_t *pidptr)
fd = flopen(pfh->pf_path,
O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode);
if (fd == -1) {
count = 0;
if (errno == EWOULDBLOCK) {
if (pidptr == NULL) {
errno = EEXIST;
} else {
count = 20;
rqtp.tv_sec = 0;
rqtp.tv_nsec = 5000000;
if (errno == EWOULDBLOCK && pidptr != NULL) {
again:
errno = pidfile_read(pfh->pf_path, pidptr);
if (errno == 0)
errno = EEXIST;
else if (errno == EAGAIN) {
if (++count <= 3) {
for (;;) {
errno = pidfile_read(pfh->pf_path,
pidptr);
if (errno != EAGAIN || --count == 0)
break;
nanosleep(&rqtp, 0);
goto again;
}
}
if (errno == EAGAIN)
*pidptr = -1;
if (errno == 0 || errno == EAGAIN)
errno = EEXIST;
}
}
error = errno;
free(pfh->pf_path);
free(pfh);
errno = error;
return (NULL);
}
/*
* Remember file information, so in pidfile_write() we are sure we write
* to the proper descriptor.
@@ -251,3 +266,14 @@ pidfile_remove(struct pidfh *pfh)
return (_pidfile_remove(pfh, 1));
}
int
pidfile_fileno(const struct pidfh *pfh)
{
if (pfh == NULL || pfh->pf_fd == -1) {
errno = EINVAL;
return (-1);
}
return (pfh->pf_fd);
}

View File

@@ -34,6 +34,12 @@
#include <string.h>
#include <stdlib.h>
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define LIBBSD_IS_PATHNAME_SEPARATOR(c) ((c) == '/' || (c) == '\\')
#else
#define LIBBSD_IS_PATHNAME_SEPARATOR(c) ((c) == '/')
#endif
#ifdef HAVE___PROGNAME
extern const char *__progname;
#else
@@ -58,11 +64,13 @@ getprogname(void)
void
setprogname(const char *progname)
{
const char *last_slash;
size_t i;
last_slash = strrchr(progname, '/');
if (last_slash == NULL)
for (i = strlen(progname); i > 0; i--) {
if (LIBBSD_IS_PATHNAME_SEPARATOR(progname[i - 1])) {
__progname = progname + i;
return;
}
}
__progname = progname;
else
__progname = last_slash + 1;
}

View File

@@ -1,4 +1,5 @@
/* $NetBSD: radixsort.c,v 1.18 2009/08/21 20:49:50 dsl Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.

View File

@@ -1,7 +1,8 @@
/* $OpenBSD: readpassphrase.c,v 1.20 2007/10/30 12:03:48 millert Exp $ */
/* $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ */
/*
* Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 2000-2002, 2007, 2010
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -35,7 +36,7 @@
#define TCSASOFT 0
#endif
static volatile sig_atomic_t signo;
static volatile sig_atomic_t signo[_NSIG];
static void handler(int);
@@ -43,7 +44,7 @@ char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
{
ssize_t nr;
int input, output, save_errno;
int input, output, save_errno, i, need_restart;
char ch, *p, *end;
struct termios term, oterm;
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
@@ -56,9 +57,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
}
restart:
signo = 0;
for (i = 0; i < _NSIG; i++)
signo[i] = 0;
nr = -1;
save_errno = 0;
need_restart = 0;
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
@@ -73,6 +76,27 @@ restart:
output = STDERR_FILENO;
}
/*
* Turn off echo if possible.
* If we are using a tty but are not the foreground pgrp this will
* generate SIGTTOU, so do it *before* installing the signal handlers.
*/
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
memcpy(&term, &oterm, sizeof(term));
if (!(flags & RPP_ECHO_ON))
term.c_lflag &= ~(ECHO | ECHONL);
#ifdef VSTATUS
if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
term.c_cc[VSTATUS] = _POSIX_VDISABLE;
#endif
(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
} else {
memset(&term, 0, sizeof(term));
term.c_lflag |= ECHO;
memset(&oterm, 0, sizeof(oterm));
oterm.c_lflag |= ECHO;
}
/*
* Catch signals that would otherwise cause the user to end
* up with echo turned off in the shell. Don't worry about
@@ -91,25 +115,6 @@ restart:
(void)sigaction(SIGTTIN, &sa, &savettin);
(void)sigaction(SIGTTOU, &sa, &savettou);
/* Turn off echo if possible. */
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
memcpy(&term, &oterm, sizeof(term));
if (!(flags & RPP_ECHO_ON))
term.c_lflag &= ~(ECHO | ECHONL);
#ifdef VSTATUS
if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
term.c_cc[VSTATUS] = _POSIX_VDISABLE;
#endif
(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
} else {
memset(&term, 0, sizeof(term));
term.c_lflag |= ECHO;
memset(&oterm, 0, sizeof(oterm));
oterm.c_lflag |= ECHO;
}
/* No I/O if we are already backgrounded. */
if (signo != SIGTTOU && signo != SIGTTIN) {
if (!(flags & RPP_STDIN))
(void)write(output, prompt, strlen(prompt));
end = buf + bufsiz - 1;
@@ -118,11 +123,11 @@ restart:
if (p < end) {
if ((flags & RPP_SEVENBIT))
ch &= 0x7f;
if (isalpha(ch)) {
if (isalpha((unsigned char)ch)) {
if ((flags & RPP_FORCELOWER))
ch = (char)tolower(ch);
ch = (char)tolower((unsigned char)ch);
if ((flags & RPP_FORCEUPPER))
ch = (char)toupper(ch);
ch = (char)toupper((unsigned char)ch);
}
*p++ = ch;
}
@@ -131,13 +136,16 @@ restart:
save_errno = errno;
if (!(term.c_lflag & ECHO))
(void)write(output, "\n", 1);
}
/* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0) {
const int sigttou = signo[SIGTTOU];
/* Ignore SIGTTOU generated when we are not the fg pgrp. */
while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
errno == EINTR)
errno == EINTR && !signo[SIGTTOU])
continue;
signo[SIGTTOU] = sigttou;
}
(void)sigaction(SIGALRM, &savealrm, NULL);
(void)sigaction(SIGHUP, &savehup, NULL);
@@ -155,15 +163,19 @@ restart:
* If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers.
*/
if (signo) {
kill(getpid(), signo);
switch (signo) {
for (i = 0; i < _NSIG; i++) {
if (signo[i]) {
kill(getpid(), i);
switch (i) {
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
need_restart = 1;
}
}
}
if (need_restart)
goto restart;
}
}
if (save_errno)
errno = save_errno;
@@ -183,5 +195,5 @@ getpass(const char *prompt)
static void handler(int s)
{
signo = s;
signo[s] = 1;
}

97
src/strtoi.c Normal file
View File

@@ -0,0 +1,97 @@
/* $NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. 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.
* 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.
*
* Original version ID:
* NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp
*
* Created by Kamil Rytarowski, based on ID:
* NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joe…
*/
#include <sys/cdefs.h>
#include <stddef.h>
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#define _DIAGASSERT(t)
intmax_t
strtoi(const char *__restrict nptr,
char **__restrict endptr, int base,
intmax_t lo, intmax_t hi, int *rstatus)
{
int serrno;
intmax_t im;
char *ep;
int rep;
_DIAGASSERT(hi >= lo);
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
if (endptr == NULL)
endptr = &ep;
if (rstatus == NULL)
rstatus = &rep;
serrno = errno;
errno = 0;
im = strtoimax(nptr, endptr, base);
*rstatus = errno;
errno = serrno;
if (*rstatus == 0) {
/* No digits were found */
if (nptr == *endptr)
*rstatus = ECANCELED;
/* There are further characters after number */
else if (**endptr != '\0')
*rstatus = ENOTSUP;
}
if (im < lo) {
if (*rstatus == 0)
*rstatus = ERANGE;
return lo;
}
if (im > hi) {
if (*rstatus == 0)
*rstatus = ERANGE;
return hi;
}
return im;
}

View File

@@ -1,67 +1,62 @@
/* $NetBSD: strtonum.c,v 1.5 2018/01/04 20:57:29 kamil Exp $ */
/*-
* Copyright (c) 2004 Ted Unangst and Todd Miller
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 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.
*
* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define INVALID 1
#define TOOSMALL 2
#define TOOLARGE 3
#include <errno.h>
#include <inttypes.h>
long long
strtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp)
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr)
{
long long ll = 0;
char *ep;
int error = 0;
struct errval {
const char *errstr;
int err;
} ev[4] = {
{ NULL, 0 },
{ "invalid", EINVAL },
{ "too small", ERANGE },
{ "too large", ERANGE },
};
int e;
long long rv;
const char *resp;
ev[0].err = errno;
errno = 0;
if (minval > maxval)
error = INVALID;
else {
ll = strtoll(numstr, &ep, 10);
if (errno == EINVAL || numstr == ep || *ep != '\0')
error = INVALID;
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
error = TOOSMALL;
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
error = TOOLARGE;
if (errstr == NULL)
errstr = &resp;
rv = (long long)strtoi(nptr, NULL, 10, minval, maxval, &e);
if (e == 0) {
*errstr = NULL;
return rv;
}
if (errstrp != NULL)
*errstrp = ev[error].errstr;
errno = ev[error].err;
if (error)
ll = 0;
return (ll);
if (e == ERANGE)
*errstr = (rv == maxval ? "too large" : "too small");
else
*errstr = "invalid";
return 0;
}

97
src/strtou.c Normal file
View File

@@ -0,0 +1,97 @@
/* $NetBSD: _strtoi.h,v 1.2 2015/01/18 17:55:22 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. 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.
* 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.
*
* Original version ID:
* NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp
*
* Created by Kamil Rytarowski, based on ID:
* NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joe…
*/
#include <sys/cdefs.h>
#include <stddef.h>
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#define _DIAGASSERT(t)
uintmax_t
strtou(const char *__restrict nptr,
char **__restrict endptr, int base,
uintmax_t lo, uintmax_t hi, int *rstatus)
{
int serrno;
uintmax_t im;
char *ep;
int rep;
_DIAGASSERT(hi >= lo);
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
if (endptr == NULL)
endptr = &ep;
if (rstatus == NULL)
rstatus = &rep;
serrno = errno;
errno = 0;
im = strtoumax(nptr, endptr, base);
*rstatus = errno;
errno = serrno;
if (*rstatus == 0) {
/* No digits were found */
if (nptr == *endptr)
*rstatus = ECANCELED;
/* There are further characters after number */
else if (**endptr != '\0')
*rstatus = ENOTSUP;
}
if (im < lo) {
if (*rstatus == 0)
*rstatus = ERANGE;
return lo;
}
if (im > hi) {
if (*rstatus == 0)
*rstatus = ERANGE;
return hi;
}
return im;
}

View File

@@ -1,3 +1,5 @@
/* $NetBSD: unvis.c,v 1.44 2014/09/26 15:43:36 roy Exp $ */
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -27,9 +29,24 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcpp"
#include <vis.h>
#pragma GCC diagnostic pop
#ifdef __weak_alias
__weak_alias(strnunvisx,_strnunvisx)
#endif
#define _DIAGASSERT(x)
/*
* decode driven by state machine
@@ -41,15 +58,128 @@
#define S_CTRL 4 /* control char started (^) */
#define S_OCTAL2 5 /* octal digit 2 */
#define S_OCTAL3 6 /* octal digit 3 */
#define S_HEX2 7 /* hex digit 2 */
#define S_HEX 7 /* mandatory hex digit */
#define S_HEX1 8 /* http hex digit */
#define S_HEX2 9 /* http hex digit 2 */
#define S_MIME1 10 /* mime hex digit 1 */
#define S_MIME2 11 /* mime hex digit 2 */
#define S_EATCRNL 12 /* mime eating CRNL */
#define S_AMP 13 /* seen & */
#define S_NUMBER 14 /* collecting number */
#define S_STRING 15 /* collecting string */
#define S_HTTP 0x080 /* %HEXHEX escape */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10))
#define isoctal(c) \
(((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7')
#define ishex(c) \
((((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '9') || \
(((unsigned char)(c)) >= 'a' && ((unsigned char)(c)) <= 'f'))
/*
* RFC 1866
*/
static const struct nv {
char name[7];
uint8_t value;
} nv[] = {
{ "AElig", 198 }, /* capital AE diphthong (ligature) */
{ "Aacute", 193 }, /* capital A, acute accent */
{ "Acirc", 194 }, /* capital A, circumflex accent */
{ "Agrave", 192 }, /* capital A, grave accent */
{ "Aring", 197 }, /* capital A, ring */
{ "Atilde", 195 }, /* capital A, tilde */
{ "Auml", 196 }, /* capital A, dieresis or umlaut mark */
{ "Ccedil", 199 }, /* capital C, cedilla */
{ "ETH", 208 }, /* capital Eth, Icelandic */
{ "Eacute", 201 }, /* capital E, acute accent */
{ "Ecirc", 202 }, /* capital E, circumflex accent */
{ "Egrave", 200 }, /* capital E, grave accent */
{ "Euml", 203 }, /* capital E, dieresis or umlaut mark */
{ "Iacute", 205 }, /* capital I, acute accent */
{ "Icirc", 206 }, /* capital I, circumflex accent */
{ "Igrave", 204 }, /* capital I, grave accent */
{ "Iuml", 207 }, /* capital I, dieresis or umlaut mark */
{ "Ntilde", 209 }, /* capital N, tilde */
{ "Oacute", 211 }, /* capital O, acute accent */
{ "Ocirc", 212 }, /* capital O, circumflex accent */
{ "Ograve", 210 }, /* capital O, grave accent */
{ "Oslash", 216 }, /* capital O, slash */
{ "Otilde", 213 }, /* capital O, tilde */
{ "Ouml", 214 }, /* capital O, dieresis or umlaut mark */
{ "THORN", 222 }, /* capital THORN, Icelandic */
{ "Uacute", 218 }, /* capital U, acute accent */
{ "Ucirc", 219 }, /* capital U, circumflex accent */
{ "Ugrave", 217 }, /* capital U, grave accent */
{ "Uuml", 220 }, /* capital U, dieresis or umlaut mark */
{ "Yacute", 221 }, /* capital Y, acute accent */
{ "aacute", 225 }, /* small a, acute accent */
{ "acirc", 226 }, /* small a, circumflex accent */
{ "acute", 180 }, /* acute accent */
{ "aelig", 230 }, /* small ae diphthong (ligature) */
{ "agrave", 224 }, /* small a, grave accent */
{ "amp", 38 }, /* ampersand */
{ "aring", 229 }, /* small a, ring */
{ "atilde", 227 }, /* small a, tilde */
{ "auml", 228 }, /* small a, dieresis or umlaut mark */
{ "brvbar", 166 }, /* broken (vertical) bar */
{ "ccedil", 231 }, /* small c, cedilla */
{ "cedil", 184 }, /* cedilla */
{ "cent", 162 }, /* cent sign */
{ "copy", 169 }, /* copyright sign */
{ "curren", 164 }, /* general currency sign */
{ "deg", 176 }, /* degree sign */
{ "divide", 247 }, /* divide sign */
{ "eacute", 233 }, /* small e, acute accent */
{ "ecirc", 234 }, /* small e, circumflex accent */
{ "egrave", 232 }, /* small e, grave accent */
{ "eth", 240 }, /* small eth, Icelandic */
{ "euml", 235 }, /* small e, dieresis or umlaut mark */
{ "frac12", 189 }, /* fraction one-half */
{ "frac14", 188 }, /* fraction one-quarter */
{ "frac34", 190 }, /* fraction three-quarters */
{ "gt", 62 }, /* greater than */
{ "iacute", 237 }, /* small i, acute accent */
{ "icirc", 238 }, /* small i, circumflex accent */
{ "iexcl", 161 }, /* inverted exclamation mark */
{ "igrave", 236 }, /* small i, grave accent */
{ "iquest", 191 }, /* inverted question mark */
{ "iuml", 239 }, /* small i, dieresis or umlaut mark */
{ "laquo", 171 }, /* angle quotation mark, left */
{ "lt", 60 }, /* less than */
{ "macr", 175 }, /* macron */
{ "micro", 181 }, /* micro sign */
{ "middot", 183 }, /* middle dot */
{ "nbsp", 160 }, /* no-break space */
{ "not", 172 }, /* not sign */
{ "ntilde", 241 }, /* small n, tilde */
{ "oacute", 243 }, /* small o, acute accent */
{ "ocirc", 244 }, /* small o, circumflex accent */
{ "ograve", 242 }, /* small o, grave accent */
{ "ordf", 170 }, /* ordinal indicator, feminine */
{ "ordm", 186 }, /* ordinal indicator, masculine */
{ "oslash", 248 }, /* small o, slash */
{ "otilde", 245 }, /* small o, tilde */
{ "ouml", 246 }, /* small o, dieresis or umlaut mark */
{ "para", 182 }, /* pilcrow (paragraph sign) */
{ "plusmn", 177 }, /* plus-or-minus sign */
{ "pound", 163 }, /* pound sterling sign */
{ "quot", 34 }, /* double quote */
{ "raquo", 187 }, /* angle quotation mark, right */
{ "reg", 174 }, /* registered sign */
{ "sect", 167 }, /* section sign */
{ "shy", 173 }, /* soft hyphen */
{ "sup1", 185 }, /* superscript one */
{ "sup2", 178 }, /* superscript two */
{ "sup3", 179 }, /* superscript three */
{ "szlig", 223 }, /* small sharp s, German (sz ligature) */
{ "thorn", 254 }, /* small thorn, Icelandic */
{ "times", 215 }, /* multiply sign */
{ "uacute", 250 }, /* small u, acute accent */
{ "ucirc", 251 }, /* small u, circumflex accent */
{ "ugrave", 249 }, /* small u, grave accent */
{ "uml", 168 }, /* umlaut (dieresis) */
{ "uuml", 252 }, /* small u, dieresis or umlaut mark */
{ "yacute", 253 }, /* small y, acute accent */
{ "yen", 165 }, /* yen sign */
{ "yuml", 255 }, /* small y, dieresis or umlaut mark */
};
/*
* unvis - decode characters previously encoded by vis
@@ -57,276 +187,389 @@
int
unvis(char *cp, int c, int *astate, int flag)
{
unsigned char uc = (unsigned char)c;
unsigned char st, ia, is, lc;
/*
* Bottom 8 bits of astate hold the state machine state.
* Top 8 bits hold the current character in the http 1866 nv string decoding
*/
#define GS(a) ((a) & 0xff)
#define SS(a, b) (((uint32_t)(a) << 24) | (b))
#define GI(a) ((uint32_t)(a) >> 24)
_DIAGASSERT(cp != NULL);
_DIAGASSERT(astate != NULL);
st = GS(*astate);
if (flag & UNVIS_END) {
if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
*astate = S_GROUND;
return (UNVIS_VALID);
switch (st) {
case S_OCTAL2:
case S_OCTAL3:
case S_HEX2:
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_GROUND:
return UNVIS_NOCHAR;
default:
return UNVIS_SYNBAD;
}
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
}
switch (*astate & ~S_HTTP) {
switch (st) {
case S_GROUND:
*cp = 0;
if (c == '\\') {
*astate = S_START;
return (0);
if ((flag & VIS_NOESCAPE) == 0 && c == '\\') {
*astate = SS(0, S_START);
return UNVIS_NOCHAR;
}
if (flag & VIS_HTTPSTYLE && c == '%') {
*astate = S_START | S_HTTP;
return (0);
if ((flag & VIS_HTTP1808) && c == '%') {
*astate = SS(0, S_HEX1);
return UNVIS_NOCHAR;
}
if ((flag & VIS_HTTP1866) && c == '&') {
*astate = SS(0, S_AMP);
return UNVIS_NOCHAR;
}
if ((flag & VIS_MIMESTYLE) && c == '=') {
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
}
*cp = c;
return (UNVIS_VALID);
return UNVIS_VALID;
case S_START:
if (*astate & S_HTTP) {
if (ishex(tolower(c))) {
*cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a');
*astate = S_HEX2;
return (0);
}
}
switch(c) {
case '\\':
*cp = c;
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
*cp = (c - '0');
*astate = S_OCTAL2;
return (0);
*astate = SS(0, S_OCTAL2);
return UNVIS_NOCHAR;
case 'M':
*cp = 0200;
*astate = S_META;
return (0);
*cp = (char)0200;
*astate = SS(0, S_META);
return UNVIS_NOCHAR;
case '^':
*astate = S_CTRL;
return (0);
*astate = SS(0, S_CTRL);
return UNVIS_NOCHAR;
case 'n':
*cp = '\n';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'r':
*cp = '\r';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'b':
*cp = '\b';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'a':
*cp = '\007';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'v':
*cp = '\v';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 't':
*cp = '\t';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'f':
*cp = '\f';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 's':
*cp = ' ';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'E':
*cp = '\033';
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'x':
*astate = SS(0, S_HEX);
return UNVIS_NOCHAR;
case '\n':
/*
* hidden newline
*/
*astate = S_GROUND;
return (UNVIS_NOCHAR);
*astate = SS(0, S_GROUND);
return UNVIS_NOCHAR;
case '$':
/*
* hidden marker
*/
*astate = S_GROUND;
return (UNVIS_NOCHAR);
*astate = SS(0, S_GROUND);
return UNVIS_NOCHAR;
default:
if (isgraph(c)) {
*cp = c;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
}
*astate = S_GROUND;
return (UNVIS_SYNBAD);
}
goto bad;
case S_META:
if (c == '-')
*astate = S_META1;
*astate = SS(0, S_META1);
else if (c == '^')
*astate = S_CTRL;
else {
*astate = S_GROUND;
return (UNVIS_SYNBAD);
}
return (0);
*astate = SS(0, S_CTRL);
else
goto bad;
return UNVIS_NOCHAR;
case S_META1:
*astate = S_GROUND;
*astate = SS(0, S_GROUND);
*cp |= c;
return (UNVIS_VALID);
return UNVIS_VALID;
case S_CTRL:
if (c == '?')
*cp |= 0177;
else
*cp |= c & 037;
*astate = S_GROUND;
return (UNVIS_VALID);
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_OCTAL2: /* second possible octal digit */
if (isoctal(c)) {
if (isoctal(uc)) {
/*
* yes - and maybe a third
*/
*cp = (*cp << 3) + (c - '0');
*astate = S_OCTAL3;
return (0);
*astate = SS(0, S_OCTAL3);
return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
*astate = S_GROUND;
return (UNVIS_VALIDPUSH);
*astate = SS(0, S_GROUND);
return UNVIS_VALIDPUSH;
case S_OCTAL3: /* third possible octal digit */
*astate = S_GROUND;
if (isoctal(c)) {
*astate = SS(0, S_GROUND);
if (isoctal(uc)) {
*cp = (*cp << 3) + (c - '0');
return (UNVIS_VALID);
return UNVIS_VALID;
}
/*
* we were done, push back passed char
*/
return (UNVIS_VALIDPUSH);
return UNVIS_VALIDPUSH;
case S_HEX2: /* second mandatory hex digit */
if (ishex(tolower(c))) {
*cp = (isdigit(c) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower(c) - 'a' + 10));
case S_HEX:
if (!isxdigit(uc))
goto bad;
/*FALLTHROUGH*/
case S_HEX1:
if (isxdigit(uc)) {
*cp = xtod(uc);
*astate = SS(0, S_HEX2);
return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
*astate = SS(0, S_GROUND);
return UNVIS_VALIDPUSH;
case S_HEX2:
*astate = S_GROUND;
return (UNVIS_VALID);
if (isxdigit(uc)) {
*cp = xtod(uc) | (*cp << 4);
return UNVIS_VALID;
}
return UNVIS_VALIDPUSH;
case S_MIME1:
if (uc == '\n' || uc == '\r') {
*astate = SS(0, S_EATCRNL);
return UNVIS_NOCHAR;
}
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*cp = XTOD(uc);
*astate = SS(0, S_MIME2);
return UNVIS_NOCHAR;
}
goto bad;
case S_MIME2:
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*astate = SS(0, S_GROUND);
*cp = XTOD(uc) | (*cp << 4);
return UNVIS_VALID;
}
goto bad;
case S_EATCRNL:
switch (uc) {
case '\r':
case '\n':
return UNVIS_NOCHAR;
case '=':
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
default:
*cp = uc;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
}
case S_AMP:
*cp = 0;
if (uc == '#') {
*astate = SS(0, S_NUMBER);
return UNVIS_NOCHAR;
}
*astate = SS(0, S_STRING);
/*FALLTHROUGH*/
case S_STRING:
ia = *cp; /* index in the array */
is = GI(*astate); /* index in the string */
lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */
if (uc == ';')
uc = '\0';
for (; ia < __arraycount(nv); ia++) {
if (is != 0 && nv[ia].name[is - 1] != lc)
goto bad;
if (nv[ia].name[is] == uc)
break;
}
if (ia == __arraycount(nv))
goto bad;
if (uc != 0) {
*cp = ia;
*astate = SS(is + 1, S_STRING);
return UNVIS_NOCHAR;
}
*cp = nv[ia].value;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_NUMBER:
if (uc == ';')
return UNVIS_VALID;
if (!isdigit(uc))
goto bad;
*cp += (*cp * 10) + uc - '0';
return UNVIS_NOCHAR;
default:
bad:
/*
* decoder in unknown state - (probably uninitialized)
*/
*astate = S_GROUND;
return (UNVIS_SYNBAD);
*astate = SS(0, S_GROUND);
return UNVIS_SYNBAD;
}
}
/*
* strunvis - decode src into dst
* strnunvisx - decode src into dst
*
* Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated.
*/
int
strunvis(char *dst, const char *src)
strnunvisx(char *dst, size_t dlen, const char *src, int flag)
{
char c;
char *start = dst;
char t = '\0', *start = dst;
int state = 0;
while ((c = *src++)) {
_DIAGASSERT(src != NULL);
_DIAGASSERT(dst != NULL);
#define CHECKSPACE() \
do { \
if (dlen-- == 0) { \
errno = ENOSPC; \
return -1; \
} \
} while (/*CONSTCOND*/0)
while ((c = *src++) != '\0') {
again:
switch (unvis(dst, c, &state, 0)) {
switch (unvis(&t, c, &state, flag)) {
case UNVIS_VALID:
dst++;
CHECKSPACE();
*dst++ = t;
break;
case UNVIS_VALIDPUSH:
dst++;
CHECKSPACE();
*dst++ = t;
goto again;
case 0:
case UNVIS_NOCHAR:
break;
case UNVIS_SYNBAD:
errno = EINVAL;
return -1;
default:
_DIAGASSERT(/*CONSTCOND*/0);
errno = EINVAL;
return -1;
}
}
if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) {
CHECKSPACE();
*dst++ = t;
}
CHECKSPACE();
*dst = '\0';
return (-1);
}
}
if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
dst++;
*dst = '\0';
return (dst - start);
}
ssize_t
strnunvis(char *dst, const char *src, size_t sz)
{
char c, p;
char *start = dst, *end = dst + sz - 1;
int state = 0;
if (sz > 0)
*end = '\0';
while ((c = *src++)) {
again:
switch (unvis(&p, c, &state, 0)) {
case UNVIS_VALID:
if (dst < end)
*dst = p;
dst++;
break;
case UNVIS_VALIDPUSH:
if (dst < end)
*dst = p;
dst++;
goto again;
case 0:
case UNVIS_NOCHAR:
break;
default:
if (dst <= end)
*dst = '\0';
return (-1);
}
}
if (unvis(&p, c, &state, UNVIS_END) == UNVIS_VALID) {
if (dst < end)
*dst = p;
dst++;
}
if (dst <= end)
*dst = '\0';
return (dst - start);
return (int)(dst - start);
}
int
strunvisx(char *dst, const char *src, int flag)
{
char c;
char *start = dst;
int state = 0;
while ((c = *src++)) {
again:
switch (unvis(dst, c, &state, flag)) {
case UNVIS_VALID:
dst++;
break;
case UNVIS_VALIDPUSH:
dst++;
goto again;
case 0:
case UNVIS_NOCHAR:
break;
default:
return (-1);
}
}
if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
dst++;
*dst = '\0';
return (dst - start);
return strnunvisx(dst, (size_t)~0, src, flag);
}
int
strunvis(char *dst, const char *src)
{
return strnunvisx(dst, (size_t)~0, src, 0);
}
/*
* NetBSD added an strnvis and unfortunately made it incompatible with the
* existing one in OpenBSD and Freedesktop's libbsd (the former having existed
* for over ten years). Despite this incompatibility being reported during
* development (see http://gnats.netbsd.org/44977) they still shipped it.
* Even more unfortunately FreeBSD and later MacOS picked up this incompatible
* implementation.
*
* Provide both implementations and default for now on the historical one to
* avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
*
* OpenBSD, 2001: strnunvis(char *dst, const char *src, size_t dlen);
* NetBSD: 2012, strnunvis(char *dst, size_t dlen, const char *src);
*/
ssize_t
strnunvis_openbsd(char *dst, const char *src, size_t dlen)
{
return strnunvisx(dst, dlen, src, 0);
}
__asm__(".symver strnunvis_openbsd,strnunvis@@LIBBSD_0.2");
int
strnunvis_netbsd(char *dst, size_t dlen, const char *src)
{
return strnunvisx(dst, dlen, src, 0);
}
__asm__(".symver strnunvis_netbsd,strnunvis@LIBBSD_0.9.1");

897
src/vis.c
View File

@@ -1,4 +1,5 @@
/* $OpenBSD: vis.c,v 1.18 2005/08/29 18:38:41 otto Exp $ */
/* $NetBSD: vis.c,v 1.74 2017/11/27 16:37:21 christos Exp $ */
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -28,220 +29,742 @@
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <vis.h>
/*-
* Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
* 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.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#define isoctal(c) \
(((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7')
#define isvisible(c) \
(((unsigned int)(c) <= UCHAR_MAX && \
isascii((unsigned char)(c)) && \
(((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \
(flag & VIS_GLOB) == 0) && \
isgraph((unsigned char)(c))) || \
((flag & VIS_SP) == 0 && (c) == ' ') || \
((flag & VIS_TAB) == 0 && (c) == '\t') || \
((flag & VIS_NL) == 0 && (c) == '\n') || \
((flag & VIS_SAFE) && ((c) == '\b' || \
(c) == '\007' || (c) == '\r' || \
isgraph((unsigned char)(c)))))
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/param.h>
#include <assert.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcpp"
#include <vis.h>
#pragma GCC diagnostic pop
#include <errno.h>
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#ifdef __weak_alias
__weak_alias(strvisx,_strvisx)
#endif
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#define _DIAGASSERT(x)
/*
* The reason for going through the trouble to deal with character encodings
* in vis(3), is that we use this to safe encode output of commands. This
* safe encoding varies depending on the character set. For example if we
* display ps output in French, we don't want to display French characters
* as M-foo.
*/
static wchar_t *do_svis(wchar_t *, wint_t, int, wint_t, const wchar_t *);
#undef BELL
#define BELL L'\a'
#if defined(LC_C_LOCALE)
#define iscgraph(c) isgraph_l(c, LC_C_LOCALE)
#else
/* Keep it simple for now, no locale stuff */
#define iscgraph(c) isgraph(c)
#ifdef notyet
#include <locale.h>
static int
iscgraph(int c) {
int rv;
char *ol;
ol = setlocale(LC_CTYPE, "C");
rv = isgraph(c);
if (ol)
setlocale(LC_CTYPE, ol);
return rv;
}
#endif
#endif
#define ISGRAPH(flags, c) \
(((flags) & VIS_NOLOCALE) ? iscgraph(c) : iswgraph(c))
#define iswoctal(c) (((u_char)(c)) >= L'0' && ((u_char)(c)) <= L'7')
#define iswwhite(c) (c == L' ' || c == L'\t' || c == L'\n')
#define iswsafe(c) (c == L'\b' || c == BELL || c == L'\r')
#define xtoa(c) L"0123456789abcdef"[c]
#define XTOA(c) L"0123456789ABCDEF"[c]
#define MAXEXTRAS 30
static const wchar_t char_shell[] = L"'`\";&<>()|{}]\\$!^~";
static const wchar_t char_glob[] = L"*?[#";
/*
* On NetBSD and glibc MB_LEN_MAX is currently > 8 which does not fit on any
* integer integral type and it is probably wrong, since currently the maximum
* number of bytes and character needs is 6. Until this is fixed, the
* loops below are using sizeof(uint64_t) - 1 instead of MB_LEN_MAX, and
* the assertion is commented out.
*/
#if 0
#ifndef CTASSERT
#define CTASSERT(x) _CTASSERT(x, __LINE__)
#define _CTASSERT(x, y) __CTASSERT(x, y)
#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
#endif
CTASSERT(MB_LEN_MAX <= sizeof(uint64_t));
#endif
/*
* This is do_hvis, for HTTP style (RFC 1808)
*/
static wchar_t *
do_hvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra)
{
if (iswalnum(c)
/* safe */
|| c == L'$' || c == L'-' || c == L'_' || c == L'.' || c == L'+'
/* extra */
|| c == L'!' || c == L'*' || c == L'\'' || c == L'(' || c == L')'
|| c == L',')
dst = do_svis(dst, c, flags, nextc, extra);
else {
*dst++ = L'%';
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
*dst++ = xtoa((unsigned int)c & 0xf);
}
return dst;
}
/*
* This is do_mvis, for Quoted-Printable MIME (RFC 2045)
* NB: No handling of long lines or CRLF.
*/
static wchar_t *
do_mvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra)
{
if ((c != L'\n') &&
/* Space at the end of the line */
((iswspace(c) && (nextc == L'\r' || nextc == L'\n')) ||
/* Out of range */
(!iswspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) ||
/* Specific char to be escaped */
wcschr(L"#$@[\\]^`{|}~", c) != NULL)) {
*dst++ = L'=';
*dst++ = XTOA(((unsigned int)c >> 4) & 0xf);
*dst++ = XTOA((unsigned int)c & 0xf);
} else
dst = do_svis(dst, c, flags, nextc, extra);
return dst;
}
/*
* Output single byte of multibyte character.
*/
static wchar_t *
do_mbyte(wchar_t *dst, wint_t c, int flags, wint_t nextc, int iswextra)
{
if (flags & VIS_CSTYLE) {
switch (c) {
case L'\n':
*dst++ = L'\\'; *dst++ = L'n';
return dst;
case L'\r':
*dst++ = L'\\'; *dst++ = L'r';
return dst;
case L'\b':
*dst++ = L'\\'; *dst++ = L'b';
return dst;
case BELL:
*dst++ = L'\\'; *dst++ = L'a';
return dst;
case L'\v':
*dst++ = L'\\'; *dst++ = L'v';
return dst;
case L'\t':
*dst++ = L'\\'; *dst++ = L't';
return dst;
case L'\f':
*dst++ = L'\\'; *dst++ = L'f';
return dst;
case L' ':
*dst++ = L'\\'; *dst++ = L's';
return dst;
case L'\0':
*dst++ = L'\\'; *dst++ = L'0';
if (iswoctal(nextc)) {
*dst++ = L'0';
*dst++ = L'0';
}
return dst;
/* We cannot encode these characters in VIS_CSTYLE
* because they special meaning */
case L'n':
case L'r':
case L'b':
case L'a':
case L'v':
case L't':
case L'f':
case L's':
case L'0':
case L'M':
case L'^':
case L'$': /* vis(1) -l */
break;
default:
if (ISGRAPH(flags, c) && !iswoctal(c)) {
*dst++ = L'\\';
*dst++ = c;
return dst;
}
}
}
if (iswextra || ((c & 0177) == L' ') || (flags & VIS_OCTAL)) {
*dst++ = L'\\';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + L'0';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + L'0';
*dst++ = (c & 07) + L'0';
} else {
if ((flags & VIS_NOSLASH) == 0)
*dst++ = L'\\';
if (c & 0200) {
c &= 0177;
*dst++ = L'M';
}
if (iswcntrl(c)) {
*dst++ = L'^';
if (c == 0177)
*dst++ = L'?';
else
*dst++ = c + L'@';
} else {
*dst++ = L'-';
*dst++ = c;
}
}
return dst;
}
/*
* This is do_vis, the central code of vis.
* dst: Pointer to the destination buffer
* c: Character to encode
* flags: Flags word
* nextc: The character following 'c'
* extra: Pointer to the list of extra characters to be
* backslash-protected.
*/
static wchar_t *
do_svis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra)
{
int iswextra, i, shft;
uint64_t bmsk, wmsk;
iswextra = wcschr(extra, c) != NULL;
if (!iswextra && (ISGRAPH(flags, c) || iswwhite(c) ||
((flags & VIS_SAFE) && iswsafe(c)))) {
*dst++ = c;
return dst;
}
/* See comment in istrsenvisx() output loop, below. */
wmsk = 0;
for (i = sizeof(wmsk) - 1; i >= 0; i--) {
shft = i * NBBY;
bmsk = (uint64_t)0xffLL << shft;
wmsk |= bmsk;
if ((c & wmsk) || i == 0)
dst = do_mbyte(dst, (wint_t)(
(uint64_t)(c & bmsk) >> shft),
flags, nextc, iswextra);
}
return dst;
}
typedef wchar_t *(*visfun_t)(wchar_t *, wint_t, int, wint_t, const wchar_t *);
/*
* Return the appropriate encoding function depending on the flags given.
*/
static visfun_t
getvisfun(int flags)
{
if (flags & VIS_HTTPSTYLE)
return do_hvis;
if (flags & VIS_MIMESTYLE)
return do_mvis;
return do_svis;
}
/*
* Expand list of extra characters to not visually encode.
*/
static wchar_t *
makeextralist(int flags, const char *src)
{
wchar_t *dst, *d;
size_t len;
const wchar_t *s;
len = strlen(src);
if ((dst = calloc(len + MAXEXTRAS, sizeof(*dst))) == NULL)
return NULL;
if ((flags & VIS_NOLOCALE) || mbstowcs(dst, src, len) == (size_t)-1) {
size_t i;
for (i = 0; i < len; i++)
dst[i] = (wchar_t)(u_char)src[i];
d = dst + len;
} else
d = dst + wcslen(dst);
if (flags & VIS_GLOB)
for (s = char_glob; *s; *d++ = *s++)
continue;
if (flags & VIS_SHELL)
for (s = char_shell; *s; *d++ = *s++)
continue;
if (flags & VIS_SP) *d++ = L' ';
if (flags & VIS_TAB) *d++ = L'\t';
if (flags & VIS_NL) *d++ = L'\n';
if (flags & VIS_DQ) *d++ = L'"';
if ((flags & VIS_NOSLASH) == 0) *d++ = L'\\';
*d = L'\0';
return dst;
}
/*
* istrsenvisx()
* The main internal function.
* All user-visible functions call this one.
*/
static int
istrsenvisx(char **mbdstp, size_t *dlen, const char *mbsrc, size_t mblength,
int flags, const char *mbextra, int *cerr_ptr)
{
wchar_t *dst, *src, *pdst, *psrc, *start, *extra;
size_t len, olen;
uint64_t bmsk, wmsk;
wint_t c;
visfun_t f;
int clen = 0, cerr, error = -1, i, shft;
char *mbdst, *mdst;
ssize_t mbslength, maxolen;
_DIAGASSERT(mbdstp != NULL);
_DIAGASSERT(mbsrc != NULL || mblength == 0);
_DIAGASSERT(mbextra != NULL);
mbslength = (ssize_t)mblength;
/*
* When inputing a single character, must also read in the
* next character for nextc, the look-ahead character.
*/
if (mbslength == 1)
mbslength++;
/*
* Input (mbsrc) is a char string considered to be multibyte
* characters. The input loop will read this string pulling
* one character, possibly multiple bytes, from mbsrc and
* converting each to wchar_t in src.
*
* The vis conversion will be done using the wide char
* wchar_t string.
*
* This will then be converted back to a multibyte string to
* return to the caller.
*/
/* Allocate space for the wide char strings */
psrc = pdst = extra = NULL;
mdst = NULL;
if ((psrc = calloc(mbslength + 1, sizeof(*psrc))) == NULL)
return -1;
if ((pdst = calloc((16 * mbslength) + 1, sizeof(*pdst))) == NULL)
goto out;
if (*mbdstp == NULL) {
if ((mdst = calloc((16 * mbslength) + 1, sizeof(*mdst))) == NULL)
goto out;
*mbdstp = mdst;
}
mbdst = *mbdstp;
dst = pdst;
src = psrc;
if (flags & VIS_NOLOCALE) {
/* Do one byte at a time conversion */
cerr = 1;
} else {
/* Use caller's multibyte conversion error flag. */
cerr = cerr_ptr ? *cerr_ptr : 0;
}
/*
* Input loop.
* Handle up to mblength characters (not bytes). We do not
* stop at NULs because we may be processing a block of data
* that includes NULs.
*/
while (mbslength > 0) {
/* Convert one multibyte character to wchar_t. */
if (!cerr)
clen = mbtowc(src, mbsrc, MB_LEN_MAX);
if (cerr || clen < 0) {
/* Conversion error, process as a byte instead. */
*src = (wint_t)(u_char)*mbsrc;
clen = 1;
cerr = 1;
}
if (clen == 0) {
/*
* NUL in input gives 0 return value. process
* as single NUL byte and keep going.
*/
clen = 1;
}
/* Advance buffer character pointer. */
src++;
/* Advance input pointer by number of bytes read. */
mbsrc += clen;
/* Decrement input byte count. */
mbslength -= clen;
}
len = src - psrc;
src = psrc;
/*
* In the single character input case, we will have actually
* processed two characters, c and nextc. Reset len back to
* just a single character.
*/
if (mblength < len)
len = mblength;
/* Convert extra argument to list of characters for this mode. */
extra = makeextralist(flags, mbextra);
if (!extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
goto out;
}
*mbdst = '\0'; /* can't create extra, return "" */
error = 0;
goto out;
}
/* Look up which processing function to call. */
f = getvisfun(flags);
/*
* Main processing loop.
* Call do_Xvis processing function one character at a time
* with next character available for look-ahead.
*/
for (start = dst; len > 0; len--) {
c = *src++;
dst = (*f)(dst, c, flags, len >= 1 ? *src : L'\0', extra);
if (dst == NULL) {
errno = ENOSPC;
goto out;
}
}
/* Terminate the string in the buffer. */
*dst = L'\0';
/*
* Output loop.
* Convert wchar_t string back to multibyte output string.
* If we have hit a multi-byte conversion error on input,
* output byte-by-byte here. Else use wctomb().
*/
len = wcslen(start);
maxolen = dlen ? *dlen : (wcslen(start) * MB_LEN_MAX + 1);
olen = 0;
for (dst = start; len > 0; len--) {
if (!cerr)
clen = wctomb(mbdst, *dst);
if (cerr || clen < 0) {
/*
* Conversion error, process as a byte(s) instead.
* Examine each byte and higher-order bytes for
* data. E.g.,
* 0x000000000000a264 -> a2 64
* 0x000000001f00a264 -> 1f 00 a2 64
*/
clen = 0;
wmsk = 0;
for (i = sizeof(wmsk) - 1; i >= 0; i--) {
shft = i * NBBY;
bmsk = (uint64_t)0xffLL << shft;
wmsk |= bmsk;
if ((*dst & wmsk) || i == 0)
mbdst[clen++] = (char)(
(uint64_t)(*dst & bmsk) >>
shft);
}
cerr = 1;
}
/* If this character would exceed our output limit, stop. */
if (olen + clen > (size_t)maxolen)
break;
/* Advance output pointer by number of bytes written. */
mbdst += clen;
/* Advance buffer character pointer. */
dst++;
/* Incrment output character count. */
olen += clen;
}
/* Terminate the output string. */
*mbdst = '\0';
if (flags & VIS_NOLOCALE) {
/* Pass conversion error flag out. */
if (cerr_ptr)
*cerr_ptr = cerr;
}
free(extra);
free(pdst);
free(psrc);
return (int)olen;
out:
free(extra);
free(pdst);
free(psrc);
free(mdst);
return error;
}
static int
istrsenvisxl(char **mbdstp, size_t *dlen, const char *mbsrc,
int flags, const char *mbextra, int *cerr_ptr)
{
return istrsenvisx(mbdstp, dlen, mbsrc,
mbsrc != NULL ? strlen(mbsrc) : 0, flags, mbextra, cerr_ptr);
}
/*
* The "svis" variants all take an "extra" arg that is a pointer
* to a NUL-terminated list of characters to be encoded, too.
* These functions are useful e. g. to encode strings in such a
* way so that they are not interpreted by a shell.
*/
char *
svis(char *mbdst, int c, int flags, int nextc, const char *mbextra)
{
char cc[2];
int ret;
cc[0] = c;
cc[1] = nextc;
ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, mbextra, NULL);
if (ret < 0)
return NULL;
return mbdst + ret;
}
char *
snvis(char *mbdst, size_t dlen, int c, int flags, int nextc, const char *mbextra)
{
char cc[2];
int ret;
cc[0] = c;
cc[1] = nextc;
ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, mbextra, NULL);
if (ret < 0)
return NULL;
return mbdst + ret;
}
int
strsvis(char *mbdst, const char *mbsrc, int flags, const char *mbextra)
{
return istrsenvisxl(&mbdst, NULL, mbsrc, flags, mbextra, NULL);
}
int
strsnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags, const char *mbextra)
{
return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, mbextra, NULL);
}
int
strsvisx(char *mbdst, const char *mbsrc, size_t len, int flags, const char *mbextra)
{
return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, mbextra, NULL);
}
int
strsnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags,
const char *mbextra)
{
return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, NULL);
}
int
strsenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags,
const char *mbextra, int *cerr_ptr)
{
return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, cerr_ptr);
}
/*
* vis - visually encode characters
*/
char *
vis(char *dst, int c, int flag, int nextc)
vis(char *mbdst, int c, int flags, int nextc)
{
c = (unsigned char)c;
char cc[2];
int ret;
if (flag & VIS_HTTPSTYLE) {
/* Described in RFC 1808 */
if (!(isalnum(c) /* alpha-numeric */
/* safe */
|| c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
/* extra */
|| c == '!' || c == '*' || c == '\'' || c == '('
|| c == ')' || c == ',')) {
*dst++ = '%';
snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c);
dst += 2;
goto done;
}
}
cc[0] = c;
cc[1] = nextc;
if ((flag & VIS_GLOB) &&
(c == '*' || c == '?' || c == '[' || c == '#'))
;
else if (isgraph(c) ||
((flag & VIS_SP) == 0 && c == ' ') ||
((flag & VIS_TAB) == 0 && c == '\t') ||
((flag & VIS_NL) == 0 && c == '\n') ||
((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
*dst++ = c;
if (c == '\\' && (flag & VIS_NOSLASH) == 0)
*dst++ = '\\';
*dst = '\0';
return (dst);
}
ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, "", NULL);
if (ret < 0)
return NULL;
return mbdst + ret;
}
if (flag & VIS_CSTYLE) {
switch(c) {
case '\n':
*dst++ = '\\';
*dst++ = 'n';
goto done;
case '\r':
*dst++ = '\\';
*dst++ = 'r';
goto done;
case '\b':
*dst++ = '\\';
*dst++ = 'b';
goto done;
case '\a':
*dst++ = '\\';
*dst++ = 'a';
goto done;
case '\v':
*dst++ = '\\';
*dst++ = 'v';
goto done;
case '\t':
*dst++ = '\\';
*dst++ = 't';
goto done;
case '\f':
*dst++ = '\\';
*dst++ = 'f';
goto done;
case ' ':
*dst++ = '\\';
*dst++ = 's';
goto done;
case '\0':
*dst++ = '\\';
*dst++ = '0';
if (isoctal(nextc)) {
*dst++ = '0';
*dst++ = '0';
}
goto done;
}
}
if (((c & 0177) == ' ') || isgraph(c) || (flag & VIS_OCTAL)) {
*dst++ = '\\';
*dst++ = ((unsigned char)c >> 6 & 07) + '0';
*dst++ = ((unsigned char)c >> 3 & 07) + '0';
*dst++ = ((unsigned char)c & 07) + '0';
goto done;
}
if ((flag & VIS_NOSLASH) == 0)
*dst++ = '\\';
if (c & 0200) {
c &= 0177;
*dst++ = 'M';
}
if (iscntrl(c)) {
*dst++ = '^';
if (c == 0177)
*dst++ = '?';
else
*dst++ = c + '@';
} else {
*dst++ = '-';
*dst++ = c;
}
done:
*dst = '\0';
return (dst);
char *
nvis(char *mbdst, size_t dlen, int c, int flags, int nextc)
{
char cc[2];
int ret;
cc[0] = c;
cc[1] = nextc;
ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, "", NULL);
if (ret < 0)
return NULL;
return mbdst + ret;
}
/*
* strvis, strnvis, strvisx - visually encode characters from src into dst
* strvis - visually encode characters from src into dst
*
* Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NUL,
* expansion. The length of dst, not including the trailing NULL,
* is returned.
*/
int
strvis(char *mbdst, const char *mbsrc, int flags)
{
return istrsenvisxl(&mbdst, NULL, mbsrc, flags, "", NULL);
}
/*
* NetBSD added an strnvis and unfortunately made it incompatible with the
* existing one in OpenBSD and Freedesktop's libbsd (the former having existed
* for over ten years). Despite this incompatibility being reported during
* development (see http://gnats.netbsd.org/44977) they still shipped it.
* Even more unfortunately FreeBSD and later MacOS picked up this incompatible
* implementation.
*
* Strnvis will write no more than siz-1 bytes (and will NULL terminate).
* The number of bytes needed to fully encode the string is returned.
* Provide both implementations and default for now on the historical one to
* avoid breakage, we will switch to the NetBSD one in libbsd 0.10.0 or so.
*
* Strvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data.
* OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag);
* NetBSD: 2012, strnvis(char *dst, size_t dlen, const char *src, int flag);
*/
int
strvis(char *dst, const char *src, int flag)
strnvis_openbsd(char *mbdst, const char *mbsrc, size_t dlen, int flags)
{
char c;
char *start;
return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL);
}
__asm__(".symver strnvis_openbsd,strnvis@@LIBBSD_0.2");
for (start = dst; (c = *src); )
dst = vis(dst, c, flag, *++src);
*dst = '\0';
return (dst - start);
int
strnvis_netbsd(char *mbdst, size_t dlen, const char *mbsrc, int flags)
{
return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL);
}
__asm__(".symver strnvis_netbsd,strnvis@LIBBSD_0.9.1");
int
stravis(char **mbdstp, const char *mbsrc, int flags)
{
*mbdstp = NULL;
return istrsenvisxl(mbdstp, NULL, mbsrc, flags, "", NULL);
}
/*
* strvisx - visually encode characters from src into dst
*
* Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL,
* is returned.
*
* Strvisx encodes exactly len characters from src into dst.
* This is useful for encoding a block of data.
*/
int
strvisx(char *mbdst, const char *mbsrc, size_t len, int flags)
{
return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, "", NULL);
}
int
strnvis(char *dst, const char *src, size_t siz, int flag)
strnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags)
{
char *start, *end;
char tbuf[5];
int c, i;
i = 0;
for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
if (isvisible(c)) {
i = 1;
*dst++ = c;
if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
/* need space for the extra '\\' */
if (dst < end)
*dst++ = '\\';
else {
dst--;
i = 2;
break;
}
}
src++;
} else {
i = vis(tbuf, c, flag, *++src) - tbuf;
if (dst + i <= end) {
memcpy(dst, tbuf, i);
dst += i;
} else {
src--;
break;
}
}
}
if (siz > 0)
*dst = '\0';
if (dst + i > end) {
/* adjust return value for truncation */
while ((c = *src))
dst += vis(tbuf, c, flag, *++src) - tbuf;
}
return (dst - start);
return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", NULL);
}
int
strvisx(char *dst, const char *src, size_t len, int flag)
strenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags,
int *cerr_ptr)
{
int c;
char *start;
for (start = dst; len > 1; len--) {
c = *src;
dst = vis(dst, c, flag, *++src);
}
if (len)
dst = vis(dst, *src, flag, '\0');
*dst = '\0';
return (dst - start);
return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", cerr_ptr);
}

2
test/.gitignore vendored
View File

@@ -19,3 +19,5 @@ setmode
strl
strmode
strnstr
vis
vis-openbsd

View File

@@ -47,6 +47,8 @@ check_PROGRAMS = \
strl \
strmode \
strnstr \
vis \
vis-openbsd \
$(nil)
if HAVE_LIBTESTU01

47
test/vis-openbsd.c Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright © 2018 Guillem Jover <guillem@hadrons.org>
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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 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 <assert.h>
#include <string.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcpp"
#include <vis.h>
#pragma GCC diagnostic pop
int
main(int argc, char **argv)
{
char str[200];
char unstr[200];
strnvis(str, "0123456789abcdef", 10, 0);
assert(strcmp(str, "0123456789") == 0);
strnunvis(unstr, str, 100);
assert(strcmp(unstr, "0123456789") == 0);
return 0;
}

46
test/vis.c Normal file
View File

@@ -0,0 +1,46 @@
/*
* Copyright © 2018 Guillem Jover <guillem@hadrons.org>
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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 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.
*/
#define LIBBSD_NETBSD_VIS 1
#include <assert.h>
#include <string.h>
#include <vis.h>
int
main(int argc, char **argv)
{
char str[200];
char unstr[200];
strnvis(str, 10, "0123456789abcdef", 0);
assert(strcmp(str, "0123456789") == 0);
strnunvis(unstr, 100, str);
assert(strcmp(unstr, "0123456789") == 0);
return 0;
}