summaryrefslogtreecommitdiff
path: root/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc')
-rw-r--r--src/lib/libc/crypt/Makefile.inc14
-rw-r--r--src/lib/libc/crypt/arc4random.3110
-rw-r--r--src/lib/libc/crypt/arc4random.c193
-rw-r--r--src/lib/libc/crypt/bcrypt.c334
-rw-r--r--src/lib/libc/crypt/blowfish.3106
-rw-r--r--src/lib/libc/crypt/blowfish.c694
-rw-r--r--src/lib/libc/crypt/cast.c779
-rw-r--r--src/lib/libc/crypt/crypt.3314
-rw-r--r--src/lib/libc/crypt/crypt.c713
-rw-r--r--src/lib/libc/crypt/md5crypt.c157
-rw-r--r--src/lib/libc/crypt/morecrypt.c628
-rw-r--r--src/lib/libc/crypt/skipjack.c258
-rw-r--r--src/lib/libc/include/namespace.h18
-rw-r--r--src/lib/libc/include/thread_private.h135
-rw-r--r--src/lib/libc/net/Makefile.inc85
-rw-r--r--src/lib/libc/net/base64.c318
-rw-r--r--src/lib/libc/net/byteorder.3183
-rw-r--r--src/lib/libc/net/ethers.3119
-rw-r--r--src/lib/libc/net/ethers.c272
-rw-r--r--src/lib/libc/net/freeaddrinfo.c49
-rw-r--r--src/lib/libc/net/gai_strerror.c76
-rw-r--r--src/lib/libc/net/getaddrinfo.3581
-rw-r--r--src/lib/libc/net/getaddrinfo.c1848
-rw-r--r--src/lib/libc/net/gethostbyname.3275
-rw-r--r--src/lib/libc/net/gethostnamadr.c1175
-rw-r--r--src/lib/libc/net/getifaddrs.3159
-rw-r--r--src/lib/libc/net/getifaddrs.c277
-rw-r--r--src/lib/libc/net/getnameinfo.3297
-rw-r--r--src/lib/libc/net/getnameinfo.c361
-rw-r--r--src/lib/libc/net/getnetbyaddr.c56
-rw-r--r--src/lib/libc/net/getnetbyname.c62
-rw-r--r--src/lib/libc/net/getnetent.3144
-rw-r--r--src/lib/libc/net/getnetent.c129
-rw-r--r--src/lib/libc/net/getnetnamadr.c391
-rw-r--r--src/lib/libc/net/getproto.c55
-rw-r--r--src/lib/libc/net/getprotoent.3134
-rw-r--r--src/lib/libc/net/getprotoent.c127
-rw-r--r--src/lib/libc/net/getprotoname.c62
-rw-r--r--src/lib/libc/net/getrrsetbyname.3166
-rw-r--r--src/lib/libc/net/getrrsetbyname.c507
-rw-r--r--src/lib/libc/net/getservbyname.c87
-rw-r--r--src/lib/libc/net/getservbyport.c60
-rw-r--r--src/lib/libc/net/getservent.3141
-rw-r--r--src/lib/libc/net/getservent.c129
-rw-r--r--src/lib/libc/net/herror.c121
-rw-r--r--src/lib/libc/net/htonl.c25
-rw-r--r--src/lib/libc/net/htons.c24
-rw-r--r--src/lib/libc/net/if_indextoname.3140
-rw-r--r--src/lib/libc/net/if_indextoname.c86
-rw-r--r--src/lib/libc/net/if_nameindex.c140
-rw-r--r--src/lib/libc/net/if_nametoindex.c81
-rw-r--r--src/lib/libc/net/inet.3349
-rw-r--r--src/lib/libc/net/inet6_option_space.3452
-rw-r--r--src/lib/libc/net/inet6_rthdr_space.3325
-rw-r--r--src/lib/libc/net/inet_addr.c187
-rw-r--r--src/lib/libc/net/inet_lnaof.c59
-rw-r--r--src/lib/libc/net/inet_makeaddr.c62
-rw-r--r--src/lib/libc/net/inet_net.3148
-rw-r--r--src/lib/libc/net/inet_net_ntop.c153
-rw-r--r--src/lib/libc/net/inet_net_pton.c206
-rw-r--r--src/lib/libc/net/inet_neta.c91
-rw-r--r--src/lib/libc/net/inet_netof.c58
-rw-r--r--src/lib/libc/net/inet_network.c92
-rw-r--r--src/lib/libc/net/inet_ntoa.c59
-rw-r--r--src/lib/libc/net/inet_ntop.c213
-rw-r--r--src/lib/libc/net/inet_pton.c222
-rw-r--r--src/lib/libc/net/ip6opt.c388
-rw-r--r--src/lib/libc/net/ipx.3127
-rw-r--r--src/lib/libc/net/ipx_addr.c228
-rw-r--r--src/lib/libc/net/ipx_ntoa.c58
-rw-r--r--src/lib/libc/net/iso_addr.3111
-rw-r--r--src/lib/libc/net/iso_addr.c119
-rw-r--r--src/lib/libc/net/link_addr.3131
-rw-r--r--src/lib/libc/net/linkaddr.c158
-rw-r--r--src/lib/libc/net/net_addrcmp.391
-rw-r--r--src/lib/libc/net/net_addrcmp.c68
-rw-r--r--src/lib/libc/net/ns.3131
-rw-r--r--src/lib/libc/net/ns_addr.c227
-rw-r--r--src/lib/libc/net/ns_ntoa.c104
-rw-r--r--src/lib/libc/net/nsap_addr.c109
-rw-r--r--src/lib/libc/net/ntohl.c25
-rw-r--r--src/lib/libc/net/ntohs.c24
-rw-r--r--src/lib/libc/net/rcmd.3270
-rw-r--r--src/lib/libc/net/rcmd.c733
-rw-r--r--src/lib/libc/net/rcmdsh.397
-rw-r--r--src/lib/libc/net/rcmdsh.c153
-rw-r--r--src/lib/libc/net/recv.c50
-rw-r--r--src/lib/libc/net/res_comp.c503
-rw-r--r--src/lib/libc/net/res_data.c117
-rw-r--r--src/lib/libc/net/res_debug.c1560
-rw-r--r--src/lib/libc/net/res_init.c639
-rw-r--r--src/lib/libc/net/res_mkquery.c242
-rw-r--r--src/lib/libc/net/res_query.c405
-rw-r--r--src/lib/libc/net/res_random.c229
-rw-r--r--src/lib/libc/net/res_send.c893
-rw-r--r--src/lib/libc/net/resolver.3345
-rw-r--r--src/lib/libc/net/rresvport.c118
-rw-r--r--src/lib/libc/net/rthdr.c310
-rw-r--r--src/lib/libc/net/send.c50
-rw-r--r--src/lib/libc/net/sethostent.c60
-rw-r--r--src/lib/libc/net/vars6.c42
-rw-r--r--src/lib/libc/stdlib/Makefile.inc56
-rw-r--r--src/lib/libc/stdlib/_rand48.c50
-rw-r--r--src/lib/libc/stdlib/a64l.3144
-rw-r--r--src/lib/libc/stdlib/a64l.c46
-rw-r--r--src/lib/libc/stdlib/abort.367
-rw-r--r--src/lib/libc/stdlib/abort.c86
-rw-r--r--src/lib/libc/stdlib/abs.369
-rw-r--r--src/lib/libc/stdlib/abs.c45
-rw-r--r--src/lib/libc/stdlib/alloca.384
-rw-r--r--src/lib/libc/stdlib/atexit.375
-rw-r--r--src/lib/libc/stdlib/atexit.c83
-rw-r--r--src/lib/libc/stdlib/atexit.h41
-rw-r--r--src/lib/libc/stdlib/atof.373
-rw-r--r--src/lib/libc/stdlib/atof.c45
-rw-r--r--src/lib/libc/stdlib/atoi.385
-rw-r--r--src/lib/libc/stdlib/atoi.c45
-rw-r--r--src/lib/libc/stdlib/atol.373
-rw-r--r--src/lib/libc/stdlib/atol.c45
-rw-r--r--src/lib/libc/stdlib/bsearch.388
-rw-r--r--src/lib/libc/stdlib/bsearch.c79
-rw-r--r--src/lib/libc/stdlib/calloc.c59
-rw-r--r--src/lib/libc/stdlib/cfree.c49
-rw-r--r--src/lib/libc/stdlib/div.367
-rw-r--r--src/lib/libc/stdlib/div.c79
-rw-r--r--src/lib/libc/stdlib/drand48.c26
-rw-r--r--src/lib/libc/stdlib/erand48.c27
-rw-r--r--src/lib/libc/stdlib/exit.392
-rw-r--r--src/lib/libc/stdlib/exit.c79
-rw-r--r--src/lib/libc/stdlib/getenv.3146
-rw-r--r--src/lib/libc/stdlib/getenv.c89
-rw-r--r--src/lib/libc/stdlib/getopt.3254
-rw-r--r--src/lib/libc/stdlib/getopt.c117
-rw-r--r--src/lib/libc/stdlib/getsubopt.3147
-rw-r--r--src/lib/libc/stdlib/getsubopt.c106
-rw-r--r--src/lib/libc/stdlib/heapsort.c183
-rw-r--r--src/lib/libc/stdlib/jrand48.c25
-rw-r--r--src/lib/libc/stdlib/l64a.c46
-rw-r--r--src/lib/libc/stdlib/labs.364
-rw-r--r--src/lib/libc/stdlib/labs.c45
-rw-r--r--src/lib/libc/stdlib/lcong48.c34
-rw-r--r--src/lib/libc/stdlib/ldiv.369
-rw-r--r--src/lib/libc/stdlib/ldiv.c58
-rw-r--r--src/lib/libc/stdlib/lrand48.c27
-rw-r--r--src/lib/libc/stdlib/malloc.3419
-rw-r--r--src/lib/libc/stdlib/malloc.c1305
-rw-r--r--src/lib/libc/stdlib/memory.369
-rw-r--r--src/lib/libc/stdlib/merge.c347
-rw-r--r--src/lib/libc/stdlib/mrand48.c27
-rw-r--r--src/lib/libc/stdlib/multibyte.c124
-rw-r--r--src/lib/libc/stdlib/nrand48.c25
-rw-r--r--src/lib/libc/stdlib/putenv.c58
-rw-r--r--src/lib/libc/stdlib/qabs.360
-rw-r--r--src/lib/libc/stdlib/qabs.c45
-rw-r--r--src/lib/libc/stdlib/qdiv.364
-rw-r--r--src/lib/libc/stdlib/qdiv.c58
-rw-r--r--src/lib/libc/stdlib/qsort.3233
-rw-r--r--src/lib/libc/stdlib/qsort.c175
-rw-r--r--src/lib/libc/stdlib/radixsort.3156
-rw-r--r--src/lib/libc/stdlib/radixsort.c317
-rw-r--r--src/lib/libc/stdlib/rand.3102
-rw-r--r--src/lib/libc/stdlib/rand.c65
-rw-r--r--src/lib/libc/stdlib/rand48.3165
-rw-r--r--src/lib/libc/stdlib/rand48.h32
-rw-r--r--src/lib/libc/stdlib/random.3190
-rw-r--r--src/lib/libc/stdlib/random.c417
-rw-r--r--src/lib/libc/stdlib/realpath.3124
-rw-r--r--src/lib/libc/stdlib/realpath.c166
-rw-r--r--src/lib/libc/stdlib/seed48.c40
-rw-r--r--src/lib/libc/stdlib/setenv.c121
-rw-r--r--src/lib/libc/stdlib/srand48.c34
-rw-r--r--src/lib/libc/stdlib/strtod.3117
-rw-r--r--src/lib/libc/stdlib/strtod.c2528
-rw-r--r--src/lib/libc/stdlib/strtol.3243
-rw-r--r--src/lib/libc/stdlib/strtol.c150
-rw-r--r--src/lib/libc/stdlib/strtoll.c166
-rw-r--r--src/lib/libc/stdlib/strtoul.3225
-rw-r--r--src/lib/libc/stdlib/strtoul.c112
-rw-r--r--src/lib/libc/stdlib/strtoull.c128
-rw-r--r--src/lib/libc/stdlib/system.3103
-rw-r--r--src/lib/libc/stdlib/system.c82
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3127
-rw-r--r--src/lib/libc/stdlib/tsearch.c126
-rw-r--r--src/lib/libc/string/Makefile.inc151
-rw-r--r--src/lib/libc/string/__strerror.c114
-rw-r--r--src/lib/libc/string/__strsignal.c102
-rw-r--r--src/lib/libc/string/bcmp.370
-rw-r--r--src/lib/libc/string/bcmp.c63
-rw-r--r--src/lib/libc/string/bcopy.370
-rw-r--r--src/lib/libc/string/bcopy.c138
-rw-r--r--src/lib/libc/string/bm.3115
-rw-r--r--src/lib/libc/string/bm.c219
-rw-r--r--src/lib/libc/string/bstring.3110
-rw-r--r--src/lib/libc/string/bzero.365
-rw-r--r--src/lib/libc/string/bzero.c56
-rw-r--r--src/lib/libc/string/ffs.360
-rw-r--r--src/lib/libc/string/ffs.c49
-rw-r--r--src/lib/libc/string/index.c54
-rw-r--r--src/lib/libc/string/memccpy.376
-rw-r--r--src/lib/libc/string/memccpy.c64
-rw-r--r--src/lib/libc/string/memchr.378
-rw-r--r--src/lib/libc/string/memchr.c58
-rw-r--r--src/lib/libc/string/memcmp.381
-rw-r--r--src/lib/libc/string/memcmp.c60
-rw-r--r--src/lib/libc/string/memcpy.380
-rw-r--r--src/lib/libc/string/memmove.373
-rw-r--r--src/lib/libc/string/memset.371
-rw-r--r--src/lib/libc/string/memset.c58
-rw-r--r--src/lib/libc/string/rindex.c56
-rw-r--r--src/lib/libc/string/strcasecmp.388
-rw-r--r--src/lib/libc/string/strcasecmp.c120
-rw-r--r--src/lib/libc/string/strcat.3135
-rw-r--r--src/lib/libc/string/strcat.c54
-rw-r--r--src/lib/libc/string/strchr.3106
-rw-r--r--src/lib/libc/string/strcmp.391
-rw-r--r--src/lib/libc/string/strcmp.c58
-rw-r--r--src/lib/libc/string/strcoll.372
-rw-r--r--src/lib/libc/string/strcoll.c52
-rw-r--r--src/lib/libc/string/strcpy.3154
-rw-r--r--src/lib/libc/string/strcpy.c53
-rw-r--r--src/lib/libc/string/strcspn.392
-rw-r--r--src/lib/libc/string/strcspn.c67
-rw-r--r--src/lib/libc/string/strdup.387
-rw-r--r--src/lib/libc/string/strdup.c62
-rw-r--r--src/lib/libc/string/strerror.369
-rw-r--r--src/lib/libc/string/strerror.c55
-rw-r--r--src/lib/libc/string/string.3161
-rw-r--r--src/lib/libc/string/strlcat.c73
-rw-r--r--src/lib/libc/string/strlcpy.3190
-rw-r--r--src/lib/libc/string/strlcpy.c69
-rw-r--r--src/lib/libc/string/strlen.365
-rw-r--r--src/lib/libc/string/strlen.c56
-rw-r--r--src/lib/libc/string/strmode.3163
-rw-r--r--src/lib/libc/string/strmode.c152
-rw-r--r--src/lib/libc/string/strncat.c67
-rw-r--r--src/lib/libc/string/strncmp.c59
-rw-r--r--src/lib/libc/string/strncpy.c67
-rw-r--r--src/lib/libc/string/strpbrk.376
-rw-r--r--src/lib/libc/string/strpbrk.c56
-rw-r--r--src/lib/libc/string/strrchr.3108
-rw-r--r--src/lib/libc/string/strsep.3116
-rw-r--r--src/lib/libc/string/strsep.c85
-rw-r--r--src/lib/libc/string/strsignal.360
-rw-r--r--src/lib/libc/string/strsignal.c49
-rw-r--r--src/lib/libc/string/strspn.388
-rw-r--r--src/lib/libc/string/strspn.c60
-rw-r--r--src/lib/libc/string/strstr.385
-rw-r--r--src/lib/libc/string/strstr.c64
-rw-r--r--src/lib/libc/string/strtok.3156
-rw-r--r--src/lib/libc/string/strtok.c99
-rw-r--r--src/lib/libc/string/strxfrm.366
-rw-r--r--src/lib/libc/string/strxfrm.c73
-rw-r--r--src/lib/libc/string/swab.365
-rw-r--r--src/lib/libc/string/swab.c65
255 files changed, 43438 insertions, 0 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc
new file mode 100644
index 0000000000..e64117fbd7
--- /dev/null
+++ b/src/lib/libc/crypt/Makefile.inc
@@ -0,0 +1,14 @@
1# $OpenBSD: Makefile.inc,v 1.13 1999/11/17 05:22:36 millert Exp $
2
3.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/crypt ${LIBCSRCDIR}/crypt
4
5SRCS+= cast.c crypt.c morecrypt.c md5crypt.c arc4random.c blowfish.c
6SRCS+= bcrypt.c skipjack.c
7
8MAN+= crypt.3 blowfish.3 arc4random.3
9MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_cipher.3
10MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3
11MLINKS+=blowfish.3 blf_dec.3 blowfish.3 blf_ecb_encrypt.3
12MLINKS+=blowfish.3 blf_ecb_decrypt.3 blowfish.3 blf_cbc_encrypt.3
13MLINKS+=blowfish.3 blf_cbc_decrypt.3
14MLINKS+=arc4random.3 arc4random_stir.3 arc4random.3 arc4random_addrandom.3
diff --git a/src/lib/libc/crypt/arc4random.3 b/src/lib/libc/crypt/arc4random.3
new file mode 100644
index 0000000000..d8e0f8cda6
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.3
@@ -0,0 +1,110 @@
1.\" $OpenBSD: arc4random.3,v 1.17 2000/12/21 14:07:41 aaron Exp $
2.\"
3.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by Niels Provos.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\" derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.\" Manual page, using -mandoc macros
32.\"
33.Dd April 15, 1997
34.Dt ARC4RANDOM 3
35.Os
36.Sh NAME
37.Nm arc4random ,
38.Nm arc4random_stir ,
39.Nm arc4random_addrandom
40.Nd arc4 random number generator
41.Sh SYNOPSIS
42.Fd #include <stdlib.h>
43.Ft u_int32_t
44.Fn arc4random "void"
45.Ft void
46.Fn arc4random_stir "void"
47.Ft void
48.Fn arc4random_addrandom "u_char *dat" "int datlen"
49.Sh DESCRIPTION
50The
51.Fn arc4random
52function provides a high quality 32-bit pseudo-random
53number very quickly.
54.Fn arc4random
55seeds itself on a regular basis from the kernel strong random number
56subsystem described in
57.Xr random 4 .
58On each call, an ARC4 generator is used to generate a new result.
59The
60.Fn arc4random
61function uses the ARC4 cipher key stream generator,
62which uses 8*8 8 bit S-Boxes.
63The S-Boxes can be in about (2**1700) states.
64.Pp
65.Fn arc4random
66fits into a middle ground not covered by other subsystems such as
67the strong, slow, and resource expensive random
68devices described in
69.Xr random 4
70versus the fast but poor quality interfaces described in
71.Xr rand 3 ,
72.Xr random 3 ,
73and
74.Xr drand48 3 .
75.Pp
76The
77.Fn arc4random_stir
78function reads data from
79.Pa /dev/arandom
80and uses it to permute the S-Boxes via
81.Fn arc4random_addrandom .
82.Pp
83There is no need to call
84.Fn arc4random_stir
85before using
86.Fn arc4random ,
87since
88.Fn arc4random
89automatically initializes itself.
90.Sh SEE ALSO
91.Xr rand 3 ,
92.Xr rand48 3 ,
93.Xr random 3
94.Sh HISTORY
95An algorithm called
96.Pa RC4
97was designed by RSA Data Security, Inc.
98It was considered a trade secret, but not trademarked.
99Because it was a trade secret, it obviously could not be patented.
100A clone of this was posted anonymously to USENET and confirmed to
101be equivalent by several sources who had access to the original cipher.
102Because of the trade secret situation, RSA Data Security, Inc. can do
103nothing about the release of the ARC4 algorithm.
104Since
105.Pa RC4
106used to be a trade secret, the cipher is now referred to as
107.Pa ARC4 .
108.Pp
109These functions first appeared in
110.Ox 2.1 .
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
new file mode 100644
index 0000000000..4e916ab99a
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.c
@@ -0,0 +1,193 @@
1/* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */
2
3/*
4 * Arc4 random number generator for OpenBSD.
5 * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
6 *
7 * Modification and redistribution in source and binary forms is
8 * permitted provided that due credit is given to the author and the
9 * OpenBSD project by leaving this copyright notice intact.
10 */
11
12/*
13 * This code is derived from section 17.1 of Applied Cryptography,
14 * second edition, which describes a stream cipher allegedly
15 * compatible with RSA Labs "RC4" cipher (the actual description of
16 * which is a trade secret). The same algorithm is used as a stream
17 * cipher called "arcfour" in Tatu Ylonen's ssh package.
18 *
19 * Here the stream cipher has been modified always to include the time
20 * when initializing the state. That makes it impossible to
21 * regenerate the same random sequence twice, so this can't be used
22 * for encryption, but will generate good random numbers.
23 *
24 * RC4 is a registered trademark of RSA Laboratories.
25 */
26
27#include <fcntl.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <sys/types.h>
31#include <sys/param.h>
32#include <sys/time.h>
33#include <sys/sysctl.h>
34
35#ifdef __GNUC__
36#define inline __inline
37#else /* !__GNUC__ */
38#define inline
39#endif /* !__GNUC__ */
40
41struct arc4_stream {
42 u_int8_t i;
43 u_int8_t j;
44 u_int8_t s[256];
45};
46
47int rs_initialized;
48static struct arc4_stream rs;
49
50static inline void
51arc4_init(as)
52 struct arc4_stream *as;
53{
54 int n;
55
56 for (n = 0; n < 256; n++)
57 as->s[n] = n;
58 as->i = 0;
59 as->j = 0;
60}
61
62static inline void
63arc4_addrandom(as, dat, datlen)
64 struct arc4_stream *as;
65 u_char *dat;
66 int datlen;
67{
68 int n;
69 u_int8_t si;
70
71 as->i--;
72 for (n = 0; n < 256; n++) {
73 as->i = (as->i + 1);
74 si = as->s[as->i];
75 as->j = (as->j + si + dat[n % datlen]);
76 as->s[as->i] = as->s[as->j];
77 as->s[as->j] = si;
78 }
79 as->j = as->i;
80}
81
82static void
83arc4_stir(as)
84 struct arc4_stream *as;
85{
86 int fd;
87 struct {
88 struct timeval tv;
89 u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)];
90 } rdat;
91
92 gettimeofday(&rdat.tv, NULL);
93 fd = open("/dev/arandom", O_RDONLY);
94 if (fd != -1) {
95 read(fd, rdat.rnd, sizeof(rdat.rnd));
96 close(fd);
97 } else {
98 int i, mib[2];
99 size_t len;
100
101 /* Device could not be opened, we might be chrooted, take
102 * randomness from sysctl. */
103
104 mib[0] = CTL_KERN;
105 mib[1] = KERN_ARND;
106
107 for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) {
108 len = sizeof(u_int);
109 if (sysctl(mib, 2, &rdat.rnd[i], &len, NULL, 0) == -1)
110 break;
111 }
112 }
113 /* fd < 0 or failed sysctl ? Ah, what the heck. We'll just take
114 * whatever was on the stack... */
115
116 arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
117}
118
119static inline u_int8_t
120arc4_getbyte(as)
121 struct arc4_stream *as;
122{
123 u_int8_t si, sj;
124
125 as->i = (as->i + 1);
126 si = as->s[as->i];
127 as->j = (as->j + si);
128 sj = as->s[as->j];
129 as->s[as->i] = sj;
130 as->s[as->j] = si;
131 return (as->s[(si + sj) & 0xff]);
132}
133
134static inline u_int32_t
135arc4_getword(as)
136 struct arc4_stream *as;
137{
138 u_int32_t val;
139 val = arc4_getbyte(as) << 24;
140 val |= arc4_getbyte(as) << 16;
141 val |= arc4_getbyte(as) << 8;
142 val |= arc4_getbyte(as);
143 return val;
144}
145
146void
147arc4random_stir()
148{
149 if (!rs_initialized) {
150 arc4_init(&rs);
151 rs_initialized = 1;
152 }
153 arc4_stir(&rs);
154}
155
156void
157arc4random_addrandom(dat, datlen)
158 u_char *dat;
159 int datlen;
160{
161 if (!rs_initialized)
162 arc4random_stir();
163 arc4_addrandom(&rs, dat, datlen);
164}
165
166u_int32_t
167arc4random()
168{
169 if (!rs_initialized)
170 arc4random_stir();
171 return arc4_getword(&rs);
172}
173
174#if 0
175/*-------- Test code for i386 --------*/
176#include <stdio.h>
177#include <machine/pctr.h>
178int
179main(int argc, char **argv)
180{
181 const int iter = 1000000;
182 int i;
183 pctrval v;
184
185 v = rdtsc();
186 for (i = 0; i < iter; i++)
187 arc4random();
188 v = rdtsc() - v;
189 v /= iter;
190
191 printf("%qd cycles\n", v);
192}
193#endif
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
new file mode 100644
index 0000000000..dec0093dd8
--- /dev/null
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -0,0 +1,334 @@
1/* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
2
3/*
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Niels Provos.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* This password hashing algorithm was designed by David Mazieres
34 * <dm@lcs.mit.edu> and works as follows:
35 *
36 * 1. state := InitState ()
37 * 2. state := ExpandKey (state, salt, password) 3.
38 * REPEAT rounds:
39 * state := ExpandKey (state, 0, salt)
40 * state := ExpandKey(state, 0, password)
41 * 4. ctext := "OrpheanBeholderScryDoubt"
42 * 5. REPEAT 64:
43 * ctext := Encrypt_ECB (state, ctext);
44 * 6. RETURN Concatenate (salt, ctext);
45 *
46 */
47
48#if 0
49#include <stdio.h>
50#endif
51
52#include <stdio.h>
53#include <stdlib.h>
54#include <sys/types.h>
55#include <string.h>
56#include <pwd.h>
57#include <blf.h>
58
59/* This implementation is adaptable to current computing power.
60 * You can have up to 2^31 rounds which should be enough for some
61 * time to come.
62 */
63
64#define BCRYPT_VERSION '2'
65#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
66#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
67#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
68
69char *bcrypt_gensalt(u_int8_t);
70
71static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
72static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
73static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
74
75static char encrypted[_PASSWORD_LEN];
76static char gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
77static char error[] = ":";
78
79const static u_int8_t Base64Code[] =
80"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
81
82const static u_int8_t index_64[128] =
83{
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
89 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
90 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
91 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
92 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
93 255, 255, 255, 255, 255, 255, 28, 29, 30,
94 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
95 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
96 51, 52, 53, 255, 255, 255, 255, 255
97};
98#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
99
100static void
101decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
102{
103 u_int8_t *bp = buffer;
104 u_int8_t *p = data;
105 u_int8_t c1, c2, c3, c4;
106 while (bp < buffer + len) {
107 c1 = CHAR64(*p);
108 c2 = CHAR64(*(p + 1));
109
110 /* Invalid data */
111 if (c1 == 255 || c2 == 255)
112 break;
113
114 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
115 if (bp >= buffer + len)
116 break;
117
118 c3 = CHAR64(*(p + 2));
119 if (c3 == 255)
120 break;
121
122 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
123 if (bp >= buffer + len)
124 break;
125
126 c4 = CHAR64(*(p + 3));
127 if (c4 == 255)
128 break;
129 *bp++ = ((c3 & 0x03) << 6) | c4;
130
131 p += 4;
132 }
133}
134
135static void
136encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
137{
138 salt[0] = '$';
139 salt[1] = BCRYPT_VERSION;
140 salt[2] = 'a';
141 salt[3] = '$';
142
143 snprintf(salt + 4, 4, "%2.2u$", logr);
144
145 encode_base64((u_int8_t *) salt + 7, csalt, clen);
146}
147/* Generates a salt for this version of crypt.
148 Since versions may change. Keeping this here
149 seems sensible.
150 */
151
152char *
153bcrypt_gensalt(u_int8_t log_rounds)
154{
155 u_int8_t csalt[BCRYPT_MAXSALT];
156 u_int16_t i;
157 u_int32_t seed = 0;
158
159 for (i = 0; i < BCRYPT_MAXSALT; i++) {
160 if (i % 4 == 0)
161 seed = arc4random();
162 csalt[i] = seed & 0xff;
163 seed = seed >> 8;
164 }
165
166 if (log_rounds < 4)
167 log_rounds = 4;
168
169 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
170 return gsalt;
171}
172/* We handle $Vers$log2(NumRounds)$salt+passwd$
173 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
174
175char *
176bcrypt(key, salt)
177 const char *key;
178 const char *salt;
179{
180 blf_ctx state;
181 u_int32_t rounds, i, k;
182 u_int16_t j;
183 u_int8_t key_len, salt_len, logr, minor;
184 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
185 u_int8_t csalt[BCRYPT_MAXSALT];
186 u_int32_t cdata[BCRYPT_BLOCKS];
187
188 /* Discard "$" identifier */
189 salt++;
190
191 if (*salt > BCRYPT_VERSION) {
192 /* How do I handle errors ? Return ':' */
193 return error;
194 }
195
196 /* Check for minor versions */
197 if (salt[1] != '$') {
198 switch (salt[1]) {
199 case 'a':
200 /* 'ab' should not yield the same as 'abab' */
201 minor = salt[1];
202 salt++;
203 break;
204 default:
205 return error;
206 }
207 } else
208 minor = 0;
209
210 /* Discard version + "$" identifier */
211 salt += 2;
212
213 if (salt[2] != '$')
214 /* Out of sync with passwd entry */
215 return error;
216
217 /* Computer power doesn't increase linear, 2^x should be fine */
218 if ((rounds = (u_int32_t) 1 << (logr = atoi(salt))) < BCRYPT_MINROUNDS)
219 return error;
220
221 /* Discard num rounds + "$" identifier */
222 salt += 3;
223
224 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
225 return error;
226
227 /* We dont want the base64 salt but the raw data */
228 decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
229 salt_len = BCRYPT_MAXSALT;
230 key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
231
232 /* Setting up S-Boxes and Subkeys */
233 Blowfish_initstate(&state);
234 Blowfish_expandstate(&state, csalt, salt_len,
235 (u_int8_t *) key, key_len);
236 for (k = 0; k < rounds; k++) {
237 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
238 Blowfish_expand0state(&state, csalt, salt_len);
239 }
240
241 /* This can be precomputed later */
242 j = 0;
243 for (i = 0; i < BCRYPT_BLOCKS; i++)
244 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
245
246 /* Now do the encryption */
247 for (k = 0; k < 64; k++)
248 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
249
250 for (i = 0; i < BCRYPT_BLOCKS; i++) {
251 ciphertext[4 * i + 3] = cdata[i] & 0xff;
252 cdata[i] = cdata[i] >> 8;
253 ciphertext[4 * i + 2] = cdata[i] & 0xff;
254 cdata[i] = cdata[i] >> 8;
255 ciphertext[4 * i + 1] = cdata[i] & 0xff;
256 cdata[i] = cdata[i] >> 8;
257 ciphertext[4 * i + 0] = cdata[i] & 0xff;
258 }
259
260
261 i = 0;
262 encrypted[i++] = '$';
263 encrypted[i++] = BCRYPT_VERSION;
264 if (minor)
265 encrypted[i++] = minor;
266 encrypted[i++] = '$';
267
268 snprintf(encrypted + i, 4, "%2.2u$", logr);
269
270 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
271 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
272 4 * BCRYPT_BLOCKS - 1);
273 return encrypted;
274}
275
276static void
277encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
278{
279 u_int8_t *bp = buffer;
280 u_int8_t *p = data;
281 u_int8_t c1, c2;
282 while (p < data + len) {
283 c1 = *p++;
284 *bp++ = Base64Code[(c1 >> 2)];
285 c1 = (c1 & 0x03) << 4;
286 if (p >= data + len) {
287 *bp++ = Base64Code[c1];
288 break;
289 }
290 c2 = *p++;
291 c1 |= (c2 >> 4) & 0x0f;
292 *bp++ = Base64Code[c1];
293 c1 = (c2 & 0x0f) << 2;
294 if (p >= data + len) {
295 *bp++ = Base64Code[c1];
296 break;
297 }
298 c2 = *p++;
299 c1 |= (c2 >> 6) & 0x03;
300 *bp++ = Base64Code[c1];
301 *bp++ = Base64Code[c2 & 0x3f];
302 }
303 *bp = '\0';
304}
305#if 0
306void
307main()
308{
309 char blubber[73];
310 char salt[100];
311 char *p;
312 salt[0] = '$';
313 salt[1] = BCRYPT_VERSION;
314 salt[2] = '$';
315
316 snprintf(salt + 3, 4, "%2.2u$", 5);
317
318 printf("24 bytes of salt: ");
319 fgets(salt + 6, 94, stdin);
320 salt[99] = 0;
321 printf("72 bytes of password: ");
322 fpurge(stdin);
323 fgets(blubber, 73, stdin);
324 blubber[72] = 0;
325
326 p = crypt(blubber, salt);
327 printf("Passwd entry: %s\n\n", p);
328
329 p = bcrypt_gensalt(5);
330 printf("Generated salt: %s\n", p);
331 p = crypt(blubber, p);
332 printf("Passwd entry: %s\n", p);
333}
334#endif
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3
new file mode 100644
index 0000000000..3e600658fa
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: blowfish.3,v 1.10 2001/08/06 10:42:25 mpech Exp $
2.\"
3.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by Niels Provos.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\" derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.\" Manual page, using -mandoc macros
32.\"
33.Dd February 13, 1997
34.Dt BLOWFISH 3
35.Os
36.Sh NAME
37.Nm blf_key ,
38.Nm blf_enc ,
39.Nm blf_dec
40.Nd Blowfish encryption
41.Sh SYNOPSIS
42.Fd #include <blf.h>
43.Ft void
44.Fn blf_key "blf_ctx *state" "const u_int8_t *key" "u_int16_t keylen"
45.Ft void
46.Fn blf_enc "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen"
47.Ft void
48.Fn blf_dec "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen"
49.Ft void
50.Fn blf_ecb_encrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
51.Ft void
52.Fn blf_ecb_decrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
53.Ft void
54.Fn blf_cbc_encrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
55.Ft void
56.Fn blf_cbc_decrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
57.Sh DESCRIPTION
58.Pa Blowfish
59is a fast unpatented block cipher designed by Bruce Schneier.
60It basically consists of a 16 times iterated Feistel network.
61The block size is 64 bit and the key size is maximal 448 bit.
62.Pp
63The
64.Fn blf_key
65function initializes the 4 8bit S-boxes and the 18 Subkeys with
66the hexadecimal digits of Pi.
67The key is used for further randomization.
68The first argument to
69.Fn blf_enc
70is the initialized state derived from
71.Fn blf_key .
72The stream of 32-bit words is encrypted in Electronic Codebook
73Mode (ECB) and
74.Pa datalen
75must be even.
76.Fn blf_dec
77is used for decrypting Blowfish encrypted blocks.
78.Pp
79The functions
80.Fn blf_ecb_encrypt
81and
82.Fn blf_ecb_decrypt
83are used for encrypting and decrypting octet streams in ECB mode.
84The functions
85.Fn blf_cbc_encrypt
86and
87.Fn blf_cbc_decrypt
88are used for encrypting and decrypting octet streams in
89Cipherblock Chaining Mode (CBC).
90.Pp
91The functions
92.Fn Blowfish_initstate ,
93.Fn Blowfish_expand0state ,
94.Fn Blowfish_expandstate ,
95.Fn Blowfish_encipher
96and
97.Fn Blowfish_decipher
98are used for customization of the
99.Pa Blowfish
100cipher, e.g., for the blowfish password hashing function.
101.Sh SEE ALSO
102.Xr passwd 1 ,
103.Xr crypt 3 ,
104.Xr passwd 5
105.Sh AUTHORS
106Niels Provos <provos@physnet.uni-hamburg.de>
diff --git a/src/lib/libc/crypt/blowfish.c b/src/lib/libc/crypt/blowfish.c
new file mode 100644
index 0000000000..8be04a6463
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.c
@@ -0,0 +1,694 @@
1/* $OpenBSD: blowfish.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
2/*
3 * Blowfish block cipher for OpenBSD
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Niels Provos.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * This code is derived from section 14.3 and the given source
37 * in section V of Applied Cryptography, second edition.
38 * Blowfish is an unpatented fast block cipher designed by
39 * Bruce Schneier.
40 */
41
42#if 0
43#include <stdio.h> /* used for debugging */
44#include <string.h>
45#endif
46
47#include <sys/types.h>
48#include <blf.h>
49
50#undef inline
51#ifdef __GNUC__
52#define inline __inline
53#else /* !__GNUC__ */
54#define inline
55#endif /* !__GNUC__ */
56
57/* Function for Feistel Networks */
58
59#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
60 + (s)[0x100 + (((x)>>16)&0xFF)]) \
61 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
62 + (s)[0x300 + ( (x) &0xFF)])
63
64#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
65
66void
67Blowfish_encipher(c, xl, xr)
68 blf_ctx *c;
69 u_int32_t *xl;
70 u_int32_t *xr;
71{
72 u_int32_t Xl;
73 u_int32_t Xr;
74 u_int32_t *s = c->S[0];
75 u_int32_t *p = c->P;
76
77 Xl = *xl;
78 Xr = *xr;
79
80 Xl ^= p[0];
81 BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
82 BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
83 BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
84 BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
85 BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
86 BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
87 BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
88 BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
89
90 *xl = Xr ^ p[17];
91 *xr = Xl;
92}
93
94void
95Blowfish_decipher(c, xl, xr)
96 blf_ctx *c;
97 u_int32_t *xl;
98 u_int32_t *xr;
99{
100 u_int32_t Xl;
101 u_int32_t Xr;
102 u_int32_t *s = c->S[0];
103 u_int32_t *p = c->P;
104
105 Xl = *xl;
106 Xr = *xr;
107
108 Xl ^= p[17];
109 BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
110 BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
111 BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
112 BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
113 BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
114 BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
115 BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
116 BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
117
118 *xl = Xr ^ p[0];
119 *xr = Xl;
120}
121
122void
123Blowfish_initstate(c)
124 blf_ctx *c;
125{
126
127/* P-box and S-box tables initialized with digits of Pi */
128
129 const blf_ctx initstate =
130
131 { {
132 {
133 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
134 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
135 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
136 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
137 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
138 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
139 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
140 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
141 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
142 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
143 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
144 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
145 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
146 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
147 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
148 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
149 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
150 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
151 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
152 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
153 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
154 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
155 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
156 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
157 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
158 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
159 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
160 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
161 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
162 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
163 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
164 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
165 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
166 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
167 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
168 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
169 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
170 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
171 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
172 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
173 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
174 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
175 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
176 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
177 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
178 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
179 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
180 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
181 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
182 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
183 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
184 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
185 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
186 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
187 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
188 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
189 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
190 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
191 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
192 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
193 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
194 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
195 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
196 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
197 {
198 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
199 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
200 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
201 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
202 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
203 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
204 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
205 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
206 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
207 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
208 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
209 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
210 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
211 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
212 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
213 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
214 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
215 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
216 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
217 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
218 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
219 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
220 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
221 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
222 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
223 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
224 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
225 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
226 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
227 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
228 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
229 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
230 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
231 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
232 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
233 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
234 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
235 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
236 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
237 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
238 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
239 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
240 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
241 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
242 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
243 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
244 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
245 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
246 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
247 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
248 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
249 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
250 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
251 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
252 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
253 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
254 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
255 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
256 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
257 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
258 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
259 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
260 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
261 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
262 {
263 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
264 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
265 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
266 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
267 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
268 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
269 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
270 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
271 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
272 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
273 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
274 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
275 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
276 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
277 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
278 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
279 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
280 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
281 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
282 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
283 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
284 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
285 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
286 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
287 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
288 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
289 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
290 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
291 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
292 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
293 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
294 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
295 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
296 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
297 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
298 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
299 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
300 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
301 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
302 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
303 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
304 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
305 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
306 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
307 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
308 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
309 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
310 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
311 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
312 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
313 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
314 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
315 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
316 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
317 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
318 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
319 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
320 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
321 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
322 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
323 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
324 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
325 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
326 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
327 {
328 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
329 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
330 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
331 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
332 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
333 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
334 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
335 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
336 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
337 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
338 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
339 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
340 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
341 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
342 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
343 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
344 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
345 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
346 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
347 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
348 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
349 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
350 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
351 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
352 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
353 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
354 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
355 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
356 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
357 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
358 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
359 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
360 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
361 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
362 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
363 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
364 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
365 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
366 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
367 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
368 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
369 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
370 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
371 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
372 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
373 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
374 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
375 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
376 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
377 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
378 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
379 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
380 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
381 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
382 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
383 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
384 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
385 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
386 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
387 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
388 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
389 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
390 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
391 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
392 },
393 {
394 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
395 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
396 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
397 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
398 0x9216d5d9, 0x8979fb1b
399 } };
400
401 *c = initstate;
402
403}
404
405u_int32_t
406Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current)
407{
408 u_int8_t i;
409 u_int16_t j;
410 u_int32_t temp;
411
412 temp = 0x00000000;
413 j = *current;
414
415 for (i = 0; i < 4; i++, j++) {
416 if (j >= databytes)
417 j = 0;
418 temp = (temp << 8) | data[j];
419 }
420
421 *current = j;
422 return temp;
423}
424
425void
426Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
427{
428 u_int16_t i;
429 u_int16_t j;
430 u_int16_t k;
431 u_int32_t temp;
432 u_int32_t datal;
433 u_int32_t datar;
434
435 j = 0;
436 for (i = 0; i < BLF_N + 2; i++) {
437 /* Extract 4 int8 to 1 int32 from keystream */
438 temp = Blowfish_stream2word(key, keybytes, &j);
439 c->P[i] = c->P[i] ^ temp;
440 }
441
442 j = 0;
443 datal = 0x00000000;
444 datar = 0x00000000;
445 for (i = 0; i < BLF_N + 2; i += 2) {
446 Blowfish_encipher(c, &datal, &datar);
447
448 c->P[i] = datal;
449 c->P[i + 1] = datar;
450 }
451
452 for (i = 0; i < 4; i++) {
453 for (k = 0; k < 256; k += 2) {
454 Blowfish_encipher(c, &datal, &datar);
455
456 c->S[i][k] = datal;
457 c->S[i][k + 1] = datar;
458 }
459 }
460}
461
462
463void
464Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
465 const u_int8_t *key, u_int16_t keybytes)
466{
467 u_int16_t i;
468 u_int16_t j;
469 u_int16_t k;
470 u_int32_t temp;
471 u_int32_t datal;
472 u_int32_t datar;
473
474 j = 0;
475 for (i = 0; i < BLF_N + 2; i++) {
476 /* Extract 4 int8 to 1 int32 from keystream */
477 temp = Blowfish_stream2word(key, keybytes, &j);
478 c->P[i] = c->P[i] ^ temp;
479 }
480
481 j = 0;
482 datal = 0x00000000;
483 datar = 0x00000000;
484 for (i = 0; i < BLF_N + 2; i += 2) {
485 datal ^= Blowfish_stream2word(data, databytes, &j);
486 datar ^= Blowfish_stream2word(data, databytes, &j);
487 Blowfish_encipher(c, &datal, &datar);
488
489 c->P[i] = datal;
490 c->P[i + 1] = datar;
491 }
492
493 for (i = 0; i < 4; i++) {
494 for (k = 0; k < 256; k += 2) {
495 datal ^= Blowfish_stream2word(data, databytes, &j);
496 datar ^= Blowfish_stream2word(data, databytes, &j);
497 Blowfish_encipher(c, &datal, &datar);
498
499 c->S[i][k] = datal;
500 c->S[i][k + 1] = datar;
501 }
502 }
503
504}
505
506void
507blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
508{
509 /* Initialize S-boxes and subkeys with Pi */
510 Blowfish_initstate(c);
511
512 /* Transform S-boxes and subkeys with key */
513 Blowfish_expand0state(c, k, len);
514}
515
516void
517blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
518{
519 u_int32_t *d;
520 u_int16_t i;
521
522 d = data;
523 for (i = 0; i < blocks; i++) {
524 Blowfish_encipher(c, d, d + 1);
525 d += 2;
526 }
527}
528
529void
530blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
531{
532 u_int32_t *d;
533 u_int16_t i;
534
535 d = data;
536 for (i = 0; i < blocks; i++) {
537 Blowfish_decipher(c, d, d + 1);
538 d += 2;
539 }
540}
541
542void
543blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
544{
545 u_int32_t l, r;
546 u_int32_t i;
547
548 for (i = 0; i < len; i += 8) {
549 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
550 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
551 Blowfish_encipher(c, &l, &r);
552 data[0] = l >> 24 & 0xff;
553 data[1] = l >> 16 & 0xff;
554 data[2] = l >> 8 & 0xff;
555 data[3] = l & 0xff;
556 data[4] = r >> 24 & 0xff;
557 data[5] = r >> 16 & 0xff;
558 data[6] = r >> 8 & 0xff;
559 data[7] = r & 0xff;
560 data += 8;
561 }
562}
563
564void
565blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
566{
567 u_int32_t l, r;
568 u_int32_t i;
569
570 for (i = 0; i < len; i += 8) {
571 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
572 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
573 Blowfish_decipher(c, &l, &r);
574 data[0] = l >> 24 & 0xff;
575 data[1] = l >> 16 & 0xff;
576 data[2] = l >> 8 & 0xff;
577 data[3] = l & 0xff;
578 data[4] = r >> 24 & 0xff;
579 data[5] = r >> 16 & 0xff;
580 data[6] = r >> 8 & 0xff;
581 data[7] = r & 0xff;
582 data += 8;
583 }
584}
585
586void
587blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
588{
589 u_int32_t l, r;
590 u_int32_t i, j;
591
592 for (i = 0; i < len; i += 8) {
593 for (j = 0; j < 8; j++)
594 data[j] ^= iv[j];
595 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
596 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
597 Blowfish_encipher(c, &l, &r);
598 data[0] = l >> 24 & 0xff;
599 data[1] = l >> 16 & 0xff;
600 data[2] = l >> 8 & 0xff;
601 data[3] = l & 0xff;
602 data[4] = r >> 24 & 0xff;
603 data[5] = r >> 16 & 0xff;
604 data[6] = r >> 8 & 0xff;
605 data[7] = r & 0xff;
606 iv = data;
607 data += 8;
608 }
609}
610
611void
612blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
613{
614 u_int32_t l, r;
615 u_int8_t *iv;
616 u_int32_t i, j;
617
618 iv = data + len - 16;
619 data = data + len - 8;
620 for (i = len - 8; i >= 8; i -= 8) {
621 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
622 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
623 Blowfish_decipher(c, &l, &r);
624 data[0] = l >> 24 & 0xff;
625 data[1] = l >> 16 & 0xff;
626 data[2] = l >> 8 & 0xff;
627 data[3] = l & 0xff;
628 data[4] = r >> 24 & 0xff;
629 data[5] = r >> 16 & 0xff;
630 data[6] = r >> 8 & 0xff;
631 data[7] = r & 0xff;
632 for (j = 0; j < 8; j++)
633 data[j] ^= iv[j];
634 iv -= 8;
635 data -= 8;
636 }
637 l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
638 r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
639 Blowfish_decipher(c, &l, &r);
640 data[0] = l >> 24 & 0xff;
641 data[1] = l >> 16 & 0xff;
642 data[2] = l >> 8 & 0xff;
643 data[3] = l & 0xff;
644 data[4] = r >> 24 & 0xff;
645 data[5] = r >> 16 & 0xff;
646 data[6] = r >> 8 & 0xff;
647 data[7] = r & 0xff;
648 for (j = 0; j < 8; j++)
649 data[j] ^= iva[j];
650}
651
652#if 0
653void
654report(u_int32_t data[], u_int16_t len)
655{
656 u_int16_t i;
657 for (i = 0; i < len; i += 2)
658 printf("Block %0hd: %08lx %08lx.\n",
659 i / 2, data[i], data[i + 1]);
660}
661void
662main(void)
663{
664
665 blf_ctx c;
666 char key[] = "AAAAA";
667 char key2[] = "abcdefghijklmnopqrstuvwxyz";
668
669 u_int32_t data[10];
670 u_int32_t data2[] =
671 {0x424c4f57l, 0x46495348l};
672
673 u_int16_t i;
674
675 /* First test */
676 for (i = 0; i < 10; i++)
677 data[i] = i;
678
679 blf_key(&c, (u_int8_t *) key, 5);
680 blf_enc(&c, data, 5);
681 blf_dec(&c, data, 1);
682 blf_dec(&c, data + 2, 4);
683 printf("Should read as 0 - 9.\n");
684 report(data, 10);
685
686 /* Second test */
687 blf_key(&c, (u_int8_t *) key2, strlen(key2));
688 blf_enc(&c, data2, 1);
689 printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
690 report(data2, 2);
691 blf_dec(&c, data2, 1);
692 report(data2, 2);
693}
694#endif
diff --git a/src/lib/libc/crypt/cast.c b/src/lib/libc/crypt/cast.c
new file mode 100644
index 0000000000..264138f03e
--- /dev/null
+++ b/src/lib/libc/crypt/cast.c
@@ -0,0 +1,779 @@
1/* $OpenBSD: cast.c,v 1.2 1998/07/21 22:42:03 provos Exp $ */
2/*
3 * CAST-128 in C
4 * Written by Steve Reid <sreid@sea-to-sky.net>
5 * 100% Public Domain - no warranty
6 * Released 1997.10.11
7 */
8
9#include <sys/types.h>
10
11#include <cast.h>
12
13/* CAST S-Boxes */
14
15static const u_int32_t cast_sbox1[256] = {
16 0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A,
17 0x1E213F2F, 0x9C004DD3, 0x6003E540, 0xCF9FC949,
18 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
19 0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E,
20 0x28683B6F, 0xC07FD059, 0xFF2379C8, 0x775F50E2,
21 0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
22 0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
23 0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
24 0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
25 0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
26 0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
27 0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
28 0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
29 0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
30 0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
31 0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
32 0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
33 0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
34 0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
35 0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
36 0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
37 0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
38 0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
39 0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
40 0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
41 0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
42 0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
43 0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
44 0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
45 0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
46 0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
47 0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
48 0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
49 0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
50 0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
51 0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
52 0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
53 0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
54 0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
55 0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
56 0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
57 0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
58 0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
59 0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
60 0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
61 0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
62 0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
63 0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
64 0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
65 0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
66 0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
67 0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
68 0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
69 0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
70 0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
71 0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
72 0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
73 0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
74 0x474D6AD7, 0x7C0C5E5C, 0xD1231959, 0x381B7298,
75 0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
76 0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571,
77 0x962BDA1C, 0xE1E696FF, 0xB141AB08, 0x7CCA89B9,
78 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
79 0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF
80};
81
82static const u_int32_t cast_sbox2[256] = {
83 0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380,
84 0xFE61CF7A, 0xEEC5207A, 0x55889C94, 0x72FC0651,
85 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
86 0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3,
87 0xA0B52F7B, 0x59E83605, 0xEE15B094, 0xE9FFD909,
88 0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
89 0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
90 0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
91 0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
92 0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
93 0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
94 0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
95 0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
96 0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
97 0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
98 0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
99 0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
100 0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
101 0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
102 0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
103 0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
104 0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
105 0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
106 0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
107 0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
108 0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
109 0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
110 0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
111 0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
112 0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
113 0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
114 0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
115 0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
116 0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
117 0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
118 0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
119 0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
120 0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
121 0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
122 0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
123 0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
124 0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
125 0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
126 0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
127 0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
128 0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
129 0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
130 0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
131 0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
132 0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
133 0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
134 0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
135 0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
136 0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
137 0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
138 0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
139 0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
140 0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
141 0xB284600C, 0xD835731D, 0xDCB1C647, 0xAC4C56EA,
142 0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
143 0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD,
144 0x649DA589, 0xA345415E, 0x5C038323, 0x3E5D3BB9,
145 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
146 0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1
147};
148
149static const u_int32_t cast_sbox3[256] = {
150 0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907,
151 0x47607FFF, 0x369FE44B, 0x8C1FC644, 0xAECECA90,
152 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
153 0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5,
154 0x11107D9F, 0x07647DB9, 0xB2E3E4D4, 0x3D4F285E,
155 0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
156 0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
157 0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
158 0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
159 0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
160 0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
161 0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
162 0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
163 0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
164 0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
165 0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
166 0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
167 0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
168 0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
169 0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
170 0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
171 0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
172 0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
173 0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
174 0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
175 0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
176 0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
177 0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
178 0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
179 0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
180 0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
181 0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
182 0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
183 0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
184 0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
185 0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
186 0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
187 0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
188 0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
189 0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
190 0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
191 0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
192 0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
193 0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
194 0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
195 0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
196 0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
197 0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
198 0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
199 0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
200 0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
201 0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
202 0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
203 0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
204 0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
205 0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
206 0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
207 0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
208 0x5727C148, 0x2BE98A1D, 0x8AB41738, 0x20E1BE24,
209 0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
210 0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0,
211 0x642B1E31, 0x9C305A00, 0x52BCE688, 0x1B03588A,
212 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
213 0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783
214};
215
216static const u_int32_t cast_sbox4[256] = {
217 0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298,
218 0x4A4F7BDB, 0x64AD8C57, 0x85510443, 0xFA020ED1,
219 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
220 0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF,
221 0x28147F5F, 0x4FA2B8CD, 0xC9430040, 0x0CC32220,
222 0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
223 0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
224 0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
225 0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
226 0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
227 0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
228 0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
229 0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
230 0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
231 0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
232 0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
233 0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
234 0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
235 0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
236 0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
237 0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
238 0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
239 0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
240 0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
241 0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
242 0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
243 0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
244 0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
245 0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
246 0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
247 0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
248 0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
249 0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
250 0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
251 0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
252 0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
253 0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
254 0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
255 0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
256 0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
257 0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
258 0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
259 0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
260 0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
261 0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
262 0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
263 0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
264 0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
265 0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
266 0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
267 0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
268 0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
269 0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
270 0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
271 0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
272 0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
273 0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
274 0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
275 0xB5676E69, 0x9BD3DDDA, 0xDF7E052F, 0xDB25701C,
276 0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
277 0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43,
278 0x41823979, 0x932BCDF6, 0xB657C34D, 0x4EDFD282,
279 0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
280 0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2
281};
282
283static const u_int32_t cast_sbox5[256] = {
284 0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
285 0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
286 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
287 0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
288 0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
289 0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
290 0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
291 0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
292 0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
293 0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
294 0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
295 0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
296 0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
297 0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
298 0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
299 0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
300 0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
301 0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
302 0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
303 0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
304 0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
305 0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
306 0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
307 0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
308 0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
309 0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
310 0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
311 0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
312 0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
313 0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
314 0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
315 0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
316 0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
317 0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
318 0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
319 0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
320 0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
321 0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
322 0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
323 0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
324 0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
325 0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
326 0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
327 0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
328 0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
329 0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
330 0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
331 0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
332 0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
333 0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
334 0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
335 0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
336 0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
337 0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
338 0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
339 0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
340 0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
341 0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
342 0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
343 0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
344 0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
345 0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
346 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
347 0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
348};
349
350static const u_int32_t cast_sbox6[256] = {
351 0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
352 0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
353 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
354 0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
355 0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
356 0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
357 0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
358 0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
359 0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
360 0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
361 0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
362 0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
363 0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
364 0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
365 0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
366 0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
367 0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
368 0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
369 0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
370 0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
371 0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
372 0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
373 0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
374 0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
375 0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
376 0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
377 0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
378 0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
379 0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
380 0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
381 0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
382 0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
383 0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
384 0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
385 0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
386 0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
387 0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
388 0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
389 0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
390 0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
391 0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
392 0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
393 0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
394 0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
395 0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
396 0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
397 0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
398 0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
399 0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
400 0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
401 0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
402 0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
403 0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
404 0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
405 0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
406 0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
407 0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
408 0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
409 0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
410 0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
411 0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
412 0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
413 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
414 0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
415};
416
417static const u_int32_t cast_sbox7[256] = {
418 0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
419 0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
420 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
421 0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
422 0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
423 0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
424 0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
425 0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
426 0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
427 0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
428 0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
429 0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
430 0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
431 0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
432 0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
433 0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
434 0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
435 0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
436 0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
437 0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
438 0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
439 0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
440 0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
441 0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
442 0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
443 0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
444 0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
445 0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
446 0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
447 0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
448 0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
449 0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
450 0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
451 0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
452 0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
453 0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
454 0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
455 0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
456 0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
457 0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
458 0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
459 0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
460 0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
461 0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
462 0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
463 0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
464 0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
465 0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
466 0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
467 0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
468 0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
469 0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
470 0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
471 0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
472 0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
473 0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
474 0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
475 0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
476 0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
477 0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
478 0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
479 0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
480 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
481 0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
482};
483
484static const u_int32_t cast_sbox8[256] = {
485 0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
486 0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
487 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
488 0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
489 0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
490 0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
491 0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
492 0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
493 0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
494 0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
495 0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
496 0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
497 0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
498 0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
499 0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
500 0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
501 0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
502 0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
503 0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
504 0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
505 0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
506 0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
507 0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
508 0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
509 0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
510 0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
511 0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
512 0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
513 0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
514 0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
515 0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
516 0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
517 0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
518 0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
519 0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
520 0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
521 0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
522 0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
523 0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
524 0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
525 0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
526 0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
527 0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
528 0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
529 0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
530 0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
531 0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
532 0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
533 0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
534 0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
535 0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
536 0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
537 0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
538 0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
539 0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
540 0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
541 0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
542 0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
543 0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
544 0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
545 0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
546 0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
547 0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
548 0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
549};
550
551/* Macros to access 8-bit bytes out of a 32-bit word */
552#define U8a(x) ( (u_int8_t) (x>>24) )
553#define U8b(x) ( (u_int8_t) ((x>>16)&255) )
554#define U8c(x) ( (u_int8_t) ((x>>8)&255) )
555#define U8d(x) ( (u_int8_t) ((x)&255) )
556
557/* Circular left shift */
558#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
559
560/* CAST-128 uses three different round functions */
561#define F1(l, r, i) \
562 t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
563 l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) - \
564 cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
565#define F2(l, r, i) \
566 t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
567 l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) + \
568 cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
569#define F3(l, r, i) \
570 t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
571 l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) ^ \
572 cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
573
574
575/***** Encryption Function *****/
576
577void cast_encrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
578{
579u_int32_t t, l, r;
580
581 /* Get inblock into l,r */
582 l = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
583 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
584 r = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
585 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
586 /* Do the work */
587 F1(l, r, 0);
588 F2(r, l, 1);
589 F3(l, r, 2);
590 F1(r, l, 3);
591 F2(l, r, 4);
592 F3(r, l, 5);
593 F1(l, r, 6);
594 F2(r, l, 7);
595 F3(l, r, 8);
596 F1(r, l, 9);
597 F2(l, r, 10);
598 F3(r, l, 11);
599 /* Only do full 16 rounds if key length > 80 bits */
600 if (key->rounds > 12) {
601 F1(l, r, 12);
602 F2(r, l, 13);
603 F3(l, r, 14);
604 F1(r, l, 15);
605 }
606 /* Put l,r into outblock */
607 outblock[0] = U8a(r);
608 outblock[1] = U8b(r);
609 outblock[2] = U8c(r);
610 outblock[3] = U8d(r);
611 outblock[4] = U8a(l);
612 outblock[5] = U8b(l);
613 outblock[6] = U8c(l);
614 outblock[7] = U8d(l);
615 /* Wipe clean */
616 t = l = r = 0;
617}
618
619
620/***** Decryption Function *****/
621
622void cast_decrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
623{
624u_int32_t t, l, r;
625
626 /* Get inblock into l,r */
627 r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
628 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
629 l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
630 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
631 /* Do the work */
632 /* Only do full 16 rounds if key length > 80 bits */
633 if (key->rounds > 12) {
634 F1(r, l, 15);
635 F3(l, r, 14);
636 F2(r, l, 13);
637 F1(l, r, 12);
638 }
639 F3(r, l, 11);
640 F2(l, r, 10);
641 F1(r, l, 9);
642 F3(l, r, 8);
643 F2(r, l, 7);
644 F1(l, r, 6);
645 F3(r, l, 5);
646 F2(l, r, 4);
647 F1(r, l, 3);
648 F3(l, r, 2);
649 F2(r, l, 1);
650 F1(l, r, 0);
651 /* Put l,r into outblock */
652 outblock[0] = U8a(l);
653 outblock[1] = U8b(l);
654 outblock[2] = U8c(l);
655 outblock[3] = U8d(l);
656 outblock[4] = U8a(r);
657 outblock[5] = U8b(r);
658 outblock[6] = U8c(r);
659 outblock[7] = U8d(r);
660 /* Wipe clean */
661 t = l = r = 0;
662}
663
664
665/***** Key Schedual *****/
666
667void cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes)
668{
669u_int32_t t[4], z[4], x[4];
670int i;
671
672 /* Set number of rounds to 12 or 16, depending on key length */
673 key->rounds = (keybytes <= 10 ? 12 : 16);
674
675 /* Copy key to workspace x */
676 for (i = 0; i < 4; i++) {
677 x[i] = 0;
678 if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
679 if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
680 if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
681 if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
682 }
683 /* Generate 32 subkeys, four at a time */
684 for (i = 0; i < 32; i+=4) {
685 switch (i & 4) {
686 case 0:
687 t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])] ^
688 cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])] ^
689 cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])];
690 t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])] ^
691 cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])] ^
692 cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])];
693 t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])] ^
694 cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])] ^
695 cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])];
696 t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^
697 cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])] ^
698 cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])];
699 break;
700 case 4:
701 t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])] ^
702 cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])] ^
703 cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])];
704 t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])] ^
705 cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])] ^
706 cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])];
707 t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])] ^
708 cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])] ^
709 cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])];
710 t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])] ^
711 cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])] ^
712 cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])];
713 break;
714 }
715 switch (i & 12) {
716 case 0:
717 case 12:
718 key->xkey[i+0] = cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])] ^
719 cast_sbox7[U8d(t[1])] ^ cast_sbox8[U8c(t[1])];
720 key->xkey[i+1] = cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])] ^
721 cast_sbox7[U8b(t[1])] ^ cast_sbox8[U8a(t[1])];
722 key->xkey[i+2] = cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])] ^
723 cast_sbox7[U8d(t[0])] ^ cast_sbox8[U8c(t[0])];
724 key->xkey[i+3] = cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])] ^
725 cast_sbox7[U8b(t[0])] ^ cast_sbox8[U8a(t[0])];
726 break;
727 case 4:
728 case 8:
729 key->xkey[i+0] = cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])] ^
730 cast_sbox7[U8a(t[3])] ^ cast_sbox8[U8b(t[3])];
731 key->xkey[i+1] = cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])] ^
732 cast_sbox7[U8c(t[3])] ^ cast_sbox8[U8d(t[3])];
733 key->xkey[i+2] = cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])] ^
734 cast_sbox7[U8a(t[2])] ^ cast_sbox8[U8b(t[2])];
735 key->xkey[i+3] = cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])] ^
736 cast_sbox7[U8c(t[2])] ^ cast_sbox8[U8d(t[2])];
737 break;
738 }
739 switch (i & 12) {
740 case 0:
741 key->xkey[i+0] ^= cast_sbox5[U8c(z[0])];
742 key->xkey[i+1] ^= cast_sbox6[U8c(z[1])];
743 key->xkey[i+2] ^= cast_sbox7[U8b(z[2])];
744 key->xkey[i+3] ^= cast_sbox8[U8a(z[3])];
745 break;
746 case 4:
747 key->xkey[i+0] ^= cast_sbox5[U8a(x[2])];
748 key->xkey[i+1] ^= cast_sbox6[U8b(x[3])];
749 key->xkey[i+2] ^= cast_sbox7[U8d(x[0])];
750 key->xkey[i+3] ^= cast_sbox8[U8d(x[1])];
751 break;
752 case 8:
753 key->xkey[i+0] ^= cast_sbox5[U8b(z[2])];
754 key->xkey[i+1] ^= cast_sbox6[U8a(z[3])];
755 key->xkey[i+2] ^= cast_sbox7[U8c(z[0])];
756 key->xkey[i+3] ^= cast_sbox8[U8c(z[1])];
757 break;
758 case 12:
759 key->xkey[i+0] ^= cast_sbox5[U8d(x[0])];
760 key->xkey[i+1] ^= cast_sbox6[U8d(x[1])];
761 key->xkey[i+2] ^= cast_sbox7[U8a(x[2])];
762 key->xkey[i+3] ^= cast_sbox8[U8b(x[3])];
763 break;
764 }
765 if (i >= 16) {
766 key->xkey[i+0] &= 31;
767 key->xkey[i+1] &= 31;
768 key->xkey[i+2] &= 31;
769 key->xkey[i+3] &= 31;
770 }
771 }
772 /* Wipe clean */
773 for (i = 0; i < 4; i++) {
774 t[i] = x[i] = z[i] = 0;
775 }
776}
777
778/* Made in Canada */
779
diff --git a/src/lib/libc/crypt/crypt.3 b/src/lib/libc/crypt/crypt.3
new file mode 100644
index 0000000000..5f0f1cdba8
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.3
@@ -0,0 +1,314 @@
1.\" $OpenBSD: crypt.3,v 1.19 2002/01/24 20:33:45 mickey Exp $
2.\"
3.\" FreeSec: libcrypt
4.\"
5.\" Copyright (c) 1994 David Burren
6.\" All rights reserved.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 4. Neither the name of the author nor the names of other contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" Manual page, using -mandoc macros
33.\"
34.Dd March 9, 1994
35.Dt CRYPT 3
36.Os
37.Sh NAME
38.Nm crypt ,
39.Nm setkey ,
40.Nm encrypt ,
41.Nm des_setkey ,
42.Nm des_cipher
43.Nd DES encryption
44.Sh SYNOPSIS
45.Fd #include <unistd.h>
46.Ft char *
47.Fn crypt "const char *key" "const char *setting"
48.Ft int
49.Fn setkey "char *key"
50.Ft int
51.Fn encrypt "char *block" "int flag"
52.Ft int
53.Fn des_setkey "const char *key"
54.Ft int
55.Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count"
56.Sh DESCRIPTION
57The
58.Fn crypt
59function performs password encryption based on the
60.Tn NBS
61Data Encryption Standard (DES).
62Additional code has been added to deter key search attempts and to use
63stronger hashing algorithms.
64.Pp
65The first argument to
66.Fn crypt
67is a
68.Dv null Ns -terminated
69string, typically a user's typed password.
70The second is in one of three forms:
71if it begins with an underscore
72.Pq Ql _
73then an extended format is used
74in interpreting both the key and the setting, as outlined below.
75If it begins
76with a string character
77.Pq Ql $
78and a number then a different algorithm is used depending on the number.
79At the moment a
80.Ql $1
81chooses MD5 hashing and a
82.Ql $2
83chooses Blowfish hashing; see below for more information.
84.Ss Extended crypt
85The
86.Ar key
87is divided into groups of 8 characters (the last group is null-padded)
88and the low-order 7 bits of each character (56 bits per group) are
89used to form the DES key as follows:
90the first group of 56 bits becomes the initial DES key.
91For each additional group, the XOR of the encryption of the current DES
92key with itself and the group bits becomes the next DES key.
93.Pp
94The setting is a 9-character array consisting of an underscore followed
95by 4 bytes of iteration count and 4 bytes of salt.
96These are encoded as printable characters, 6 bits per character,
97least significant character first.
98The values 0 to 63 are encoded as
99.Dq \&./0-9A-Za-z .
100This allows 24 bits for both
101.Fa count
102and
103.Fa salt .
104.Ss "MD5" crypt
105For
106.Tn MD5
107crypt the version number,
108.Fa salt
109and the hashed password are separated by the
110.Ql $
111character.
112The maximum length of a password is limited by
113the length counter of the MD5 context, which is about
1142**64.
115A valid MD5 password entry looks like this:
116.Pp
117.Dq $1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1 .
118.Pp
119The whole MD5 password string is passed as
120.Fa setting
121for interpretation.
122.Ss "Blowfish" crypt
123The
124.Tn Blowfish
125version of crypt has 128 bits of
126.Fa salt
127in order to make building dictionaries of common passwords space consuming.
128The initial state of the
129.Tn Blowfish
130cipher is expanded using the
131.Fa salt
132and the
133.Fa password
134repeating the process a variable number of rounds, which is encoded in
135the password string.
136The maximum password length is 72.
137The final Blowfish password entry is created by encrypting the string
138.Pp
139.Dq OrpheanBeholderScryDoubt
140.Pp
141with the
142.Tn Blowfish
143state 64 times.
144.Pp
145The version number, the logarithm of the number of rounds and
146the concatenation of salt and hashed password are separated by the
147.Ql $
148character.
149An encoded
150.Sq 8
151would specify 256 rounds.
152A valid Blowfish password looks like this:
153.Pp
154.Dq $2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC .
155.Pp
156The whole Blowfish password string is passed as
157.Fa setting
158for interpretation.
159.Ss "Traditional" crypt
160The first 8 bytes of the key are null-padded, and the low-order 7 bits of
161each character is used to form the 56-bit
162.Tn DES
163key.
164.Pp
165The setting is a 2-character array of the ASCII-encoded salt.
166Thus only 12 bits of
167.Fa salt
168are used.
169.Fa count
170is set to 25.
171.Ss DES Algorithm
172The
173.Fa salt
174introduces disorder in the
175.Tn DES
176algorithm in one of 16777216 or 4096 possible ways
177(i.e., with 24 or 12 bits: if bit
178.Em i
179of the
180.Ar salt
181is set, then bits
182.Em i
183and
184.Em i+24
185are swapped in the
186.Tn DES
187E-box output).
188.Pp
189The DES key is used to encrypt a 64-bit constant using
190.Ar count
191iterations of
192.Tn DES .
193The value returned is a
194.Dv null Ns -terminated
195string, 20 or 13 bytes (plus null) in length, consisting of the
196.Ar setting
197followed by the encoded 64-bit encryption.
198.Pp
199The functions
200.Fn encrypt ,
201.Fn setkey ,
202.Fn des_setkey ,
203and
204.Fn des_cipher
205provide access to the
206.Tn DES
207algorithm itself.
208.Fn setkey
209is passed a 64-byte array of binary values (numeric 0 or 1).
210A 56-bit key is extracted from this array by dividing the
211array into groups of 8, and ignoring the last bit in each group.
212That bit is reserved for a byte parity check by DES, but is ignored
213by these functions.
214.Pp
215The
216.Fa block
217argument to
218.Fn encrypt
219is also a 64-byte array of binary values.
220If the value of
221.Fa flag
222is 0,
223.Fa block
224is encrypted otherwise it is decrypted.
225The result is returned in the original array
226.Fa block
227after using the key specified by
228.Fn setkey
229to process it.
230.Pp
231The argument to
232.Fn des_setkey
233is a character array of length 8.
234The least significant bit (the parity bit) in each character is ignored,
235and the remaining bits are concatenated to form a 56-bit key.
236The function
237.Fn des_cipher
238encrypts (or decrypts if
239.Fa count
240is negative) the 64-bits stored in the 8 characters at
241.Fa in
242using
243.Xr abs 3
244of
245.Fa count
246iterations of
247.Tn DES
248and stores the 64-bit result in the 8 characters at
249.Fa out
250(which may be the same as
251.Fa in ) .
252The
253.Fa salt
254specifies perturbations to the
255.Tn DES
256E-box output as described above.
257.Pp
258The function
259.Fn crypt
260returns a pointer to the encrypted value on success, and
261.Dv NULL
262on failure.
263The functions
264.Fn setkey ,
265.Fn encrypt ,
266.Fn des_setkey ,
267and
268.Fn des_cipher
269return 0 on success and 1 on failure.
270.Pp
271The
272.Fn crypt ,
273.Fn setkey ,
274and
275.Fn des_setkey
276functions all manipulate the same key space.
277.Sh SEE ALSO
278.Xr login 1 ,
279.Xr passwd 1 ,
280.Xr blowfish 3 ,
281.Xr getpass 3 ,
282.Xr md5 3 ,
283.Xr passwd 5
284.Sh AUTHORS
285David Burren <davidb@werj.com.au>
286.Sh HISTORY
287A rotor-based
288.Fn crypt
289function appeared in
290.At v3 .
291The current style
292.Fn crypt
293first appeared in
294.At v7 .
295.Pp
296This library (FreeSec 1.0) was developed outside the United States of America
297as an unencumbered replacement for the U.S.-only libcrypt encryption
298library.
299Programs linked against the
300.Fn crypt
301interface may be exported from the U.S.A. only if they use
302.Fn crypt
303solely for authentication purposes and avoid use of
304the other programmer interfaces listed above.
305Special care has been taken
306in the library so that programs which only use the
307.Fn crypt
308interface do not pull in the other components.
309.Sh BUGS
310The
311.Fn crypt
312function returns a pointer to static data, and subsequent calls to
313.Fn crypt
314will modify the same object.
diff --git a/src/lib/libc/crypt/crypt.c b/src/lib/libc/crypt/crypt.c
new file mode 100644
index 0000000000..17b50b7f52
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.c
@@ -0,0 +1,713 @@
1/* $OpenBSD: crypt.c,v 1.16 2002/04/29 06:26:50 pvalchev Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 *
48 * NOTE:
49 * This file has a static version of des_setkey() so that crypt.o exports
50 * only the crypt() interface. This is required to make binaries linked
51 * against crypt.o exportable or re-exportable from the USA.
52 */
53
54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: crypt.c,v 1.16 2002/04/29 06:26:50 pvalchev Exp $";
56#endif /* LIBC_SCCS and not lint */
57
58#include <sys/types.h>
59#include <sys/param.h>
60#include <pwd.h>
61#include <string.h>
62
63#ifdef DEBUG
64# include <stdio.h>
65#endif
66
67static u_char IP[64] = {
68 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
69 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
70 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
71 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
72};
73
74static u_char inv_key_perm[64];
75static u_char u_key_perm[56];
76static u_char key_perm[56] = {
77 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
78 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
79 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
80 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
81};
82
83static u_char key_shifts[16] = {
84 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
85};
86
87static u_char inv_comp_perm[56];
88static u_char comp_perm[48] = {
89 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
90 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
91 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
92 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
93};
94
95/*
96 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
97 */
98
99static u_char u_sbox[8][64];
100static u_char sbox[8][64] = {
101 {
102 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
103 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
104 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
105 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
106 },
107 {
108 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
109 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
110 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
111 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
112 },
113 {
114 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
115 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
116 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
117 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
118 },
119 {
120 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
121 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
122 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
123 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
124 },
125 {
126 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
127 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
128 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
129 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
130 },
131 {
132 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
133 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
134 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
135 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
136 },
137 {
138 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
139 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
140 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
141 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
142 },
143 {
144 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
145 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
146 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
147 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
148 }
149};
150
151static u_char un_pbox[32];
152static u_char pbox[32] = {
153 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
154 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
155};
156
157static u_int32_t bits32[32] =
158{
159 0x80000000, 0x40000000, 0x20000000, 0x10000000,
160 0x08000000, 0x04000000, 0x02000000, 0x01000000,
161 0x00800000, 0x00400000, 0x00200000, 0x00100000,
162 0x00080000, 0x00040000, 0x00020000, 0x00010000,
163 0x00008000, 0x00004000, 0x00002000, 0x00001000,
164 0x00000800, 0x00000400, 0x00000200, 0x00000100,
165 0x00000080, 0x00000040, 0x00000020, 0x00000010,
166 0x00000008, 0x00000004, 0x00000002, 0x00000001
167};
168
169static u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
170
171static u_int32_t saltbits;
172static int32_t old_salt;
173static u_int32_t *bits28, *bits24;
174static u_char init_perm[64], final_perm[64];
175static u_int32_t en_keysl[16], en_keysr[16];
176static u_int32_t de_keysl[16], de_keysr[16];
177static int des_initialised = 0;
178static u_char m_sbox[4][4096];
179static u_int32_t psbox[4][256];
180static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
181static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
182static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
183static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
184static u_int32_t old_rawkey0, old_rawkey1;
185
186static u_char ascii64[] =
187 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
188/* 0000000000111111111122222222223333333333444444444455555555556666 */
189/* 0123456789012345678901234567890123456789012345678901234567890123 */
190
191static __inline int
192ascii_to_bin(ch)
193 char ch;
194{
195 if (ch > 'z')
196 return(0);
197 if (ch >= 'a')
198 return(ch - 'a' + 38);
199 if (ch > 'Z')
200 return(0);
201 if (ch >= 'A')
202 return(ch - 'A' + 12);
203 if (ch > '9')
204 return(0);
205 if (ch >= '.')
206 return(ch - '.');
207 return(0);
208}
209
210static void
211des_init()
212{
213 int i, j, b, k, inbit, obit;
214 u_int32_t *p, *il, *ir, *fl, *fr;
215
216 old_rawkey0 = old_rawkey1 = 0;
217 saltbits = 0;
218 old_salt = 0;
219 bits24 = (bits28 = bits32 + 4) + 4;
220
221 /*
222 * Invert the S-boxes, reordering the input bits.
223 */
224 for (i = 0; i < 8; i++)
225 for (j = 0; j < 64; j++) {
226 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
227 u_sbox[i][j] = sbox[i][b];
228 }
229
230 /*
231 * Convert the inverted S-boxes into 4 arrays of 8 bits.
232 * Each will handle 12 bits of the S-box input.
233 */
234 for (b = 0; b < 4; b++)
235 for (i = 0; i < 64; i++)
236 for (j = 0; j < 64; j++)
237 m_sbox[b][(i << 6) | j] =
238 (u_sbox[(b << 1)][i] << 4) |
239 u_sbox[(b << 1) + 1][j];
240
241 /*
242 * Set up the initial & final permutations into a useful form, and
243 * initialise the inverted key permutation.
244 */
245 for (i = 0; i < 64; i++) {
246 init_perm[final_perm[i] = IP[i] - 1] = i;
247 inv_key_perm[i] = 255;
248 }
249
250 /*
251 * Invert the key permutation and initialise the inverted key
252 * compression permutation.
253 */
254 for (i = 0; i < 56; i++) {
255 u_key_perm[i] = key_perm[i] - 1;
256 inv_key_perm[key_perm[i] - 1] = i;
257 inv_comp_perm[i] = 255;
258 }
259
260 /*
261 * Invert the key compression permutation.
262 */
263 for (i = 0; i < 48; i++) {
264 inv_comp_perm[comp_perm[i] - 1] = i;
265 }
266
267 /*
268 * Set up the OR-mask arrays for the initial and final permutations,
269 * and for the key initial and compression permutations.
270 */
271 for (k = 0; k < 8; k++) {
272 for (i = 0; i < 256; i++) {
273 *(il = &ip_maskl[k][i]) = 0;
274 *(ir = &ip_maskr[k][i]) = 0;
275 *(fl = &fp_maskl[k][i]) = 0;
276 *(fr = &fp_maskr[k][i]) = 0;
277 for (j = 0; j < 8; j++) {
278 inbit = 8 * k + j;
279 if (i & bits8[j]) {
280 if ((obit = init_perm[inbit]) < 32)
281 *il |= bits32[obit];
282 else
283 *ir |= bits32[obit-32];
284 if ((obit = final_perm[inbit]) < 32)
285 *fl |= bits32[obit];
286 else
287 *fr |= bits32[obit - 32];
288 }
289 }
290 }
291 for (i = 0; i < 128; i++) {
292 *(il = &key_perm_maskl[k][i]) = 0;
293 *(ir = &key_perm_maskr[k][i]) = 0;
294 for (j = 0; j < 7; j++) {
295 inbit = 8 * k + j;
296 if (i & bits8[j + 1]) {
297 if ((obit = inv_key_perm[inbit]) == 255)
298 continue;
299 if (obit < 28)
300 *il |= bits28[obit];
301 else
302 *ir |= bits28[obit - 28];
303 }
304 }
305 *(il = &comp_maskl[k][i]) = 0;
306 *(ir = &comp_maskr[k][i]) = 0;
307 for (j = 0; j < 7; j++) {
308 inbit = 7 * k + j;
309 if (i & bits8[j + 1]) {
310 if ((obit=inv_comp_perm[inbit]) == 255)
311 continue;
312 if (obit < 24)
313 *il |= bits24[obit];
314 else
315 *ir |= bits24[obit - 24];
316 }
317 }
318 }
319 }
320
321 /*
322 * Invert the P-box permutation, and convert into OR-masks for
323 * handling the output of the S-box arrays setup above.
324 */
325 for (i = 0; i < 32; i++)
326 un_pbox[pbox[i] - 1] = i;
327
328 for (b = 0; b < 4; b++)
329 for (i = 0; i < 256; i++) {
330 *(p = &psbox[b][i]) = 0;
331 for (j = 0; j < 8; j++) {
332 if (i & bits8[j])
333 *p |= bits32[un_pbox[8 * b + j]];
334 }
335 }
336
337 des_initialised = 1;
338}
339
340static void
341setup_salt(salt)
342 int32_t salt;
343{
344 u_int32_t obit, saltbit;
345 int i;
346
347 if (salt == old_salt)
348 return;
349 old_salt = salt;
350
351 saltbits = 0;
352 saltbit = 1;
353 obit = 0x800000;
354 for (i = 0; i < 24; i++) {
355 if (salt & saltbit)
356 saltbits |= obit;
357 saltbit <<= 1;
358 obit >>= 1;
359 }
360}
361
362static int
363des_setkey(key)
364 const char *key;
365{
366 u_int32_t k0, k1, rawkey0, rawkey1;
367 int shifts, round;
368
369 if (!des_initialised)
370 des_init();
371
372 rawkey0 = ntohl(*(u_int32_t *) key);
373 rawkey1 = ntohl(*(u_int32_t *) (key + 4));
374
375 if ((rawkey0 | rawkey1)
376 && rawkey0 == old_rawkey0
377 && rawkey1 == old_rawkey1) {
378 /*
379 * Already setup for this key.
380 * This optimisation fails on a zero key (which is weak and
381 * has bad parity anyway) in order to simplify the starting
382 * conditions.
383 */
384 return(0);
385 }
386 old_rawkey0 = rawkey0;
387 old_rawkey1 = rawkey1;
388
389 /*
390 * Do key permutation and split into two 28-bit subkeys.
391 */
392 k0 = key_perm_maskl[0][rawkey0 >> 25]
393 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
394 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
395 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
396 | key_perm_maskl[4][rawkey1 >> 25]
397 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
398 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
399 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
400 k1 = key_perm_maskr[0][rawkey0 >> 25]
401 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
402 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
403 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
404 | key_perm_maskr[4][rawkey1 >> 25]
405 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
406 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
407 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
408 /*
409 * Rotate subkeys and do compression permutation.
410 */
411 shifts = 0;
412 for (round = 0; round < 16; round++) {
413 u_int32_t t0, t1;
414
415 shifts += key_shifts[round];
416
417 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
418 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
419
420 de_keysl[15 - round] =
421 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
422 | comp_maskl[1][(t0 >> 14) & 0x7f]
423 | comp_maskl[2][(t0 >> 7) & 0x7f]
424 | comp_maskl[3][t0 & 0x7f]
425 | comp_maskl[4][(t1 >> 21) & 0x7f]
426 | comp_maskl[5][(t1 >> 14) & 0x7f]
427 | comp_maskl[6][(t1 >> 7) & 0x7f]
428 | comp_maskl[7][t1 & 0x7f];
429
430 de_keysr[15 - round] =
431 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
432 | comp_maskr[1][(t0 >> 14) & 0x7f]
433 | comp_maskr[2][(t0 >> 7) & 0x7f]
434 | comp_maskr[3][t0 & 0x7f]
435 | comp_maskr[4][(t1 >> 21) & 0x7f]
436 | comp_maskr[5][(t1 >> 14) & 0x7f]
437 | comp_maskr[6][(t1 >> 7) & 0x7f]
438 | comp_maskr[7][t1 & 0x7f];
439 }
440 return(0);
441}
442
443static int
444do_des(l_in, r_in, l_out, r_out, count)
445 u_int32_t l_in, r_in, *l_out, *r_out;
446 int count;
447{
448 /*
449 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
450 */
451 u_int32_t l, r, *kl, *kr, *kl1, *kr1;
452 u_int32_t f, r48l, r48r;
453 int round;
454
455 if (count == 0) {
456 return(1);
457 } else if (count > 0) {
458 /*
459 * Encrypting
460 */
461 kl1 = en_keysl;
462 kr1 = en_keysr;
463 } else {
464 /*
465 * Decrypting
466 */
467 count = -count;
468 kl1 = de_keysl;
469 kr1 = de_keysr;
470 }
471
472 /*
473 * Do initial permutation (IP).
474 */
475 l = ip_maskl[0][l_in >> 24]
476 | ip_maskl[1][(l_in >> 16) & 0xff]
477 | ip_maskl[2][(l_in >> 8) & 0xff]
478 | ip_maskl[3][l_in & 0xff]
479 | ip_maskl[4][r_in >> 24]
480 | ip_maskl[5][(r_in >> 16) & 0xff]
481 | ip_maskl[6][(r_in >> 8) & 0xff]
482 | ip_maskl[7][r_in & 0xff];
483 r = ip_maskr[0][l_in >> 24]
484 | ip_maskr[1][(l_in >> 16) & 0xff]
485 | ip_maskr[2][(l_in >> 8) & 0xff]
486 | ip_maskr[3][l_in & 0xff]
487 | ip_maskr[4][r_in >> 24]
488 | ip_maskr[5][(r_in >> 16) & 0xff]
489 | ip_maskr[6][(r_in >> 8) & 0xff]
490 | ip_maskr[7][r_in & 0xff];
491
492 while (count--) {
493 /*
494 * Do each round.
495 */
496 kl = kl1;
497 kr = kr1;
498 round = 16;
499 while (round--) {
500 /*
501 * Expand R to 48 bits (simulate the E-box).
502 */
503 r48l = ((r & 0x00000001) << 23)
504 | ((r & 0xf8000000) >> 9)
505 | ((r & 0x1f800000) >> 11)
506 | ((r & 0x01f80000) >> 13)
507 | ((r & 0x001f8000) >> 15);
508
509 r48r = ((r & 0x0001f800) << 7)
510 | ((r & 0x00001f80) << 5)
511 | ((r & 0x000001f8) << 3)
512 | ((r & 0x0000001f) << 1)
513 | ((r & 0x80000000) >> 31);
514 /*
515 * Do salting for crypt() and friends, and
516 * XOR with the permuted key.
517 */
518 f = (r48l ^ r48r) & saltbits;
519 r48l ^= f ^ *kl++;
520 r48r ^= f ^ *kr++;
521 /*
522 * Do sbox lookups (which shrink it back to 32 bits)
523 * and do the pbox permutation at the same time.
524 */
525 f = psbox[0][m_sbox[0][r48l >> 12]]
526 | psbox[1][m_sbox[1][r48l & 0xfff]]
527 | psbox[2][m_sbox[2][r48r >> 12]]
528 | psbox[3][m_sbox[3][r48r & 0xfff]];
529 /*
530 * Now that we've permuted things, complete f().
531 */
532 f ^= l;
533 l = r;
534 r = f;
535 }
536 r = l;
537 l = f;
538 }
539 /*
540 * Do final permutation (inverse of IP).
541 */
542 *l_out = fp_maskl[0][l >> 24]
543 | fp_maskl[1][(l >> 16) & 0xff]
544 | fp_maskl[2][(l >> 8) & 0xff]
545 | fp_maskl[3][l & 0xff]
546 | fp_maskl[4][r >> 24]
547 | fp_maskl[5][(r >> 16) & 0xff]
548 | fp_maskl[6][(r >> 8) & 0xff]
549 | fp_maskl[7][r & 0xff];
550 *r_out = fp_maskr[0][l >> 24]
551 | fp_maskr[1][(l >> 16) & 0xff]
552 | fp_maskr[2][(l >> 8) & 0xff]
553 | fp_maskr[3][l & 0xff]
554 | fp_maskr[4][r >> 24]
555 | fp_maskr[5][(r >> 16) & 0xff]
556 | fp_maskr[6][(r >> 8) & 0xff]
557 | fp_maskr[7][r & 0xff];
558 return(0);
559}
560
561static int
562des_cipher(in, out, salt, count)
563 const char *in;
564 char *out;
565 int32_t salt;
566 int count;
567{
568 u_int32_t l_out, r_out, rawl, rawr;
569 u_int32_t x[2];
570 int retval;
571
572 if (!des_initialised)
573 des_init();
574
575 setup_salt(salt);
576
577 memcpy(x, in, sizeof x);
578 rawl = ntohl(x[0]);
579 rawr = ntohl(x[1]);
580 retval = do_des(rawl, rawr, &l_out, &r_out, count);
581
582 x[0] = htonl(l_out);
583 x[1] = htonl(r_out);
584 memcpy(out, x, sizeof x);
585 return(retval);
586}
587
588char *
589crypt(key, setting)
590 const char *key;
591 const char *setting;
592{
593 int i;
594 u_int32_t count, salt, l, r0, r1, keybuf[2];
595 u_char *p, *q;
596 static u_char output[21];
597 extern char *md5crypt(const char *, const char *);
598 extern char *bcrypt(const char *, const char *);
599
600 if (setting[0] == '$') {
601 switch (setting[1]) {
602 case '1':
603 return (md5crypt(key, setting));
604 default:
605 return bcrypt(key, setting);
606 }
607 }
608
609 if (!des_initialised)
610 des_init();
611
612 /*
613 * Copy the key, shifting each character up by one bit
614 * and padding with zeros.
615 */
616 q = (u_char *) keybuf;
617 while ((q - (u_char *) keybuf) < sizeof(keybuf)) {
618 if ((*q++ = *key << 1))
619 key++;
620 }
621 if (des_setkey((u_char *) keybuf))
622 return(NULL);
623
624 if (*setting == _PASSWORD_EFMT1) {
625 /*
626 * "new"-style:
627 * setting - underscore, 4 bytes of count, 4 bytes of salt
628 * key - unlimited characters
629 */
630 for (i = 1, count = 0; i < 5; i++)
631 count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
632
633 for (i = 5, salt = 0; i < 9; i++)
634 salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
635
636 while (*key) {
637 /*
638 * Encrypt the key with itself.
639 */
640 if (des_cipher((u_char*)keybuf, (u_char*)keybuf, 0, 1))
641 return(NULL);
642 /*
643 * And XOR with the next 8 characters of the key.
644 */
645 q = (u_char *) keybuf;
646 while (((q - (u_char *) keybuf) < sizeof(keybuf)) &&
647 *key)
648 *q++ ^= *key++ << 1;
649
650 if (des_setkey((u_char *) keybuf))
651 return(NULL);
652 }
653 strlcpy((char *)output, setting, 10);
654
655 /*
656 * Double check that we weren't given a short setting.
657 * If we were, the above code will probably have created
658 * weird values for count and salt, but we don't really care.
659 * Just make sure the output string doesn't have an extra
660 * NUL in it.
661 */
662 p = output + strlen((const char *)output);
663 } else {
664 /*
665 * "old"-style:
666 * setting - 2 bytes of salt
667 * key - up to 8 characters
668 */
669 count = 25;
670
671 salt = (ascii_to_bin(setting[1]) << 6)
672 | ascii_to_bin(setting[0]);
673
674 output[0] = setting[0];
675 /*
676 * If the encrypted password that the salt was extracted from
677 * is only 1 character long, the salt will be corrupted. We
678 * need to ensure that the output string doesn't have an extra
679 * NUL in it!
680 */
681 output[1] = setting[1] ? setting[1] : output[0];
682
683 p = output + 2;
684 }
685 setup_salt(salt);
686 /*
687 * Do it.
688 */
689 if (do_des(0, 0, &r0, &r1, count))
690 return(NULL);
691 /*
692 * Now encode the result...
693 */
694 l = (r0 >> 8);
695 *p++ = ascii64[(l >> 18) & 0x3f];
696 *p++ = ascii64[(l >> 12) & 0x3f];
697 *p++ = ascii64[(l >> 6) & 0x3f];
698 *p++ = ascii64[l & 0x3f];
699
700 l = (r0 << 16) | ((r1 >> 16) & 0xffff);
701 *p++ = ascii64[(l >> 18) & 0x3f];
702 *p++ = ascii64[(l >> 12) & 0x3f];
703 *p++ = ascii64[(l >> 6) & 0x3f];
704 *p++ = ascii64[l & 0x3f];
705
706 l = r1 << 2;
707 *p++ = ascii64[(l >> 12) & 0x3f];
708 *p++ = ascii64[(l >> 6) & 0x3f];
709 *p++ = ascii64[l & 0x3f];
710 *p = 0;
711
712 return((char *)output);
713}
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c
new file mode 100644
index 0000000000..56ab66fbb5
--- /dev/null
+++ b/src/lib/libc/crypt/md5crypt.c
@@ -0,0 +1,157 @@
1/* $OpenBSD: md5crypt.c,v 1.10 2002/02/16 21:27:22 millert Exp $ */
2
3/*
4 * ----------------------------------------------------------------------------
5 * "THE BEER-WARE LICENSE" (Revision 42):
6 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
7 * can do whatever you want with this stuff. If we meet some day, and you think
8 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
9 * ----------------------------------------------------------------------------
10 *
11 * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
12 *
13 */
14
15#if defined(LIBC_SCCS) && !defined(lint)
16static char rcsid[] = "$OpenBSD: md5crypt.c,v 1.10 2002/02/16 21:27:22 millert Exp $";
17#endif /* LIBC_SCCS and not lint */
18
19#include <unistd.h>
20#include <stdio.h>
21#include <string.h>
22#include <md5.h>
23#include <string.h>
24
25static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
26 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
27
28static void to64(char *, u_int32_t, int);
29
30static void
31to64(s, v, n)
32 char *s;
33 u_int32_t v;
34 int n;
35{
36 while (--n >= 0) {
37 *s++ = itoa64[v&0x3f];
38 v >>= 6;
39 }
40}
41
42/*
43 * UNIX password
44 *
45 * Use MD5 for what it is best at...
46 */
47
48char *
49md5crypt(pw, salt)
50 register const char *pw;
51 register const char *salt;
52{
53 /*
54 * This string is magic for this algorithm. Having
55 * it this way, we can get get better later on
56 */
57 static unsigned char *magic = (unsigned char *)"$1$";
58
59 static char passwd[120], *p;
60 static const unsigned char *sp,*ep;
61 unsigned char final[16];
62 int sl,pl,i;
63 MD5_CTX ctx,ctx1;
64 u_int32_t l;
65
66 /* Refine the Salt first */
67 sp = (const unsigned char *)salt;
68
69 /* If it starts with the magic string, then skip that */
70 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
71 sp += strlen((const char *)magic);
72
73 /* It stops at the first '$', max 8 chars */
74 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
75 continue;
76
77 /* get the length of the true salt */
78 sl = ep - sp;
79
80 MD5Init(&ctx);
81
82 /* The password first, since that is what is most unknown */
83 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
84
85 /* Then our magic string */
86 MD5Update(&ctx,magic,strlen((const char *)magic));
87
88 /* Then the raw salt */
89 MD5Update(&ctx,sp,sl);
90
91 /* Then just as many characters of the MD5(pw,salt,pw) */
92 MD5Init(&ctx1);
93 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
94 MD5Update(&ctx1,sp,sl);
95 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
96 MD5Final(final,&ctx1);
97 for(pl = strlen(pw); pl > 0; pl -= 16)
98 MD5Update(&ctx,final,pl>16 ? 16 : pl);
99
100 /* Don't leave anything around in vm they could use. */
101 memset(final,0,sizeof final);
102
103 /* Then something really weird... */
104 for (i = strlen(pw); i ; i >>= 1)
105 if(i&1)
106 MD5Update(&ctx, final, 1);
107 else
108 MD5Update(&ctx, (const unsigned char *)pw, 1);
109
110 /* Now make the output string */
111 strcpy(passwd,(const char *)magic);
112 strncat(passwd,(const char *)sp,sl);
113 strcat(passwd,"$");
114
115 MD5Final(final,&ctx);
116
117 /*
118 * and now, just to make sure things don't run too fast
119 * On a 60 Mhz Pentium this takes 34 msec, so you would
120 * need 30 seconds to build a 1000 entry dictionary...
121 */
122 for(i=0;i<1000;i++) {
123 MD5Init(&ctx1);
124 if(i & 1)
125 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
126 else
127 MD5Update(&ctx1,final,16);
128
129 if(i % 3)
130 MD5Update(&ctx1,sp,sl);
131
132 if(i % 7)
133 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
134
135 if(i & 1)
136 MD5Update(&ctx1,final,16);
137 else
138 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
139 MD5Final(final,&ctx1);
140 }
141
142 p = passwd + strlen(passwd);
143
144 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
145 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
146 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
147 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
148 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
149 l = final[11] ; to64(p,l,2); p += 2;
150 *p = '\0';
151
152 /* Don't leave anything around in vm they could use. */
153 memset(final,0,sizeof final);
154
155 return passwd;
156}
157
diff --git a/src/lib/libc/crypt/morecrypt.c b/src/lib/libc/crypt/morecrypt.c
new file mode 100644
index 0000000000..e9e0ced4c1
--- /dev/null
+++ b/src/lib/libc/crypt/morecrypt.c
@@ -0,0 +1,628 @@
1/* $OpenBSD: morecrypt.c,v 1.9 1998/03/22 19:01:20 niklas Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 *
48 * NOTE:
49 * This file must copy certain chunks of crypt.c for legal reasons.
50 * crypt.c can only export the interface crypt(), to make binaries
51 * exportable from the USA. Hence, to also have the other crypto interfaces
52 * available we have to copy pieces...
53 */
54
55#if defined(LIBC_SCCS) && !defined(lint)
56static char rcsid[] = "$OpenBSD: morecrypt.c,v 1.9 1998/03/22 19:01:20 niklas Exp $";
57#endif /* LIBC_SCCS and not lint */
58
59#include <sys/types.h>
60#include <sys/param.h>
61#include <pwd.h>
62#include <string.h>
63
64#ifdef DEBUG
65# include <stdio.h>
66#endif
67
68static u_char IP[64] = {
69 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
70 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
71 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
72 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
73};
74
75static u_char inv_key_perm[64];
76static u_char u_key_perm[56];
77static u_char key_perm[56] = {
78 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
79 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
80 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
81 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
82};
83
84static u_char key_shifts[16] = {
85 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
86};
87
88static u_char inv_comp_perm[56];
89static u_char comp_perm[48] = {
90 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
91 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
92 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
93 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
94};
95
96/*
97 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
98 */
99
100static u_char u_sbox[8][64];
101static u_char sbox[8][64] = {
102 {
103 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
104 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
105 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
106 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
107 },
108 {
109 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
110 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
111 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
112 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
113 },
114 {
115 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
116 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
117 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
118 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
119 },
120 {
121 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
122 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
123 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
124 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
125 },
126 {
127 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
128 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
129 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
130 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
131 },
132 {
133 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
134 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
135 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
136 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
137 },
138 {
139 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
140 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
141 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
142 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
143 },
144 {
145 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
146 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
147 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
148 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
149 }
150};
151
152static u_char un_pbox[32];
153static u_char pbox[32] = {
154 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
155 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
156};
157
158static u_int32_t bits32[32] =
159{
160 0x80000000, 0x40000000, 0x20000000, 0x10000000,
161 0x08000000, 0x04000000, 0x02000000, 0x01000000,
162 0x00800000, 0x00400000, 0x00200000, 0x00100000,
163 0x00080000, 0x00040000, 0x00020000, 0x00010000,
164 0x00008000, 0x00004000, 0x00002000, 0x00001000,
165 0x00000800, 0x00000400, 0x00000200, 0x00000100,
166 0x00000080, 0x00000040, 0x00000020, 0x00000010,
167 0x00000008, 0x00000004, 0x00000002, 0x00000001
168};
169
170static u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
171
172static u_int32_t saltbits;
173static int32_t old_salt;
174static u_int32_t *bits28, *bits24;
175static u_char init_perm[64], final_perm[64];
176static u_int32_t en_keysl[16], en_keysr[16];
177static u_int32_t de_keysl[16], de_keysr[16];
178static int des_initialised = 0;
179static u_char m_sbox[4][4096];
180static u_int32_t psbox[4][256];
181static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
182static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
183static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
184static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
185static u_int32_t old_rawkey0, old_rawkey1;
186
187static __inline int
188ascii_to_bin(ch)
189 char ch;
190{
191 if (ch > 'z')
192 return(0);
193 if (ch >= 'a')
194 return(ch - 'a' + 38);
195 if (ch > 'Z')
196 return(0);
197 if (ch >= 'A')
198 return(ch - 'A' + 12);
199 if (ch > '9')
200 return(0);
201 if (ch >= '.')
202 return(ch - '.');
203 return(0);
204}
205
206void
207des_init()
208{
209 int i, j, b, k, inbit, obit;
210 u_int32_t *p, *il, *ir, *fl, *fr;
211
212 old_rawkey0 = old_rawkey1 = 0;
213 saltbits = 0;
214 old_salt = 0;
215 bits24 = (bits28 = bits32 + 4) + 4;
216
217 /*
218 * Invert the S-boxes, reordering the input bits.
219 */
220 for (i = 0; i < 8; i++)
221 for (j = 0; j < 64; j++) {
222 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
223 u_sbox[i][j] = sbox[i][b];
224 }
225
226 /*
227 * Convert the inverted S-boxes into 4 arrays of 8 bits.
228 * Each will handle 12 bits of the S-box input.
229 */
230 for (b = 0; b < 4; b++)
231 for (i = 0; i < 64; i++)
232 for (j = 0; j < 64; j++)
233 m_sbox[b][(i << 6) | j] =
234 (u_sbox[(b << 1)][i] << 4) |
235 u_sbox[(b << 1) + 1][j];
236
237 /*
238 * Set up the initial & final permutations into a useful form, and
239 * initialise the inverted key permutation.
240 */
241 for (i = 0; i < 64; i++) {
242 init_perm[final_perm[i] = IP[i] - 1] = i;
243 inv_key_perm[i] = 255;
244 }
245
246 /*
247 * Invert the key permutation and initialise the inverted key
248 * compression permutation.
249 */
250 for (i = 0; i < 56; i++) {
251 u_key_perm[i] = key_perm[i] - 1;
252 inv_key_perm[key_perm[i] - 1] = i;
253 inv_comp_perm[i] = 255;
254 }
255
256 /*
257 * Invert the key compression permutation.
258 */
259 for (i = 0; i < 48; i++) {
260 inv_comp_perm[comp_perm[i] - 1] = i;
261 }
262
263 /*
264 * Set up the OR-mask arrays for the initial and final permutations,
265 * and for the key initial and compression permutations.
266 */
267 for (k = 0; k < 8; k++) {
268 for (i = 0; i < 256; i++) {
269 *(il = &ip_maskl[k][i]) = 0;
270 *(ir = &ip_maskr[k][i]) = 0;
271 *(fl = &fp_maskl[k][i]) = 0;
272 *(fr = &fp_maskr[k][i]) = 0;
273 for (j = 0; j < 8; j++) {
274 inbit = 8 * k + j;
275 if (i & bits8[j]) {
276 if ((obit = init_perm[inbit]) < 32)
277 *il |= bits32[obit];
278 else
279 *ir |= bits32[obit-32];
280 if ((obit = final_perm[inbit]) < 32)
281 *fl |= bits32[obit];
282 else
283 *fr |= bits32[obit - 32];
284 }
285 }
286 }
287 for (i = 0; i < 128; i++) {
288 *(il = &key_perm_maskl[k][i]) = 0;
289 *(ir = &key_perm_maskr[k][i]) = 0;
290 for (j = 0; j < 7; j++) {
291 inbit = 8 * k + j;
292 if (i & bits8[j + 1]) {
293 if ((obit = inv_key_perm[inbit]) == 255)
294 continue;
295 if (obit < 28)
296 *il |= bits28[obit];
297 else
298 *ir |= bits28[obit - 28];
299 }
300 }
301 *(il = &comp_maskl[k][i]) = 0;
302 *(ir = &comp_maskr[k][i]) = 0;
303 for (j = 0; j < 7; j++) {
304 inbit = 7 * k + j;
305 if (i & bits8[j + 1]) {
306 if ((obit=inv_comp_perm[inbit]) == 255)
307 continue;
308 if (obit < 24)
309 *il |= bits24[obit];
310 else
311 *ir |= bits24[obit - 24];
312 }
313 }
314 }
315 }
316
317 /*
318 * Invert the P-box permutation, and convert into OR-masks for
319 * handling the output of the S-box arrays setup above.
320 */
321 for (i = 0; i < 32; i++)
322 un_pbox[pbox[i] - 1] = i;
323
324 for (b = 0; b < 4; b++)
325 for (i = 0; i < 256; i++) {
326 *(p = &psbox[b][i]) = 0;
327 for (j = 0; j < 8; j++) {
328 if (i & bits8[j])
329 *p |= bits32[un_pbox[8 * b + j]];
330 }
331 }
332
333 des_initialised = 1;
334}
335
336void
337setup_salt(salt)
338 int32_t salt;
339{
340 u_int32_t obit, saltbit;
341 int i;
342
343 if (salt == old_salt)
344 return;
345 old_salt = salt;
346
347 saltbits = 0;
348 saltbit = 1;
349 obit = 0x800000;
350 for (i = 0; i < 24; i++) {
351 if (salt & saltbit)
352 saltbits |= obit;
353 saltbit <<= 1;
354 obit >>= 1;
355 }
356}
357
358int
359do_des(l_in, r_in, l_out, r_out, count)
360 u_int32_t l_in, r_in, *l_out, *r_out;
361 int count;
362{
363 /*
364 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
365 */
366 u_int32_t l, r, *kl, *kr, *kl1, *kr1;
367 u_int32_t f, r48l, r48r;
368 int round;
369
370 if (count == 0) {
371 return(1);
372 } else if (count > 0) {
373 /*
374 * Encrypting
375 */
376 kl1 = en_keysl;
377 kr1 = en_keysr;
378 } else {
379 /*
380 * Decrypting
381 */
382 count = -count;
383 kl1 = de_keysl;
384 kr1 = de_keysr;
385 }
386
387 /*
388 * Do initial permutation (IP).
389 */
390 l = ip_maskl[0][l_in >> 24]
391 | ip_maskl[1][(l_in >> 16) & 0xff]
392 | ip_maskl[2][(l_in >> 8) & 0xff]
393 | ip_maskl[3][l_in & 0xff]
394 | ip_maskl[4][r_in >> 24]
395 | ip_maskl[5][(r_in >> 16) & 0xff]
396 | ip_maskl[6][(r_in >> 8) & 0xff]
397 | ip_maskl[7][r_in & 0xff];
398 r = ip_maskr[0][l_in >> 24]
399 | ip_maskr[1][(l_in >> 16) & 0xff]
400 | ip_maskr[2][(l_in >> 8) & 0xff]
401 | ip_maskr[3][l_in & 0xff]
402 | ip_maskr[4][r_in >> 24]
403 | ip_maskr[5][(r_in >> 16) & 0xff]
404 | ip_maskr[6][(r_in >> 8) & 0xff]
405 | ip_maskr[7][r_in & 0xff];
406
407 while (count--) {
408 /*
409 * Do each round.
410 */
411 kl = kl1;
412 kr = kr1;
413 round = 16;
414 while (round--) {
415 /*
416 * Expand R to 48 bits (simulate the E-box).
417 */
418 r48l = ((r & 0x00000001) << 23)
419 | ((r & 0xf8000000) >> 9)
420 | ((r & 0x1f800000) >> 11)
421 | ((r & 0x01f80000) >> 13)
422 | ((r & 0x001f8000) >> 15);
423
424 r48r = ((r & 0x0001f800) << 7)
425 | ((r & 0x00001f80) << 5)
426 | ((r & 0x000001f8) << 3)
427 | ((r & 0x0000001f) << 1)
428 | ((r & 0x80000000) >> 31);
429 /*
430 * Do salting for crypt() and friends, and
431 * XOR with the permuted key.
432 */
433 f = (r48l ^ r48r) & saltbits;
434 r48l ^= f ^ *kl++;
435 r48r ^= f ^ *kr++;
436 /*
437 * Do sbox lookups (which shrink it back to 32 bits)
438 * and do the pbox permutation at the same time.
439 */
440 f = psbox[0][m_sbox[0][r48l >> 12]]
441 | psbox[1][m_sbox[1][r48l & 0xfff]]
442 | psbox[2][m_sbox[2][r48r >> 12]]
443 | psbox[3][m_sbox[3][r48r & 0xfff]];
444 /*
445 * Now that we've permuted things, complete f().
446 */
447 f ^= l;
448 l = r;
449 r = f;
450 }
451 r = l;
452 l = f;
453 }
454 /*
455 * Do final permutation (inverse of IP).
456 */
457 *l_out = fp_maskl[0][l >> 24]
458 | fp_maskl[1][(l >> 16) & 0xff]
459 | fp_maskl[2][(l >> 8) & 0xff]
460 | fp_maskl[3][l & 0xff]
461 | fp_maskl[4][r >> 24]
462 | fp_maskl[5][(r >> 16) & 0xff]
463 | fp_maskl[6][(r >> 8) & 0xff]
464 | fp_maskl[7][r & 0xff];
465 *r_out = fp_maskr[0][l >> 24]
466 | fp_maskr[1][(l >> 16) & 0xff]
467 | fp_maskr[2][(l >> 8) & 0xff]
468 | fp_maskr[3][l & 0xff]
469 | fp_maskr[4][r >> 24]
470 | fp_maskr[5][(r >> 16) & 0xff]
471 | fp_maskr[6][(r >> 8) & 0xff]
472 | fp_maskr[7][r & 0xff];
473 return(0);
474}
475
476int
477des_cipher(in, out, salt, count)
478 const char *in;
479 char *out;
480 long salt;
481 int count;
482{
483 u_int32_t l_out, r_out, rawl, rawr;
484 u_int32_t x[2];
485 int retval;
486
487 if (!des_initialised)
488 des_init();
489
490 setup_salt((int32_t)salt);
491
492 memcpy(x, in, sizeof x);
493 rawl = ntohl(x[0]);
494 rawr = ntohl(x[1]);
495 retval = do_des(rawl, rawr, &l_out, &r_out, count);
496
497 x[0] = htonl(l_out);
498 x[1] = htonl(r_out);
499 memcpy(out, x, sizeof x);
500 return(retval);
501}
502
503int
504des_setkey(key)
505 const char *key;
506{
507 u_int32_t k0, k1, rawkey0, rawkey1;
508 int shifts, round;
509
510 if (!des_initialised)
511 des_init();
512
513 rawkey0 = ntohl(*(u_int32_t *) key);
514 rawkey1 = ntohl(*(u_int32_t *) (key + 4));
515
516 if ((rawkey0 | rawkey1)
517 && rawkey0 == old_rawkey0
518 && rawkey1 == old_rawkey1) {
519 /*
520 * Already setup for this key.
521 * This optimisation fails on a zero key (which is weak and
522 * has bad parity anyway) in order to simplify the starting
523 * conditions.
524 */
525 return(0);
526 }
527 old_rawkey0 = rawkey0;
528 old_rawkey1 = rawkey1;
529
530 /*
531 * Do key permutation and split into two 28-bit subkeys.
532 */
533 k0 = key_perm_maskl[0][rawkey0 >> 25]
534 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
535 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
536 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
537 | key_perm_maskl[4][rawkey1 >> 25]
538 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
539 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
540 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
541 k1 = key_perm_maskr[0][rawkey0 >> 25]
542 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
543 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
544 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
545 | key_perm_maskr[4][rawkey1 >> 25]
546 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
547 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
548 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
549 /*
550 * Rotate subkeys and do compression permutation.
551 */
552 shifts = 0;
553 for (round = 0; round < 16; round++) {
554 u_int32_t t0, t1;
555
556 shifts += key_shifts[round];
557
558 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
559 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
560
561 de_keysl[15 - round] =
562 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
563 | comp_maskl[1][(t0 >> 14) & 0x7f]
564 | comp_maskl[2][(t0 >> 7) & 0x7f]
565 | comp_maskl[3][t0 & 0x7f]
566 | comp_maskl[4][(t1 >> 21) & 0x7f]
567 | comp_maskl[5][(t1 >> 14) & 0x7f]
568 | comp_maskl[6][(t1 >> 7) & 0x7f]
569 | comp_maskl[7][t1 & 0x7f];
570
571 de_keysr[15 - round] =
572 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
573 | comp_maskr[1][(t0 >> 14) & 0x7f]
574 | comp_maskr[2][(t0 >> 7) & 0x7f]
575 | comp_maskr[3][t0 & 0x7f]
576 | comp_maskr[4][(t1 >> 21) & 0x7f]
577 | comp_maskr[5][(t1 >> 14) & 0x7f]
578 | comp_maskr[6][(t1 >> 7) & 0x7f]
579 | comp_maskr[7][t1 & 0x7f];
580 }
581 return(0);
582}
583
584int
585setkey(key)
586 const char *key;
587{
588 int i, j;
589 u_int32_t packed_keys[2];
590 u_char *p;
591
592 p = (u_char *) packed_keys;
593
594 for (i = 0; i < 8; i++) {
595 p[i] = 0;
596 for (j = 0; j < 8; j++)
597 if (*key++ & 1)
598 p[i] |= bits8[j];
599 }
600 return(des_setkey(p));
601}
602
603int
604encrypt(block, flag)
605 char *block;
606 int flag;
607{
608 u_int32_t io[2];
609 u_char *p;
610 int i, j, retval;
611
612 if (!des_initialised)
613 des_init();
614
615 setup_salt((int32_t)0);
616 p = (u_char *)block;
617 for (i = 0; i < 2; i++) {
618 io[i] = 0L;
619 for (j = 0; j < 32; j++)
620 if (*p++ & 1)
621 io[i] |= bits32[j];
622 }
623 retval = do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
624 for (i = 0; i < 2; i++)
625 for (j = 0; j < 32; j++)
626 block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0;
627 return(retval);
628}
diff --git a/src/lib/libc/crypt/skipjack.c b/src/lib/libc/crypt/skipjack.c
new file mode 100644
index 0000000000..e700f40c39
--- /dev/null
+++ b/src/lib/libc/crypt/skipjack.c
@@ -0,0 +1,258 @@
1/*
2 * Further optimized test implementation of SKIPJACK algorithm
3 * Mark Tillotson <markt@chaos.org.uk>, 25 June 98
4 * Optimizations suit RISC (lots of registers) machine best.
5 *
6 * based on unoptimized implementation of
7 * Panu Rissanen <bande@lut.fi> 960624
8 *
9 * SKIPJACK and KEA Algorithm Specifications
10 * Version 2.0
11 * 29 May 1998
12*/
13
14#include <sys/param.h>
15#include <skipjack.h>
16#include <stdlib.h>
17
18static const u_int8_t ftable[0x100] =
19{
20 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4,
21 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9,
22 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e,
23 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28,
24 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68,
25 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53,
26 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19,
27 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2,
28 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b,
29 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8,
30 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0,
31 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90,
32 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69,
33 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76,
34 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20,
35 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d,
36 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43,
37 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18,
38 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa,
39 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4,
40 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87,
41 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40,
42 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b,
43 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5,
44 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0,
45 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2,
46 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1,
47 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8,
48 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5,
49 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac,
50 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3,
51 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46
52};
53
54/*
55 * For each key byte generate a table to represent the function
56 * ftable [in ^ keybyte]
57 *
58 * These tables used to save an XOR in each stage of the G-function
59 * the tables are hopefully pointed to by register allocated variables
60 * k0, k1..k9
61 */
62void
63subkey_table_gen (u_int8_t *key, u_int8_t **key_tables)
64{
65 int i, k;
66
67 for (k = 0; k < 10; k++) {
68 u_int8_t key_byte = key[k];
69 u_int8_t * table = (u_int8_t *) malloc(0x100);
70 /* XXX */
71
72 key_tables[k] = table;
73 for (i = 0; i < 0x100; i++)
74 table[i] = ftable[i ^ key_byte];
75 }
76}
77
78
79#define g(k0, k1, k2, k3, ih, il, oh, ol) \
80{ \
81 oh = k##k0 [il] ^ ih; \
82 ol = k##k1 [oh] ^ il; \
83 oh = k##k2 [ol] ^ oh; \
84 ol = k##k3 [oh] ^ ol; \
85}
86
87#define g0(ih, il, oh, ol) g(0, 1, 2, 3, ih, il, oh, ol)
88#define g4(ih, il, oh, ol) g(4, 5, 6, 7, ih, il, oh, ol)
89#define g8(ih, il, oh, ol) g(8, 9, 0, 1, ih, il, oh, ol)
90#define g2(ih, il, oh, ol) g(2, 3, 4, 5, ih, il, oh, ol)
91#define g6(ih, il, oh, ol) g(6, 7, 8, 9, ih, il, oh, ol)
92
93
94#define g_inv(k0, k1, k2, k3, ih, il, oh, ol) \
95{ \
96 ol = k##k3 [ih] ^ il; \
97 oh = k##k2 [ol] ^ ih; \
98 ol = k##k1 [oh] ^ ol; \
99 oh = k##k0 [ol] ^ oh; \
100}
101
102
103#define g0_inv(ih, il, oh, ol) g_inv(0, 1, 2, 3, ih, il, oh, ol)
104#define g4_inv(ih, il, oh, ol) g_inv(4, 5, 6, 7, ih, il, oh, ol)
105#define g8_inv(ih, il, oh, ol) g_inv(8, 9, 0, 1, ih, il, oh, ol)
106#define g2_inv(ih, il, oh, ol) g_inv(2, 3, 4, 5, ih, il, oh, ol)
107#define g6_inv(ih, il, oh, ol) g_inv(6, 7, 8, 9, ih, il, oh, ol)
108
109/* optimized version of Skipjack algorithm
110 *
111 * the appropriate g-function is inlined for each round
112 *
113 * the data movement is minimized by rotating the names of the
114 * variables w1..w4, not their contents (saves 3 moves per round)
115 *
116 * the loops are completely unrolled (needed to staticize choice of g)
117 *
118 * compiles to about 470 instructions on a Sparc (gcc -O)
119 * which is about 58 instructions per byte, 14 per round.
120 * gcc seems to leave in some unnecessary and with 0xFF operations
121 * but only in the latter part of the functions. Perhaps it
122 * runs out of resources to properly optimize long inlined function?
123 * in theory should get about 11 instructions per round, not 14
124 */
125
126void
127skipjack_forwards(u_int8_t *plain, u_int8_t *cipher, u_int8_t **key_tables)
128{
129 u_int8_t wh1 = plain[0]; u_int8_t wl1 = plain[1];
130 u_int8_t wh2 = plain[2]; u_int8_t wl2 = plain[3];
131 u_int8_t wh3 = plain[4]; u_int8_t wl3 = plain[5];
132 u_int8_t wh4 = plain[6]; u_int8_t wl4 = plain[7];
133
134 u_int8_t * k0 = key_tables [0];
135 u_int8_t * k1 = key_tables [1];
136 u_int8_t * k2 = key_tables [2];
137 u_int8_t * k3 = key_tables [3];
138 u_int8_t * k4 = key_tables [4];
139 u_int8_t * k5 = key_tables [5];
140 u_int8_t * k6 = key_tables [6];
141 u_int8_t * k7 = key_tables [7];
142 u_int8_t * k8 = key_tables [8];
143 u_int8_t * k9 = key_tables [9];
144
145 /* first 8 rounds */
146 g0 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 1; wh4 ^= wh1;
147 g4 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 2; wh3 ^= wh4;
148 g8 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 3; wh2 ^= wh3;
149 g2 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 4; wh1 ^= wh2;
150 g6 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 5; wh4 ^= wh1;
151 g0 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 6; wh3 ^= wh4;
152 g4 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 7; wh2 ^= wh3;
153 g8 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 8; wh1 ^= wh2;
154
155 /* second 8 rounds */
156 wh2 ^= wh1; wl2 ^= wl1 ^ 9 ; g2 (wh1,wl1, wh1,wl1);
157 wh1 ^= wh4; wl1 ^= wl4 ^ 10; g6 (wh4,wl4, wh4,wl4);
158 wh4 ^= wh3; wl4 ^= wl3 ^ 11; g0 (wh3,wl3, wh3,wl3);
159 wh3 ^= wh2; wl3 ^= wl2 ^ 12; g4 (wh2,wl2, wh2,wl2);
160 wh2 ^= wh1; wl2 ^= wl1 ^ 13; g8 (wh1,wl1, wh1,wl1);
161 wh1 ^= wh4; wl1 ^= wl4 ^ 14; g2 (wh4,wl4, wh4,wl4);
162 wh4 ^= wh3; wl4 ^= wl3 ^ 15; g6 (wh3,wl3, wh3,wl3);
163 wh3 ^= wh2; wl3 ^= wl2 ^ 16; g0 (wh2,wl2, wh2,wl2);
164
165 /* third 8 rounds */
166 g4 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 17; wh4 ^= wh1;
167 g8 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 18; wh3 ^= wh4;
168 g2 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 19; wh2 ^= wh3;
169 g6 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 20; wh1 ^= wh2;
170 g0 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 21; wh4 ^= wh1;
171 g4 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 22; wh3 ^= wh4;
172 g8 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 23; wh2 ^= wh3;
173 g2 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 24; wh1 ^= wh2;
174
175 /* last 8 rounds */
176 wh2 ^= wh1; wl2 ^= wl1 ^ 25; g6 (wh1,wl1, wh1,wl1);
177 wh1 ^= wh4; wl1 ^= wl4 ^ 26; g0 (wh4,wl4, wh4,wl4);
178 wh4 ^= wh3; wl4 ^= wl3 ^ 27; g4 (wh3,wl3, wh3,wl3);
179 wh3 ^= wh2; wl3 ^= wl2 ^ 28; g8 (wh2,wl2, wh2,wl2);
180 wh2 ^= wh1; wl2 ^= wl1 ^ 29; g2 (wh1,wl1, wh1,wl1);
181 wh1 ^= wh4; wl1 ^= wl4 ^ 30; g6 (wh4,wl4, wh4,wl4);
182 wh4 ^= wh3; wl4 ^= wl3 ^ 31; g0 (wh3,wl3, wh3,wl3);
183 wh3 ^= wh2; wl3 ^= wl2 ^ 32; g4 (wh2,wl2, wh2,wl2);
184
185 /* pack into byte vector */
186 cipher [0] = wh1; cipher [1] = wl1;
187 cipher [2] = wh2; cipher [3] = wl2;
188 cipher [4] = wh3; cipher [5] = wl3;
189 cipher [6] = wh4; cipher [7] = wl4;
190}
191
192
193void
194skipjack_backwards (u_int8_t *cipher, u_int8_t *plain, u_int8_t **key_tables)
195{
196 /* setup 4 16-bit portions */
197 u_int8_t wh1 = cipher[0]; u_int8_t wl1 = cipher[1];
198 u_int8_t wh2 = cipher[2]; u_int8_t wl2 = cipher[3];
199 u_int8_t wh3 = cipher[4]; u_int8_t wl3 = cipher[5];
200 u_int8_t wh4 = cipher[6]; u_int8_t wl4 = cipher[7];
201
202 u_int8_t * k0 = key_tables [0];
203 u_int8_t * k1 = key_tables [1];
204 u_int8_t * k2 = key_tables [2];
205 u_int8_t * k3 = key_tables [3];
206 u_int8_t * k4 = key_tables [4];
207 u_int8_t * k5 = key_tables [5];
208 u_int8_t * k6 = key_tables [6];
209 u_int8_t * k7 = key_tables [7];
210 u_int8_t * k8 = key_tables [8];
211 u_int8_t * k9 = key_tables [9];
212
213 /* first 8 rounds */
214 g4_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 32; wh3 ^= wh2;
215 g0_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 31; wh4 ^= wh3;
216 g6_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 30; wh1 ^= wh4;
217 g2_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 29; wh2 ^= wh1;
218 g8_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 28; wh3 ^= wh2;
219 g4_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 27; wh4 ^= wh3;
220 g0_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 26; wh1 ^= wh4;
221 g6_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 25; wh2 ^= wh1;
222
223 /* second 8 rounds */
224 wh1 ^= wh2; wl1 ^= wl2 ^ 24; g2_inv (wh2,wl2, wh2,wl2);
225 wh2 ^= wh3; wl2 ^= wl3 ^ 23; g8_inv (wh3,wl3, wh3,wl3);
226 wh3 ^= wh4; wl3 ^= wl4 ^ 22; g4_inv (wh4,wl4, wh4,wl4);
227 wh4 ^= wh1; wl4 ^= wl1 ^ 21; g0_inv (wh1,wl1, wh1,wl1);
228 wh1 ^= wh2; wl1 ^= wl2 ^ 20; g6_inv (wh2,wl2, wh2,wl2);
229 wh2 ^= wh3; wl2 ^= wl3 ^ 19; g2_inv (wh3,wl3, wh3,wl3);
230 wh3 ^= wh4; wl3 ^= wl4 ^ 18; g8_inv (wh4,wl4, wh4,wl4);
231 wh4 ^= wh1; wl4 ^= wl1 ^ 17; g4_inv (wh1,wl1, wh1,wl1);
232
233 /* third 8 rounds */
234 g0_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 16; wh3 ^= wh2;
235 g6_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 15; wh4 ^= wh3;
236 g2_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 14; wh1 ^= wh4;
237 g8_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 13; wh2 ^= wh1;
238 g4_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 12; wh3 ^= wh2;
239 g0_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 11; wh4 ^= wh3;
240 g6_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 10; wh1 ^= wh4;
241 g2_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 9; wh2 ^= wh1;
242
243 /* last 8 rounds */
244 wh1 ^= wh2; wl1 ^= wl2 ^ 8; g8_inv (wh2,wl2, wh2,wl2);
245 wh2 ^= wh3; wl2 ^= wl3 ^ 7; g4_inv (wh3,wl3, wh3,wl3);
246 wh3 ^= wh4; wl3 ^= wl4 ^ 6; g0_inv (wh4,wl4, wh4,wl4);
247 wh4 ^= wh1; wl4 ^= wl1 ^ 5; g6_inv (wh1,wl1, wh1,wl1);
248 wh1 ^= wh2; wl1 ^= wl2 ^ 4; g2_inv (wh2,wl2, wh2,wl2);
249 wh2 ^= wh3; wl2 ^= wl3 ^ 3; g8_inv (wh3,wl3, wh3,wl3);
250 wh3 ^= wh4; wl3 ^= wl4 ^ 2; g4_inv (wh4,wl4, wh4,wl4);
251 wh4 ^= wh1; wl4 ^= wl1 ^ 1; g0_inv (wh1,wl1, wh1,wl1);
252
253 /* pack into byte vector */
254 plain [0] = wh1; plain [1] = wl1;
255 plain [2] = wh2; plain [3] = wl2;
256 plain [4] = wh3; plain [5] = wl3;
257 plain [6] = wh4; plain [7] = wl4;
258}
diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h
new file mode 100644
index 0000000000..4a51f15ddf
--- /dev/null
+++ b/src/lib/libc/include/namespace.h
@@ -0,0 +1,18 @@
1/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */
2
3#define catclose _catclose
4#define catgets _catgets
5#define catopen _catopen
6#define err _err
7#define errx _errx
8#define strtoq _strtoq
9#define strtouq _strtouq
10#define sys_errlist _sys_errlist
11#define sys_nerr _sys_nerr
12#define sys_siglist _sys_siglist
13#define verr _verr
14#define verrx _verrx
15#define vwarn _vwarn
16#define vwarnx _vwarnx
17#define warn _warn
18#define warnx _warnx
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h
new file mode 100644
index 0000000000..8cf06a86c4
--- /dev/null
+++ b/src/lib/libc/include/thread_private.h
@@ -0,0 +1,135 @@
1/* $OpenBSD: thread_private.h,v 1.11 2002/02/16 21:27:23 millert Exp $ */
2
3#ifndef _THREAD_PRIVATE_H_
4#define _THREAD_PRIVATE_H_
5
6#include <pthread.h>
7
8/*
9 * This variable is initially 0 when there is exactly one thread.
10 * It should never decrease.
11 */
12extern int __isthreaded;
13
14/*
15 * Weak symbols are used in libc so that the thread library can
16 * efficiently wrap libc functions.
17 *
18 * Use WEAK_NAME(n) to get a libc-private name for n (_weak_n),
19 * WEAK_ALIAS(n) to generate the weak symbol n pointing to _weak_n,
20 * WEAK_PROTOTYPE(n) to generate a prototype for _weak_n (based on n).
21 *
22 * If the symbol _NO_WEAK_ALIASES is defined, then symbols will be
23 */
24
25#ifdef _NO_WEAK_ALIASES
26#ifdef _THREAD_SAFE
27#define WEAK_NAME(name) __CONCAT(_weak,name)
28#else
29#define WEAK_NAME(name) name
30#endif
31#define WEAK_ALIAS(name) /* unavailable */
32#define WEAK_PROTOTYPE(name) /* unnecessary */
33#else /* !_NO_WEAK_ALIASES */
34#define WEAK_NAME(name) __CONCAT(_weak_,name)
35#define WEAK_ALIAS(name) __weak_alias(name, WEAK_NAME(name))
36#ifdef __GNUC__
37#define WEAK_PROTOTYPE(name) __typeof__(name) WEAK_NAME(name)
38#else
39#define WEAK_PROTOTYPE(name) /* typeof() only in gcc */
40#endif
41#endif /* !_NO_WEAK_ALIASES */
42
43/*
44 * These macros help in making persistent storage thread-specific.
45 * Libc makes extensive use of private static data structures
46 * that hold state across function invocation, and these macros
47 * are no-ops when running single-threaded.
48 *
49 * Linking against the user-thread library causes these macros to
50 * allocate storage on a per-thread basis.
51 */
52
53#define __THREAD_MUTEX_NAME(name) __CONCAT(_libc_storage_mutex_,name)
54#define __THREAD_KEY_NAME(name) __CONCAT(_libc_storage_key_,name)
55
56struct _thread_private_key_struct {
57 pthread_once_t once;
58 void (*cleanfn)(void *);
59 pthread_key_t key;
60};
61
62void _libc_private_storage_lock(pthread_mutex_t *);
63void _libc_private_storage_unlock(pthread_mutex_t *);
64void * _libc_private_storage(volatile struct _thread_private_key_struct *,
65 void *, size_t, void *);
66
67/* Declare a module mutex. */
68#define _THREAD_PRIVATE_MUTEX(name) \
69 static pthread_mutex_t __THREAD_MUTEX_NAME(name) = \
70 PTHREAD_MUTEX_INITIALIZER
71
72/* Lock a module mutex against use by any other threads. */
73#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
74 _libc_private_storage_lock(&__THREAD_MUTEX_NAME(name))
75
76/* Unlock a module mutex. */
77#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
78 _libc_private_storage_unlock(&__THREAD_MUTEX_NAME(name))
79
80/* Declare a thread-private storage key. */
81#define _THREAD_PRIVATE_KEY(name) \
82 static volatile struct _thread_private_key_struct \
83 __THREAD_KEY_NAME(name) = { \
84 PTHREAD_ONCE_INIT, \
85 0 \
86 }
87
88/*
89 * In threaded mode, return a pointer to thread-private memory of
90 * the same size as, and (initially) with the same contents as 'storage'. If
91 * an error occurs, the 'error' parameter is returned.
92 * In single-threaded mode, no storage is allocated. Instead, a pointer
93 * to storage is always returned.
94 * The 'cleanfn' function of the key structure is called to free the storage.
95 * If 'cleanfn' is NULL, then free() is used. This hook can be useful for
96 * getting rid of memory leaks.
97 */
98#define _THREAD_PRIVATE(keyname, storage, error) \
99 _libc_private_storage(&__THREAD_KEY_NAME(keyname), \
100 &(storage), sizeof (storage), error)
101
102/*
103 * Macros for locking and unlocking FILEs. These test if the
104 * process is threaded to avoid locking when not required.
105 */
106#ifdef _FLOCK_DEBUG
107#define FLOCKFILE(fp) _flockfile_debug(fp, __FILE__, __LINE__)
108#else
109#define FLOCKFILE(fp) flockfile(fp)
110#endif
111#define FUNLOCKFILE(fp) funlockfile(fp)
112
113/*
114 * File descriptor locking definitions.
115 */
116#define FD_READ 0x1
117#define FD_WRITE 0x2
118#define FD_RDWR (FD_READ | FD_WRITE)
119
120#ifdef _LOCK_DEBUG
121#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
122 _ts, __FILE__, __LINE__)
123#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
124 __FILE__, __LINE__)
125#else
126#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
127#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
128#endif
129
130int _thread_fd_lock(int, int, struct timespec *);
131int _thread_fd_lock_debug(int, int, struct timespec *, char *, int);
132void _thread_fd_unlock(int, int);
133void _thread_fd_unlock_debug(int, int, char *, int);
134
135#endif /* _THREAD_PRIVATE_H_ */
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
new file mode 100644
index 0000000000..805ae5d224
--- /dev/null
+++ b/src/lib/libc/net/Makefile.inc
@@ -0,0 +1,85 @@
1# $OpenBSD: Makefile.inc,v 1.31 2001/08/06 14:40:47 jakob Exp $
2
3# net sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net
5
6CFLAGS+=-DRESOLVSORT
7
8SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
9 getifaddrs.c getnameinfo.c getnetbyaddr.c getnetbyname.c getnetent.c \
10 getnetnamadr.c getproto.c getprotoent.c getprotoname.c \
11 getservbyname.c getservbyport.c getservent.c getrrsetbyname.c \
12 herror.c if_indextoname.c if_nameindex.c if_nametoindex.c inet_addr.c \
13 inet_lnaof.c inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
14 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c inet_pton.c \
15 ipx_addr.c ipx_ntoa.c iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c \
16 nsap_addr.c \
17 net_addrcmp.c \
18 rcmd.c rresvport.c recv.c res_comp.c res_data.c res_debug.c \
19 res_init.c res_mkquery.c res_query.c res_random.c res_send.c send.c \
20 sethostent.c ethers.c rcmdsh.c
21
22# IPv6
23SRCS+= ip6opt.c rthdr.c vars6.c
24
25# machine-dependent net sources
26# m-d Makefile.inc must include sources for:
27# htonl() htons() ntohl() ntohs()
28
29.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc"
30
31MAN+= byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 getifaddrs.3 \
32 getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 inet.3 \
33 if_indextoname.3 inet_net.3 iso_addr.3 link_addr.3 ns.3 ipx.3 \
34 rcmd.3 rcmdsh.3 resolver.3 net_addrcmp.3 \
35 inet6_option_space.3 inet6_rthdr_space.3 \
36 getrrsetbyname.3
37
38MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
39 byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \
40 byteorder.3 betoh16.3 byteorder.3 betoh32.3 byteorder.3 htole16.3 \
41 byteorder.3 htole32.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \
42 byteorder.3 swap16.3 byteorder.3 swap32.3
43MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
44 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 ethers.3 ether_addr.3
45MLINKS+= getaddrinfo.3 freeaddrinfo.3 getaddrinfo.3 gai_strerror.3
46MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
47 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
48 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \
49 gethostbyname.3 hstrerror.3
50MLINKS+=getifaddrs.3 freeifaddrs.3
51MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
52 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
53MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
54 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3
55MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
56 getservent.3 getservbyport.3 getservent.3 setservent.3
57MLINKS+= if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
58 if_indextoname.3 if_freenameindex.3
59MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \
60 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \
61 inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \
62 inet.3 ntoa.3 inet.3 inet_ntop.3 inet.3 inet_pton.3
63MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3
64MLINKS+=iso_addr.3 iso_ntoa.3
65MLINKS+=link_addr.3 link_ntoa.3
66MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
67MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
68MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 \
69 rcmd.3 rresvport_af.3 rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3
70MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
71 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
72 resolver.3 res_search.3
73MLINKS+=inet6_option_space.3 inet6_option_init.3 \
74 inet6_option_space.3 inet6_option_append.3 \
75 inet6_option_space.3 inet6_option_alloc.3 \
76 inet6_option_space.3 inet6_option_next.3 \
77 inet6_option_space.3 inet6_option_find.3
78MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \
79 inet6_rthdr_space.3 inet6_rthdr_add.3 \
80 inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \
81 inet6_rthdr_space.3 inet6_rthdr_reverse.3 \
82 inet6_rthdr_space.3 inet6_rthdr_segments.3 \
83 inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
84 inet6_rthdr_space.3 inet6_rthdr_getflags.3
85MLINKS+=getrrsetbyname.3 freerrset.3
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c
new file mode 100644
index 0000000000..33b6ffdc41
--- /dev/null
+++ b/src/lib/libc/net/base64.c
@@ -0,0 +1,318 @@
1/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/socket.h>
48#include <netinet/in.h>
49#include <arpa/inet.h>
50#include <arpa/nameser.h>
51
52#include <ctype.h>
53#include <resolv.h>
54#include <stdio.h>
55
56#include <stdlib.h>
57#include <string.h>
58
59/* XXX abort illegal in library */
60#define Assert(Cond) if (!(Cond)) abort()
61
62static const char Base64[] =
63 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
64static const char Pad64 = '=';
65
66/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
67 The following encoding technique is taken from RFC 1521 by Borenstein
68 and Freed. It is reproduced here in a slightly edited form for
69 convenience.
70
71 A 65-character subset of US-ASCII is used, enabling 6 bits to be
72 represented per printable character. (The extra 65th character, "=",
73 is used to signify a special processing function.)
74
75 The encoding process represents 24-bit groups of input bits as output
76 strings of 4 encoded characters. Proceeding from left to right, a
77 24-bit input group is formed by concatenating 3 8-bit input groups.
78 These 24 bits are then treated as 4 concatenated 6-bit groups, each
79 of which is translated into a single digit in the base64 alphabet.
80
81 Each 6-bit group is used as an index into an array of 64 printable
82 characters. The character referenced by the index is placed in the
83 output string.
84
85 Table 1: The Base64 Alphabet
86
87 Value Encoding Value Encoding Value Encoding Value Encoding
88 0 A 17 R 34 i 51 z
89 1 B 18 S 35 j 52 0
90 2 C 19 T 36 k 53 1
91 3 D 20 U 37 l 54 2
92 4 E 21 V 38 m 55 3
93 5 F 22 W 39 n 56 4
94 6 G 23 X 40 o 57 5
95 7 H 24 Y 41 p 58 6
96 8 I 25 Z 42 q 59 7
97 9 J 26 a 43 r 60 8
98 10 K 27 b 44 s 61 9
99 11 L 28 c 45 t 62 +
100 12 M 29 d 46 u 63 /
101 13 N 30 e 47 v
102 14 O 31 f 48 w (pad) =
103 15 P 32 g 49 x
104 16 Q 33 h 50 y
105
106 Special processing is performed if fewer than 24 bits are available
107 at the end of the data being encoded. A full encoding quantum is
108 always completed at the end of a quantity. When fewer than 24 input
109 bits are available in an input group, zero bits are added (on the
110 right) to form an integral number of 6-bit groups. Padding at the
111 end of the data is performed using the '=' character.
112
113 Since all base64 input is an integral number of octets, only the
114 -------------------------------------------------
115 following cases can arise:
116
117 (1) the final quantum of encoding input is an integral
118 multiple of 24 bits; here, the final unit of encoded
119 output will be an integral multiple of 4 characters
120 with no "=" padding,
121 (2) the final quantum of encoding input is exactly 8 bits;
122 here, the final unit of encoded output will be two
123 characters followed by two "=" padding characters, or
124 (3) the final quantum of encoding input is exactly 16 bits;
125 here, the final unit of encoded output will be three
126 characters followed by one "=" padding character.
127 */
128
129int
130b64_ntop(src, srclength, target, targsize)
131 u_char const *src;
132 size_t srclength;
133 char *target;
134 size_t targsize;
135{
136 size_t datalength = 0;
137 u_char input[3];
138 u_char output[4];
139 int i;
140
141 while (2 < srclength) {
142 input[0] = *src++;
143 input[1] = *src++;
144 input[2] = *src++;
145 srclength -= 3;
146
147 output[0] = input[0] >> 2;
148 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
149 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
150 output[3] = input[2] & 0x3f;
151 Assert(output[0] < 64);
152 Assert(output[1] < 64);
153 Assert(output[2] < 64);
154 Assert(output[3] < 64);
155
156 if (datalength + 4 > targsize)
157 return (-1);
158 target[datalength++] = Base64[output[0]];
159 target[datalength++] = Base64[output[1]];
160 target[datalength++] = Base64[output[2]];
161 target[datalength++] = Base64[output[3]];
162 }
163
164 /* Now we worry about padding. */
165 if (0 != srclength) {
166 /* Get what's left. */
167 input[0] = input[1] = input[2] = '\0';
168 for (i = 0; i < srclength; i++)
169 input[i] = *src++;
170
171 output[0] = input[0] >> 2;
172 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
173 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
174 Assert(output[0] < 64);
175 Assert(output[1] < 64);
176 Assert(output[2] < 64);
177
178 if (datalength + 4 > targsize)
179 return (-1);
180 target[datalength++] = Base64[output[0]];
181 target[datalength++] = Base64[output[1]];
182 if (srclength == 1)
183 target[datalength++] = Pad64;
184 else
185 target[datalength++] = Base64[output[2]];
186 target[datalength++] = Pad64;
187 }
188 if (datalength >= targsize)
189 return (-1);
190 target[datalength] = '\0'; /* Returned value doesn't count \0. */
191 return (datalength);
192}
193
194/* skips all whitespace anywhere.
195 converts characters, four at a time, starting at (or after)
196 src from base - 64 numbers into three 8 bit bytes in the target area.
197 it returns the number of data bytes stored at the target, or -1 on error.
198 */
199
200int
201b64_pton(src, target, targsize)
202 char const *src;
203 u_char *target;
204 size_t targsize;
205{
206 int tarindex, state, ch;
207 char *pos;
208
209 state = 0;
210 tarindex = 0;
211
212 while ((ch = *src++) != '\0') {
213 if (isspace(ch)) /* Skip whitespace anywhere. */
214 continue;
215
216 if (ch == Pad64)
217 break;
218
219 pos = strchr(Base64, ch);
220 if (pos == 0) /* A non-base64 character. */
221 return (-1);
222
223 switch (state) {
224 case 0:
225 if (target) {
226 if (tarindex >= targsize)
227 return (-1);
228 target[tarindex] = (pos - Base64) << 2;
229 }
230 state = 1;
231 break;
232 case 1:
233 if (target) {
234 if (tarindex + 1 >= targsize)
235 return (-1);
236 target[tarindex] |= (pos - Base64) >> 4;
237 target[tarindex+1] = ((pos - Base64) & 0x0f)
238 << 4 ;
239 }
240 tarindex++;
241 state = 2;
242 break;
243 case 2:
244 if (target) {
245 if (tarindex + 1 >= targsize)
246 return (-1);
247 target[tarindex] |= (pos - Base64) >> 2;
248 target[tarindex+1] = ((pos - Base64) & 0x03)
249 << 6;
250 }
251 tarindex++;
252 state = 3;
253 break;
254 case 3:
255 if (target) {
256 if (tarindex >= targsize)
257 return (-1);
258 target[tarindex] |= (pos - Base64);
259 }
260 tarindex++;
261 state = 0;
262 break;
263 }
264 }
265
266 /*
267 * We are done decoding Base-64 chars. Let's see if we ended
268 * on a byte boundary, and/or with erroneous trailing characters.
269 */
270
271 if (ch == Pad64) { /* We got a pad char. */
272 ch = *src++; /* Skip it, get next. */
273 switch (state) {
274 case 0: /* Invalid = in first position */
275 case 1: /* Invalid = in second position */
276 return (-1);
277
278 case 2: /* Valid, means one byte of info */
279 /* Skip any number of spaces. */
280 for (; ch != '\0'; ch = *src++)
281 if (!isspace(ch))
282 break;
283 /* Make sure there is another trailing = sign. */
284 if (ch != Pad64)
285 return (-1);
286 ch = *src++; /* Skip the = */
287 /* Fall through to "single trailing =" case. */
288 /* FALLTHROUGH */
289
290 case 3: /* Valid, means two bytes of info */
291 /*
292 * We know this char is an =. Is there anything but
293 * whitespace after it?
294 */
295 for (; ch != '\0'; ch = *src++)
296 if (!isspace(ch))
297 return (-1);
298
299 /*
300 * Now make sure for cases 2 and 3 that the "extra"
301 * bits that slopped past the last full byte were
302 * zeros. If we don't check them, they become a
303 * subliminal channel.
304 */
305 if (target && target[tarindex] != 0)
306 return (-1);
307 }
308 } else {
309 /*
310 * We ended by seeing the end of the string. Make sure we
311 * have no partial bytes lying around.
312 */
313 if (state != 0)
314 return (-1);
315 }
316
317 return (tarindex);
318}
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3
new file mode 100644
index 0000000000..9d8fa7221f
--- /dev/null
+++ b/src/lib/libc/net/byteorder.3
@@ -0,0 +1,183 @@
1.\" $OpenBSD: byteorder.3,v 1.8 2000/04/18 03:01:30 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt BYTEORDER 3
36.Os
37.Sh NAME
38.Nm htonl ,
39.Nm htons ,
40.Nm ntohl ,
41.Nm ntohs ,
42.Nm htobe32 ,
43.Nm htobe16 ,
44.Nm betoh32 ,
45.Nm betoh16 ,
46.Nm htole32 ,
47.Nm htole16 ,
48.Nm letoh32 ,
49.Nm letoh16 ,
50.Nm swap32 ,
51.Nm swap16
52.Nd convert values between different byte orderings
53.Sh SYNOPSIS
54.Fd #include <sys/types.h>
55.Fd #include <machine/endian.h>
56.Ft u_int32_t
57.Fn htonl "u_int32_t host32"
58.Ft u_int16_t
59.Fn htons "u_int16_t host16"
60.Ft u_int32_t
61.Fn ntohl "u_int32_t net32"
62.Ft u_int16_t
63.Fn ntohs "u_int16_t net16"
64.Ft u_int32_t
65.Fn htobe32 "u_int32_t host32"
66.Ft u_int16_t
67.Fn htobe16 "u_int16_t host16"
68.Ft u_int32_t
69.Fn betoh32 "u_int32_t big32"
70.Ft u_int16_t
71.Fn betoh16 "u_int16_t big16"
72.Ft u_int32_t
73.Fn htole32 "u_int32_t host32"
74.Ft u_int16_t
75.Fn htole16 "u_int16_t host16"
76.Ft u_int32_t
77.Fn letoh32 "u_int32_t little32"
78.Ft u_int16_t
79.Fn letoh16 "u_int16_t little16"
80.Ft u_int32_t
81.Fn swap32 "u_int32_t val32"
82.Ft u_int16_t
83.Fn swap16 "u_int16_t val16"
84.Sh DESCRIPTION
85These routines convert 16- and 32-bit quantities between different
86byte orderings.
87The
88.Dq swap
89functions reverse the byte ordering of
90the given quantity, the others converts either from/to the native
91byte order used by the host to/from either little- or big-endian (a.k.a
92network) order.
93.Pp
94Apart from the swap functions, the names can be described by this form:
95{src-order}to{dst-order}{size}.
96Both {src-order} and {dst-order} can take the following forms:
97.Pp
98.Bl -tag -width "be " -offset indent -compact
99.It h
100Host order.
101.It n
102Network order (big-endian).
103.It be
104Big-endian (most significant byte first).
105.It le
106Little-endian (least significant byte first).
107.El
108.Pp
109One of the specified orderings must be
110.Sq h .
111{size} will take these forms:
112.Pp
113.Bl -tag -width "32 " -offset indent -compact
114.It l
115Long (32-bit, used in conjunction with forms involving
116.Sq n ) .
117.It s
118Short (16-bit, used in conjunction with forms involving
119.Sq n ) .
120.It 16
12116-bit.
122.It 32
12332-bit.
124.El
125.Pp
126The swap functions are of the form: swap{size}.
127.Pp
128Names involving
129.Sq n
130convert quantities between network
131byte order and host byte order.
132The last letter
133.Pf ( Sq s
134or
135.Sq l )
136is a mnemonic
137for the traditional names for such quantities,
138.Li short
139and
140.Li long ,
141respectively.
142Today, the C concept of
143.Li short
144and
145.Li long
146integers need not coincide with this traditional misunderstanding.
147On machines which have a byte order which is the same as the network
148order, routines are defined as null macros.
149.Pp
150The functions involving either
151.Dq be ,
152.Dq le ,
153or
154.Dq swap
155use the numbers
15616 and 32 for specifying the bitwidth of the quantities they operate on.
157Currently all supported architectures are either big- or little-endian
158so either the
159.Dq be
160or
161.Dq le
162variants are implemented as null macros.
163.Pp
164The routines mentioned above which have either {src-order} or {dst-order}
165set to
166.Sq n
167are most often used in
168conjunction with Internet addresses and ports as returned by
169.Xr gethostbyname 3
170and
171.Xr getservent 3 .
172.Sh SEE ALSO
173.Xr gethostbyname 3 ,
174.Xr getservent 3
175.Sh HISTORY
176The
177.Nm byteorder
178functions appeared in
179.Bx 4.2 .
180.Sh BUGS
181On the vax, alpha, i386, and so far mips,
182bytes are handled backwards from most everyone else in the world.
183This is not expected to be fixed in the near future.
diff --git a/src/lib/libc/net/ethers.3 b/src/lib/libc/net/ethers.3
new file mode 100644
index 0000000000..0509c121b8
--- /dev/null
+++ b/src/lib/libc/net/ethers.3
@@ -0,0 +1,119 @@
1.\" $OpenBSD: ethers.3,v 1.14 2001/08/06 10:42:26 mpech Exp $
2.\"
3.\" Written by roland@frob.com. Public domain.
4.\"
5.Dd December 16, 1993
6.Dt ETHERS 3
7.Os
8.Sh NAME
9.Nm ether_aton ,
10.Nm ether_ntoa ,
11.Nm ether_addr ,
12.Nm ether_ntohost ,
13.Nm ether_hostton ,
14.Nm ether_line
15.Nd get ethers entry
16.Sh SYNOPSIS
17.Fd #include <netinet/if_ether.h>
18.Ft char *
19.Fn ether_ntoa "struct ether_addr *e"
20.Ft struct ether_addr *
21.Fn ether_aton "char *s"
22.Ft int
23.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
24.Ft int
25.Fn ether_hostton "char *hostname" "struct ether_addr *e"
26.Ft int
27.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
28.Sh DESCRIPTION
29Ethernet addresses are represented by the
30following structure:
31.Bd -literal -offset indent
32struct ether_addr {
33 u_int8_t ether_addr_octet[6];
34};
35.Ed
36.Pp
37The
38.Fn ether_ntoa
39function converts this structure into an
40.Tn ASCII
41string of the form
42.Dq xx:xx:xx:xx:xx:xx ,
43consisting of 6 hexadecimal numbers separated
44by colons.
45It returns a pointer to a static buffer that is reused for each call.
46The
47.Fn ether_aton
48converts an
49.Tn ASCII
50string of the same form and to a structure
51containing the 6 octets of the address.
52It returns a pointer to a static structure that is reused for each call.
53.Pp
54The
55.Fn ether_ntohost
56and
57.Fn ether_hostton
58functions interrogate the database mapping host names to Ethernet
59addresses,
60.Pa /etc/ethers .
61The
62.Fn ether_ntohost
63function looks up the given Ethernet address and writes the associated
64host name into the character buffer passed.
65This buffer should be
66.Dv MAXHOSTNAMELEN
67characters in size.
68The
69.Fn ether_hostton
70function looks up the given host name and writes the associated
71Ethernet address into the structure passed.
72Both functions return
73zero if they find the requested host name or address, and \-1 if not.
74.Pp
75Each call reads
76.Pa /etc/ethers
77from the beginning; if a
78.Ql +
79appears alone on a line in the file, then
80.Fn ether_hostton
81will consult the
82.Pa ethers.byname
83YP map, and
84.Fn ether_ntohost
85will consult the
86.Pa ethers.byaddr
87YP map.
88.Pp
89The
90.Fn ether_line
91function parses a line from the
92.Pa /etc/ethers
93file and fills in the passed
94.Li struct ether_addr
95and character buffer with the Ethernet address and host name on the line.
96It returns zero if the line was successfully parsed and \-1 if not.
97The character buffer should be
98.Dv MAXHOSTNAMELEN
99characters in size.
100.Sh FILES
101.Bl -tag -width /etc/ethers -compact
102.It Pa /etc/ethers
103.El
104.Sh SEE ALSO
105.Xr ethers 5
106.Sh HISTORY
107The
108.Fn ether_ntoa ,
109.Fn ether_aton ,
110.Fn ether_ntohost ,
111.Fn ether_hostton ,
112and
113.Fn ether_line
114functions were adopted from SunOS and appeared in
115.Nx 0.9 b.
116.Sh BUGS
117The data space used by these functions is static; if future use
118requires the data, it should be copied before any subsequent calls to
119these functions overwrite it.
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
new file mode 100644
index 0000000000..858ac5b3f3
--- /dev/null
+++ b/src/lib/libc/net/ethers.c
@@ -0,0 +1,272 @@
1/* $OpenBSD: ethers.c,v 1.14 2002/05/24 21:22:37 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * ethers(3) a la Sun.
32 * Originally Written by Roland McGrath <roland@frob.com> 10/14/93.
33 * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com>
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char rcsid[] = "$OpenBSD: ethers.c,v 1.14 2002/05/24 21:22:37 deraadt Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <net/if.h>
43#include <netinet/in.h>
44#include <netinet/if_ether.h>
45#include <sys/param.h>
46#include <paths.h>
47#include <errno.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <ctype.h>
52#ifdef YP
53#include <rpcsvc/ypclnt.h>
54#endif
55
56#ifndef _PATH_ETHERS
57#define _PATH_ETHERS "/etc/ethers"
58#endif
59
60static char * _ether_aton(char *, struct ether_addr *);
61
62char *
63ether_ntoa(e)
64 struct ether_addr *e;
65{
66 static char a[] = "xx:xx:xx:xx:xx:xx";
67
68 if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF ||
69 e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF ||
70 e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) {
71 errno = EINVAL;
72 return (NULL);
73 }
74
75 (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
76 e->ether_addr_octet[0], e->ether_addr_octet[1],
77 e->ether_addr_octet[2], e->ether_addr_octet[3],
78 e->ether_addr_octet[4], e->ether_addr_octet[5]);
79
80 return (a);
81}
82
83static char *
84_ether_aton(s, e)
85 char *s;
86 struct ether_addr *e;
87{
88 int i;
89 long l;
90 char *pp;
91
92 while (isspace(*s))
93 s++;
94
95 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
96 for (i = 0; i < 6; i++) {
97 l = strtol(s, &pp, 16);
98 if (pp == s || l > 0xFF || l < 0)
99 return (NULL);
100 if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
101 return (NULL);
102 e->ether_addr_octet[i] = (u_char)l;
103 s = pp + 1;
104 }
105
106 /* return character after the octets ala strtol(3) */
107 return (pp);
108}
109
110struct ether_addr *
111ether_aton(s)
112 char *s;
113{
114 static struct ether_addr n;
115
116 return (_ether_aton(s, &n) ? &n : NULL);
117}
118
119int
120ether_ntohost(hostname, e)
121 char *hostname;
122 struct ether_addr *e;
123{
124 FILE *f;
125 char buf[BUFSIZ+1], *p;
126 size_t len;
127 struct ether_addr try;
128#ifdef YP
129 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
130 int trylen;
131#endif
132
133 if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF ||
134 e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF ||
135 e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) {
136 errno = EINVAL;
137 return (-1);
138 }
139
140#ifdef YP
141 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
142 e->ether_addr_octet[0], e->ether_addr_octet[1],
143 e->ether_addr_octet[2], e->ether_addr_octet[3],
144 e->ether_addr_octet[4], e->ether_addr_octet[5]);
145 trylen = strlen(trybuf);
146#endif
147
148 f = fopen(_PATH_ETHERS, "r");
149 if (f == NULL)
150 return (-1);
151 while ((p = fgetln(f, &len)) != NULL) {
152 if (p[len-1] == '\n')
153 len--;
154 if (len > sizeof(buf) - 2)
155 continue;
156 (void)memcpy(buf, p, len);
157 buf[len] = '\n'; /* code assumes newlines later on */
158 buf[len+1] = '\0';
159#ifdef YP
160 /* A + in the file means try YP now. */
161 if (!strncmp(buf, "+\n", sizeof(buf))) {
162 char *ypbuf, *ypdom;
163 int ypbuflen;
164
165 if (yp_get_default_domain(&ypdom))
166 continue;
167 if (yp_match(ypdom, "ethers.byaddr", trybuf,
168 trylen, &ypbuf, &ypbuflen))
169 continue;
170 if (ether_line(ypbuf, &try, hostname) == 0) {
171 free(ypbuf);
172 (void)fclose(f);
173 return (0);
174 }
175 free(ypbuf);
176 continue;
177 }
178#endif
179 if (ether_line(buf, &try, hostname) == 0 &&
180 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
181 (void)fclose(f);
182 return (0);
183 }
184 }
185 (void)fclose(f);
186 errno = ENOENT;
187 return (-1);
188}
189
190int
191ether_hostton(hostname, e)
192 char *hostname;
193 struct ether_addr *e;
194{
195 FILE *f;
196 char buf[BUFSIZ+1], *p;
197 char try[MAXHOSTNAMELEN];
198 size_t len;
199#ifdef YP
200 int hostlen = strlen(hostname);
201#endif
202
203 f = fopen(_PATH_ETHERS, "r");
204 if (f==NULL)
205 return (-1);
206
207 while ((p = fgetln(f, &len)) != NULL) {
208 if (p[len-1] == '\n')
209 len--;
210 if (len > sizeof(buf) - 2)
211 continue;
212 memcpy(buf, p, len);
213 buf[len] = '\n'; /* code assumes newlines later on */
214 buf[len+1] = '\0';
215#ifdef YP
216 /* A + in the file means try YP now. */
217 if (!strncmp(buf, "+\n", sizeof(buf))) {
218 char *ypbuf, *ypdom;
219 int ypbuflen;
220
221 if (yp_get_default_domain(&ypdom))
222 continue;
223 if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
224 &ypbuf, &ypbuflen))
225 continue;
226 if (ether_line(ypbuf, e, try) == 0) {
227 free(ypbuf);
228 (void)fclose(f);
229 return (0);
230 }
231 free(ypbuf);
232 continue;
233 }
234#endif
235 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
236 (void)fclose(f);
237 return (0);
238 }
239 }
240 (void)fclose(f);
241 errno = ENOENT;
242 return (-1);
243}
244
245int
246ether_line(line, e, hostname)
247 char *line;
248 struct ether_addr *e;
249 char *hostname;
250{
251 char *p;
252 size_t n;
253
254 /* Parse "xx:xx:xx:xx:xx:xx" */
255 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
256 goto bad;
257
258 /* Now get the hostname */
259 while (isspace(*p))
260 p++;
261 if (*p == '\0')
262 goto bad;
263 n = strcspn(p, " \t\n");
264 if (n >= MAXHOSTNAMELEN)
265 goto bad;
266 strlcpy(hostname, p, n + 1);
267 return (0);
268
269bad:
270 errno = EINVAL;
271 return (-1);
272}
diff --git a/src/lib/libc/net/freeaddrinfo.c b/src/lib/libc/net/freeaddrinfo.c
new file mode 100644
index 0000000000..30fbecb805
--- /dev/null
+++ b/src/lib/libc/net/freeaddrinfo.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 1996, 1997, 1998, 1999, Craig Metz, All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Craig Metz and
15 * by other contributors.
16 * 4. Neither the name of the author nor the names of contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <stdlib.h>
34#include <netdb.h>
35
36void
37freeaddrinfo(ai)
38 struct addrinfo *ai;
39{
40 struct addrinfo *p;
41
42 do {
43 p = ai;
44 ai = ai->ai_next;
45 if (p->ai_canonname)
46 free(p->ai_canonname);
47 free((void *)p);
48 } while (ai);
49}
diff --git a/src/lib/libc/net/gai_strerror.c b/src/lib/libc/net/gai_strerror.c
new file mode 100644
index 0000000000..a191cb5b28
--- /dev/null
+++ b/src/lib/libc/net/gai_strerror.c
@@ -0,0 +1,76 @@
1/* $OpenBSD: gai_strerror.c,v 1.5 2001/06/05 02:31:34 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1997-1999, Craig Metz, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Craig Metz and
17 * by other contributors.
18 * 4. Neither the name of the author nor the names of contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/* gai_strerror() v1.38 */
36
37#include <sys/types.h>
38#include <netdb.h>
39#include <errno.h>
40
41char *
42gai_strerror(int errnum)
43{
44 switch (errnum) {
45 case 0:
46 return "no error";
47 case EAI_BADFLAGS:
48 return "invalid value for ai_flags";
49 case EAI_NONAME:
50 return "name or service is not known";
51 case EAI_AGAIN:
52 return "temporary failure in name resolution";
53 case EAI_FAIL:
54 return "non-recoverable failure in name resolution";
55 case EAI_NODATA:
56 return "no address associated with name";
57 case EAI_FAMILY:
58 return "ai_family not supported";
59 case EAI_SOCKTYPE:
60 return "ai_socktype not supported";
61 case EAI_SERVICE:
62 return "service not supported for ai_socktype";
63 case EAI_ADDRFAMILY:
64 return "address family for name not supported";
65 case EAI_MEMORY:
66 return "memory allocation failure";
67 case EAI_SYSTEM:
68 return "system error";
69 case EAI_BADHINTS:
70 return "invalid value for hints";
71 case EAI_PROTOCOL:
72 return "resolved protocol is unknown";
73 default:
74 return "unknown/invalid error";
75 }
76}
diff --git a/src/lib/libc/net/getaddrinfo.3 b/src/lib/libc/net/getaddrinfo.3
new file mode 100644
index 0000000000..5c4be16732
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.3
@@ -0,0 +1,581 @@
1.\" $OpenBSD: getaddrinfo.3,v 1.20 2002/04/30 16:31:42 mpech Exp $
2.\" $KAME: getaddrinfo.3,v 1.29 2001/02/12 09:24:45 itojun Exp $
3.\"
4.\" Copyright (c) 1983, 1987, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
36.\"
37.Dd May 25, 1995
38.Dt GETADDRINFO 3
39.Os
40.\"
41.Sh NAME
42.Nm getaddrinfo ,
43.Nm freeaddrinfo ,
44.Nm gai_strerror
45.Nd nodename-to-address translation in protocol-independent manner
46.\"
47.Sh SYNOPSIS
48.Fd #include <sys/types.h>
49.Fd #include <sys/socket.h>
50.Fd #include <netdb.h>
51.Ft int
52.Fn getaddrinfo "const char *nodename" "const char *servname" \
53"const struct addrinfo *hints" "struct addrinfo **res"
54.Ft void
55.Fn freeaddrinfo "struct addrinfo *ai"
56.Ft "char *"
57.Fn gai_strerror "int ecode"
58.\"
59.Sh DESCRIPTION
60The
61.Fn getaddrinfo
62function is defined for protocol-independent nodename-to-address translation.
63It performs the functionality of
64.Xr gethostbyname 3
65and
66.Xr getservbyname 3 ,
67but in a more sophisticated manner.
68.Pp
69The
70.Li addrinfo
71structure is defined as a result of including the
72.Aq Pa netdb.h
73header:
74.Bd -literal -offset
75struct addrinfo { *
76 int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
77 int ai_family; /* PF_xxx */
78 int ai_socktype; /* SOCK_xxx */
79 int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
80 size_t ai_addrlen; /* length of ai_addr */
81 char *ai_canonname; /* canonical name for nodename */
82 struct sockaddr *ai_addr; /* binary address */
83 struct addrinfo *ai_next; /* next structure in linked list */
84};
85.Ed
86.Pp
87The
88.Fa nodename
89and
90.Fa servname
91arguments are pointers to NUL-terminated strings or
92.Dv NULL .
93One or both of these two arguments must be a non-null pointer.
94In the normal client scenario, both the
95.Fa nodename
96and
97.Fa servname
98are specified.
99In the normal server scenario, only the
100.Fa servname
101is specified.
102A non-null
103.Fa nodename
104string can be either a node name or a numeric host address string
105(i.e., a dotted-decimal IPv4 address or an IPv6 hex address).
106A non-null
107.Fa servname
108string can be either a service name or a decimal port number.
109.Pp
110The caller can optionally pass an
111.Li addrinfo
112structure, pointed to by the third argument,
113to provide hints concerning the type of socket that the caller supports.
114In this
115.Fa hints
116structure all members other than
117.Fa ai_flags ,
118.Fa ai_family ,
119.Fa ai_socktype ,
120and
121.Fa ai_protocol
122must be zero or a null pointer.
123A value of
124.Dv PF_UNSPEC
125for
126.Fa ai_family
127means the caller will accept any protocol family.
128A value of 0 for
129.Fa ai_socktype
130means the caller will accept any socket type.
131A value of 0 for
132.Fa ai_protocol
133means the caller will accept any protocol.
134For example, if the caller handles only TCP and not UDP, then the
135.Fa ai_socktype
136member of the hints structure should be set to
137.Dv SOCK_STREAM
138when
139.Fn getaddrinfo
140is called.
141If the caller handles only IPv4 and not IPv6, then the
142.Fa ai_family
143member of the
144.Fa hints
145structure should be set to
146.Dv PF_INET
147when
148.Fn getaddrinfo
149is called.
150If the third argument to
151.Fn getaddrinfo
152is a null pointer, this is the same as if the caller had filled in an
153.Li addrinfo
154structure initialized to zero with
155.Fa ai_family
156set to
157.Dv PF_UNSPEC .
158.Pp
159Upon successful return a pointer to a linked list of one or more
160.Li addrinfo
161structures is returned through the final argument.
162The caller can process each
163.Li addrinfo
164structure in this list by following the
165.Fa ai_next
166pointer, until a null pointer is encountered.
167In each returned
168.Li addrinfo
169structure the three members
170.Fa ai_family ,
171.Fa ai_socktype ,
172and
173.Fa ai_protocol
174are the corresponding arguments for a call to the
175.Fn socket
176function.
177In each
178.Li addrinfo
179structure the
180.Fa ai_addr
181member points to a filled-in socket address structure whose length is
182specified by the
183.Fa ai_addrlen
184member.
185.Pp
186If the
187.Dv AI_PASSIVE
188bit is set in the
189.Fa ai_flags
190member of the
191.Fa hints
192structure, then the caller plans to use the returned socket address
193structure in a call to
194.Fn bind .
195In this case, if the
196.Fa nodename
197argument is a null pointer, then the IP address portion of the socket
198address structure will be set to
199.Dv INADDR_ANY
200for an IPv4 address or
201.Dv IN6ADDR_ANY_INIT
202for an IPv6 address.
203.Pp
204If the
205.Dv AI_PASSIVE
206bit is not set in the
207.Fa ai_flags
208member of the
209.Fa hints
210structure, then the returned socket address structure will be ready for a
211call to
212.Fn connect
213.Pq for a connection-oriented protocol
214or either
215.Fn connect ,
216.Fn sendto ,
217or
218.Fn sendmsg
219.Pq for a connectionless protocol .
220In this case, if the
221.Fa nodename
222argument is a null pointer, then the IP address portion of the
223socket address structure will be set to the loopback address.
224.Pp
225If the
226.Dv AI_CANONNAME
227bit is set in the
228.Fa ai_flags
229member of the
230.Fa hints
231structure, then upon successful return the
232.Fa ai_canonname
233member of the first
234.Li addrinfo
235structure in the linked list will point to a NUL-terminated string
236containing the canonical name of the specified
237.Fa nodename .
238.Pp
239If the
240.Dv AI_NUMERICHOST
241bit is set in the
242.Fa ai_flags
243member of the
244.Fa hints
245structure, then a non-null
246.Fa nodename
247string must be a numeric host address string.
248Otherwise an error of
249.Dv EAI_NONAME
250is returned.
251This flag prevents any type of name resolution service (e.g., the DNS)
252from being called.
253.Pp
254The arguments to
255.Fn getaddrinfo
256must sufficiently be consistent and unambiguous.
257Here are pitfall cases you may encounter:
258.Bl -bullet
259.It
260.Fn getaddrinfo
261will raise an error if members of the
262.Fa hints
263structure are not consistent.
264For example, for internet address families,
265.Fn getaddrinfo
266will raise an error if you specify
267.Dv SOCK_STREAM
268to
269.Fa ai_socktype
270while you specify
271.Dv IPPROTO_UDP
272to
273.Fa ai_protocol .
274.It
275If you specify a
276.Fa servname
277which is defined only for certain
278.Fa ai_socktype ,
279.Fn getaddrinfo
280will raise an error because the arguments are not consistent.
281For example,
282.Fn getaddrinfo
283will raise an error if you ask for
284.Dq Li tftp
285service on
286.Dv SOCK_STREAM .
287.It
288For internet address families, if you specify
289.Fa servname
290while you set
291.Fa ai_socktype
292to
293.Dv SOCK_RAW ,
294.Fn getaddrinfo
295will raise an error, because service names are not defined for the internet
296.Dv SOCK_RAW
297space.
298.It
299If you specify a numeric
300.Fa servname ,
301while leaving
302.Fa ai_socktype
303and
304.Fa ai_protocol
305unspecified,
306.Fn getaddrinfo
307will raise an error.
308This is because the numeric
309.Fa servname
310does not identify any socket type, and
311.Fn getaddrinfo
312is not allowed to glob the argument in such case.
313.El
314.Pp
315All of the information returned by
316.Fn getaddrinfo
317is dynamically allocated:
318the
319.Li addrinfo
320structures, the socket address structures, and canonical node name
321strings pointed to by the addrinfo structures.
322To return this information to the system the function
323.Fn freeaddrinfo
324is called.
325The
326.Fa addrinfo
327structure pointed to by the
328.Fa ai argument
329is freed, along with any dynamic storage pointed to by the structure.
330This operation is repeated until a
331.Dv NULL
332.Fa ai_next
333pointer is encountered.
334.Pp
335To aid applications in printing error messages based on the
336.Dv EAI_xxx
337codes returned by
338.Fn getaddrinfo ,
339.Fn gai_strerror
340is defined.
341The argument is one of the
342.Dv EAI_xxx
343values defined earlier and the return value points to a string describing
344the error.
345If the argument is not one of the
346.Dv EAI_xxx
347values, the function still returns a pointer to a string whose contents
348indicate an unknown error.
349.\"
350.Ss Extension for scoped IPv6 address
351The implementation allows experimental numeric IPv6 address notation with
352scope identifier.
353By appending the percent character and scope identifier to addresses,
354you can fill
355.Li sin6_scope_id
356field for addresses.
357This would make management of scoped address easier,
358and allows cut-and-paste input of scoped address.
359.Pp
360At this moment the code supports only link-local addresses with the format.
361Scope identifier is hardcoded to name of hardware interface associated
362with the link.
363.Po
364such as
365.Li ne0
366.Pc .
367Example would be like
368.Dq Li fe80::1%ne0 ,
369which means
370.Do
371.Li fe80::1
372on the link associated with
373.Li ne0
374interface
375.Dc .
376.Pp
377The implementation is still very experimental and non-standard.
378The current implementation assumes one-by-one relationship between
379interface and link, which is not necessarily true from the specification.
380.\"
381.Sh EXAMPLES
382The following code tries to connect to
383.Dq Li www.kame.net
384service
385.Dq Li http .
386via stream socket.
387It loops through all the addresses available, regardless from address family.
388If the destination resolves to IPv4 address, it will use
389.Dv AF_INET
390socket.
391Similarly, if it resolves to IPv6,
392.Dv AF_INET6
393socket is used.
394Observe that there is no hardcoded reference to particular address family.
395The code works even if
396.Nm getaddrinfo
397returns addresses that are not IPv4/v6.
398.Bd -literal -offset indent
399struct addrinfo hints, *res, *res0;
400int error;
401int s;
402const char *cause = NULL;
403
404memset(&hints, 0, sizeof(hints));
405hints.ai_family = PF_UNSPEC;
406hints.ai_socktype = SOCK_STREAM;
407error = getaddrinfo("www.kame.net", "http", &hints, &res0);
408if (error) {
409 errx(1, "%s", gai_strerror(error));
410 /*NOTREACHED*/
411}
412s = -1;
413for (res = res0; res; res = res->ai_next) {
414 s = socket(res->ai_family, res->ai_socktype,
415 res->ai_protocol);
416 if (s < 0) {
417 cause = "socket";
418 continue;
419 }
420
421 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
422 cause = "connect";
423 close(s);
424 s = -1;
425 continue;
426 }
427
428 break; /* okay we got one */
429}
430if (s < 0) {
431 err(1, cause);
432 /*NOTREACHED*/
433}
434freeaddrinfo(res0);
435.Ed
436.Pp
437The following example tries to open a wildcard listening socket onto service
438.Dq Li http ,
439for all the address families available.
440.Bd -literal -offset indent
441struct addrinfo hints, *res, *res0;
442int error;
443int s[MAXSOCK];
444int nsock;
445const char *cause = NULL;
446
447memset(&hints, 0, sizeof(hints));
448hints.ai_family = PF_UNSPEC;
449hints.ai_socktype = SOCK_STREAM;
450hints.ai_flags = AI_PASSIVE;
451error = getaddrinfo(NULL, "http", &hints, &res0);
452if (error) {
453 errx(1, "%s", gai_strerror(error));
454 /*NOTREACHED*/
455}
456nsock = 0;
457for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
458 s[nsock] = socket(res->ai_family, res->ai_socktype,
459 res->ai_protocol);
460 if (s[nsock] < 0) {
461 cause = "socket";
462 continue;
463 }
464
465 if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) {
466 cause = "bind";
467 close(s[nsock]);
468 continue;
469 }
470 (void) listen(s[nsock], 5);
471
472 nsock++;
473}
474if (nsock == 0) {
475 err(1, cause);
476 /*NOTREACHED*/
477}
478freeaddrinfo(res0);
479.Ed
480.\"
481.Sh DIAGNOSTICS
482Error return status from
483.Fn getaddrinfo
484is zero on success and non-zero on errors.
485Non-zero error codes are defined in
486.Aq Pa netdb.h ,
487and as follows:
488.Pp
489.Bl -tag -width EAI_ADDRFAMILY -compact
490.It Dv EAI_ADDRFAMILY
491Address family for
492.Fa nodename
493not supported.
494.It Dv EAI_AGAIN
495Temporary failure in name resolution.
496.It Dv EAI_BADFLAGS
497Invalid value for
498.Fa ai_flags .
499.It Dv EAI_FAIL
500Non-recoverable failure in name resolution.
501.It Dv EAI_FAMILY
502.Fa ai_family
503not supported.
504.It Dv EAI_MEMORY
505Memory allocation failure.
506.It Dv EAI_NODATA
507No address associated with
508.Fa nodename .
509.It Dv EAI_NONAME
510.Fa nodename
511nor
512.Fa servname
513provided, or not known.
514.It Dv EAI_SERVICE
515.Fa servname
516not supported for
517.Fa ai_socktype .
518.It Dv EAI_SOCKTYPE
519.Fa ai_socktype
520not supported.
521.It Dv EAI_SYSTEM
522System error returned in
523.Va errno .
524.El
525.Pp
526If called with proper argument,
527.Fn gai_strerror
528returns a pointer to a string describing the given error code.
529If the argument is not one of the
530.Dv EAI_xxx
531values, the function still returns a pointer to a string whose contents
532indicate an unknown error.
533.\"
534.Sh SEE ALSO
535.Xr getnameinfo 3 ,
536.Xr gethostbyname 3 ,
537.Xr getservbyname 3 ,
538.Xr hosts 5 ,
539.Xr resolv.conf 5 ,
540.Xr services 5 ,
541.Xr hostname 7 ,
542.Xr named 8
543.Rs
544.%A R. Gilligan
545.%A S. Thomson
546.%A J. Bound
547.%A W. Stevens
548.%T Basic Socket Interface Extensions for IPv6
549.%R RFC2553
550.%D March 1999
551.Re
552.Rs
553.%A Tatsuya Jinmei
554.%A Atsushi Onoe
555.%T "An Extension of Format for IPv6 Scoped Addresses"
556.%R internet draft
557.%N draft-ietf-ipngwg-scopedaddr-format-02.txt
558.%O work in progress material
559.Re
560.Rs
561.%A Craig Metz
562.%T Protocol Independence Using the Sockets API
563.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
564.%D June 2000
565.Re
566.\"
567.Sh HISTORY
568The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
569.\"
570.Sh STANDARDS
571The
572.Fn getaddrinfo
573function is defined in IEEE POSIX 1003.1g draft specification,
574and documented in
575.Dq Basic Socket Interface Extensions for IPv6
576.Pq RFC2553 .
577.\"
578.Sh BUGS
579The current implementation is not thread-safe.
580.Pp
581The text was shamelessly copied from RFC2553.
diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c
new file mode 100644
index 0000000000..915286a404
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.c
@@ -0,0 +1,1848 @@
1/* $OpenBSD: getaddrinfo.c,v 1.43 2002/08/27 08:53:13 itojun Exp $ */
2/* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Issues to be discussed:
35 * - Thread safe-ness must be checked.
36 * - Return values. There are nonstandard return values defined and used
37 * in the source code. This is because RFC2553 is silent about which error
38 * code must be returned for which situation.
39 * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2
40 * says to use inet_aton() to convert IPv4 numeric to binary (alows
41 * classful form as a result).
42 * current code - disallow classful form for IPv4 (due to use of inet_pton).
43 * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is
44 * invalid.
45 * current code - SEGV on freeaddrinfo(NULL)
46 * Note:
47 * - We use getipnodebyname() just for thread-safeness. There's no intent
48 * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
49 * getipnodebyname().
50 * - The code filters out AFs that are not supported by the kernel,
51 * when globbing NULL hostname (to loopback, or wildcard). Is it the right
52 * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG
53 * in ai_flags?
54 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
55 * (1) what should we do against numeric hostname (2) what should we do
56 * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready?
57 * non-loopback address configured? global address configured?
58 * - To avoid search order issue, we have a big amount of code duplicate
59 * from gethnamaddr.c and some other places. The issues that there's no
60 * lower layer function to lookup "IPv4 or IPv6" record. Calling
61 * gethostbyname2 from getaddrinfo will end up in wrong search order, as
62 * follows:
63 * - The code makes use of following calls when asked to resolver with
64 * ai_family = PF_UNSPEC:
65 * getipnodebyname(host, AF_INET6);
66 * getipnodebyname(host, AF_INET);
67 * This will result in the following queries if the node is configure to
68 * prefer /etc/hosts than DNS:
69 * lookup /etc/hosts for IPv6 address
70 * lookup DNS for IPv6 address
71 * lookup /etc/hosts for IPv4 address
72 * lookup DNS for IPv4 address
73 * which may not meet people's requirement.
74 * The right thing to happen is to have underlying layer which does
75 * PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
76 * This would result in a bit of code duplicate with _dns_ghbyname() and
77 * friends.
78 */
79
80#ifndef INET6
81#define INET6
82#endif
83
84#include <sys/types.h>
85#include <sys/param.h>
86#include <sys/socket.h>
87#include <net/if.h>
88#include <netinet/in.h>
89#include <arpa/inet.h>
90#include <arpa/nameser.h>
91#include <netdb.h>
92#include <resolv.h>
93#include <string.h>
94#include <stdlib.h>
95#include <stddef.h>
96#include <ctype.h>
97#include <unistd.h>
98#include <stdio.h>
99#include <errno.h>
100
101#include <syslog.h>
102#include <stdarg.h>
103
104#ifdef YP
105#include <rpc/rpc.h>
106#include <rpcsvc/yp.h>
107#include <rpcsvc/ypclnt.h>
108#include "ypinternal.h"
109#endif
110
111#include "thread_private.h"
112
113#define SUCCESS 0
114#define ANY 0
115#define YES 1
116#define NO 0
117
118static const char in_addrany[] = { 0, 0, 0, 0 };
119static const char in6_addrany[] = {
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
121};
122static const char in_loopback[] = { 127, 0, 0, 1 };
123static const char in6_loopback[] = {
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
125};
126
127static const struct afd {
128 int a_af;
129 int a_addrlen;
130 int a_socklen;
131 int a_off;
132 const char *a_addrany;
133 const char *a_loopback;
134 int a_scoped;
135} afdl [] = {
136#ifdef INET6
137 {PF_INET6, sizeof(struct in6_addr),
138 sizeof(struct sockaddr_in6),
139 offsetof(struct sockaddr_in6, sin6_addr),
140 in6_addrany, in6_loopback, 1},
141#endif
142 {PF_INET, sizeof(struct in_addr),
143 sizeof(struct sockaddr_in),
144 offsetof(struct sockaddr_in, sin_addr),
145 in_addrany, in_loopback, 0},
146 {0, 0, 0, 0, NULL, NULL, 0},
147};
148
149struct explore {
150 int e_af;
151 int e_socktype;
152 int e_protocol;
153 const char *e_protostr;
154 int e_wild;
155#define WILD_AF(ex) ((ex)->e_wild & 0x01)
156#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
157#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
158};
159
160static const struct explore explore[] = {
161#if 0
162 { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
163#endif
164#ifdef INET6
165 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
166 { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
167 { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
168#endif
169 { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
170 { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
171 { PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
172 { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
173 { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
174 { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
175 { -1, 0, 0, NULL, 0 },
176};
177
178#ifdef INET6
179#define PTON_MAX 16
180#else
181#define PTON_MAX 4
182#endif
183
184#define MAXPACKET (64*1024)
185
186typedef union {
187 HEADER hdr;
188 u_char buf[MAXPACKET];
189} querybuf;
190
191struct res_target {
192 struct res_target *next;
193 const char *name; /* domain name */
194 int qclass, qtype; /* class and type of query */
195 u_char *answer; /* buffer to put answer */
196 int anslen; /* size of answer buffer */
197 int n; /* result length */
198};
199
200static int str_isnumber(const char *);
201static int explore_fqdn(const struct addrinfo *, const char *,
202 const char *, struct addrinfo **);
203static int explore_null(const struct addrinfo *,
204 const char *, struct addrinfo **);
205static int explore_numeric(const struct addrinfo *, const char *,
206 const char *, struct addrinfo **);
207static int explore_numeric_scope(const struct addrinfo *, const char *,
208 const char *, struct addrinfo **);
209static int get_canonname(const struct addrinfo *,
210 struct addrinfo *, const char *);
211static struct addrinfo *get_ai(const struct addrinfo *,
212 const struct afd *, const char *);
213static int get_portmatch(const struct addrinfo *, const char *);
214static int get_port(struct addrinfo *, const char *, int);
215static const struct afd *find_afd(int);
216#if 0
217static int addrconfig(const struct addrinfo *);
218#endif
219#ifdef INET6
220static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
221#endif
222
223static void _sethtent(void);
224static void _endhtent(void);
225static struct addrinfo * _gethtent(const char *, const struct addrinfo *);
226static struct addrinfo *_files_getaddrinfo(const char *,
227 const struct addrinfo *);
228
229#ifdef YP
230static struct addrinfo *_yphostent(char *, const struct addrinfo *);
231static struct addrinfo *_yp_getaddrinfo(const char *,
232 const struct addrinfo *);
233#endif
234
235static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
236 const struct addrinfo *);
237static int res_queryN(const char *, struct res_target *);
238static int res_searchN(const char *, struct res_target *);
239static int res_querydomainN(const char *, const char *, struct res_target *);
240static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *);
241
242
243/* XXX macros that make external reference is BAD. */
244
245#define GET_AI(ai, afd, addr) \
246do { \
247 /* external reference: pai, error, and label free */ \
248 (ai) = get_ai(pai, (afd), (addr)); \
249 if ((ai) == NULL) { \
250 error = EAI_MEMORY; \
251 goto free; \
252 } \
253} while (/*CONSTCOND*/0)
254
255#define GET_PORT(ai, serv) \
256do { \
257 /* external reference: error and label free */ \
258 error = get_port((ai), (serv), 0); \
259 if (error != 0) \
260 goto free; \
261} while (/*CONSTCOND*/0)
262
263#define GET_CANONNAME(ai, str) \
264do { \
265 /* external reference: pai, error and label free */ \
266 error = get_canonname(pai, (ai), (str)); \
267 if (error != 0) \
268 goto free; \
269} while (/*CONSTCOND*/0)
270
271#define ERR(err) \
272do { \
273 /* external reference: error, and label bad */ \
274 error = (err); \
275 goto bad; \
276 /*NOTREACHED*/ \
277} while (/*CONSTCOND*/0)
278
279#define MATCH_FAMILY(x, y, w) \
280 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
281#define MATCH(x, y, w) \
282 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
283
284static int
285str_isnumber(p)
286 const char *p;
287{
288 char *ep;
289
290 if (*p == '\0')
291 return NO;
292 ep = NULL;
293 errno = 0;
294 (void)strtoul(p, &ep, 10);
295 if (errno == 0 && ep && *ep == '\0')
296 return YES;
297 else
298 return NO;
299}
300
301int
302getaddrinfo(hostname, servname, hints, res)
303 const char *hostname, *servname;
304 const struct addrinfo *hints;
305 struct addrinfo **res;
306{
307 struct addrinfo sentinel;
308 struct addrinfo *cur;
309 int error = 0;
310 struct addrinfo ai;
311 struct addrinfo ai0;
312 struct addrinfo *pai;
313 const struct explore *ex;
314
315 memset(&sentinel, 0, sizeof(sentinel));
316 cur = &sentinel;
317 pai = &ai;
318 pai->ai_flags = 0;
319 pai->ai_family = PF_UNSPEC;
320 pai->ai_socktype = ANY;
321 pai->ai_protocol = ANY;
322 pai->ai_addrlen = 0;
323 pai->ai_canonname = NULL;
324 pai->ai_addr = NULL;
325 pai->ai_next = NULL;
326
327 if (hostname == NULL && servname == NULL)
328 return EAI_NONAME;
329 if (hints) {
330 /* error check for hints */
331 if (hints->ai_addrlen || hints->ai_canonname ||
332 hints->ai_addr || hints->ai_next)
333 ERR(EAI_BADHINTS); /* xxx */
334 if (hints->ai_flags & ~AI_MASK)
335 ERR(EAI_BADFLAGS);
336 switch (hints->ai_family) {
337 case PF_UNSPEC:
338 case PF_INET:
339#ifdef INET6
340 case PF_INET6:
341#endif
342 break;
343 default:
344 ERR(EAI_FAMILY);
345 }
346 memcpy(pai, hints, sizeof(*pai));
347
348 /*
349 * if both socktype/protocol are specified, check if they
350 * are meaningful combination.
351 */
352 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
353 for (ex = explore; ex->e_af >= 0; ex++) {
354 if (pai->ai_family != ex->e_af)
355 continue;
356 if (ex->e_socktype == ANY)
357 continue;
358 if (ex->e_protocol == ANY)
359 continue;
360 if (pai->ai_socktype == ex->e_socktype
361 && pai->ai_protocol != ex->e_protocol) {
362 ERR(EAI_BADHINTS);
363 }
364 }
365 }
366 }
367
368 /*
369 * check for special cases. (1) numeric servname is disallowed if
370 * socktype/protocol are left unspecified. (2) servname is disallowed
371 * for raw and other inet{,6} sockets.
372 */
373 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
374#ifdef PF_INET6
375 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
376#endif
377 ) {
378 ai0 = *pai; /* backup *pai */
379
380 if (pai->ai_family == PF_UNSPEC) {
381#ifdef PF_INET6
382 pai->ai_family = PF_INET6;
383#else
384 pai->ai_family = PF_INET;
385#endif
386 }
387 error = get_portmatch(pai, servname);
388 if (error)
389 ERR(error);
390
391 *pai = ai0;
392 }
393
394 ai0 = *pai;
395
396 /* NULL hostname, or numeric hostname */
397 for (ex = explore; ex->e_af >= 0; ex++) {
398 *pai = ai0;
399
400 /* PF_UNSPEC entries are prepared for DNS queries only */
401 if (ex->e_af == PF_UNSPEC)
402 continue;
403
404 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
405 continue;
406 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
407 continue;
408 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
409 continue;
410
411 if (pai->ai_family == PF_UNSPEC)
412 pai->ai_family = ex->e_af;
413 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
414 pai->ai_socktype = ex->e_socktype;
415 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
416 pai->ai_protocol = ex->e_protocol;
417
418 if (hostname == NULL)
419 error = explore_null(pai, servname, &cur->ai_next);
420 else
421 error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next);
422
423 if (error)
424 goto free;
425
426 while (cur && cur->ai_next)
427 cur = cur->ai_next;
428 }
429
430 /*
431 * XXX
432 * If numreic representation of AF1 can be interpreted as FQDN
433 * representation of AF2, we need to think again about the code below.
434 */
435 if (sentinel.ai_next)
436 goto good;
437
438 if (pai->ai_flags & AI_NUMERICHOST)
439 ERR(EAI_NODATA);
440 if (hostname == NULL)
441 ERR(EAI_NODATA);
442
443 /*
444 * hostname as alphabetical name.
445 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
446 * outer loop by AFs.
447 */
448 for (ex = explore; ex->e_af >= 0; ex++) {
449 *pai = ai0;
450
451 /* require exact match for family field */
452 if (pai->ai_family != ex->e_af)
453 continue;
454
455 if (!MATCH(pai->ai_socktype, ex->e_socktype,
456 WILD_SOCKTYPE(ex))) {
457 continue;
458 }
459 if (!MATCH(pai->ai_protocol, ex->e_protocol,
460 WILD_PROTOCOL(ex))) {
461 continue;
462 }
463
464 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
465 pai->ai_socktype = ex->e_socktype;
466 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
467 pai->ai_protocol = ex->e_protocol;
468
469 error = explore_fqdn(pai, hostname, servname,
470 &cur->ai_next);
471
472 while (cur && cur->ai_next)
473 cur = cur->ai_next;
474 }
475
476 /* XXX */
477 if (sentinel.ai_next)
478 error = 0;
479
480 if (error)
481 goto free;
482 if (error == 0) {
483 if (sentinel.ai_next) {
484 good:
485 *res = sentinel.ai_next;
486 return SUCCESS;
487 } else
488 error = EAI_FAIL;
489 }
490 free:
491 bad:
492 if (sentinel.ai_next)
493 freeaddrinfo(sentinel.ai_next);
494 *res = NULL;
495 return error;
496}
497
498/*
499 * FQDN hostname, DNS lookup
500 */
501
502_THREAD_PRIVATE_MUTEX(getaddrinfo_explore_fqdn);
503
504static int
505explore_fqdn(pai, hostname, servname, res)
506 const struct addrinfo *pai;
507 const char *hostname;
508 const char *servname;
509 struct addrinfo **res;
510{
511 struct addrinfo *result;
512 struct addrinfo *cur;
513 int error = 0;
514 char lookups[MAXDNSLUS];
515 int i;
516
517 _THREAD_PRIVATE_MUTEX_LOCK(getaddrinfo_explore_fqdn);
518
519 result = NULL;
520
521#if 0
522 /*
523 * If AI_ADDRCONFIG is specified, check if we are expected to
524 * return the address family or not.
525 * XXX does not handle PF_UNSPEC case, should filter final result
526 */
527 if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(pai)) {
528 _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
529 return 0;
530 }
531#endif
532
533 /*
534 * if the servname does not match socktype/protocol, ignore it.
535 */
536 if (get_portmatch(pai, servname) != 0) {
537 _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
538 return 0;
539 }
540
541 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
542 strlcpy(lookups, "f", sizeof lookups);
543 else {
544 bcopy(_res.lookups, lookups, sizeof lookups);
545 if (lookups[0] == '\0')
546 strlcpy(lookups, "bf", sizeof lookups);
547 }
548
549 for (i = 0; i < MAXDNSLUS && result == NULL && lookups[i]; i++) {
550 switch (lookups[i]) {
551#ifdef YP
552 case 'y':
553 result = _yp_getaddrinfo(hostname, pai);
554 break;
555#endif
556 case 'b':
557 result = _dns_getaddrinfo(hostname, pai);
558 break;
559 case 'f':
560 result = _files_getaddrinfo(hostname, pai);
561 break;
562 }
563 }
564 if (result) {
565 for (cur = result; cur; cur = cur->ai_next) {
566 GET_PORT(cur, servname);
567 /* canonname should be filled already */
568 }
569 *res = result;
570 _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
571 return 0;
572 } else {
573 /* translate error code */
574 switch (h_errno) {
575 case NETDB_SUCCESS:
576 error = EAI_FAIL; /*XXX strange */
577 break;
578 case HOST_NOT_FOUND:
579 error = EAI_NODATA;
580 break;
581 case TRY_AGAIN:
582 error = EAI_AGAIN;
583 break;
584 case NO_RECOVERY:
585 error = EAI_FAIL;
586 break;
587 case NO_DATA:
588#if NO_ADDRESS != NO_DATA
589 case NO_ADDRESS:
590#endif
591 error = EAI_NODATA;
592 break;
593 default: /* unknown ones */
594 error = EAI_FAIL;
595 break;
596 }
597 }
598
599free:
600 if (result)
601 freeaddrinfo(result);
602 _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
603 return error;
604}
605
606/*
607 * hostname == NULL.
608 * passive socket -> anyaddr (0.0.0.0 or ::)
609 * non-passive socket -> localhost (127.0.0.1 or ::1)
610 */
611static int
612explore_null(pai, servname, res)
613 const struct addrinfo *pai;
614 const char *servname;
615 struct addrinfo **res;
616{
617 int s;
618 const struct afd *afd;
619 struct addrinfo *cur;
620 struct addrinfo sentinel;
621 int error;
622
623 *res = NULL;
624 sentinel.ai_next = NULL;
625 cur = &sentinel;
626
627 /*
628 * filter out AFs that are not supported by the kernel
629 * XXX errno?
630 */
631 s = socket(pai->ai_family, SOCK_DGRAM, 0);
632 if (s < 0) {
633 if (errno != EMFILE)
634 return 0;
635 } else
636 close(s);
637
638 /*
639 * if the servname does not match socktype/protocol, ignore it.
640 */
641 if (get_portmatch(pai, servname) != 0)
642 return 0;
643
644 afd = find_afd(pai->ai_family);
645 if (afd == NULL)
646 return 0;
647
648 if (pai->ai_flags & AI_PASSIVE) {
649 GET_AI(cur->ai_next, afd, afd->a_addrany);
650 /* xxx meaningless?
651 * GET_CANONNAME(cur->ai_next, "anyaddr");
652 */
653 GET_PORT(cur->ai_next, servname);
654 } else {
655 GET_AI(cur->ai_next, afd, afd->a_loopback);
656 /* xxx meaningless?
657 * GET_CANONNAME(cur->ai_next, "localhost");
658 */
659 GET_PORT(cur->ai_next, servname);
660 }
661 cur = cur->ai_next;
662
663 *res = sentinel.ai_next;
664 return 0;
665
666free:
667 if (sentinel.ai_next)
668 freeaddrinfo(sentinel.ai_next);
669 return error;
670}
671
672/*
673 * numeric hostname
674 */
675static int
676explore_numeric(pai, hostname, servname, res)
677 const struct addrinfo *pai;
678 const char *hostname;
679 const char *servname;
680 struct addrinfo **res;
681{
682 const struct afd *afd;
683 struct addrinfo *cur;
684 struct addrinfo sentinel;
685 int error;
686 char pton[PTON_MAX];
687
688 *res = NULL;
689 sentinel.ai_next = NULL;
690 cur = &sentinel;
691
692 /*
693 * if the servname does not match socktype/protocol, ignore it.
694 */
695 if (get_portmatch(pai, servname) != 0)
696 return 0;
697
698 afd = find_afd(pai->ai_family);
699 if (afd == NULL)
700 return 0;
701
702 switch (afd->a_af) {
703#if 0 /*X/Open spec*/
704 case AF_INET:
705 if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
706 if (pai->ai_family == afd->a_af ||
707 pai->ai_family == PF_UNSPEC /*?*/) {
708 GET_AI(cur->ai_next, afd, pton);
709 GET_PORT(cur->ai_next, servname);
710 while (cur && cur->ai_next)
711 cur = cur->ai_next;
712 } else
713 ERR(EAI_FAMILY); /*xxx*/
714 }
715 break;
716#endif
717 default:
718 if (inet_pton(afd->a_af, hostname, pton) == 1) {
719 if (pai->ai_family == afd->a_af ||
720 pai->ai_family == PF_UNSPEC /*?*/) {
721 GET_AI(cur->ai_next, afd, pton);
722 GET_PORT(cur->ai_next, servname);
723 while (cur && cur->ai_next)
724 cur = cur->ai_next;
725 } else
726 ERR(EAI_FAMILY); /*xxx*/
727 }
728 break;
729 }
730
731 *res = sentinel.ai_next;
732 return 0;
733
734free:
735bad:
736 if (sentinel.ai_next)
737 freeaddrinfo(sentinel.ai_next);
738 return error;
739}
740
741/*
742 * numeric hostname with scope
743 */
744static int
745explore_numeric_scope(pai, hostname, servname, res)
746 const struct addrinfo *pai;
747 const char *hostname;
748 const char *servname;
749 struct addrinfo **res;
750{
751#if !defined(SCOPE_DELIMITER) || !defined(INET6)
752 return explore_numeric(pai, hostname, servname, res);
753#else
754 const struct afd *afd;
755 struct addrinfo *cur;
756 int error;
757 char *cp, *hostname2 = NULL, *scope, *addr;
758 struct sockaddr_in6 *sin6;
759
760 /*
761 * if the servname does not match socktype/protocol, ignore it.
762 */
763 if (get_portmatch(pai, servname) != 0)
764 return 0;
765
766 afd = find_afd(pai->ai_family);
767 if (afd == NULL)
768 return 0;
769
770 if (!afd->a_scoped)
771 return explore_numeric(pai, hostname, servname, res);
772
773 cp = strchr(hostname, SCOPE_DELIMITER);
774 if (cp == NULL)
775 return explore_numeric(pai, hostname, servname, res);
776
777 /*
778 * Handle special case of <scoped_address><delimiter><scope id>
779 */
780 hostname2 = strdup(hostname);
781 if (hostname2 == NULL)
782 return EAI_MEMORY;
783 /* terminate at the delimiter */
784 hostname2[cp - hostname] = '\0';
785 addr = hostname2;
786 scope = cp + 1;
787
788 error = explore_numeric(pai, addr, servname, res);
789 if (error == 0) {
790 u_int32_t scopeid;
791
792 for (cur = *res; cur; cur = cur->ai_next) {
793 if (cur->ai_family != AF_INET6)
794 continue;
795 sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
796 if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
797 free(hostname2);
798 return(EAI_NODATA); /* XXX: is return OK? */
799 }
800 sin6->sin6_scope_id = scopeid;
801 }
802 }
803
804 free(hostname2);
805
806 return error;
807#endif
808}
809
810static int
811get_canonname(pai, ai, str)
812 const struct addrinfo *pai;
813 struct addrinfo *ai;
814 const char *str;
815{
816 if ((pai->ai_flags & AI_CANONNAME) != 0) {
817 ai->ai_canonname = strdup(str);
818 if (ai->ai_canonname == NULL)
819 return EAI_MEMORY;
820 }
821 return 0;
822}
823
824static struct addrinfo *
825get_ai(pai, afd, addr)
826 const struct addrinfo *pai;
827 const struct afd *afd;
828 const char *addr;
829{
830 char *p;
831 struct addrinfo *ai;
832
833 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
834 + (afd->a_socklen));
835 if (ai == NULL)
836 return NULL;
837
838 memcpy(ai, pai, sizeof(struct addrinfo));
839 ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
840 memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
841 ai->ai_addr->sa_len = afd->a_socklen;
842 ai->ai_addrlen = afd->a_socklen;
843 ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
844 p = (char *)(void *)(ai->ai_addr);
845 memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
846 return ai;
847}
848
849static int
850get_portmatch(ai, servname)
851 const struct addrinfo *ai;
852 const char *servname;
853{
854
855 /* get_port does not touch first argument. when matchonly == 1. */
856 /* LINTED const cast */
857 return get_port((struct addrinfo *)ai, servname, 1);
858}
859
860static int
861get_port(ai, servname, matchonly)
862 struct addrinfo *ai;
863 const char *servname;
864 int matchonly;
865{
866 const char *proto;
867 struct servent *sp;
868 int port;
869 int allownumeric;
870
871 if (servname == NULL)
872 return 0;
873 switch (ai->ai_family) {
874 case AF_INET:
875#ifdef AF_INET6
876 case AF_INET6:
877#endif
878 break;
879 default:
880 return 0;
881 }
882
883 switch (ai->ai_socktype) {
884 case SOCK_RAW:
885 return EAI_SERVICE;
886 case SOCK_DGRAM:
887 case SOCK_STREAM:
888 allownumeric = 1;
889 break;
890 case ANY:
891 allownumeric = 0;
892 break;
893 default:
894 return EAI_SOCKTYPE;
895 }
896
897 if (str_isnumber(servname)) {
898 if (!allownumeric)
899 return EAI_SERVICE;
900 port = atoi(servname);
901 if (port < 0 || port > 65535)
902 return EAI_SERVICE;
903 port = htons(port);
904 } else {
905 switch (ai->ai_socktype) {
906 case SOCK_DGRAM:
907 proto = "udp";
908 break;
909 case SOCK_STREAM:
910 proto = "tcp";
911 break;
912 default:
913 proto = NULL;
914 break;
915 }
916
917 if ((sp = getservbyname(servname, proto)) == NULL)
918 return EAI_SERVICE;
919 port = sp->s_port;
920 }
921
922 if (!matchonly) {
923 switch (ai->ai_family) {
924 case AF_INET:
925 ((struct sockaddr_in *)(void *)
926 ai->ai_addr)->sin_port = port;
927 break;
928#ifdef INET6
929 case AF_INET6:
930 ((struct sockaddr_in6 *)(void *)
931 ai->ai_addr)->sin6_port = port;
932 break;
933#endif
934 }
935 }
936
937 return 0;
938}
939
940static const struct afd *
941find_afd(af)
942 int af;
943{
944 const struct afd *afd;
945
946 if (af == PF_UNSPEC)
947 return NULL;
948 for (afd = afdl; afd->a_af; afd++) {
949 if (afd->a_af == af)
950 return afd;
951 }
952 return NULL;
953}
954
955#if 0
956/*
957 * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend
958 * will take care of it.
959 * the semantics of AI_ADDRCONFIG is not defined well. we are not sure
960 * if the code is right or not.
961 */
962static int
963addrconfig(pai)
964 const struct addrinfo *pai;
965{
966 int s;
967
968 /* XXX errno */
969 s = socket(pai->ai_family, SOCK_DGRAM, 0);
970 if (s < 0)
971 return 0;
972 close(s);
973 return 1;
974}
975#endif
976
977#ifdef INET6
978/* convert a string to a scope identifier. XXX: IPv6 specific */
979static int
980ip6_str2scopeid(scope, sin6, scopeid)
981 char *scope;
982 struct sockaddr_in6 *sin6;
983 u_int32_t *scopeid;
984{
985 u_long lscopeid;
986 struct in6_addr *a6 = &sin6->sin6_addr;
987 char *ep;
988
989 /* empty scopeid portion is invalid */
990 if (*scope == '\0')
991 return -1;
992
993 if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
994 /*
995 * We currently assume a one-to-one mapping between links
996 * and interfaces, so we simply use interface indices for
997 * like-local scopes.
998 */
999 *scopeid = if_nametoindex(scope);
1000 if (*scopeid == 0)
1001 goto trynumeric;
1002 return 0;
1003 }
1004
1005 /* still unclear about literal, allow numeric only - placeholder */
1006 if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1007 goto trynumeric;
1008 if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1009 goto trynumeric;
1010 else
1011 goto trynumeric; /* global */
1012
1013 /* try to convert to a numeric id as a last resort */
1014 trynumeric:
1015 errno = 0;
1016 lscopeid = strtoul(scope, &ep, 10);
1017 *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1018 if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1019 return 0;
1020 else
1021 return -1;
1022}
1023#endif
1024
1025/* code duplicate with gethnamaddr.c */
1026
1027static const char AskedForGot[] =
1028 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1029static FILE *hostf = NULL;
1030
1031static struct addrinfo *
1032getanswer(answer, anslen, qname, qtype, pai)
1033 const querybuf *answer;
1034 int anslen;
1035 const char *qname;
1036 int qtype;
1037 const struct addrinfo *pai;
1038{
1039 struct addrinfo sentinel, *cur;
1040 struct addrinfo ai;
1041 const struct afd *afd;
1042 char *canonname;
1043 const HEADER *hp;
1044 const u_char *cp;
1045 int n;
1046 const u_char *eom;
1047 char *bp, *ep;
1048 int type, class, ancount, qdcount;
1049 int haveanswer, had_error;
1050 char tbuf[MAXDNAME];
1051 int (*name_ok)(const char *);
1052 char hostbuf[8*1024];
1053
1054 memset(&sentinel, 0, sizeof(sentinel));
1055 cur = &sentinel;
1056
1057 canonname = NULL;
1058 eom = answer->buf + anslen;
1059 switch (qtype) {
1060 case T_A:
1061 case T_AAAA:
1062 case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/
1063 name_ok = res_hnok;
1064 break;
1065 default:
1066 return (NULL); /* XXX should be abort() -- but that is illegal */
1067 }
1068 /*
1069 * find first satisfactory answer
1070 */
1071 hp = &answer->hdr;
1072 ancount = ntohs(hp->ancount);
1073 qdcount = ntohs(hp->qdcount);
1074 bp = hostbuf;
1075 ep = hostbuf + sizeof hostbuf;
1076 cp = answer->buf + HFIXEDSZ;
1077 if (qdcount != 1) {
1078 h_errno = NO_RECOVERY;
1079 return (NULL);
1080 }
1081 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1082 if ((n < 0) || !(*name_ok)(bp)) {
1083 h_errno = NO_RECOVERY;
1084 return (NULL);
1085 }
1086 cp += n + QFIXEDSZ;
1087 if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1088 /* res_send() has already verified that the query name is the
1089 * same as the one we sent; this just gets the expanded name
1090 * (i.e., with the succeeding search-domain tacked on).
1091 */
1092 n = strlen(bp) + 1; /* for the \0 */
1093 if (n >= MAXHOSTNAMELEN) {
1094 h_errno = NO_RECOVERY;
1095 return (NULL);
1096 }
1097 canonname = bp;
1098 bp += n;
1099 /* The qname can be abbreviated, but h_name is now absolute. */
1100 qname = canonname;
1101 }
1102 haveanswer = 0;
1103 had_error = 0;
1104 while (ancount-- > 0 && cp < eom && !had_error) {
1105 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1106 if ((n < 0) || !(*name_ok)(bp)) {
1107 had_error++;
1108 continue;
1109 }
1110 cp += n; /* name */
1111 type = _getshort(cp);
1112 cp += INT16SZ; /* type */
1113 class = _getshort(cp);
1114 cp += INT16SZ + INT32SZ; /* class, TTL */
1115 n = _getshort(cp);
1116 cp += INT16SZ; /* len */
1117 if (class != C_IN) {
1118 /* XXX - debug? syslog? */
1119 cp += n;
1120 continue; /* XXX - had_error++ ? */
1121 }
1122 if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1123 type == T_CNAME) {
1124 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1125 if ((n < 0) || !(*name_ok)(tbuf)) {
1126 had_error++;
1127 continue;
1128 }
1129 cp += n;
1130 /* Get canonical name. */
1131 n = strlen(tbuf) + 1; /* for the \0 */
1132 if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1133 had_error++;
1134 continue;
1135 }
1136 strcpy(bp, tbuf);
1137 canonname = bp;
1138 bp += n;
1139 continue;
1140 }
1141 if (qtype == T_ANY) {
1142 if (!(type == T_A || type == T_AAAA)) {
1143 cp += n;
1144 continue;
1145 }
1146 } else if (type != qtype) {
1147 if (type != T_KEY && type != T_SIG)
1148 syslog(LOG_NOTICE|LOG_AUTH,
1149 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1150 qname, p_class(C_IN), p_type(qtype),
1151 p_type(type));
1152 cp += n;
1153 continue; /* XXX - had_error++ ? */
1154 }
1155 switch (type) {
1156 case T_A:
1157 case T_AAAA:
1158 if (strcasecmp(canonname, bp) != 0) {
1159 syslog(LOG_NOTICE|LOG_AUTH,
1160 AskedForGot, canonname, bp);
1161 cp += n;
1162 continue; /* XXX - had_error++ ? */
1163 }
1164 if (type == T_A && n != INADDRSZ) {
1165 cp += n;
1166 continue;
1167 }
1168 if (type == T_AAAA && n != IN6ADDRSZ) {
1169 cp += n;
1170 continue;
1171 }
1172 if (type == T_AAAA) {
1173 struct in6_addr in6;
1174 memcpy(&in6, cp, IN6ADDRSZ);
1175 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1176 cp += n;
1177 continue;
1178 }
1179 }
1180 if (!haveanswer) {
1181 int nn;
1182
1183 canonname = bp;
1184 nn = strlen(bp) + 1; /* for the \0 */
1185 bp += nn;
1186 }
1187
1188 /* don't overwrite pai */
1189 ai = *pai;
1190 ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1191 afd = find_afd(ai.ai_family);
1192 if (afd == NULL) {
1193 cp += n;
1194 continue;
1195 }
1196 cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1197 if (cur->ai_next == NULL)
1198 had_error++;
1199 while (cur && cur->ai_next)
1200 cur = cur->ai_next;
1201 cp += n;
1202 break;
1203 default:
1204 abort(); /* XXX abort illegal in library */
1205 }
1206 if (!had_error)
1207 haveanswer++;
1208 }
1209 if (haveanswer) {
1210 if (!canonname)
1211 (void)get_canonname(pai, sentinel.ai_next, qname);
1212 else
1213 (void)get_canonname(pai, sentinel.ai_next, canonname);
1214 h_errno = NETDB_SUCCESS;
1215 return sentinel.ai_next;
1216 }
1217
1218 h_errno = NO_RECOVERY;
1219 return NULL;
1220}
1221
1222/*ARGSUSED*/
1223static struct addrinfo *
1224_dns_getaddrinfo(name, pai)
1225 const char *name;
1226 const struct addrinfo *pai;
1227{
1228 struct addrinfo *ai;
1229 querybuf *buf, *buf2;
1230 struct addrinfo sentinel, *cur;
1231 struct res_target q, q2;
1232
1233 memset(&q, 0, sizeof(q2));
1234 memset(&q2, 0, sizeof(q2));
1235 memset(&sentinel, 0, sizeof(sentinel));
1236 cur = &sentinel;
1237
1238 buf = malloc(sizeof(*buf));
1239 if (buf == NULL) {
1240 h_errno = NETDB_INTERNAL;
1241 return NULL;
1242 }
1243 buf2 = malloc(sizeof(*buf2));
1244 if (buf2 == NULL) {
1245 free(buf);
1246 h_errno = NETDB_INTERNAL;
1247 return NULL;
1248 }
1249
1250 switch (pai->ai_family) {
1251 case AF_UNSPEC:
1252 /* prefer IPv6 */
1253 q.qclass = C_IN;
1254 q.qtype = T_AAAA;
1255 q.answer = buf->buf;
1256 q.anslen = sizeof(buf->buf);
1257 q.next = &q2;
1258 q2.qclass = C_IN;
1259 q2.qtype = T_A;
1260 q2.answer = buf2->buf;
1261 q2.anslen = sizeof(buf2->buf);
1262 break;
1263 case AF_INET:
1264 q.qclass = C_IN;
1265 q.qtype = T_A;
1266 q.answer = buf->buf;
1267 q.anslen = sizeof(buf->buf);
1268 break;
1269 case AF_INET6:
1270 q.qclass = C_IN;
1271 q.qtype = T_AAAA;
1272 q.answer = buf->buf;
1273 q.anslen = sizeof(buf->buf);
1274 break;
1275 default:
1276 free(buf);
1277 free(buf2);
1278 return NULL;
1279 }
1280 if (res_searchN(name, &q) < 0) {
1281 free(buf);
1282 free(buf2);
1283 return NULL;
1284 }
1285 ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1286 if (ai) {
1287 cur->ai_next = ai;
1288 while (cur && cur->ai_next)
1289 cur = cur->ai_next;
1290 }
1291 if (q.next) {
1292 ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1293 if (ai)
1294 cur->ai_next = ai;
1295 }
1296 free(buf);
1297 free(buf2);
1298 return sentinel.ai_next;
1299}
1300
1301static FILE *hostf;
1302
1303static void
1304_sethtent()
1305{
1306 if (!hostf)
1307 hostf = fopen(_PATH_HOSTS, "r" );
1308 else
1309 rewind(hostf);
1310}
1311
1312static void
1313_endhtent()
1314{
1315 if (hostf) {
1316 (void) fclose(hostf);
1317 hostf = NULL;
1318 }
1319}
1320
1321static struct addrinfo *
1322_gethtent(name, pai)
1323 const char *name;
1324 const struct addrinfo *pai;
1325{
1326 char *p;
1327 char *cp, *tname, *cname;
1328 struct addrinfo hints, *res0, *res;
1329 int error;
1330 const char *addr;
1331 char hostbuf[8*1024];
1332
1333 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" )))
1334 return (NULL);
1335 again:
1336 if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
1337 return (NULL);
1338 if (*p == '#')
1339 goto again;
1340 if (!(cp = strpbrk(p, "#\n")))
1341 goto again;
1342 *cp = '\0';
1343 if (!(cp = strpbrk(p, " \t")))
1344 goto again;
1345 *cp++ = '\0';
1346 addr = p;
1347 /* if this is not something we're looking for, skip it. */
1348 cname = NULL;
1349 while (cp && *cp) {
1350 if (*cp == ' ' || *cp == '\t') {
1351 cp++;
1352 continue;
1353 }
1354 if (!cname)
1355 cname = cp;
1356 tname = cp;
1357 if ((cp = strpbrk(cp, " \t")) != NULL)
1358 *cp++ = '\0';
1359 if (strcasecmp(name, tname) == 0)
1360 goto found;
1361 }
1362 goto again;
1363
1364found:
1365 hints = *pai;
1366 hints.ai_flags = AI_NUMERICHOST;
1367 error = getaddrinfo(addr, NULL, &hints, &res0);
1368 if (error)
1369 goto again;
1370 for (res = res0; res; res = res->ai_next) {
1371 /* cover it up */
1372 res->ai_flags = pai->ai_flags;
1373
1374 if (pai->ai_flags & AI_CANONNAME) {
1375 if (get_canonname(pai, res, cname) != 0) {
1376 freeaddrinfo(res0);
1377 goto again;
1378 }
1379 }
1380 }
1381 return res0;
1382}
1383
1384/*ARGSUSED*/
1385static struct addrinfo *
1386_files_getaddrinfo(name, pai)
1387 const char *name;
1388 const struct addrinfo *pai;
1389{
1390 struct addrinfo sentinel, *cur;
1391 struct addrinfo *p;
1392
1393 memset(&sentinel, 0, sizeof(sentinel));
1394 cur = &sentinel;
1395
1396 _sethtent();
1397 while ((p = _gethtent(name, pai)) != NULL) {
1398 cur->ai_next = p;
1399 while (cur && cur->ai_next)
1400 cur = cur->ai_next;
1401 }
1402 _endhtent();
1403
1404 return sentinel.ai_next;
1405}
1406
1407#ifdef YP
1408static char *__ypdomain;
1409
1410/*ARGSUSED*/
1411static struct addrinfo *
1412_yphostent(line, pai)
1413 char *line;
1414 const struct addrinfo *pai;
1415{
1416 struct addrinfo sentinel, *cur;
1417 struct addrinfo hints, *res, *res0;
1418 int error;
1419 char *p = line;
1420 const char *addr, *canonname;
1421 char *nextline;
1422 char *cp;
1423
1424 addr = canonname = NULL;
1425
1426 memset(&sentinel, 0, sizeof(sentinel));
1427 cur = &sentinel;
1428
1429nextline:
1430 /* terminate line */
1431 cp = strchr(p, '\n');
1432 if (cp) {
1433 *cp++ = '\0';
1434 nextline = cp;
1435 } else
1436 nextline = NULL;
1437
1438 cp = strpbrk(p, " \t");
1439 if (cp == NULL) {
1440 if (canonname == NULL)
1441 return (NULL);
1442 else
1443 goto done;
1444 }
1445 *cp++ = '\0';
1446
1447 addr = p;
1448
1449 while (cp && *cp) {
1450 if (*cp == ' ' || *cp == '\t') {
1451 cp++;
1452 continue;
1453 }
1454 if (!canonname)
1455 canonname = cp;
1456 if ((cp = strpbrk(cp, " \t")) != NULL)
1457 *cp++ = '\0';
1458 }
1459
1460 hints = *pai;
1461 hints.ai_flags = AI_NUMERICHOST;
1462 error = getaddrinfo(addr, NULL, &hints, &res0);
1463 if (error == 0) {
1464 for (res = res0; res; res = res->ai_next) {
1465 /* cover it up */
1466 res->ai_flags = pai->ai_flags;
1467
1468 if (pai->ai_flags & AI_CANONNAME)
1469 (void)get_canonname(pai, res, canonname);
1470 }
1471 } else
1472 res0 = NULL;
1473 if (res0) {
1474 cur->ai_next = res0;
1475 while (cur && cur->ai_next)
1476 cur = cur->ai_next;
1477 }
1478
1479 if (nextline) {
1480 p = nextline;
1481 goto nextline;
1482 }
1483
1484done:
1485 return sentinel.ai_next;
1486}
1487
1488/*ARGSUSED*/
1489static struct addrinfo *
1490_yp_getaddrinfo(name, pai)
1491 const char *name;
1492 const struct addrinfo *pai;
1493{
1494 struct addrinfo sentinel, *cur;
1495 struct addrinfo *ai = NULL;
1496 static char *__ypcurrent;
1497 int __ypcurrentlen, r;
1498
1499 memset(&sentinel, 0, sizeof(sentinel));
1500 cur = &sentinel;
1501
1502 if (!__ypdomain) {
1503 if (_yp_check(&__ypdomain) == 0)
1504 return NULL;
1505 }
1506 if (__ypcurrent)
1507 free(__ypcurrent);
1508 __ypcurrent = NULL;
1509
1510 /* hosts.byname is only for IPv4 (Solaris8) */
1511 if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
1512 r = yp_match(__ypdomain, "hosts.byname", name,
1513 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1514 if (r == 0) {
1515 struct addrinfo ai4;
1516
1517 ai4 = *pai;
1518 ai4.ai_family = AF_INET;
1519 ai = _yphostent(__ypcurrent, &ai4);
1520 if (ai) {
1521 cur->ai_next = ai;
1522 while (cur && cur->ai_next)
1523 cur = cur->ai_next;
1524 }
1525 }
1526 }
1527
1528 /* ipnodes.byname can hold both IPv4/v6 */
1529 r = yp_match(__ypdomain, "ipnodes.byname", name,
1530 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1531 if (r == 0) {
1532 ai = _yphostent(__ypcurrent, pai);
1533 if (ai) {
1534 cur->ai_next = ai;
1535 while (cur && cur->ai_next)
1536 cur = cur->ai_next;
1537 }
1538 }
1539
1540 return sentinel.ai_next;
1541}
1542#endif
1543
1544
1545/* resolver logic */
1546
1547extern const char *__hostalias(const char *);
1548extern int h_errno;
1549extern int res_opt(int, u_char *, int, int);
1550
1551/*
1552 * Formulate a normal query, send, and await answer.
1553 * Returned answer is placed in supplied buffer "answer".
1554 * Perform preliminary check of answer, returning success only
1555 * if no error is indicated and the answer count is nonzero.
1556 * Return the size of the response on success, -1 on error.
1557 * Error number is left in h_errno.
1558 *
1559 * Caller must parse answer and determine whether it answers the question.
1560 */
1561static int
1562res_queryN(name, target)
1563 const char *name; /* domain name */
1564 struct res_target *target;
1565{
1566 u_char buf[MAXPACKET];
1567 HEADER *hp;
1568 int n;
1569 struct res_target *t;
1570 int rcode;
1571 int ancount;
1572
1573 rcode = NOERROR;
1574 ancount = 0;
1575
1576 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1577 h_errno = NETDB_INTERNAL;
1578 return (-1);
1579 }
1580
1581 for (t = target; t; t = t->next) {
1582 int class, type;
1583 u_char *answer;
1584 int anslen;
1585
1586 hp = (HEADER *)(void *)t->answer;
1587 hp->rcode = NOERROR; /* default */
1588
1589 /* make it easier... */
1590 class = t->qclass;
1591 type = t->qtype;
1592 answer = t->answer;
1593 anslen = t->anslen;
1594#ifdef DEBUG
1595 if (_res.options & RES_DEBUG)
1596 printf(";; res_query(%s, %d, %d)\n", name, class, type);
1597#endif
1598
1599 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
1600 buf, sizeof(buf));
1601 if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
1602 n = res_opt(n, buf, sizeof(buf), anslen);
1603 if (n <= 0) {
1604#ifdef DEBUG
1605 if (_res.options & RES_DEBUG)
1606 printf(";; res_query: mkquery failed\n");
1607#endif
1608 h_errno = NO_RECOVERY;
1609 return (n);
1610 }
1611 n = res_send(buf, n, answer, anslen);
1612#if 0
1613 if (n < 0) {
1614#ifdef DEBUG
1615 if (_res.options & RES_DEBUG)
1616 printf(";; res_query: send error\n");
1617#endif
1618 h_errno = TRY_AGAIN;
1619 return (n);
1620 }
1621#endif
1622
1623 if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1624 rcode = hp->rcode; /* record most recent error */
1625#ifdef DEBUG
1626 if (_res.options & RES_DEBUG)
1627 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
1628 ntohs(hp->ancount));
1629#endif
1630 continue;
1631 }
1632
1633 ancount += ntohs(hp->ancount);
1634
1635 t->n = n;
1636 }
1637
1638 if (ancount == 0) {
1639 switch (rcode) {
1640 case NXDOMAIN:
1641 h_errno = HOST_NOT_FOUND;
1642 break;
1643 case SERVFAIL:
1644 h_errno = TRY_AGAIN;
1645 break;
1646 case NOERROR:
1647 h_errno = NO_DATA;
1648 break;
1649 case FORMERR:
1650 case NOTIMP:
1651 case REFUSED:
1652 default:
1653 h_errno = NO_RECOVERY;
1654 break;
1655 }
1656 return (-1);
1657 }
1658 return (ancount);
1659}
1660
1661/*
1662 * Formulate a normal query, send, and retrieve answer in supplied buffer.
1663 * Return the size of the response on success, -1 on error.
1664 * If enabled, implement search rules until answer or unrecoverable failure
1665 * is detected. Error code, if any, is left in h_errno.
1666 */
1667static int
1668res_searchN(name, target)
1669 const char *name; /* domain name */
1670 struct res_target *target;
1671{
1672 const char *cp, * const *domain;
1673 HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
1674 u_int dots;
1675 int trailing_dot, ret, saved_herrno;
1676 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
1677
1678 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1679 h_errno = NETDB_INTERNAL;
1680 return (-1);
1681 }
1682
1683 errno = 0;
1684 h_errno = HOST_NOT_FOUND; /* default, if we never query */
1685 dots = 0;
1686 for (cp = name; *cp; cp++)
1687 dots += (*cp == '.');
1688 trailing_dot = 0;
1689 if (cp > name && *--cp == '.')
1690 trailing_dot++;
1691
1692 /*
1693 * if there aren't any dots, it could be a user-level alias
1694 */
1695 if (!dots && (cp = __hostalias(name)) != NULL)
1696 return (res_queryN(cp, target));
1697
1698 /*
1699 * If there are dots in the name already, let's just give it a try
1700 * 'as is'. The threshold can be set with the "ndots" option.
1701 */
1702 saved_herrno = -1;
1703 if (dots >= _res.ndots) {
1704 ret = res_querydomainN(name, NULL, target);
1705 if (ret > 0)
1706 return (ret);
1707 saved_herrno = h_errno;
1708 tried_as_is++;
1709 }
1710
1711 /*
1712 * We do at least one level of search if
1713 * - there is no dot and RES_DEFNAME is set, or
1714 * - there is at least one dot, there is no trailing dot,
1715 * and RES_DNSRCH is set.
1716 */
1717 if ((!dots && (_res.options & RES_DEFNAMES)) ||
1718 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
1719 int done = 0;
1720
1721 for (domain = (const char * const *)_res.dnsrch;
1722 *domain && !done;
1723 domain++) {
1724
1725 ret = res_querydomainN(name, *domain, target);
1726 if (ret > 0)
1727 return (ret);
1728
1729 /*
1730 * If no server present, give up.
1731 * If name isn't found in this domain,
1732 * keep trying higher domains in the search list
1733 * (if that's enabled).
1734 * On a NO_DATA error, keep trying, otherwise
1735 * a wildcard entry of another type could keep us
1736 * from finding this entry higher in the domain.
1737 * If we get some other error (negative answer or
1738 * server failure), then stop searching up,
1739 * but try the input name below in case it's
1740 * fully-qualified.
1741 */
1742 if (errno == ECONNREFUSED) {
1743 h_errno = TRY_AGAIN;
1744 return (-1);
1745 }
1746
1747 switch (h_errno) {
1748 case NO_DATA:
1749 got_nodata++;
1750 /* FALLTHROUGH */
1751 case HOST_NOT_FOUND:
1752 /* keep trying */
1753 break;
1754 case TRY_AGAIN:
1755 if (hp->rcode == SERVFAIL) {
1756 /* try next search element, if any */
1757 got_servfail++;
1758 break;
1759 }
1760 /* FALLTHROUGH */
1761 default:
1762 /* anything else implies that we're done */
1763 done++;
1764 }
1765 /*
1766 * if we got here for some reason other than DNSRCH,
1767 * we only wanted one iteration of the loop, so stop.
1768 */
1769 if (!(_res.options & RES_DNSRCH))
1770 done++;
1771 }
1772 }
1773
1774 /*
1775 * if we have not already tried the name "as is", do that now.
1776 * note that we do this regardless of how many dots were in the
1777 * name or whether it ends with a dot.
1778 */
1779 if (!tried_as_is) {
1780 ret = res_querydomainN(name, NULL, target);
1781 if (ret > 0)
1782 return (ret);
1783 }
1784
1785 /*
1786 * if we got here, we didn't satisfy the search.
1787 * if we did an initial full query, return that query's h_errno
1788 * (note that we wouldn't be here if that query had succeeded).
1789 * else if we ever got a nodata, send that back as the reason.
1790 * else send back meaningless h_errno, that being the one from
1791 * the last DNSRCH we did.
1792 */
1793 if (saved_herrno != -1)
1794 h_errno = saved_herrno;
1795 else if (got_nodata)
1796 h_errno = NO_DATA;
1797 else if (got_servfail)
1798 h_errno = TRY_AGAIN;
1799 return (-1);
1800}
1801
1802/*
1803 * Perform a call on res_query on the concatenation of name and domain,
1804 * removing a trailing dot from name if domain is NULL.
1805 */
1806static int
1807res_querydomainN(name, domain, target)
1808 const char *name, *domain;
1809 struct res_target *target;
1810{
1811 char nbuf[MAXDNAME];
1812 const char *longname = nbuf;
1813 size_t n, d;
1814
1815 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1816 h_errno = NETDB_INTERNAL;
1817 return (-1);
1818 }
1819#ifdef DEBUG
1820 if (_res.options & RES_DEBUG)
1821 printf(";; res_querydomain(%s, %s)\n",
1822 name, domain?domain:"<Nil>");
1823#endif
1824 if (domain == NULL) {
1825 /*
1826 * Check for trailing '.';
1827 * copy without '.' if present.
1828 */
1829 n = strlen(name);
1830 if (n >= MAXDNAME) {
1831 h_errno = NO_RECOVERY;
1832 return (-1);
1833 }
1834 if (n > 0 && name[--n] == '.') {
1835 strlcpy(nbuf, name, n + 1);
1836 } else
1837 longname = name;
1838 } else {
1839 n = strlen(name);
1840 d = strlen(domain);
1841 if (n + d + 1 >= MAXDNAME) {
1842 h_errno = NO_RECOVERY;
1843 return (-1);
1844 }
1845 snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
1846 }
1847 return (res_queryN(longname, target));
1848}
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
new file mode 100644
index 0000000000..d90ea55542
--- /dev/null
+++ b/src/lib/libc/net/gethostbyname.3
@@ -0,0 +1,275 @@
1.\" $OpenBSD: gethostbyname.3,v 1.17 2002/04/30 16:31:42 mpech Exp $
2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd March 13, 1997
35.Dt GETHOSTBYNAME 3
36.Os
37.Sh NAME
38.Nm gethostbyname ,
39.Nm gethostbyname2 ,
40.Nm gethostbyaddr ,
41.Nm gethostent ,
42.Nm sethostent ,
43.Nm endhostent ,
44.Nm hstrerror ,
45.Nm herror
46.Nd get network host entry
47.Sh SYNOPSIS
48.Fd #include <netdb.h>
49.Fd extern int h_errno;
50.Ft struct hostent *
51.Fn gethostbyname "const char *name"
52.Ft struct hostent *
53.Fn gethostbyname2 "const char *name" "int af"
54.Ft struct hostent *
55.Fn gethostbyaddr "const char *addr" "int len" "int af"
56.Ft struct hostent *
57.Fn gethostent void
58.Ft void
59.Fn sethostent "int stayopen"
60.Ft void
61.Fn endhostent void
62.Ft void
63.Fn herror "const char *string"
64.Ft const char *
65.Fn hstrerror "int err"
66.Sh DESCRIPTION
67The
68.Fn gethostbyname
69and
70.Fn gethostbyaddr
71functions each return a pointer to an object with the following structure
72describing an internet host referenced by name or by address, respectively.
73This structure contains either information obtained from the name server (i.e.,
74.Xr resolver 3
75and
76.Xr named 8 ) ,
77broken-out fields from a line in
78.Pa /etc/hosts ,
79or database entries supplied by the
80.Xr yp 8
81system.
82.Xr resolv.conf 5
83describes how the particular database is chosen.
84.Bd -literal
85struct hostent {
86 char *h_name; /* official name of host */
87 char **h_aliases; /* alias list */
88 int h_addrtype; /* host address type */
89 int h_length; /* length of address */
90 char **h_addr_list; /* list of addresses from name server */
91};
92#define h_addr h_addr_list[0] /* address, for backward compatibility */
93.Ed
94.Pp
95The members of this structure are:
96.Bl -tag -width h_addr_list
97.It Fa h_name
98Official name of the host.
99.It Fa h_aliases
100A zero-terminated array of alternate names for the host.
101.It Fa h_addrtype
102The type of address being returned.
103.It Fa h_length
104The length, in bytes, of the address.
105.It Fa h_addr_list
106A zero-terminated array of network addresses for the host.
107Host addresses are returned in network byte order.
108.It Fa h_addr
109The first address in
110.Fa h_addr_list ;
111this is for backward compatibility.
112.El
113.Pp
114The function
115.Fn gethostbyname
116will search for the named host in the current domain and its parents
117using the search lookup semantics detailed in
118.Xr resolv.conf 5
119and
120.Xr hostname 7 .
121.Pp
122.Fn gethostbyname2
123is an advanced form of
124.Fn gethostbyname
125which allows lookups in address families other than
126.Dv AF_INET ,
127for example
128.Dv AF_INET6 .
129.Pp
130The
131.Fn gethostbyaddr
132function will search for the specified address of length
133.Fa len
134in the address family
135.Fa af .
136The only address family currently supported is
137.Dv AF_INET .
138.Pp
139The
140.Fn sethostent
141function may be used to request the use of a connected
142.Tn TCP
143socket for queries.
144If the
145.Fa stayopen
146flag is non-zero,
147this sets the option to send all queries to the name server using
148.Tn TCP
149and to retain the connection after each call to
150.Fn gethostbyname
151or
152.Fn gethostbyaddr .
153Otherwise, queries are performed using
154.Tn UDP
155datagrams.
156.Pp
157The
158.Fn endhostent
159function closes the
160.Tn TCP
161connection.
162.Pp
163The
164.Fn herror
165function prints an error message describing the failure.
166If its argument
167.Fa string
168is non-null,
169it is prepended to the message string and separated from it by a colon
170.Pq Ql \&:
171and a space.
172The error message is printed with a trailing newline.
173The contents of the error message is the same as that returned by
174.Fn hstrerror
175with argument
176.Fa h_errno .
177.Sh FILES
178.Bl -tag -width /etc/resolv.conf -compact
179.It Pa /etc/hosts
180.It Pa /etc/resolv.conf
181.El
182.Sh DIAGNOSTICS
183Error return status from
184.Fn gethostbyname ,
185.Fn gethostbyname2 ,
186and
187.Fn gethostbyaddr
188is indicated by return of a null pointer.
189The external integer
190.Va h_errno
191may then be checked to see whether this is a temporary failure
192or an invalid or unknown host.
193.Pp
194The variable
195.Va h_errno
196can have the following values:
197.Bl -tag -width HOST_NOT_FOUND
198.It Dv HOST_NOT_FOUND
199No such host is known.
200.It Dv TRY_AGAIN
201This is usually a temporary error
202and means that the local server did not receive
203a response from an authoritative server.
204A retry at some later time may succeed.
205.It Dv NO_RECOVERY
206Some unexpected server failure was encountered.
207This is a non-recoverable error.
208.It Dv NO_DATA
209The requested name is valid but does not have an IP address;
210this is not a temporary error.
211This means that the name is known to the name server but there is no address
212associated with this name.
213Another type of request to the name server using this domain name
214will result in an answer;
215for example, a mail-forwarder may be registered for this domain.
216.El
217.Sh SEE ALSO
218.Xr resolver 3 ,
219.Xr getaddrinfo 3 ,
220.Xr getnameinfo 3 ,
221.Xr hosts 5 ,
222.Xr resolv.conf 5 ,
223.Xr hostname 7 ,
224.Xr named 8
225.Sh CAVEATS
226If the search routines in
227.Xr resolv.conf 5
228decide to read the
229.Pa /etc/hosts
230file,
231.Fn gethostent
232and other functions will
233read the next line of the file,
234re-opening the file if necessary.
235.Pp
236The
237.Fn sethostent
238function opens and/or rewinds the file
239.Pa /etc/hosts .
240If the
241.Fa stayopen
242argument is non-zero, the file will not be closed after each call to
243.Fn gethostbyname ,
244.Fn gethostbyname2 ,
245or
246.Fn gethostbyaddr .
247.Pp
248The
249.Fn endhostent
250function closes the file.
251.Sh HISTORY
252The
253.Fn herror
254function appeared in
255.Bx 4.3 .
256The
257.Fn endhostent ,
258.Fn gethostbyaddr ,
259.Fn gethostbyname ,
260.Fn gethostent ,
261and
262.Fn sethostent
263functions appeared in
264.Bx 4.2 .
265.Sh BUGS
266These functions use static data storage;
267if the data is needed for future use, it should be
268copied before any subsequent calls overwrite it.
269Only the Internet
270address formats are currently understood.
271.Pp
272YP does not support any address families other than
273.Dv AF_INET
274and uses
275the traditional database format.
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
new file mode 100644
index 0000000000..909ce573b7
--- /dev/null
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -0,0 +1,1175 @@
1/*-
2 * Copyright (c) 1985, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 * -
33 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
34 *
35 * Permission to use, copy, modify, and distribute this software for any
36 * purpose with or without fee is hereby granted, provided that the above
37 * copyright notice and this permission notice appear in all copies, and that
38 * the name of Digital Equipment Corporation not be used in advertising or
39 * publicity pertaining to distribution of the document or software without
40 * specific, written prior permission.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
43 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
45 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
46 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
47 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 * SOFTWARE.
50 * -
51 * --Copyright--
52 */
53
54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.53 2002/08/27 08:53:13 itojun Exp $";
56#endif /* LIBC_SCCS and not lint */
57
58#include <sys/param.h>
59#include <sys/socket.h>
60#include <netinet/in.h>
61#include <arpa/inet.h>
62#include <arpa/nameser.h>
63#include <netdb.h>
64#include <resolv.h>
65#include <stdio.h>
66#include <ctype.h>
67#include <errno.h>
68#include <string.h>
69#include <syslog.h>
70#include <stdlib.h>
71#ifdef YP
72#include <rpc/rpc.h>
73#include <rpcsvc/yp.h>
74#include <rpcsvc/ypclnt.h>
75#include "ypinternal.h"
76#endif
77#include "thread_private.h"
78
79#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
80
81#define MAXALIASES 35
82#define MAXADDRS 35
83
84static char *h_addr_ptrs[MAXADDRS + 1];
85
86#ifdef YP
87static char *__ypdomain;
88#endif
89
90static struct hostent host;
91static char *host_aliases[MAXALIASES];
92static char hostbuf[BUFSIZ+1];
93static union {
94 struct in_addr _host_in_addr;
95 u_char _host_addr[16]; /* IPv4 or IPv6 */
96} _host_addr_u;
97#define host_addr _host_addr_u._host_addr
98static FILE *hostf = NULL;
99static int stayopen = 0;
100
101static void map_v4v6_address(const char *src, char *dst);
102static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
103
104#ifdef RESOLVSORT
105static void addrsort(char **, int);
106#endif
107
108int _hokchar(const char *);
109
110static const char AskedForGot[] =
111 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
112
113#define MAXPACKET (64*1024)
114
115typedef union {
116 HEADER hdr;
117 u_char buf[MAXPACKET];
118} querybuf;
119
120typedef union {
121 int32_t al;
122 char ac;
123} align;
124
125static struct hostent *getanswer(const querybuf *, int, const char *, int);
126
127extern int h_errno;
128
129int
130_hokchar(p)
131 const char *p;
132{
133 char c;
134
135 /*
136 * Many people do not obey RFC 822 and 1035. The valid
137 * characters are a-z, A-Z, 0-9, '-' and . But the others
138 * tested for below can happen, and we must be more permissive
139 * than the resolver until those idiots clean up their act.
140 * We let '/' through, but not '..'
141 */
142 while ((c = *p++)) {
143 if (('a' <= c && c <= 'z') ||
144 ('A' <= c && c <= 'Z') ||
145 ('0' <= c && c <= '9'))
146 continue;
147 if (strchr("-_/", c))
148 continue;
149 if (c == '.' && *p != '.')
150 continue;
151 return 0;
152 }
153 return 1;
154}
155
156static struct hostent *
157getanswer(answer, anslen, qname, qtype)
158 const querybuf *answer;
159 int anslen;
160 const char *qname;
161 int qtype;
162{
163 register const HEADER *hp;
164 register const u_char *cp;
165 register int n;
166 const u_char *eom;
167 char *bp, **ap, **hap, *ep;
168 int type, class, ancount, qdcount;
169 int haveanswer, had_error;
170 int toobig = 0;
171 char tbuf[MAXDNAME];
172 const char *tname;
173 int (*name_ok)(const char *);
174
175 tname = qname;
176 host.h_name = NULL;
177 eom = answer->buf + anslen;
178 switch (qtype) {
179 case T_A:
180 case T_AAAA:
181#ifdef USE_RESOLV_NAME_OK
182 name_ok = res_hnok;
183 break;
184#endif
185 case T_PTR:
186#ifdef USE_RESOLV_NAME_OK
187 name_ok = res_dnok;
188#else
189 name_ok = _hokchar;
190#endif
191 break;
192 default:
193 return (NULL);
194 }
195 /*
196 * find first satisfactory answer
197 */
198 hp = &answer->hdr;
199 ancount = ntohs(hp->ancount);
200 qdcount = ntohs(hp->qdcount);
201 bp = hostbuf;
202 ep = hostbuf + sizeof hostbuf;
203 cp = answer->buf + HFIXEDSZ;
204 if (qdcount != 1) {
205 h_errno = NO_RECOVERY;
206 return (NULL);
207 }
208 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
209 if ((n < 0) || !(*name_ok)(bp)) {
210 h_errno = NO_RECOVERY;
211 return (NULL);
212 }
213 cp += n + QFIXEDSZ;
214 if (qtype == T_A || qtype == T_AAAA) {
215 /* res_send() has already verified that the query name is the
216 * same as the one we sent; this just gets the expanded name
217 * (i.e., with the succeeding search-domain tacked on).
218 */
219 n = strlen(bp) + 1; /* for the \0 */
220 host.h_name = bp;
221 bp += n;
222 /* The qname can be abbreviated, but h_name is now absolute. */
223 qname = host.h_name;
224 }
225 ap = host_aliases;
226 *ap = NULL;
227 host.h_aliases = host_aliases;
228 hap = h_addr_ptrs;
229 *hap = NULL;
230 host.h_addr_list = h_addr_ptrs;
231 haveanswer = 0;
232 had_error = 0;
233 while (ancount-- > 0 && cp < eom && !had_error) {
234 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
235 if ((n < 0) || !(*name_ok)(bp)) {
236 had_error++;
237 continue;
238 }
239 cp += n; /* name */
240 type = _getshort(cp);
241 cp += INT16SZ; /* type */
242 class = _getshort(cp);
243 cp += INT16SZ + INT32SZ; /* class, TTL */
244 n = _getshort(cp);
245 cp += INT16SZ; /* len */
246 if (type == T_SIG) {
247 /* XXX - ignore signatures as we don't use them yet */
248 cp += n;
249 continue;
250 }
251 if (class != C_IN) {
252 /* XXX - debug? syslog? */
253 cp += n;
254 continue; /* XXX - had_error++ ? */
255 }
256 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
257 if (ap >= &host_aliases[MAXALIASES-1])
258 continue;
259 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
260 if ((n < 0) || !(*name_ok)(tbuf)) {
261 had_error++;
262 continue;
263 }
264 cp += n;
265 /* Store alias. */
266 *ap++ = bp;
267 n = strlen(bp) + 1; /* for the \0 */
268 bp += n;
269 /* Get canonical name. */
270 n = strlen(tbuf) + 1; /* for the \0 */
271 if (n > ep - bp) {
272 had_error++;
273 continue;
274 }
275 strlcpy(bp, tbuf, ep - bp);
276 host.h_name = bp;
277 bp += n;
278 continue;
279 }
280 if (qtype == T_PTR && type == T_CNAME) {
281 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
282#ifdef USE_RESOLV_NAME_OK
283 if ((n < 0) || !res_hnok(tbuf)) {
284#else
285 if ((n < 0) || !_hokchar(tbuf)) {
286#endif
287 had_error++;
288 continue;
289 }
290 cp += n;
291 /* Get canonical name. */
292 n = strlen(tbuf) + 1; /* for the \0 */
293 if (n > ep - bp) {
294 had_error++;
295 continue;
296 }
297 strlcpy(bp, tbuf, ep - bp);
298 tname = bp;
299 bp += n;
300 continue;
301 }
302 if (type != qtype) {
303 syslog(LOG_NOTICE|LOG_AUTH,
304 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
305 qname, p_class(C_IN), p_type(qtype),
306 p_type(type));
307 cp += n;
308 continue; /* XXX - had_error++ ? */
309 }
310 switch (type) {
311 case T_PTR:
312 if (strcasecmp(tname, bp) != 0) {
313 syslog(LOG_NOTICE|LOG_AUTH,
314 AskedForGot, qname, bp);
315 cp += n;
316 continue; /* XXX - had_error++ ? */
317 }
318 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
319#ifdef USE_RESOLV_NAME_OK
320 if ((n < 0) || !res_hnok(bp)) {
321#else
322 if ((n < 0) || !_hokchar(bp)) {
323#endif
324 had_error++;
325 break;
326 }
327#if MULTI_PTRS_ARE_ALIASES
328 cp += n;
329 if (!haveanswer)
330 host.h_name = bp;
331 else if (ap < &host_aliases[MAXALIASES-1])
332 *ap++ = bp;
333 else
334 n = -1;
335 if (n != -1) {
336 n = strlen(bp) + 1; /* for the \0 */
337 bp += n;
338 }
339 break;
340#else
341 host.h_name = bp;
342 if (_res.options & RES_USE_INET6) {
343 n = strlen(bp) + 1; /* for the \0 */
344 bp += n;
345 map_v4v6_hostent(&host, &bp, ep);
346 }
347 h_errno = NETDB_SUCCESS;
348 return (&host);
349#endif
350 case T_A:
351 case T_AAAA:
352 if (strcasecmp(host.h_name, bp) != 0) {
353 syslog(LOG_NOTICE|LOG_AUTH,
354 AskedForGot, host.h_name, bp);
355 cp += n;
356 continue; /* XXX - had_error++ ? */
357 }
358 if (n != host.h_length) {
359 cp += n;
360 continue;
361 }
362 if (type == T_AAAA) {
363 struct in6_addr in6;
364 memcpy(&in6, cp, IN6ADDRSZ);
365 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
366 cp += n;
367 continue;
368 }
369 }
370 if (!haveanswer) {
371 register int nn;
372
373 host.h_name = bp;
374 nn = strlen(bp) + 1; /* for the \0 */
375 bp += nn;
376 }
377
378 bp += sizeof(align) - ((u_long)bp % sizeof(align));
379
380 if (bp + n >= &hostbuf[sizeof hostbuf]) {
381#ifdef DEBUG
382 if (_res.options & RES_DEBUG)
383 printf("size (%d) too big\n", n);
384#endif
385 had_error++;
386 continue;
387 }
388 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
389 if (!toobig++)
390#ifdef DEBUG
391 if (_res.options & RES_DEBUG)
392 printf("Too many addresses (%d)\n", MAXADDRS);
393#endif
394 cp += n;
395 continue;
396 }
397 bcopy(cp, *hap++ = bp, n);
398 bp += n;
399 cp += n;
400 break;
401 }
402 if (!had_error)
403 haveanswer++;
404 }
405 if (haveanswer) {
406 *ap = NULL;
407 *hap = NULL;
408# if defined(RESOLVSORT)
409 /*
410 * Note: we sort even if host can take only one address
411 * in its return structures - should give it the "best"
412 * address in that case, not some random one
413 */
414 if (_res.nsort && haveanswer > 1 && qtype == T_A)
415 addrsort(h_addr_ptrs, haveanswer);
416# endif /*RESOLVSORT*/
417 if (!host.h_name) {
418 n = strlen(qname) + 1; /* for the \0 */
419 if (n > ep - bp)
420 goto try_again;
421 strlcpy(bp, qname, ep - bp);
422 host.h_name = bp;
423 bp += n;
424 }
425 if (_res.options & RES_USE_INET6)
426 map_v4v6_hostent(&host, &bp, ep);
427 h_errno = NETDB_SUCCESS;
428 return (&host);
429 }
430 try_again:
431 h_errno = TRY_AGAIN;
432 return (NULL);
433}
434
435#ifdef notyet
436/*
437 * XXX This is an extremely bogus implementation.
438 *
439 * FreeBSD has this interface:
440 * int gethostbyaddr_r(const char *addr, int len, int type,
441 * struct hostent *result, struct hostent_data *buffer)
442 */
443
444struct hostent *
445gethostbyname_r(name, hp, buf, buflen, errorp)
446 const char * name;
447 struct hostent * hp;
448 char * buf;
449 int buflen;
450 int * errorp;
451{
452 struct hostent *res;
453
454 res = gethostbyname(name);
455 *errorp = h_errno;
456 if (res == NULL)
457 return NULL;
458 memcpy(hp, res, sizeof *hp); /* XXX not sufficient */
459 return hp;
460}
461
462/*
463 * XXX This is an extremely bogus implementation.
464 */
465struct hostent *
466gethostbyaddr_r(addr, len, af, he, buf, buflen, errorp)
467 const char *addr; /* XXX should have been def'd as u_char! */
468 int len, af;
469 struct hostent * he;
470 char * buf;
471 int buflen;
472 int * errorp;
473{
474 struct hostent * res;
475
476 res = gethostbyaddr(addr, len, af);
477 *errorp = h_errno;
478 if (res == NULL)
479 return NULL;
480 memcpy(he, res, sizeof *he); /* XXX not sufficient */
481 return he;
482}
483
484/* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */
485#endif
486
487_THREAD_PRIVATE_MUTEX(gethostnamadr);
488
489struct hostent *
490gethostbyname(name)
491 const char *name;
492{
493 struct hostent *hp;
494 extern struct hostent *_gethtbyname2();
495
496 _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr);
497 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
498 hp = _gethtbyname2(name, AF_INET);
499
500 else if (_res.options & RES_USE_INET6) {
501 hp = gethostbyname2(name, AF_INET6);
502 if (hp == NULL)
503 hp = gethostbyname2(name, AF_INET);
504 }
505 else
506 hp = gethostbyname2(name, AF_INET);
507 _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
508 return hp;
509}
510
511struct hostent *
512gethostbyname2(name, af)
513 const char *name;
514 int af;
515{
516 querybuf *buf;
517 register const char *cp;
518 char *bp, *ep;
519 int n, size, type, i;
520 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname();
521 register struct hostent *hp;
522 char lookups[MAXDNSLUS];
523
524 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
525 return (_gethtbyname2(name, af));
526
527 switch (af) {
528 case AF_INET:
529 size = INADDRSZ;
530 type = T_A;
531 break;
532 case AF_INET6:
533 size = IN6ADDRSZ;
534 type = T_AAAA;
535 break;
536 default:
537 h_errno = NETDB_INTERNAL;
538 errno = EAFNOSUPPORT;
539 return (NULL);
540 }
541
542 host.h_addrtype = af;
543 host.h_length = size;
544
545 /*
546 * if there aren't any dots, it could be a user-level alias.
547 * this is also done in res_query() since we are not the only
548 * function that looks up host names.
549 */
550 if (!strchr(name, '.') && (cp = __hostalias(name)))
551 name = cp;
552
553 /*
554 * disallow names consisting only of digits/dots, unless
555 * they end in a dot.
556 */
557 if (isdigit(name[0]))
558 for (cp = name;; ++cp) {
559 if (!*cp) {
560 if (*--cp == '.')
561 break;
562 /*
563 * All-numeric, no dot at the end.
564 * Fake up a hostent as if we'd actually
565 * done a lookup.
566 */
567 if (inet_pton(af, name, host_addr) <= 0) {
568 h_errno = HOST_NOT_FOUND;
569 return (NULL);
570 }
571 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
572 bp = hostbuf + MAXHOSTNAMELEN;
573 ep = hostbuf + sizeof(hostbuf);
574 host.h_name = hostbuf;
575 host.h_aliases = host_aliases;
576 host_aliases[0] = NULL;
577 h_addr_ptrs[0] = (char *)host_addr;
578 h_addr_ptrs[1] = NULL;
579 host.h_addr_list = h_addr_ptrs;
580 if (_res.options & RES_USE_INET6)
581 map_v4v6_hostent(&host, &bp, ep);
582 h_errno = NETDB_SUCCESS;
583 return (&host);
584 }
585 if (!isdigit(*cp) && *cp != '.')
586 break;
587 }
588 if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
589 name[0] == ':')
590 for (cp = name;; ++cp) {
591 if (!*cp) {
592 if (*--cp == '.')
593 break;
594 /*
595 * All-IPv6-legal, no dot at the end.
596 * Fake up a hostent as if we'd actually
597 * done a lookup.
598 */
599 if (inet_pton(af, name, host_addr) <= 0) {
600 h_errno = HOST_NOT_FOUND;
601 return (NULL);
602 }
603 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
604 bp = hostbuf + MAXHOSTNAMELEN;
605 ep = hostbuf + sizeof(hostbuf);
606 host.h_name = hostbuf;
607 host.h_aliases = host_aliases;
608 host_aliases[0] = NULL;
609 h_addr_ptrs[0] = (char *)host_addr;
610 h_addr_ptrs[1] = NULL;
611 host.h_addr_list = h_addr_ptrs;
612 h_errno = NETDB_SUCCESS;
613 return (&host);
614 }
615 if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
616 break;
617 }
618
619 bcopy(_res.lookups, lookups, sizeof lookups);
620 if (lookups[0] == '\0')
621 strlcpy(lookups, "bf", sizeof lookups);
622
623 hp = (struct hostent *)NULL;
624 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
625 switch (lookups[i]) {
626#ifdef YP
627 case 'y':
628 /* YP only supports AF_INET. */
629 if (af == AF_INET)
630 hp = _yp_gethtbyname(name);
631 break;
632#endif
633 case 'b':
634 buf = malloc(sizeof(*buf));
635 if (buf == NULL)
636 break;
637 if ((n = res_search(name, C_IN, type, buf->buf,
638 sizeof(buf->buf))) < 0) {
639 free(buf);
640#ifdef DEBUG
641 if (_res.options & RES_DEBUG)
642 printf("res_search failed\n");
643#endif
644 break;
645 }
646 hp = getanswer(buf, n, name, type);
647 free(buf);
648 break;
649 case 'f':
650 hp = _gethtbyname2(name, af);
651 break;
652 }
653 }
654 /* XXX h_errno not correct in all cases... */
655 return (hp);
656}
657
658struct hostent *
659gethostbyaddr(addr, len, af)
660 const char *addr; /* XXX should have been def'd as u_char! */
661 int len, af;
662{
663 const u_char *uaddr = (const u_char *)addr;
664 int n, size, i;
665 querybuf *buf;
666 register struct hostent *hp;
667 char qbuf[MAXDNAME+1], *qp;
668 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr();
669 char lookups[MAXDNSLUS];
670 struct hostent *res;
671
672 _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr);
673 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
674 res = _gethtbyaddr(addr, len, af);
675 _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
676 return (res);
677 }
678
679 if (af == AF_INET6 && len == IN6ADDRSZ &&
680 (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)uaddr) ||
681 IN6_IS_ADDR_SITELOCAL((struct in6_addr *)uaddr))) {
682 h_errno = HOST_NOT_FOUND;
683 return (NULL);
684 }
685 if (af == AF_INET6 && len == IN6ADDRSZ &&
686 (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)uaddr) ||
687 IN6_IS_ADDR_V4COMPAT((struct in6_addr *)uaddr))) {
688 /* Unmap. */
689 addr += IN6ADDRSZ - INADDRSZ;
690 uaddr += IN6ADDRSZ - INADDRSZ;
691 af = AF_INET;
692 len = INADDRSZ;
693 }
694 switch (af) {
695 case AF_INET:
696 size = INADDRSZ;
697 break;
698 case AF_INET6:
699 size = IN6ADDRSZ;
700 break;
701 default:
702 errno = EAFNOSUPPORT;
703 h_errno = NETDB_INTERNAL;
704 _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
705 return (NULL);
706 }
707 if (size != len) {
708 errno = EINVAL;
709 h_errno = NETDB_INTERNAL;
710 _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
711 return (NULL);
712 }
713 switch (af) {
714 case AF_INET:
715 (void) snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u.in-addr.arpa",
716 (uaddr[3] & 0xff), (uaddr[2] & 0xff),
717 (uaddr[1] & 0xff), (uaddr[0] & 0xff));
718 break;
719 case AF_INET6:
720 qp = qbuf;
721 for (n = IN6ADDRSZ - 1; n >= 0; n--) {
722 qp += sprintf(qp, "%x.%x.",
723 uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
724 }
725 break;
726 }
727
728 bcopy(_res.lookups, lookups, sizeof lookups);
729 if (lookups[0] == '\0')
730 strlcpy(lookups, "bf", sizeof lookups);
731
732 hp = (struct hostent *)NULL;
733 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
734 switch (lookups[i]) {
735#ifdef YP
736 case 'y':
737 /* YP only supports AF_INET. */
738 if (af == AF_INET)
739 hp = _yp_gethtbyaddr(addr);
740 break;
741#endif
742 case 'b':
743 if (af == AF_INET6)
744 strcpy(qp, "ip6.arpa");
745 buf = malloc(sizeof(*buf));
746 if (!buf)
747 break;
748 n = res_query(qbuf, C_IN, T_PTR, buf->buf,
749 sizeof(buf->buf));
750 if (n < 0 && af == AF_INET6) {
751 strcpy(qp, "ip6.int");
752 n = res_query(qbuf, C_IN, T_PTR,
753 buf->buf, sizeof(buf->buf));
754 }
755 if (n < 0) {
756 free(buf);
757#ifdef DEBUG
758 if (_res.options & RES_DEBUG)
759 printf("res_query failed\n");
760#endif
761 break;
762 }
763 if (!(hp = getanswer(buf, n, qbuf, T_PTR))) {
764 free(buf);
765 break;
766 }
767 free(buf);
768 hp->h_addrtype = af;
769 hp->h_length = len;
770 bcopy(addr, host_addr, len);
771 h_addr_ptrs[0] = (char *)host_addr;
772 h_addr_ptrs[1] = NULL;
773 if (af == AF_INET && (_res.options & RES_USE_INET6)) {
774 map_v4v6_address((char*)host_addr,
775 (char*)host_addr);
776 hp->h_addrtype = AF_INET6;
777 hp->h_length = IN6ADDRSZ;
778 }
779 h_errno = NETDB_SUCCESS;
780 break;
781 case 'f':
782 hp = _gethtbyaddr(addr, len, af);
783 break;
784 }
785 }
786 _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
787 /* XXX h_errno not correct in all cases... */
788 return (hp);
789}
790
791void
792_sethtent(f)
793 int f;
794{
795 if (hostf == NULL)
796 hostf = fopen(_PATH_HOSTS, "r" );
797 else
798 rewind(hostf);
799 stayopen = f;
800}
801
802void
803_endhtent()
804{
805 if (hostf && !stayopen) {
806 (void) fclose(hostf);
807 hostf = NULL;
808 }
809}
810
811struct hostent *
812_gethtent()
813{
814 char *p;
815 register char *cp, **q;
816 int af;
817 size_t len;
818
819 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
820 h_errno = NETDB_INTERNAL;
821 return (NULL);
822 }
823 again:
824 if ((p = fgetln(hostf, &len)) == NULL) {
825 h_errno = HOST_NOT_FOUND;
826 return (NULL);
827 }
828 if (p[len-1] == '\n')
829 len--;
830 if (len >= sizeof(hostbuf) || len == 0)
831 goto again;
832 p = memcpy(hostbuf, p, len);
833 hostbuf[len] = '\0';
834 if (*p == '#')
835 goto again;
836 if ((cp = strchr(p, '#')))
837 *cp = '\0';
838 if (!(cp = strpbrk(p, " \t")))
839 goto again;
840 *cp++ = '\0';
841 if (inet_pton(AF_INET6, p, host_addr) > 0) {
842 af = AF_INET6;
843 len = IN6ADDRSZ;
844 } else if (inet_pton(AF_INET, p, host_addr) > 0) {
845 if (_res.options & RES_USE_INET6) {
846 map_v4v6_address((char*)host_addr, (char*)host_addr);
847 af = AF_INET6;
848 len = IN6ADDRSZ;
849 } else {
850 af = AF_INET;
851 len = INADDRSZ;
852 }
853 } else {
854 goto again;
855 }
856 /* if this is not something we're looking for, skip it. */
857 if (host.h_addrtype != af)
858 goto again;
859 if (host.h_length != len)
860 goto again;
861 h_addr_ptrs[0] = (char *)host_addr;
862 h_addr_ptrs[1] = NULL;
863 host.h_addr_list = h_addr_ptrs;
864 host.h_length = len;
865 host.h_addrtype = af;
866 while (*cp == ' ' || *cp == '\t')
867 cp++;
868 host.h_name = cp;
869 q = host.h_aliases = host_aliases;
870 if ((cp = strpbrk(cp, " \t")))
871 *cp++ = '\0';
872 while (cp && *cp) {
873 if (*cp == ' ' || *cp == '\t') {
874 cp++;
875 continue;
876 }
877 if (q < &host_aliases[MAXALIASES - 1])
878 *q++ = cp;
879 if ((cp = strpbrk(cp, " \t")))
880 *cp++ = '\0';
881 }
882 *q = NULL;
883 if (_res.options & RES_USE_INET6) {
884 char *bp = hostbuf;
885 char *ep = hostbuf + sizeof hostbuf;
886
887 map_v4v6_hostent(&host, &bp, ep);
888 }
889 h_errno = NETDB_SUCCESS;
890 return (&host);
891}
892
893struct hostent *
894_gethtbyname(name)
895 const char *name;
896{
897 extern struct hostent *_gethtbyname2();
898 struct hostent *hp;
899
900 if (_res.options & RES_USE_INET6) {
901 hp = _gethtbyname2(name, AF_INET6);
902 if (hp)
903 return (hp);
904 }
905 return (_gethtbyname2(name, AF_INET));
906}
907
908struct hostent *
909_gethtbyname2(name, af)
910 const char *name;
911 int af;
912{
913 register struct hostent *p;
914 register char **cp;
915
916 _sethtent(0);
917 while ((p = _gethtent())) {
918 if (p->h_addrtype != af)
919 continue;
920 if (strcasecmp(p->h_name, name) == 0)
921 break;
922 for (cp = p->h_aliases; *cp != 0; cp++)
923 if (strcasecmp(*cp, name) == 0)
924 goto found;
925 }
926 found:
927 _endhtent();
928 return (p);
929}
930
931struct hostent *
932_gethtbyaddr(addr, len, af)
933 const char *addr;
934 int len, af;
935{
936 register struct hostent *p;
937
938 host.h_length = len;
939 host.h_addrtype = af;
940
941 _sethtent(0);
942 while ((p = _gethtent()))
943 if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
944 break;
945 _endhtent();
946 return (p);
947}
948
949#ifdef YP
950struct hostent *
951_yphostent(line)
952 char *line;
953{
954 static struct in_addr host_addrs[MAXADDRS];
955 char *p = line;
956 char *cp, **q;
957 char **hap;
958 struct in_addr *buf;
959 int more;
960
961 host.h_name = NULL;
962 host.h_addr_list = h_addr_ptrs;
963 host.h_length = INADDRSZ;
964 host.h_addrtype = AF_INET;
965 hap = h_addr_ptrs;
966 buf = host_addrs;
967 q = host.h_aliases = host_aliases;
968
969nextline:
970 /* check for host_addrs overflow */
971 if (buf >= &host_addrs[sizeof(host_addrs) / sizeof(host_addrs[0])])
972 goto done;
973
974 more = 0;
975 cp = strpbrk(p, " \t");
976 if (cp == NULL)
977 goto done;
978 *cp++ = '\0';
979
980 *hap++ = (char *)buf;
981 (void) inet_aton(p, buf++);
982
983 while (*cp == ' ' || *cp == '\t')
984 cp++;
985 p = cp;
986 cp = strpbrk(p, " \t\n");
987 if (cp != NULL) {
988 if (*cp == '\n')
989 more = 1;
990 *cp++ = '\0';
991 }
992 if (!host.h_name)
993 host.h_name = p;
994 else if (strcmp(host.h_name, p)==0)
995 ;
996 else if (q < &host_aliases[MAXALIASES - 1])
997 *q++ = p;
998 p = cp;
999 if (more)
1000 goto nextline;
1001
1002 while (cp && *cp) {
1003 if (*cp == ' ' || *cp == '\t') {
1004 cp++;
1005 continue;
1006 }
1007 if (*cp == '\n') {
1008 cp++;
1009 goto nextline;
1010 }
1011 if (q < &host_aliases[MAXALIASES - 1])
1012 *q++ = cp;
1013 cp = strpbrk(cp, " \t");
1014 if (cp != NULL)
1015 *cp++ = '\0';
1016 }
1017done:
1018 if (host.h_name == NULL)
1019 return (NULL);
1020 *q = NULL;
1021 *hap = NULL;
1022 return (&host);
1023}
1024
1025struct hostent *
1026_yp_gethtbyaddr(addr)
1027 const char *addr;
1028{
1029 struct hostent *hp = (struct hostent *)NULL;
1030 static char *__ypcurrent;
1031 int __ypcurrentlen, r;
1032 char name[sizeof("xxx.xxx.xxx.xxx")];
1033
1034 if (!__ypdomain) {
1035 if (_yp_check(&__ypdomain) == 0)
1036 return (hp);
1037 }
1038 snprintf(name, sizeof name, "%u.%u.%u.%u",
1039 ((unsigned)addr[0] & 0xff), ((unsigned)addr[1] & 0xff),
1040 ((unsigned)addr[2] & 0xff), ((unsigned)addr[3] & 0xff));
1041 if (__ypcurrent)
1042 free(__ypcurrent);
1043 __ypcurrent = NULL;
1044 r = yp_match(__ypdomain, "hosts.byaddr", name,
1045 strlen(name), &__ypcurrent, &__ypcurrentlen);
1046 if (r==0)
1047 hp = _yphostent(__ypcurrent);
1048 if (hp==NULL)
1049 h_errno = HOST_NOT_FOUND;
1050 return (hp);
1051}
1052
1053struct hostent *
1054_yp_gethtbyname(name)
1055 const char *name;
1056{
1057 struct hostent *hp = (struct hostent *)NULL;
1058 static char *__ypcurrent;
1059 int __ypcurrentlen, r;
1060
1061 if (strlen(name) >= MAXHOSTNAMELEN)
1062 return (NULL);
1063 if (!__ypdomain) {
1064 if (_yp_check(&__ypdomain) == 0)
1065 return (hp);
1066 }
1067 if (__ypcurrent)
1068 free(__ypcurrent);
1069 __ypcurrent = NULL;
1070 r = yp_match(__ypdomain, "hosts.byname", name,
1071 strlen(name), &__ypcurrent, &__ypcurrentlen);
1072 if (r == 0)
1073 hp = _yphostent(__ypcurrent);
1074 if (hp == NULL)
1075 h_errno = HOST_NOT_FOUND;
1076 return (hp);
1077}
1078#endif
1079
1080static void
1081map_v4v6_address(src, dst)
1082 const char *src;
1083 char *dst;
1084{
1085 u_char *p = (u_char *)dst;
1086 char tmp[INADDRSZ];
1087 int i;
1088
1089 /* Stash a temporary copy so our caller can update in place. */
1090 bcopy(src, tmp, INADDRSZ);
1091 /* Mark this ipv6 addr as a mapped ipv4. */
1092 for (i = 0; i < 10; i++)
1093 *p++ = 0x00;
1094 *p++ = 0xff;
1095 *p++ = 0xff;
1096 /* Retrieve the saved copy and we're done. */
1097 bcopy(tmp, (void*)p, INADDRSZ);
1098}
1099
1100static void
1101map_v4v6_hostent(hp, bpp, ep)
1102 struct hostent *hp;
1103 char **bpp;
1104 char *ep;
1105{
1106 char **ap;
1107
1108 if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
1109 return;
1110 hp->h_addrtype = AF_INET6;
1111 hp->h_length = IN6ADDRSZ;
1112 for (ap = hp->h_addr_list; *ap; ap++) {
1113 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1114
1115 if (ep - *bpp < (i + IN6ADDRSZ)) {
1116 /* Out of memory. Truncate address list here. XXX */
1117 *ap = NULL;
1118 return;
1119 }
1120 *bpp += i;
1121 map_v4v6_address(*ap, *bpp);
1122 *ap = *bpp;
1123 *bpp += IN6ADDRSZ;
1124 }
1125}
1126
1127struct hostent *
1128gethostent()
1129{
1130 return (_gethtent());
1131}
1132
1133#ifdef RESOLVSORT
1134static void
1135addrsort(ap, num)
1136 char **ap;
1137 int num;
1138{
1139 int i, j;
1140 char **p;
1141 short aval[MAXADDRS];
1142 int needsort = 0;
1143
1144 p = ap;
1145 for (i = 0; i < num; i++, p++) {
1146 for (j = 0 ; (unsigned)j < _res.nsort; j++)
1147 if (_res.sort_list[j].addr.s_addr ==
1148 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
1149 break;
1150 aval[i] = j;
1151 if (needsort == 0 && i > 0 && j < aval[i-1])
1152 needsort = i;
1153 }
1154 if (!needsort)
1155 return;
1156
1157 while (needsort < num) {
1158 for (j = needsort - 1; j >= 0; j--) {
1159 if (aval[j] > aval[j+1]) {
1160 char *hp;
1161
1162 i = aval[j];
1163 aval[j] = aval[j+1];
1164 aval[j+1] = i;
1165
1166 hp = ap[j];
1167 ap[j] = ap[j+1];
1168 ap[j+1] = hp;
1169 } else
1170 break;
1171 }
1172 needsort++;
1173 }
1174}
1175#endif
diff --git a/src/lib/libc/net/getifaddrs.3 b/src/lib/libc/net/getifaddrs.3
new file mode 100644
index 0000000000..2743bf6fc2
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.3
@@ -0,0 +1,159 @@
1.\" $OpenBSD: getifaddrs.3,v 1.8 2002/01/02 06:08:55 nordin Exp $
2.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp
3.\"
4.\" Copyright (c) 1995, 1999
5.\" Berkeley Software Design, Inc. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.Dd "October 12, 1995"
25.Dt GETIFADDRS 3
26.Os
27.Sh NAME
28.Nm getifaddrs
29.Nd get interface addresses
30.Sh SYNOPSIS
31.Fd #include <sys/types.h>
32.Fd #include <sys/socket.h>
33.Fd #include <ifaddrs.h>
34.Ft int
35.Fn getifaddrs "struct ifaddrs **ifap"
36.Ft void
37.Fn freeifaddrs "struct ifaddrs *ifap"
38.Sh DESCRIPTION
39The
40.Fn getifaddrs
41function stores a reference to a linked list of the network interfaces
42on the local machine in the memory referenced by
43.Fa ifap .
44The list consists of
45.Nm ifaddrs
46structures, as defined in the include file
47.Aq Pa ifaddrs.h .
48The
49.Nm ifaddrs
50structure contains at least the following entries:
51.Bd -literal
52 struct ifaddrs *ifa_next; /* Pointer to next struct */
53 char *ifa_name; /* Interface name */
54 u_int ifa_flags; /* Interface flags */
55 struct sockaddr *ifa_addr; /* Interface address */
56 struct sockaddr *ifa_netmask; /* Interface netmask */
57 struct sockaddr *ifa_broadaddr; /* Interface broadcast address */
58 struct sockaddr *ifa_dstaddr; /* P2P interface destination */
59 void *ifa_data; /* Address specific data */
60.Ed
61.Pp
62.Bl -tag -width Ds
63.It Fa ifa_next
64Contains a pointer to the next structure on the list.
65This field is set to
66.Dv NULL
67in last structure on the list.
68.It Fa ifa_name
69Contains the interface name.
70.It Fa ifa_flags
71Contains the interface flags, as set by
72.Xr ifconfig 8 .
73.It Fa ifa_addr
74References either the address of the interface or the link level
75address of the interface, if one exists, otherwise it is
76.Dv NULL .
77(The
78.Fa sa_family
79field of the
80.Fa ifa_addr
81field should be consulted to determine the format of the
82.Fa ifa_addr
83address.)
84.It Fa ifa_netmask
85References the netmask associated with
86.Fa ifa_addr ,
87if one is set, otherwise it is
88.Dv NULL .
89.It Fa ifa_broadaddr
90This field, which should only be referenced for non-P2P interfaces,
91references the broadcast address associated with
92.Fa ifa_addr ,
93if one exists, otherwise it is
94.Dv NULL .
95.It Fa ifa_dstaddr
96References the destination address on a P2P interface,
97if one exists, otherwise it is
98.Dv NULL .
99.It Fa ifa_data
100References address family specific data.
101For
102.Dv AF_LINK
103addresses it contains a pointer to the
104.Li struct if_data
105(as defined in include file
106.Aq Pa net/if.h )
107which contains various interface attributes and statistics.
108For all other address families, it contains a pointer to the
109.Li struct ifa_data
110(as defined in include file
111.Aq Pa net/if.h )
112which contains per-address interface statistics.
113.El
114.Pp
115The data returned by
116.Fn getifaddrs
117is dynamically allocated and should be freed using
118.Fn freeifaddrs
119when no longer needed.
120.Sh RETURN VALUES
121Upon successful completion, a value of 0 is returned.
122Otherwise, a value of \-1 is returned and
123.Va errno
124is set to indicate the error.
125.Sh ERRORS
126The
127.Fn getifaddrs
128may fail and set
129.Va errno
130for any of the errors specified for the library routines
131.Xr ioctl 2 ,
132.Xr socket 2 ,
133.Xr malloc 3 ,
134or
135.Xr sysctl 3 .
136.Sh BUGS
137If both
138.Aq Pa net/if.h
139and
140.Aq Pa ifaddrs.h
141are being included,
142.Aq Pa net/if.h
143.Em must
144be included before
145.Aq Pa ifaddrs.h .
146.Sh SEE ALSO
147.Xr ioctl 2 ,
148.Xr socket 2 ,
149.Xr sysctl 3 ,
150.Xr networking 4 ,
151.Xr ifconfig 8
152.Sh HISTORY
153The
154.Fn getifaddrs
155function first appeared in BSDI BSD/OS.
156The function is supplied on
157.Ox
158since
159.Ox 2.7 .
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c
new file mode 100644
index 0000000000..0db89f6c19
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.c
@@ -0,0 +1,277 @@
1/* $OpenBSD: getifaddrs.c,v 1.9 2002/08/09 06:12:25 itojun Exp $ */
2
3/*
4 * Copyright (c) 1995, 1999
5 * Berkeley Software Design, Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp
26 */
27
28#include <sys/types.h>
29#include <sys/ioctl.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <sys/param.h>
33#include <net/route.h>
34#include <sys/sysctl.h>
35#include <net/if_dl.h>
36
37#include <errno.h>
38#include <ifaddrs.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#define SALIGN (sizeof(long) - 1)
44#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
45
46int
47getifaddrs(struct ifaddrs **pif)
48{
49 int icnt = 1;
50 int dcnt = 0;
51 int ncnt = 0;
52 int mib[6];
53 size_t needed;
54 char *buf;
55 char *next;
56 struct ifaddrs *cif = 0;
57 char *p, *p0;
58 struct rt_msghdr *rtm;
59 struct if_msghdr *ifm;
60 struct ifa_msghdr *ifam;
61 struct sockaddr_dl *dl;
62 struct sockaddr *sa;
63 u_short index = 0;
64 size_t len, alen;
65 struct ifaddrs *ifa, *ift;
66 int i;
67 char *data;
68 char *names;
69
70 mib[0] = CTL_NET;
71 mib[1] = PF_ROUTE;
72 mib[2] = 0; /* protocol */
73 mib[3] = 0; /* wildcard address family */
74 mib[4] = NET_RT_IFLIST;
75 mib[5] = 0; /* no flags */
76 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
77 return (-1);
78 if ((buf = malloc(needed)) == NULL)
79 return (-1);
80 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
81 free(buf);
82 return (-1);
83 }
84
85 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
86 rtm = (struct rt_msghdr *)next;
87 if (rtm->rtm_version != RTM_VERSION)
88 continue;
89 switch (rtm->rtm_type) {
90 case RTM_IFINFO:
91 ifm = (struct if_msghdr *)rtm;
92 if (ifm->ifm_addrs & RTA_IFP) {
93 index = ifm->ifm_index;
94 ++icnt;
95 dl = (struct sockaddr_dl *)(ifm + 1);
96 dcnt += SA_RLEN((struct sockaddr *)dl) +
97 ALIGNBYTES;
98 dcnt += sizeof(ifm->ifm_data);
99 ncnt += dl->sdl_nlen + 1;
100 } else
101 index = 0;
102 break;
103
104 case RTM_NEWADDR:
105 ifam = (struct ifa_msghdr *)rtm;
106 if (index && ifam->ifam_index != index)
107 abort(); /* XXX abort illegal in library */
108
109#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD)
110 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
111 break;
112 p = (char *)(ifam + 1);
113 ++icnt;
114 /* Scan to look for length of address */
115 alen = 0;
116 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
117 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
118 == 0)
119 continue;
120 sa = (struct sockaddr *)p;
121 len = SA_RLEN(sa);
122 if (i == RTAX_IFA) {
123 alen = len;
124 break;
125 }
126 p += len;
127 }
128 for (p = p0, i = 0; i < RTAX_MAX; i++) {
129 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
130 == 0)
131 continue;
132 sa = (struct sockaddr *)p;
133 len = SA_RLEN(sa);
134 if (i == RTAX_NETMASK && sa->sa_len == 0)
135 dcnt += alen;
136 else
137 dcnt += len;
138 p += len;
139 }
140 break;
141 }
142 }
143
144 if (icnt + dcnt + ncnt == 1) {
145 *pif = NULL;
146 free(buf);
147 return (0);
148 }
149 data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
150 if (data == NULL) {
151 free(buf);
152 return(-1);
153 }
154
155 ifa = (struct ifaddrs *)data;
156 data += sizeof(struct ifaddrs) * icnt;
157 names = data + dcnt;
158
159 memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
160 ift = ifa;
161
162 index = 0;
163 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
164 rtm = (struct rt_msghdr *)next;
165 if (rtm->rtm_version != RTM_VERSION)
166 continue;
167 switch (rtm->rtm_type) {
168 case RTM_IFINFO:
169 ifm = (struct if_msghdr *)rtm;
170 if (ifm->ifm_addrs & RTA_IFP) {
171 index = ifm->ifm_index;
172 dl = (struct sockaddr_dl *)(ifm + 1);
173
174 cif = ift;
175 ift->ifa_name = names;
176 ift->ifa_flags = (int)ifm->ifm_flags;
177 memcpy(names, dl->sdl_data, dl->sdl_nlen);
178 names[dl->sdl_nlen] = 0;
179 names += dl->sdl_nlen + 1;
180
181 ift->ifa_addr = (struct sockaddr *)data;
182 memcpy(data, dl,
183 ((struct sockaddr *)dl)->sa_len);
184 data += SA_RLEN((struct sockaddr *)dl);
185
186 /* ifm_data needs to be aligned */
187 ift->ifa_data = data = (void *)ALIGN(data);
188 memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
189 data += sizeof(ifm->ifm_data);
190
191 ift = (ift->ifa_next = ift + 1);
192 } else
193 index = 0;
194 break;
195
196 case RTM_NEWADDR:
197 ifam = (struct ifa_msghdr *)rtm;
198 if (index && ifam->ifam_index != index)
199 abort(); /* XXX abort illegal in library */
200
201 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
202 break;
203 ift->ifa_name = cif->ifa_name;
204 ift->ifa_flags = cif->ifa_flags;
205 ift->ifa_data = NULL;
206 p = (char *)(ifam + 1);
207 /* Scan to look for length of address */
208 alen = 0;
209 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
210 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
211 == 0)
212 continue;
213 sa = (struct sockaddr *)p;
214 len = SA_RLEN(sa);
215 if (i == RTAX_IFA) {
216 alen = len;
217 break;
218 }
219 p += len;
220 }
221 for (p = p0, i = 0; i < RTAX_MAX; i++) {
222 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
223 == 0)
224 continue;
225 sa = (struct sockaddr *)p;
226 len = SA_RLEN(sa);
227 switch (i) {
228 case RTAX_IFA:
229 ift->ifa_addr = (struct sockaddr *)data;
230 memcpy(data, p, len);
231 data += len;
232 break;
233
234 case RTAX_NETMASK:
235 ift->ifa_netmask =
236 (struct sockaddr *)data;
237 if (sa->sa_len == 0) {
238 memset(data, 0, alen);
239 data += alen;
240 break;
241 }
242 memcpy(data, p, len);
243 data += len;
244 break;
245
246 case RTAX_BRD:
247 ift->ifa_broadaddr =
248 (struct sockaddr *)data;
249 memcpy(data, p, len);
250 data += len;
251 break;
252 }
253 p += len;
254 }
255
256
257 ift = (ift->ifa_next = ift + 1);
258 break;
259 }
260 }
261
262 free(buf);
263 if (--ift >= ifa) {
264 ift->ifa_next = NULL;
265 *pif = ifa;
266 } else {
267 *pif = NULL;
268 free(ifa);
269 }
270 return (0);
271}
272
273void
274freeifaddrs(struct ifaddrs *ifp)
275{
276 free(ifp);
277}
diff --git a/src/lib/libc/net/getnameinfo.3 b/src/lib/libc/net/getnameinfo.3
new file mode 100644
index 0000000000..76c6449906
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.3
@@ -0,0 +1,297 @@
1.\" $OpenBSD: getnameinfo.3,v 1.17 2001/11/15 06:53:09 itojun Exp $
2.\" $KAME: getnameinfo.3,v 1.20 2001/01/05 13:37:37 itojun Exp $
3.\"
4.\" Copyright (c) 1983, 1987, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
36.\"
37.Dd May 25, 1995
38.Dt GETNAMEINFO 3
39.Os
40.\"
41.Sh NAME
42.Nm getnameinfo
43.Nd address-to-nodename translation in protocol-independent manner
44.\"
45.Sh SYNOPSIS
46.Fd #include <sys/types.h>
47.Fd #include <sys/socket.h>
48.Fd #include <netdb.h>
49.Ft int
50.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" \
51"char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
52.\"
53.Sh DESCRIPTION
54The
55.Fn getnameinfo
56function is defined for protocol-independent address-to-nodename translation.
57Its functionality is a reverse conversion of
58.Xr getaddrinfo 3 ,
59and implements similar functionality with
60.Xr gethostbyaddr 3
61and
62.Xr getservbyport 3
63in more sophisticated manner.
64.Pp
65This function looks up an IP address and port number provided by the
66caller in the DNS and system-specific database, and returns text
67strings for both in buffers provided by the caller.
68The function indicates successful completion by a zero return value;
69a non-zero return value indicates failure.
70.Pp
71The first argument,
72.Fa sa ,
73points to either a
74.Li sockaddr_in
75structure (for IPv4) or a
76.Li sockaddr_in6
77structure (for IPv6) that holds the IP address and port number.
78The
79.Fa salen
80argument gives the length of the
81.Li sockaddr_in
82or
83.Li sockaddr_in6
84structure.
85.Pp
86The function returns the nodename associated with the IP address in
87the buffer pointed to by the
88.Fa host
89argument.
90The caller provides the size of this buffer via the
91.Fa hostlen
92argument.
93The service name associated with the port number is returned in the buffer
94pointed to by
95.Fa serv ,
96and the
97.Fa servlen
98argument gives the length of this buffer.
99The caller specifies not to return either string by providing a zero
100value for the
101.Fa hostlen
102or
103.Fa servlen
104arguments.
105Otherwise, the caller must provide buffers large enough to hold the
106nodename and the service name, including the terminating null characters.
107.Pp
108Unfortunately most systems do not provide constants that specify the
109maximum size of either a fully-qualified domain name or a service name.
110Therefore to aid the application in allocating buffers for these two
111returned strings the following constants are defined in
112.Aq Pa netdb.h :
113.Bd -literal -offset
114#define NI_MAXHOST MAXHOSTNAMELEN
115#define NI_MAXSERV 32
116.Ed
117.Pp
118The first value is actually defined as the constant
119.Dv MAXDNAME
120in recent versions of BIND's
121.Aq Pa arpa/nameser.h
122header (older versions of BIND define this constant to be 256)
123and the second is a guess based on the services listed in the current
124Assigned Numbers RFC.
125.Pp
126The final argument is a
127.Fa flag
128that changes the default actions of this function.
129By default the fully-qualified domain name (FQDN) for the host is
130looked up in the DNS and returned.
131If the flag bit
132.Dv NI_NOFQDN
133is set, only the nodename portion of the FQDN is returned for local hosts.
134.Pp
135If the
136.Fa flag
137bit
138.Dv NI_NUMERICHOST
139is set, or if the host's name cannot be located in the DNS,
140the numeric form of the host's address is returned instead of its name
141.Po
142e.g., by calling
143.Fn inet_ntop
144instead of
145.Fn gethostbyaddr
146.Pc .
147If the
148.Fa flag
149bit
150.Dv NI_NAMEREQD
151is set, an error is returned if the host's name cannot be located in the DNS.
152.Pp
153If the flag bit
154.Dv NI_NUMERICSERV
155is set, the numeric form of the service address is returned
156.Pq e.g., its port number
157instead of its name.
158The two
159.Dv NI_NUMERICxxx
160flags are required to support the
161.Fl n
162flag that many commands provide.
163.Pp
164A fifth flag bit,
165.Dv NI_DGRAM ,
166specifies that the service is a datagram service, and causes
167.Fn getservbyport
168to be called with a second argument of
169.Qq udp
170instead of its default of
171.Qq tcp .
172This is required for the few ports (512-514)
173that have different services for UDP and TCP.
174.Pp
175These
176.Dv NI_xxx
177flags are defined in
178.Aq Pa netdb.h .
179.\"
180.Ss Extension for scoped IPv6 address
181The implementation allows experimental numeric IPv6 address notation with
182scope identifier.
183IPv6 link-local address will appear as string like
184.Dq Li fe80::1%ne0 .
185Refer to
186.Xr getaddrinfo 3
187for the notation.
188.\"
189.Sh EXAMPLES
190The following code tries to get numeric hostname, and service name,
191for given socket address.
192Observe that there is no hardcoded reference to particular address family.
193.Bd -literal -offset indent
194struct sockaddr *sa; /* input */
195char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
196
197if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
198 sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
199 errx(1, "could not get numeric hostname");
200 /*NOTREACHED*/
201}
202printf("host=%s, serv=%s\en", hbuf, sbuf);
203.Ed
204.Pp
205The following version checks if the socket address has reverse address mapping.
206.Bd -literal -offset indent
207struct sockaddr *sa; /* input */
208char hbuf[NI_MAXHOST];
209
210if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
211 NI_NAMEREQD)) {
212 errx(1, "could not resolve hostname");
213 /*NOTREACHED*/
214}
215printf("host=%s\en", hbuf);
216.Ed
217.\"
218.Sh DIAGNOSTICS
219The function indicates successful completion by a zero return value;
220a non-zero return value indicates failure.
221Error codes are as below:
222.Bl -tag -width Er
223.It Dv EAI_AGAIN
224The name could not be resolved at this time.
225Future attempts may succeed.
226.It Dv EAI_BADFLAGS
227The flags had an invalid value.
228.It Dv EAI_FAIL
229A non-recoverable error occurred.
230.It Dv EAI_FAMILY
231The address family was not recognized or the address length was invalid
232for the specified family.
233.It Dv EAI_MEMORY
234There was a memory allocation failure.
235.It Dv EAI_NONAME
236The name does not resolve for the supplied parameters.
237.Dv NI_NAMEREQD
238is set and the host's name cannot be located,
239or both nodename and servname were null.
240.It Dv EAI_SYSTEM
241A system error occurred.
242The error code can be found in errno.
243.El
244.\"
245.Sh SEE ALSO
246.Xr getaddrinfo 3 ,
247.Xr gethostbyaddr 3 ,
248.Xr getservbyport 3 ,
249.Xr hosts 5 ,
250.Xr resolv.conf 5 ,
251.Xr services 5 ,
252.Xr hostname 7 ,
253.Xr named 8
254.Rs
255.%A R. Gilligan
256.%A S. Thomson
257.%A J. Bound
258.%A W. Stevens
259.%T Basic Socket Interface Extensions for IPv6
260.%R RFC2553
261.%D March 1999
262.Re
263.Rs
264.%A Tatsuya Jinmei
265.%A Atsushi Onoe
266.%T "An Extension of Format for IPv6 Scoped Addresses"
267.%R internet draft
268.%N draft-ietf-ipngwg-scopedaddr-format-02.txt
269.%O work in progress material
270.Re
271.Rs
272.%A Craig Metz
273.%T Protocol Independence Using the Sockets API
274.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
275.%D June 2000
276.Re
277.\"
278.Sh HISTORY
279The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
280.\"
281.Sh STANDARDS
282The
283.Fn getaddrinfo
284function is defined IEEE POSIX 1003.1g draft specification,
285and documented in
286.Dq Basic Socket Interface Extensions for IPv6
287.Pq RFC2553 .
288.\"
289.Sh BUGS
290The current implementation is not thread-safe.
291.Pp
292The text was shamelessly copied from RFC2553.
293.Pp
294.Ox
295intentionally uses different
296.Dv NI_MAXHOST
297value from what RFC2553 suggests, to avoid buffer length handling mistakes.
diff --git a/src/lib/libc/net/getnameinfo.c b/src/lib/libc/net/getnameinfo.c
new file mode 100644
index 0000000000..2311eba7a0
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.c
@@ -0,0 +1,361 @@
1/* $OpenBSD: getnameinfo.c,v 1.25 2002/06/27 09:24:28 itojun Exp $ */
2/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Issues to be discussed:
35 * - Thread safe-ness must be checked
36 * - RFC2553 says that we should raise error on short buffer. X/Open says
37 * we need to truncate the result. We obey RFC2553 (and X/Open should be
38 * modified). ipngwg rough consensus seems to follow RFC2553.
39 * - What is "local" in NI_FQDN?
40 * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
41 * - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
42 * sin6_scope_id is filled - standardization status?
43 * XXX breaks backward compat for code that expects no scopeid.
44 * beware on merge.
45 */
46
47#ifndef INET6
48#define INET6
49#endif
50
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <net/if.h>
54#include <netinet/in.h>
55#include <arpa/inet.h>
56#include <arpa/nameser.h>
57#include <netdb.h>
58#include <resolv.h>
59#include <string.h>
60#include <stddef.h>
61
62static const struct afd {
63 int a_af;
64 int a_addrlen;
65 int a_socklen;
66 int a_off;
67} afdl [] = {
68#ifdef INET6
69 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
70 offsetof(struct sockaddr_in6, sin6_addr)},
71#endif
72 {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
73 offsetof(struct sockaddr_in, sin_addr)},
74 {0, 0, 0},
75};
76
77struct sockinet {
78 u_char si_len;
79 u_char si_family;
80 u_short si_port;
81};
82
83#ifdef INET6
84static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
85 size_t, int);
86static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
87#endif
88
89int
90getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
91 const struct sockaddr *sa;
92 socklen_t salen;
93 char *host;
94 size_t hostlen;
95 char *serv;
96 size_t servlen;
97 int flags;
98{
99 const struct afd *afd;
100 struct servent *sp;
101 struct hostent *hp;
102 u_short port;
103 int family, i;
104 const char *addr;
105 u_int32_t v4a;
106 int h_error;
107 char numserv[512];
108 char numaddr[512];
109
110 if (sa == NULL)
111 return EAI_FAIL;
112
113 if (sa->sa_len != salen)
114 return EAI_FAIL;
115
116 family = sa->sa_family;
117 for (i = 0; afdl[i].a_af; i++)
118 if (afdl[i].a_af == family) {
119 afd = &afdl[i];
120 goto found;
121 }
122 return EAI_FAMILY;
123
124 found:
125 if (salen != afd->a_socklen)
126 return EAI_FAIL;
127
128 /* network byte order */
129 port = ((const struct sockinet *)sa)->si_port;
130 addr = (const char *)sa + afd->a_off;
131
132 if (serv == NULL || servlen == 0) {
133 /*
134 * do nothing in this case.
135 * in case you are wondering if "&&" is more correct than
136 * "||" here: rfc2553bis-03 says that serv == NULL OR
137 * servlen == 0 means that the caller does not want the result.
138 */
139 } else {
140 if (flags & NI_NUMERICSERV)
141 sp = NULL;
142 else {
143 sp = getservbyport(port,
144 (flags & NI_DGRAM) ? "udp" : "tcp");
145 }
146 if (sp) {
147 if (strlen(sp->s_name) + 1 > servlen)
148 return EAI_MEMORY;
149 strlcpy(serv, sp->s_name, servlen);
150 } else {
151 snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
152 if (strlen(numserv) + 1 > servlen)
153 return EAI_MEMORY;
154 strlcpy(serv, numserv, servlen);
155 }
156 }
157
158 switch (sa->sa_family) {
159 case AF_INET:
160 v4a = (u_int32_t)
161 ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
162 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
163 flags |= NI_NUMERICHOST;
164 v4a >>= IN_CLASSA_NSHIFT;
165 if (v4a == 0)
166 flags |= NI_NUMERICHOST;
167 break;
168#ifdef INET6
169 case AF_INET6:
170 {
171 const struct sockaddr_in6 *sin6;
172 sin6 = (const struct sockaddr_in6 *)sa;
173 switch (sin6->sin6_addr.s6_addr[0]) {
174 case 0x00:
175 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
176 ;
177 else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
178 ;
179 else
180 flags |= NI_NUMERICHOST;
181 break;
182 default:
183 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
184 flags |= NI_NUMERICHOST;
185 }
186 else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
187 flags |= NI_NUMERICHOST;
188 break;
189 }
190 }
191 break;
192#endif
193 }
194 if (host == NULL || hostlen == 0) {
195 /*
196 * do nothing in this case.
197 * in case you are wondering if "&&" is more correct than
198 * "||" here: rfc2553bis-03 says that host == NULL or
199 * hostlen == 0 means that the caller does not want the result.
200 */
201 } else if (flags & NI_NUMERICHOST) {
202 int numaddrlen;
203
204 /* NUMERICHOST and NAMEREQD conflicts with each other */
205 if (flags & NI_NAMEREQD)
206 return EAI_NONAME;
207
208 switch(afd->a_af) {
209#ifdef INET6
210 case AF_INET6:
211 {
212 int error;
213
214 if ((error = ip6_parsenumeric(sa, addr, host,
215 hostlen, flags)) != 0)
216 return(error);
217 break;
218 }
219#endif
220 default:
221 if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
222 == NULL)
223 return EAI_SYSTEM;
224 numaddrlen = strlen(numaddr);
225 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
226 return EAI_MEMORY;
227 strlcpy(host, numaddr, hostlen);
228 break;
229 }
230 } else {
231 hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
232 h_error = h_errno;
233
234 if (hp) {
235#if 0
236 /*
237 * commented out, since "for local host" is not
238 * implemented here - see RFC2553 p30
239 */
240 if (flags & NI_NOFQDN) {
241 char *p;
242 p = strchr(hp->h_name, '.');
243 if (p)
244 *p = '\0';
245 }
246#endif
247 if (strlen(hp->h_name) + 1 > hostlen) {
248 return EAI_MEMORY;
249 }
250 strlcpy(host, hp->h_name, hostlen);
251 } else {
252 if (flags & NI_NAMEREQD)
253 return EAI_NONAME;
254 switch(afd->a_af) {
255#ifdef INET6
256 case AF_INET6:
257 {
258 int error;
259
260 if ((error = ip6_parsenumeric(sa, addr, host,
261 hostlen,
262 flags)) != 0)
263 return(error);
264 break;
265 }
266#endif
267 default:
268 if (inet_ntop(afd->a_af, addr, host,
269 hostlen) == NULL)
270 return EAI_SYSTEM;
271 break;
272 }
273 }
274 }
275 return(0);
276}
277
278#ifdef INET6
279static int
280ip6_parsenumeric(sa, addr, host, hostlen, flags)
281 const struct sockaddr *sa;
282 const char *addr;
283 char *host;
284 size_t hostlen;
285 int flags;
286{
287 int numaddrlen;
288 char numaddr[512];
289
290 if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
291 return EAI_SYSTEM;
292
293 numaddrlen = strlen(numaddr);
294 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
295 return EAI_MEMORY;
296 strlcpy(host, numaddr, hostlen);
297
298 if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
299 char zonebuf[MAXHOSTNAMELEN];
300 int zonelen;
301
302 zonelen = ip6_sa2str(
303 (const struct sockaddr_in6 *)(const void *)sa,
304 zonebuf, sizeof(zonebuf), flags);
305 if (zonelen < 0)
306 return EAI_MEMORY;
307 if (zonelen + 1 + numaddrlen + 1 > hostlen)
308 return EAI_MEMORY;
309
310 /* construct <numeric-addr><delim><zoneid> */
311 memcpy(host + numaddrlen + 1, zonebuf,
312 (size_t)zonelen);
313 host[numaddrlen] = SCOPE_DELIMITER;
314 host[numaddrlen + 1 + zonelen] = '\0';
315 }
316
317 return 0;
318}
319
320/* ARGSUSED */
321static int
322ip6_sa2str(sa6, buf, bufsiz, flags)
323 const struct sockaddr_in6 *sa6;
324 char *buf;
325 size_t bufsiz;
326 int flags;
327{
328 unsigned int ifindex;
329 const struct in6_addr *a6;
330 int n;
331
332 ifindex = (unsigned int)sa6->sin6_scope_id;
333 a6 = &sa6->sin6_addr;
334
335#ifdef notdef
336 if ((flags & NI_NUMERICSCOPE) != 0) {
337 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
338 if (n < 0 || n >= bufsiz)
339 return -1;
340 else
341 return n;
342 }
343#endif
344
345 /* if_indextoname() does not take buffer size. not a good api... */
346 if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
347 bufsiz >= IF_NAMESIZE) {
348 char *p = if_indextoname(ifindex, buf);
349 if (p) {
350 return(strlen(p));
351 }
352 }
353
354 /* last resort */
355 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
356 if (n < 0 || n >= bufsiz)
357 return -1;
358 else
359 return n;
360}
361#endif /* INET6 */
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c
new file mode 100644
index 0000000000..925d1d5895
--- /dev/null
+++ b/src/lib/libc/net/getnetbyaddr.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.5 1997/07/09 01:08:28 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39
40extern int _net_stayopen;
41
42struct netent *
43_getnetbyaddr(net, type)
44 register in_addr_t net;
45 register int type;
46{
47 register struct netent *p;
48
49 setnetent(_net_stayopen);
50 while ((p = getnetent()))
51 if (p->n_addrtype == type && p->n_net == net)
52 break;
53 if (!_net_stayopen)
54 endnetent();
55 return (p);
56}
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
new file mode 100644
index 0000000000..4e39cf6860
--- /dev/null
+++ b/src/lib/libc/net/getnetbyname.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.5 1997/07/09 01:08:29 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _net_stayopen;
42
43struct netent *
44_getnetbyname(name)
45 register const char *name;
46{
47 register struct netent *p;
48 register char **cp;
49
50 setnetent(_net_stayopen);
51 while ((p = getnetent())) {
52 if (strcasecmp(p->n_name, name) == 0)
53 break;
54 for (cp = p->n_aliases; *cp != 0; cp++)
55 if (strcasecmp(*cp, name) == 0)
56 goto found;
57 }
58found:
59 if (!_net_stayopen)
60 endnetent();
61 return (p);
62}
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
new file mode 100644
index 0000000000..0c401c74ff
--- /dev/null
+++ b/src/lib/libc/net/getnetent.3
@@ -0,0 +1,144 @@
1.\" $OpenBSD: getnetent.3,v 1.11 2000/12/24 00:30:56 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd March 13, 1997
35.Dt GETNETENT 3
36.Os
37.Sh NAME
38.Nm getnetent ,
39.Nm getnetbyaddr ,
40.Nm getnetbyname ,
41.Nm setnetent ,
42.Nm endnetent
43.Nd get network entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct netent *
47.Fn getnetent "void"
48.Ft struct netent *
49.Fn getnetbyname "char *name"
50.Ft struct netent *
51.Fn getnetbyaddr "in_addr_t net" "int type"
52.Ft void
53.Fn setnetent "int stayopen"
54.Ft void
55.Fn endnetent "void"
56.Sh DESCRIPTION
57The
58.Fn getnetent ,
59.Fn getnetbyname ,
60and
61.Fn getnetbyaddr
62functions each return a pointer to an object with the following structure
63containing the broken-out fields of a line in the network database,
64.Pa /etc/networks .
65.Bd -literal -offset indent
66struct netent {
67 char *n_name; /* official name of net */
68 char **n_aliases; /* alias list */
69 int n_addrtype; /* net number type */
70 in_addr_t n_net; /* net number */
71};
72.Ed
73.Pp
74The members of this structure are:
75.Bl -tag -width n_addrtype
76.It Fa n_name
77The official name of the network.
78.It Fa n_aliases
79A zero-terminated list of alternate names for the network.
80.It Fa n_addrtype
81The type of the network number returned; currently only
82.Dv AF_INET .
83.It Fa n_net
84The network number.
85Network numbers are returned in machine byte order.
86.El
87.Pp
88The
89.Fn getnetent
90function reads the next line of the file, opening the file if necessary.
91.Pp
92The
93.Fn setnetent
94function opens and rewinds the file.
95If the
96.Fa stayopen
97flag is non-zero,
98the net database will not be closed after each call to
99.Fn getnetbyname
100or
101.Fn getnetbyaddr .
102.Pp
103The
104.Fn endnetent
105function closes the file.
106.Pp
107The
108.Fn getnetbyname
109and
110.Fn getnetbyaddr
111functions search the domain name server if the system is configured to use one.
112If the search fails, or no name server is configured, they sequentially
113search from the beginning of the file until a matching net name or
114net address and type is found, or until
115.Dv EOF
116is encountered.
117Network numbers are supplied in host order.
118.Sh FILES
119.Bl -tag -width /etc/networks -compact
120.It Pa /etc/networks
121.El
122.Sh DIAGNOSTICS
123Null pointer (0) returned on
124.Dv EOF
125or error.
126.Sh SEE ALSO
127.Xr resolver 3 ,
128.Xr networks 5
129.Sh HISTORY
130The
131.Fn getnetent ,
132.Fn getnetbyaddr ,
133.Fn getnetbyname ,
134.Fn setnetent ,
135and
136.Fn endnetent
137functions appeared in
138.Bx 4.2 .
139.Sh BUGS
140The data space used by these functions is static; if future use
141requires the data, it should be copied before any subsequent calls
142to these functions overwrite it.
143Only Internet network numbers are currently understood.
144Expecting network numbers to fit in no more than 32 bits is naive.
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
new file mode 100644
index 0000000000..8f618a1d5e
--- /dev/null
+++ b/src/lib/libc/net/getnetent.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetent.c,v 1.8 1998/03/16 05:06:57 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <arpa/inet.h>
42#include <netdb.h>
43#include <stdio.h>
44#include <string.h>
45
46#define MAXALIASES 35
47
48static FILE *netf;
49static char line[BUFSIZ+1];
50static struct netent net;
51static char *net_aliases[MAXALIASES];
52int _net_stayopen;
53
54void
55setnetent(f)
56 int f;
57{
58 if (netf == NULL)
59 netf = fopen(_PATH_NETWORKS, "r" );
60 else
61 rewind(netf);
62 _net_stayopen |= f;
63}
64
65void
66endnetent()
67{
68 if (netf) {
69 fclose(netf);
70 netf = NULL;
71 }
72 _net_stayopen = 0;
73}
74
75struct netent *
76getnetent()
77{
78 char *p, *cp, **q;
79 size_t len;
80
81 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
82 return (NULL);
83again:
84 if ((p = fgetln(netf, &len)) == NULL)
85 return (NULL);
86 if (p[len-1] == '\n')
87 len--;
88 if (len >= sizeof(line) || len == 0)
89 goto again;
90 p = memcpy(line, p, len);
91 line[len] = '\0';
92 if (*p == '#')
93 goto again;
94 if ((cp = strchr(p, '#')) != NULL)
95 *cp = '\0';
96 net.n_name = p;
97 if (strlen(net.n_name) >= MAXHOSTNAMELEN-1)
98 net.n_name[MAXHOSTNAMELEN-1] = '\0';
99 cp = strpbrk(p, " \t");
100 if (cp == NULL)
101 goto again;
102 *cp++ = '\0';
103 while (*cp == ' ' || *cp == '\t')
104 cp++;
105 p = strpbrk(cp, " \t");
106 if (p != NULL)
107 *p++ = '\0';
108 net.n_net = inet_network(cp);
109 net.n_addrtype = AF_INET;
110 q = net.n_aliases = net_aliases;
111 if (p != NULL)
112 cp = p;
113 while (cp && *cp) {
114 if (*cp == ' ' || *cp == '\t') {
115 cp++;
116 continue;
117 }
118 if (q < &net_aliases[MAXALIASES - 1]) {
119 *q++ = cp;
120 if (strlen(cp) >= MAXHOSTNAMELEN-1)
121 cp[MAXHOSTNAMELEN-1] = '\0';
122 }
123 cp = strpbrk(cp, " \t");
124 if (cp != NULL)
125 *cp++ = '\0';
126 }
127 *q = NULL;
128 return (&net);
129}
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000000..abbfdbd64c
--- /dev/null
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,391 @@
1/* $OpenBSD: getnetnamadr.c,v 1.18 2002/08/27 08:53:13 itojun Exp $ */
2
3/*
4 * Copyright (c) 1997, Jason Downs. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Jason Downs for the
17 * OpenBSD system.
18 * 4. Neither the name(s) of the author(s) nor the name OpenBSD
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
35 * Dep. Matematica Universidade de Coimbra, Portugal, Europe
36 *
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies.
40 */
41/*
42 * Copyright (c) 1983, 1993
43 * The Regents of the University of California. All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by the University of
56 * California, Berkeley and its contributors.
57 * 4. Neither the name of the University nor the names of its contributors
58 * may be used to endorse or promote products derived from this software
59 * without specific prior written permission.
60 *
61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * SUCH DAMAGE.
72 */
73
74#if defined(LIBC_SCCS) && !defined(lint)
75#if 0
76static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
77static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
78static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
79#else
80static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.18 2002/08/27 08:53:13 itojun Exp $";
81#endif
82#endif /* LIBC_SCCS and not lint */
83
84#include <sys/types.h>
85#include <sys/param.h>
86#include <sys/socket.h>
87#include <netinet/in.h>
88#include <arpa/inet.h>
89#include <arpa/nameser.h>
90
91#include <stdio.h>
92#include <netdb.h>
93#include <resolv.h>
94#include <ctype.h>
95#include <errno.h>
96#include <string.h>
97#include <stdlib.h>
98
99extern int h_errno;
100
101struct netent *_getnetbyaddr(in_addr_t net, int type);
102struct netent *_getnetbyname(const char *name);
103
104int _hokchar(const char *);
105
106#define BYADDR 0
107#define BYNAME 1
108#define MAXALIASES 35
109
110#define MAXPACKET (64*1024)
111
112typedef union {
113 HEADER hdr;
114 u_char buf[MAXPACKET];
115} querybuf;
116
117typedef union {
118 long al;
119 char ac;
120} align;
121
122static struct netent *
123getnetanswer(answer, anslen, net_i)
124 querybuf *answer;
125 int anslen;
126 int net_i;
127{
128
129 register HEADER *hp;
130 register u_char *cp;
131 register int n;
132 u_char *eom;
133 int type, class, ancount, qdcount, haveanswer, i, nchar;
134 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
135 char *in, *st, *pauxt, *bp, **ap, *ep;
136 char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
137 static struct netent net_entry;
138 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
139
140 /*
141 * find first satisfactory answer
142 *
143 * answer --> +------------+ ( MESSAGE )
144 * | Header |
145 * +------------+
146 * | Question | the question for the name server
147 * +------------+
148 * | Answer | RRs answering the question
149 * +------------+
150 * | Authority | RRs pointing toward an authority
151 * | Additional | RRs holding additional information
152 * +------------+
153 */
154 eom = answer->buf + anslen;
155 hp = &answer->hdr;
156 ancount = ntohs(hp->ancount); /* #/records in the answer section */
157 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
158 bp = netbuf;
159 ep = netbuf + sizeof(netbuf);
160 cp = answer->buf + HFIXEDSZ;
161 if (!qdcount) {
162 if (hp->aa)
163 h_errno = HOST_NOT_FOUND;
164 else
165 h_errno = TRY_AGAIN;
166 return (NULL);
167 }
168 while (qdcount-- > 0)
169 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
170 ap = net_aliases;
171 *ap = NULL;
172 net_entry.n_aliases = net_aliases;
173 haveanswer = 0;
174 while (--ancount >= 0 && cp < eom) {
175 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
176#ifdef USE_RESOLV_NAME_OK
177 if ((n < 0) || !res_dnok(bp))
178#else
179 if ((n < 0) || !_hokchar(bp))
180#endif
181 break;
182 cp += n;
183 ans[0] = '\0';
184 strlcpy(&ans[0], bp, sizeof ans);
185 GETSHORT(type, cp);
186 GETSHORT(class, cp);
187 cp += INT32SZ; /* TTL */
188 GETSHORT(n, cp);
189 if (class == C_IN && type == T_PTR) {
190 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
191#ifdef USE_RESOLV_NAME_OK
192 if ((n < 0) || !res_hnok(bp))
193#else
194 if ((n < 0) || !_hokchar(bp))
195#endif
196 {
197 cp += n;
198 return (NULL);
199 }
200 cp += n;
201 *ap++ = bp;
202 bp += strlen(bp) + 1;
203 net_entry.n_addrtype =
204 (class == C_IN) ? AF_INET : AF_UNSPEC;
205 haveanswer++;
206 }
207 }
208 if (haveanswer) {
209 *ap = NULL;
210 switch (net_i) {
211 case BYADDR:
212 net_entry.n_name = *net_entry.n_aliases;
213 net_entry.n_net = 0L;
214 break;
215 case BYNAME:
216 in = *net_entry.n_aliases;
217 net_entry.n_name = &ans[0];
218 aux2[0] = '\0';
219 for (i = 0; i < 4; i++) {
220 for (st = in, nchar = 0;
221 *st != '.';
222 st++, nchar++)
223 ;
224 if (nchar != 1 || *in != '0' || flag) {
225 flag = 1;
226 strlcpy(paux1,
227 (i==0) ? in : in-1,
228 (i==0) ? nchar+1 : nchar+2);
229 pauxt = paux2;
230 paux2 = strcat(paux1, paux2);
231 paux1 = pauxt;
232 }
233 in = ++st;
234 }
235 net_entry.n_net = inet_network(paux2);
236 break;
237 }
238 net_entry.n_aliases++;
239 return (&net_entry);
240 }
241 h_errno = TRY_AGAIN;
242 return (NULL);
243}
244
245struct netent *
246getnetbyaddr(net, net_type)
247 register in_addr_t net;
248 register int net_type;
249{
250 unsigned int netbr[4];
251 int nn, anslen;
252 querybuf *buf;
253 char qbuf[MAXDNAME];
254 in_addr_t net2;
255 struct netent *net_entry = NULL;
256 char lookups[MAXDNSLUS];
257 int i;
258
259 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
260 return(_getnetbyaddr(net, net_type));
261
262 bcopy(_res.lookups, lookups, sizeof lookups);
263 if (lookups[0] == '\0')
264 strlcpy(lookups, "bf", sizeof lookups);
265
266 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
267 switch (lookups[i]) {
268#ifdef YP
269 case 'y':
270 /* There is no YP support. */
271 break;
272#endif /* YP */
273 case 'b':
274 if (net_type != AF_INET)
275 break; /* DNS only supports AF_INET? */
276
277 for (nn = 4, net2 = net; net2; net2 >>= 8)
278 netbr[--nn] = net2 & 0xff;
279 switch (nn) {
280 case 3: /* Class A */
281 snprintf(qbuf, sizeof(qbuf),
282 "0.0.0.%u.in-addr.arpa", netbr[3]);
283 break;
284 case 2: /* Class B */
285 snprintf(qbuf, sizeof(qbuf),
286 "0.0.%u.%u.in-addr.arpa",
287 netbr[3], netbr[2]);
288 break;
289 case 1: /* Class C */
290 snprintf(qbuf, sizeof(qbuf),
291 "0.%u.%u.%u.in-addr.arpa",
292 netbr[3], netbr[2], netbr[1]);
293 break;
294 case 0: /* Class D - E */
295 snprintf(qbuf, sizeof(qbuf),
296 "%u.%u.%u.%u.in-addr.arpa",
297 netbr[3], netbr[2], netbr[1], netbr[0]);
298 break;
299 }
300 buf = malloc(sizeof(*buf));
301 if (buf == NULL)
302 break;
303 anslen = res_query(qbuf, C_IN, T_PTR, buf->buf,
304 sizeof(buf->buf));
305 if (anslen < 0) {
306 free(buf);
307#ifdef DEBUG
308 if (_res.options & RES_DEBUG)
309 printf("res_query failed\n");
310#endif
311 break;
312 }
313 net_entry = getnetanswer(buf, anslen, BYADDR);
314 free(buf);
315 if (net_entry != NULL) {
316 unsigned u_net = net; /* maybe net should be unsigned ? */
317
318 /* Strip trailing zeros */
319 while ((u_net & 0xff) == 0 && u_net != 0)
320 u_net >>= 8;
321 net_entry->n_net = u_net;
322 return (net_entry);
323 }
324 break;
325 case 'f':
326 net_entry = _getnetbyaddr(net, net_type);
327 if (net_entry != NULL)
328 return (net_entry);
329 }
330 }
331
332 /* Nothing matched. */
333 return (NULL);
334}
335
336struct netent *
337getnetbyname(net)
338 register const char *net;
339{
340 int anslen;
341 querybuf *buf;
342 char qbuf[MAXDNAME];
343 struct netent *net_entry = NULL;
344 char lookups[MAXDNSLUS];
345 int i;
346
347 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
348 return (_getnetbyname(net));
349
350 bcopy(_res.lookups, lookups, sizeof lookups);
351 if (lookups[0] == '\0')
352 strlcpy(lookups, "bf", sizeof lookups);
353
354 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
355 switch (lookups[i]) {
356#ifdef YP
357 case 'y':
358 /* There is no YP support. */
359 break;
360#endif /* YP */
361 case 'b':
362 strlcpy(qbuf, net, sizeof qbuf);
363 buf = malloc(sizeof(*buf));
364 if (buf == NULL)
365 break;
366 anslen = res_search(qbuf, C_IN, T_PTR, buf->buf,
367 sizeof(buf->buf));
368 if (anslen < 0) {
369 free(buf);
370#ifdef DEBUG
371 if (_res.options & RES_DEBUG)
372 printf("res_query failed\n");
373#endif
374 break;
375 }
376 net_entry = getnetanswer(buf, anslen, BYNAME);
377 free(buf);
378 if (net_entry != NULL)
379 return (net_entry);
380 break;
381 case 'f':
382 net_entry = _getnetbyname(net);
383 if (net_entry != NULL)
384 return (net_entry);
385 break;
386 }
387 }
388
389 /* Nothing matched. */
390 return (NULL);
391}
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c
new file mode 100644
index 0000000000..474d8d9427
--- /dev/null
+++ b/src/lib/libc/net/getproto.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getproto.c,v 1.3 1997/07/09 01:08:31 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39
40extern int _proto_stayopen;
41
42struct protoent *
43getprotobynumber(proto)
44 register int proto;
45{
46 register struct protoent *p;
47
48 setprotoent(_proto_stayopen);
49 while ((p = getprotoent()))
50 if (p->p_proto == proto)
51 break;
52 if (!_proto_stayopen)
53 endprotoent();
54 return (p);
55}
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3
new file mode 100644
index 0000000000..1f95529532
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.3
@@ -0,0 +1,134 @@
1.\" $OpenBSD: getprotoent.3,v 1.8 2000/12/24 00:30:56 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt GETPROTOENT 3
36.Os
37.Sh NAME
38.Nm getprotoent ,
39.Nm getprotobynumber ,
40.Nm getprotobyname ,
41.Nm setprotoent ,
42.Nm endprotoent
43.Nd get protocol entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct protoent *
47.Fn getprotoent "void"
48.Ft struct protoent *
49.Fn getprotobyname "char *name"
50.Ft struct protoent *
51.Fn getprotobynumber "int proto"
52.Ft void
53.Fn setprotoent "int stayopen"
54.Ft void
55.Fn endprotoent "void"
56.Sh DESCRIPTION
57The
58.Fn getprotoent ,
59.Fn getprotobyname ,
60and
61.Fn getprotobynumber
62functions each return a pointer to an object with the following structure
63containing the broken-out fields of a line in the network protocol database,
64.Pa /etc/protocols .
65.Bd -literal -offset indent
66.Pp
67struct protoent {
68 char *p_name; /* official name of protocol */
69 char **p_aliases; /* alias list */
70 int p_proto; /* protocol number */
71};
72.Ed
73.Pp
74The members of this structure are:
75.Bl -tag -width p_aliases
76.It Fa p_name
77The official name of the protocol.
78.It Fa p_aliases
79A zero-terminated list of alternate names for the protocol.
80.It Fa p_proto
81The protocol number.
82.El
83.Pp
84The
85.Fn getprotoent
86function reads the next line of the file, opening the file if necessary.
87.Pp
88The
89.Fn setprotoent
90function opens and rewinds the file.
91If the
92.Fa stayopen
93flag is non-zero,
94the net database will not be closed after each call to
95.Fn getprotobyname
96or
97.Fn getprotobynumber .
98.Pp
99The
100.Fn endprotoent
101function closes the file.
102.Pp
103The
104.Fn getprotobyname
105and
106.Fn getprotobynumber
107functions sequentially search from the beginning of the file until a
108matching protocol name or protocol number is found, or until
109.Dv EOF
110is encountered.
111.Sh RETURN VALUES
112Null pointer (0) returned on
113.Dv EOF
114or error.
115.Sh FILES
116.Bl -tag -width /etc/protocols -compact
117.It Pa /etc/protocols
118.El
119.Sh SEE ALSO
120.Xr protocols 5
121.Sh HISTORY
122The
123.Fn getprotoent ,
124.Fn getprotobynumber ,
125.Fn getprotobyname ,
126.Fn setprotoent ,
127and
128.Fn endprotoent
129functions appeared in
130.Bx 4.2 .
131.Sh BUGS
132These functions use a static data space; if the data is needed for future use,
133it should be copied before any subsequent calls overwrite it.
134Only the Internet protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
new file mode 100644
index 0000000000..2f8b267611
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.c
@@ -0,0 +1,127 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.4 1999/09/03 16:23:18 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netdb.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#define MAXALIASES 35
46
47static FILE *protof = NULL;
48static char line[BUFSIZ+1];
49static struct protoent proto;
50static char *proto_aliases[MAXALIASES];
51int _proto_stayopen;
52
53void
54setprotoent(f)
55 int f;
56{
57 if (protof == NULL)
58 protof = fopen(_PATH_PROTOCOLS, "r" );
59 else
60 rewind(protof);
61 _proto_stayopen |= f;
62}
63
64void
65endprotoent()
66{
67 if (protof) {
68 fclose(protof);
69 protof = NULL;
70 }
71 _proto_stayopen = 0;
72}
73
74struct protoent *
75getprotoent()
76{
77 char *p, *cp, **q, *endp;
78 long l;
79 size_t len;
80
81 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
82 return (NULL);
83again:
84 if ((p = fgetln(protof, &len)) == NULL)
85 return (NULL);
86 if (p[len-1] == '\n')
87 len--;
88 if (len >= sizeof(line) || len == 0)
89 goto again;
90 p = memcpy(line, p, len);
91 line[len] = '\0';
92 if (*p == '#')
93 goto again;
94 if ((cp = strchr(p, '#')) != NULL)
95 *cp = '\0';
96 proto.p_name = p;
97 cp = strpbrk(p, " \t");
98 if (cp == NULL)
99 goto again;
100 *cp++ = '\0';
101 while (*cp == ' ' || *cp == '\t')
102 cp++;
103 p = strpbrk(cp, " \t");
104 if (p != NULL)
105 *p++ = '\0';
106 l = strtol(cp, &endp, 10);
107 if (endp == cp || *endp != '\0' || l < 0 || l >= INT_MAX)
108 goto again;
109 proto.p_proto = l;
110 q = proto.p_aliases = proto_aliases;
111 if (p != NULL) {
112 cp = p;
113 while (cp && *cp) {
114 if (*cp == ' ' || *cp == '\t') {
115 cp++;
116 continue;
117 }
118 if (q < &proto_aliases[MAXALIASES - 1])
119 *q++ = cp;
120 cp = strpbrk(cp, " \t");
121 if (cp != NULL)
122 *cp++ = '\0';
123 }
124 }
125 *q = NULL;
126 return (&proto);
127}
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c
new file mode 100644
index 0000000000..7a4e5fede5
--- /dev/null
+++ b/src/lib/libc/net/getprotoname.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.3 1997/07/09 01:08:32 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _proto_stayopen;
42
43struct protoent *
44getprotobyname(name)
45 register const char *name;
46{
47 register struct protoent *p;
48 register char **cp;
49
50 setprotoent(_proto_stayopen);
51 while ((p = getprotoent())) {
52 if (strcmp(p->p_name, name) == 0)
53 break;
54 for (cp = p->p_aliases; *cp != 0; cp++)
55 if (strcmp(*cp, name) == 0)
56 goto found;
57 }
58found:
59 if (!_proto_stayopen)
60 endprotoent();
61 return (p);
62}
diff --git a/src/lib/libc/net/getrrsetbyname.3 b/src/lib/libc/net/getrrsetbyname.3
new file mode 100644
index 0000000000..50cadfd372
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.3
@@ -0,0 +1,166 @@
1.\" $OpenBSD: getrrsetbyname.3,v 1.7 2002/06/09 05:03:59 deraadt Exp $
2.\"
3.\" Copyright (C) 2000, 2001 Internet Software Consortium.
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
10.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
11.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
12.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
13.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd Oct 18, 2000
19.Dt GETRRSETBYNAME 3
20.Os
21.Sh NAME
22.Nm getrrsetbyname
23.Nd retrieve DNS records
24.Sh SYNOPSIS
25.Fd #include <netdb.h>
26.Ft int
27.Fn getrrsetbyname "const char *hostname" "unsigned int rdclass" \
28"unsigned int rdtype" "unsigned int flags" "struct rrsetinfo **res"
29.Ft int
30.Fn freerrset "struct rrsetinfo **rrset"
31.Sh DESCRIPTION
32.Fn getrrsetbyname
33gets a set of resource records associated with a
34.Fa hostname ,
35.Fa class
36and
37.Fa type .
38.Fa hostname
39is a pointer a to null-terminated string.
40The
41.Fa flags
42field is currently unused and must be zero.
43.Pp
44After a successful call to
45.Fn getrrsetbyname ,
46.Fa *res
47is a pointer to an
48.Li rrsetinfo
49structure, containing a list of one or more
50.Li rdatainfo
51structures containing resource records and potentially another list of
52.Li rdatainfo
53structures containing SIG resource records associated with those records.
54The members
55.Li rri_rdclass
56and
57.Li rri_rdtype
58are copied from the parameters.
59.Li rri_ttl
60and
61.Li rri_name
62are properties of the obtained rrset.
63The resource records contained in
64.Li rri_rdatas
65and
66.Li rri_sigs
67are in uncompressed DNS wire format.
68Properties of the rdataset are represented in the
69.Li rri_flags
70bitfield.
71If the
72.Dv RRSET_VALIDATED
73bit is set, the data has been DNSSEC
74validated and the signatures verified.
75.Pp
76The following structures are used:
77.Bd -literal -offset
78struct rdatainfo {
79 unsigned int rdi_length; /* length of data */
80 unsigned char *rdi_data; /* record data */
81};
82
83struct rrsetinfo {
84 unsigned int rri_flags; /* RRSET_VALIDATED ... */
85 unsigned int rri_rdclass; /* class number */
86 unsigned int rri_rdtype; /* RR type number */
87 unsigned int rri_ttl; /* time to live */
88 unsigned int rri_nrdatas; /* size of rdatas array */
89 unsigned int rri_nsigs; /* size of sigs array */
90 char *rri_name; /* canonical name */
91 struct rdatainfo *rri_rdatas; /* individual records */
92 struct rdatainfo *rri_sigs; /* individual signatures */
93};
94.Ed
95.Pp
96All of the information returned by
97.Fn getrrsetbyname
98is dynamically allocated: the
99.Li rrsetinfo
100and
101.Li rdatainfo
102structures,
103and the canonical host name strings pointed to by the
104.Li rrsetinfo
105u lib/libc/sys/lseek.2
106structure.
107Memory allocated for the dynamically allocated structures created by
108a successful call to
109.Fn getrrsetbyname
110is released by
111.Fn freerrset .
112.Li rrset
113is a pointer to a
114.Li struct rrset
115created by a call to
116.Fn getrrsetbyname .
117.Pp
118If the EDNS0 option is activated in
119.Xr resolv.conf 3 ,
120.Fn getrrsetbyname
121will request DNSSEC authentication using the EDNS0 DNSSEC OK (DO) bit.
122.Sh "RETURN VALUES"
123.Fn getrrsetbyname
124returns zero on success, and one of the following error
125codes if an error occurred:
126.Pp
127.Bl -tag -width ERRSET_NOMEMORY -compact
128.It Dv ERRSET_NONAME
129the name does not exist
130.It Dv ERRSET_NODATA
131the name exists, but does not have data of the desired type
132.It Dv ERRSET_NOMEMORY
133memory could not be allocated
134.It Dv ERRSET_INVAL
135a parameter is invalid
136.It Dv ERRSET_FAIL
137other failure
138.El
139.Sh SEE ALSO
140.Xr resolver 3 ,
141.Xr resolv.conf 5 ,
142.Xr named 8
143.Sh AUTHORS
144Jakob Schlyter
145.Aq jakob@openbsd.org
146.Sh HISTORY
147.Fn getrrsetbyname
148first appeared in
149.Ox 3.0 .
150The API first appeared in ISC BIND version 9.
151.Sh BUGS
152The data in
153.Li *rdi_data
154should be returned in uncompressed wire format.
155Currently, the data is in compressed format and the caller can't
156uncompress since it doesn't have the full message.
157.Sh CAVEATS
158The
159.Dv RRSET_VALIDATED
160flag in
161.Li rri_flags
162is set if the AD (autenticated data) bit in the DNS answer is
163set. This flag
164.Em should not
165be trusted unless the transport between the nameserver and the resolver
166is secure (e.g. IPsec, trusted network, loopback communication).
diff --git a/src/lib/libc/net/getrrsetbyname.c b/src/lib/libc/net/getrrsetbyname.c
new file mode 100644
index 0000000000..87ae8fc229
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.c
@@ -0,0 +1,507 @@
1/* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */
2
3/*
4 * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Portions Copyright (c) 1999-2001 Internet Software Consortium.
31 *
32 * Permission to use, copy, modify, and distribute this software for any
33 * purpose with or without fee is hereby granted, provided that the above
34 * copyright notice and this permission notice appear in all copies.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
37 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
39 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
40 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
41 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
42 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
43 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46#include <sys/types.h>
47#include <netinet/in.h>
48#include <arpa/nameser.h>
49#include <netdb.h>
50#include <resolv.h>
51#include <stdlib.h>
52#include <string.h>
53
54#define ANSWER_BUFFER_SIZE 1024*64
55
56struct dns_query {
57 char *name;
58 u_int16_t type;
59 u_int16_t class;
60 struct dns_query *next;
61};
62
63struct dns_rr {
64 char *name;
65 u_int16_t type;
66 u_int16_t class;
67 u_int16_t ttl;
68 u_int16_t size;
69 void *rdata;
70 struct dns_rr *next;
71};
72
73struct dns_response {
74 HEADER header;
75 struct dns_query *query;
76 struct dns_rr *answer;
77 struct dns_rr *authority;
78 struct dns_rr *additional;
79};
80
81static struct dns_response *parse_dns_response(const char *, int);
82static struct dns_query *parse_dns_qsection(const char *, int, const char **,
83 int);
84static struct dns_rr *parse_dns_rrsection(const char *, int, const char **,
85 int);
86
87static void free_dns_query(struct dns_query *);
88static void free_dns_rr(struct dns_rr *);
89static void free_dns_response(struct dns_response *);
90
91static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
92
93int
94getrrsetbyname(const char *hostname, unsigned int rdclass,
95 unsigned int rdtype, unsigned int flags,
96 struct rrsetinfo **res)
97{
98 int result;
99 struct rrsetinfo *rrset = NULL;
100 struct dns_response *response;
101 struct dns_rr *rr;
102 struct rdatainfo *rdata;
103 unsigned int length, index_ans, index_sig;
104 char answer[ANSWER_BUFFER_SIZE];
105
106 /* check for invalid class and type */
107 if (rdclass > 0xffff || rdtype > 0xffff) {
108 result = ERRSET_INVAL;
109 goto fail;
110 }
111
112 /* don't allow queries of class or type ANY */
113 if (rdclass == 0xff || rdtype == 0xff) {
114 result = ERRSET_INVAL;
115 goto fail;
116 }
117
118 /* don't allow flags yet, unimplemented */
119 if (flags) {
120 result = ERRSET_INVAL;
121 goto fail;
122 }
123
124 /* initialize resolver */
125 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
126 result = ERRSET_FAIL;
127 goto fail;
128 }
129
130#ifdef DEBUG
131 _res.options |= RES_DEBUG;
132#endif /* DEBUG */
133
134#ifdef RES_USE_DNSSEC
135 /* turn on DNSSEC if EDNS0 is configured */
136 if (_res.options & RES_USE_EDNS0)
137 _res.options |= RES_USE_DNSSEC;
138#endif /* RES_USE_DNSEC */
139
140 /* make query */
141 length = res_query(hostname, rdclass, rdtype, answer, sizeof(answer));
142 if (length < 0) {
143 switch(h_errno) {
144 case HOST_NOT_FOUND:
145 result = ERRSET_NONAME;
146 goto fail;
147 case NO_DATA:
148 result = ERRSET_NODATA;
149 goto fail;
150 default:
151 result = ERRSET_FAIL;
152 goto fail;
153 }
154 }
155
156 /* parse result */
157 response = parse_dns_response(answer, length);
158 if (response == NULL) {
159 result = ERRSET_FAIL;
160 goto fail;
161 }
162
163 if (response->header.qdcount != 1) {
164 result = ERRSET_FAIL;
165 goto fail;
166 }
167
168 /* initialize rrset */
169 rrset = calloc(1, sizeof(struct rrsetinfo));
170 if (rrset == NULL) {
171 result = ERRSET_NOMEMORY;
172 goto fail;
173 }
174 rrset->rri_rdclass = response->query->class;
175 rrset->rri_rdtype = response->query->type;
176 rrset->rri_ttl = response->answer->ttl;
177 rrset->rri_nrdatas = response->header.ancount;
178
179 /* check for authenticated data */
180 if (response->header.ad == 1)
181 rrset->rri_flags |= RRSET_VALIDATED;
182
183 /* copy name from answer section */
184 length = strlen(response->answer->name);
185 rrset->rri_name = malloc(length + 1);
186 if (rrset->rri_name == NULL) {
187 result = ERRSET_NOMEMORY;
188 goto fail;
189 }
190 strlcpy(rrset->rri_name, response->answer->name, length + 1);
191
192 /* count answers */
193 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
194 rrset->rri_rdtype);
195 rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
196 T_SIG);
197
198 /* allocate memory for answers */
199 rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
200 sizeof(struct rdatainfo));
201 if (rrset->rri_rdatas == NULL) {
202 result = ERRSET_NOMEMORY;
203 goto fail;
204 }
205
206 /* allocate memory for signatures */
207 rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
208 if (rrset->rri_sigs == NULL) {
209 result = ERRSET_NOMEMORY;
210 goto fail;
211 }
212
213 /* copy answers & signatures */
214 for (rr = response->answer, index_ans = 0, index_sig = 0;
215 rr; rr = rr->next) {
216
217 rdata = NULL;
218
219 if (rr->class == rrset->rri_rdclass &&
220 rr->type == rrset->rri_rdtype)
221 rdata = &rrset->rri_rdatas[index_ans++];
222
223 if (rr->class == rrset->rri_rdclass &&
224 rr->type == T_SIG)
225 rdata = &rrset->rri_sigs[index_sig++];
226
227 if (rdata) {
228 rdata->rdi_length = rr->size;
229 rdata->rdi_data = malloc(rr->size);
230
231 if (rdata->rdi_data == NULL) {
232 result = ERRSET_NOMEMORY;
233 goto fail;
234 }
235 memcpy(rdata->rdi_data, rr->rdata, rr->size);
236 }
237 }
238
239 *res = rrset;
240 return (ERRSET_SUCCESS);
241
242fail:
243 if (rrset != NULL)
244 freerrset(rrset);
245 return (result);
246}
247
248void
249freerrset(struct rrsetinfo *rrset)
250{
251 u_int16_t i;
252
253 if (rrset == NULL)
254 return;
255
256 if (rrset->rri_rdatas) {
257 for (i = 0; i < rrset->rri_nrdatas; i++) {
258 if (rrset->rri_rdatas[i].rdi_data == NULL)
259 break;
260 free(rrset->rri_rdatas[i].rdi_data);
261 }
262 free(rrset->rri_rdatas);
263 }
264
265 if (rrset->rri_sigs) {
266 for (i = 0; i < rrset->rri_nsigs; i++) {
267 if (rrset->rri_sigs[i].rdi_data == NULL)
268 break;
269 free(rrset->rri_sigs[i].rdi_data);
270 }
271 free(rrset->rri_sigs);
272 }
273
274 if (rrset->rri_name)
275 free(rrset->rri_name);
276 free(rrset);
277}
278
279/*
280 * DNS response parsing routines
281 */
282static struct dns_response *
283parse_dns_response(const char *answer, int size)
284{
285 struct dns_response *resp;
286 const char *cp;
287
288 /* allocate memory for the response */
289 resp = calloc(1, sizeof(*resp));
290 if (resp == NULL)
291 return (NULL);
292
293 /* initialize current pointer */
294 cp = answer;
295
296 /* copy header */
297 memcpy(&resp->header, cp, HFIXEDSZ);
298 cp += HFIXEDSZ;
299
300 /* fix header byte order */
301 resp->header.qdcount = ntohs(resp->header.qdcount);
302 resp->header.ancount = ntohs(resp->header.ancount);
303 resp->header.nscount = ntohs(resp->header.nscount);
304 resp->header.arcount = ntohs(resp->header.arcount);
305
306 /* there must be at least one query */
307 if (resp->header.qdcount < 1) {
308 free_dns_response(resp);
309 return (NULL);
310 }
311
312 /* parse query section */
313 resp->query = parse_dns_qsection(answer, size, &cp,
314 resp->header.qdcount);
315 if (resp->header.qdcount && resp->query == NULL) {
316 free_dns_response(resp);
317 return (NULL);
318 }
319
320 /* parse answer section */
321 resp->answer = parse_dns_rrsection(answer, size, &cp,
322 resp->header.ancount);
323 if (resp->header.ancount && resp->answer == NULL) {
324 free_dns_response(resp);
325 return (NULL);
326 }
327
328 /* parse authority section */
329 resp->authority = parse_dns_rrsection(answer, size, &cp,
330 resp->header.nscount);
331 if (resp->header.nscount && resp->authority == NULL) {
332 free_dns_response(resp);
333 return (NULL);
334 }
335
336 /* parse additional section */
337 resp->additional = parse_dns_rrsection(answer, size, &cp,
338 resp->header.arcount);
339 if (resp->header.arcount && resp->additional == NULL) {
340 free_dns_response(resp);
341 return (NULL);
342 }
343
344 return (resp);
345}
346
347static struct dns_query *
348parse_dns_qsection(const char *answer, int size, const char **cp, int count)
349{
350 struct dns_query *head, *curr, *prev;
351 int i, length;
352 char name[MAXDNAME];
353
354 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
355
356 /* allocate and initialize struct */
357 curr = calloc(1, sizeof(struct dns_query));
358 if (curr == NULL) {
359 free_dns_query(head);
360 return (NULL);
361 }
362 if (head == NULL)
363 head = curr;
364 if (prev != NULL)
365 prev->next = curr;
366
367 /* name */
368 length = dn_expand(answer, answer + size, *cp, name,
369 sizeof(name));
370 if (length < 0) {
371 free_dns_query(head);
372 return (NULL);
373 }
374 curr->name = strdup(name);
375 if (curr->name == NULL) {
376 free_dns_query(head);
377 return (NULL);
378 }
379 *cp += length;
380
381 /* type */
382 curr->type = _getshort(*cp);
383 *cp += INT16SZ;
384
385 /* class */
386 curr->class = _getshort(*cp);
387 *cp += INT16SZ;
388 }
389
390 return (head);
391}
392
393static struct dns_rr *
394parse_dns_rrsection(const char *answer, int size, const char **cp, int count)
395{
396 struct dns_rr *head, *curr, *prev;
397 int i, length;
398 char name[MAXDNAME];
399
400 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
401
402 /* allocate and initialize struct */
403 curr = calloc(1, sizeof(struct dns_rr));
404 if (curr == NULL) {
405 free_dns_rr(head);
406 return (NULL);
407 }
408 if (head == NULL)
409 head = curr;
410 if (prev != NULL)
411 prev->next = curr;
412
413 /* name */
414 length = dn_expand(answer, answer + size, *cp, name,
415 sizeof(name));
416 if (length < 0) {
417 free_dns_rr(head);
418 return (NULL);
419 }
420 curr->name = strdup(name);
421 if (curr->name == NULL) {
422 free_dns_rr(head);
423 return (NULL);
424 }
425 *cp += length;
426
427 /* type */
428 curr->type = _getshort(*cp);
429 *cp += INT16SZ;
430
431 /* class */
432 curr->class = _getshort(*cp);
433 *cp += INT16SZ;
434
435 /* ttl */
436 curr->ttl = _getlong(*cp);
437 *cp += INT32SZ;
438
439 /* rdata size */
440 curr->size = _getshort(*cp);
441 *cp += INT16SZ;
442
443 /* rdata itself */
444 curr->rdata = malloc(curr->size);
445 if (curr->rdata == NULL) {
446 free_dns_rr(head);
447 return (NULL);
448 }
449 memcpy(curr->rdata, *cp, curr->size);
450 *cp += curr->size;
451 }
452
453 return (head);
454}
455
456static void
457free_dns_query(struct dns_query *p)
458{
459 if (p == NULL)
460 return;
461
462 if (p->name)
463 free(p->name);
464 free_dns_query(p->next);
465 free(p);
466}
467
468static void
469free_dns_rr(struct dns_rr *p)
470{
471 if (p == NULL)
472 return;
473
474 if (p->name)
475 free(p->name);
476 if (p->rdata)
477 free(p->rdata);
478 free_dns_rr(p->next);
479 free(p);
480}
481
482static void
483free_dns_response(struct dns_response *p)
484{
485 if (p == NULL)
486 return;
487
488 free_dns_query(p->query);
489 free_dns_rr(p->answer);
490 free_dns_rr(p->authority);
491 free_dns_rr(p->additional);
492 free(p);
493}
494
495static int
496count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
497{
498 int n = 0;
499
500 while(p) {
501 if (p->class == class && p->type == type)
502 n++;
503 p = p->next;
504 }
505
506 return (n);
507}
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c
new file mode 100644
index 0000000000..16602cc3a6
--- /dev/null
+++ b/src/lib/libc/net/getservbyname.c
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.5 2000/01/06 08:24:17 d Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40#include "thread_private.h"
41
42extern int _serv_stayopen;
43
44_THREAD_PRIVATE_MUTEX(getservbyname_r);
45
46struct servent *
47getservbyname_r(name, proto, se, buf, buflen)
48 const char *name, *proto;
49 struct servent *se;
50 char *buf;
51 int buflen;
52{
53 register struct servent *p;
54 register char **cp;
55
56 _THREAD_PRIVATE_MUTEX_LOCK(getservbyname_r);
57 setservent(_serv_stayopen);
58 while ((p = getservent())) {
59 if (strcmp(name, p->s_name) == 0)
60 goto gotname;
61 for (cp = p->s_aliases; *cp; cp++)
62 if (strcmp(name, *cp) == 0)
63 goto gotname;
64 continue;
65gotname:
66 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
67 break;
68 }
69 if (!_serv_stayopen)
70 endservent();
71 _THREAD_PRIVATE_MUTEX_UNLOCK(getservbyname_r);
72 return (p);
73}
74
75struct servent *getservbyname(name, proto)
76 const char *name, *proto;
77{
78 _THREAD_PRIVATE_KEY(getservbyname);
79 static char buf[4096];
80 char *bufp = (char*)_THREAD_PRIVATE(getservbyname, buf, NULL);
81
82 if (bufp == NULL)
83 return (NULL);
84 return getservbyname_r(name, proto, (struct servent*) bufp,
85 bufp + sizeof(struct servent),
86 sizeof buf - sizeof(struct servent) );
87}
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c
new file mode 100644
index 0000000000..4b063760d2
--- /dev/null
+++ b/src/lib/libc/net/getservbyport.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.3 1997/07/09 01:08:35 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <netdb.h>
39#include <string.h>
40
41extern int _serv_stayopen;
42
43struct servent *
44getservbyport(port, proto)
45 int port;
46 const char *proto;
47{
48 register struct servent *p;
49
50 setservent(_serv_stayopen);
51 while ((p = getservent())) {
52 if (p->s_port != port)
53 continue;
54 if (proto == 0 || strcmp(p->s_proto, proto) == 0)
55 break;
56 }
57 if (!_serv_stayopen)
58 endservent();
59 return (p);
60}
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3
new file mode 100644
index 0000000000..85e0d65352
--- /dev/null
+++ b/src/lib/libc/net/getservent.3
@@ -0,0 +1,141 @@
1.\" $OpenBSD: getservent.3,v 1.11 2000/12/24 00:30:56 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd January 12, 1994
35.Dt GETSERVENT 3
36.Os
37.Sh NAME
38.Nm getservent ,
39.Nm getservbyport ,
40.Nm getservbyname ,
41.Nm setservent ,
42.Nm endservent
43.Nd get service entry
44.Sh SYNOPSIS
45.Fd #include <netdb.h>
46.Ft struct servent *
47.Fn getservent "void"
48.Ft struct servent *
49.Fn getservbyname "char *name" "char *proto"
50.Ft struct servent *
51.Fn getservbyport "int port" "char *proto"
52.Ft void
53.Fn setservent "int stayopen"
54.Ft void
55.Fn endservent "void"
56.Sh DESCRIPTION
57The
58.Fn getservent ,
59.Fn getservbyname ,
60and
61.Fn getservbyport
62functions each return a pointer to an object with the following structure
63containing the broken-out fields of a line in the network services database,
64.Pa /etc/services .
65.Bd -literal -offset indent
66struct servent {
67 char *s_name; /* official name of service */
68 char **s_aliases; /* alias list */
69 int s_port; /* port service resides at */
70 char *s_proto; /* protocol to use */
71};
72.Ed
73.Pp
74The members of this structure are:
75.Bl -tag -width s_aliases
76.It Fa s_name
77The official name of the service.
78.It Fa s_aliases
79A zero-terminated list of alternate names for the service.
80.It Fa s_port
81The port number at which the service resides.
82Port numbers are returned in network byte order.
83.It Fa s_proto
84The name of the protocol to use when contacting the service.
85.El
86.Pp
87The
88.Fn getservent
89function reads the next line of the file, opening the file if necessary.
90.Pp
91The
92.Fn setservent
93function opens and rewinds the file.
94If the
95.Fa stayopen
96flag is non-zero,
97the net database will not be closed after each call to
98.Fn getservbyname
99or
100.Fn getservbyport .
101.Pp
102The
103.Fn endservent
104function closes the file.
105.Pp
106The
107.Fn getservbyname
108and
109.Fn getservbyport
110functions sequentially search from the beginning of the file until a
111matching protocol name or port number (specified in network byte order)
112is found, or until
113.Dv EOF
114is encountered.
115If a protocol name is also supplied (non-null),
116searches must also match the protocol.
117.Sh FILES
118.Bl -tag -width /etc/services -compact
119.It Pa /etc/services
120.El
121.Sh DIAGNOSTICS
122Null pointer (0) returned on
123.Dv EOF
124or error.
125.Sh SEE ALSO
126.Xr getprotoent 3 ,
127.Xr services 5
128.Sh HISTORY
129The
130.Fn getservent ,
131.Fn getservbyport ,
132.Fn getservbyname ,
133.Fn setservent ,
134and
135.Fn endservent
136functions appeared in
137.Bx 4.2 .
138.Sh BUGS
139These functions use static data storage; if the data is needed for future use,
140it should be copied before any subsequent calls overwrite it.
141Expecting port numbers to fit in a 32-bit quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
new file mode 100644
index 0000000000..ff6bf1e57f
--- /dev/null
+++ b/src/lib/libc/net/getservent.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getservent.c,v 1.5 1999/09/03 16:23:19 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <netdb.h>
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44
45#define MAXALIASES 35
46
47static FILE *servf = NULL;
48static char line[BUFSIZ+1];
49static struct servent serv;
50static char *serv_aliases[MAXALIASES];
51int _serv_stayopen;
52
53void
54setservent(f)
55 int f;
56{
57 if (servf == NULL)
58 servf = fopen(_PATH_SERVICES, "r" );
59 else
60 rewind(servf);
61 _serv_stayopen |= f;
62}
63
64void
65endservent()
66{
67 if (servf) {
68 fclose(servf);
69 servf = NULL;
70 }
71 _serv_stayopen = 0;
72}
73
74struct servent *
75getservent()
76{
77 char *p, *cp, **q, *endp;
78 long l;
79 size_t len;
80
81 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
82 return (NULL);
83again:
84 if ((p = fgetln(servf, &len)) == NULL)
85 return (NULL);
86 if (p[len-1] == '\n')
87 len--;
88 if (len >= sizeof(line) || len == 0)
89 goto again;
90 p = memcpy(line, p, len);
91 line[len] = '\0';
92 if (*p == '#')
93 goto again;
94 if ((cp = strchr(p, '#')) != NULL)
95 *cp = '\0';
96 serv.s_name = p;
97 p = strpbrk(p, " \t");
98 if (p == NULL)
99 goto again;
100 *p++ = '\0';
101 while (*p == ' ' || *p == '\t')
102 p++;
103 cp = strpbrk(p, ",/");
104 if (cp == NULL)
105 goto again;
106 *cp++ = '\0';
107 l = strtol(p, &endp, 10);
108 if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
109 goto again;
110 serv.s_port = htons((in_port_t)l);
111 serv.s_proto = cp;
112 q = serv.s_aliases = serv_aliases;
113 cp = strpbrk(cp, " \t");
114 if (cp != NULL)
115 *cp++ = '\0';
116 while (cp && *cp) {
117 if (*cp == ' ' || *cp == '\t') {
118 cp++;
119 continue;
120 }
121 if (q < &serv_aliases[MAXALIASES - 1])
122 *q++ = cp;
123 cp = strpbrk(cp, " \t");
124 if (cp != NULL)
125 *cp++ = '\0';
126 }
127 *q = NULL;
128 return (&serv);
129}
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
new file mode 100644
index 0000000000..737bb115a7
--- /dev/null
+++ b/src/lib/libc/net/herror.c
@@ -0,0 +1,121 @@
1/* $OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1987, 1993
5 * -
6 * Copyright (c) 1987, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <sys/uio.h>
70#include <netdb.h>
71#include <unistd.h>
72#include <string.h>
73
74const char *h_errlist[] = {
75 "Resolver Error 0 (no error)",
76 "Unknown host", /* 1 HOST_NOT_FOUND */
77 "Host name lookup failure", /* 2 TRY_AGAIN */
78 "Unknown server error", /* 3 NO_RECOVERY */
79 "No address associated with name", /* 4 NO_ADDRESS */
80};
81int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
82
83extern int h_errno;
84
85/*
86 * herror --
87 * print the error indicated by the h_errno value.
88 */
89void
90herror(s)
91 const char *s;
92{
93 struct iovec iov[4];
94 register struct iovec *v = iov;
95
96 if (s && *s) {
97 v->iov_base = (char *)s;
98 v->iov_len = strlen(s);
99 v++;
100 v->iov_base = ": ";
101 v->iov_len = 2;
102 v++;
103 }
104 v->iov_base = (char *)hstrerror(h_errno);
105 v->iov_len = strlen(v->iov_base);
106 v++;
107 v->iov_base = "\n";
108 v->iov_len = 1;
109 writev(STDERR_FILENO, iov, (v - iov) + 1);
110}
111
112const char *
113hstrerror(err)
114 int err;
115{
116 if (err < 0)
117 return ("Resolver internal error");
118 else if (err < h_nerr)
119 return (h_errlist[err]);
120 return ("Unknown resolver error");
121}
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c
new file mode 100644
index 0000000000..73b7432731
--- /dev/null
+++ b/src/lib/libc/net/htonl.c
@@ -0,0 +1,25 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: htonl.c,v 1.4 1996/12/12 03:19:55 tholo Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef htonl
14
15u_int32_t
16htonl(x)
17 u_int32_t x;
18{
19#if BYTE_ORDER == LITTLE_ENDIAN
20 u_char *s = (u_char *)&x;
21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
22#else
23 return x;
24#endif
25}
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c
new file mode 100644
index 0000000000..ded70712ea
--- /dev/null
+++ b/src/lib/libc/net/htons.c
@@ -0,0 +1,24 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: htons.c,v 1.7 2002/02/19 19:39:36 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef htons
14
15u_int16_t
16htons(u_int16_t x)
17{
18#if BYTE_ORDER == LITTLE_ENDIAN
19 u_char *s = (u_char *) &x;
20 return (u_int16_t)(s[0] << 8 | s[1]);
21#else
22 return x;
23#endif
24}
diff --git a/src/lib/libc/net/if_indextoname.3 b/src/lib/libc/net/if_indextoname.3
new file mode 100644
index 0000000000..85269c3769
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.3
@@ -0,0 +1,140 @@
1.\" $OpenBSD: if_indextoname.3,v 1.5 2002/03/07 22:41:12 millert Exp $
2.\" Copyright (c) 1983, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. All advertising materials mentioning features or use of this software
14.\" must display the following acknowledgement:
15.\" This product includes software developed by the University of
16.\" California, Berkeley and its contributors.
17.\" 4. Neither the name of the University nor the names of its contributors
18.\" may be used to endorse or promote products derived from this software
19.\" without specific prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
34.\"
35.Dd May 21, 1998
36.Dt IF_NAMETOINDEX 3
37.Os
38.Sh NAME
39.Nm if_nametoindex ,
40.Nm if_indextoname ,
41.Nm if_nameindex ,
42.Nm if_freenameindex
43.Nd convert interface index to name, and vice versa
44.Sh SYNOPSIS
45.Fd #include <net/if.h>
46.Ft "unsigned int"
47.Fn if_nametoindex "const char *ifname"
48.Ft "char *"
49.Fn if_indextoname "unsigned int ifindex" "char *ifname"
50.Ft "struct if_nameindex *"
51.Fn if_nameindex "void"
52.Ft "void"
53.Fn if_freenameindex "struct if_nameindex *ptr"
54.Sh DESCRIPTION
55These functions map interface indexes to interface names (such as
56.Dq lo0 ) ,
57and vice versa.
58.Pp
59The
60.Fn if_nametoindex
61function converts an interface name specified by the
62.Fa ifname
63argument to an interface index (positive integer value).
64If the specified interface does not exist, 0 will be returned.
65.Pp
66.Fn if_indextoname
67converts an interface index specified by the
68.Fa ifindex
69argument to an interface name.
70The
71.Fa ifname
72argument must point to a buffer of at least
73.Dv IF_NAMESIZE
74bytes into which the interface name corresponding to the specified index is
75returned.
76.Pf ( Dv IF_NAMESIZE
77is also defined in
78.Aq Pa net/if.h
79and its value includes a terminating null byte at the end of the
80interface name.)
81This pointer is also the return value of the function.
82If there is no interface corresponding to the specified index,
83.Dv NULL
84is returned.
85.Pp
86.Fn if_nameindex
87returns an array of
88.Fa if_nameindex
89structures.
90.Fa if_nametoindex
91is also defined in
92.Aq Pa net/if.h ,
93and is as follows:
94.Bd -literal -offset
95struct if_nameindex {
96 unsigned int if_index; /* 1, 2, ... */
97 char *if_name; /* null terminated name: "le0", ... */
98};
99.Ed
100.Pp
101The end of the array of structures is indicated by a structure with
102an
103.Fa if_index
104of 0 and an
105.Fa if_name
106of
107.Dv NULL .
108The function returns a null pointer on error.
109The memory used for this array of structures along with the interface
110names pointed to by the
111.Fa if_name
112members is obtained dynamically.
113This memory is freed by the
114.Fn if_freenameindex
115function.
116.Pp
117.Fn if_freenameindex
118takes a pointer that was returned by
119.Fn if_nameindex
120as argument
121.Pq Fa ptr ,
122and it reclaims the region allocated.
123.Sh DIAGNOSTICS
124.Fn if_nametoindex
125returns 0 on error, positive integer on success.
126.Fn if_indextoname
127and
128.Fn if_nameindex
129return
130.Dv NULL
131on errors.
132.Sh SEE ALSO
133.Xr getifaddrs 3 ,
134.Xr networking 4
135.Pp
136R. Gilligan, S. Thomson, J. Bound, and W. Stevens,
137``Basic Socket Interface Extensions for IPv6,'' RFC2553, March 1999.
138.Sh STANDARDS
139These functions are defined in ``Basic Socket Interface Extensions for IPv6''
140.Pq RFC2533 .
diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c
new file mode 100644
index 0000000000..f99e52e387
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.c
@@ -0,0 +1,86 @@
1/* $OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2533:
40 *
41 * The second function maps an interface index into its corresponding
42 * name.
43 *
44 * #include <net/if.h>
45 *
46 * char *if_indextoname(unsigned int ifindex, char *ifname);
47 *
48 * The ifname argument must point to a buffer of at least IF_NAMESIZE
49 * bytes into which the interface name corresponding to the specified
50 * index is returned. (IF_NAMESIZE is also defined in <net/if.h> and
51 * its value includes a terminating null byte at the end of the
52 * interface name.) This pointer is also the return value of the
53 * function. If there is no interface corresponding to the specified
54 * index, NULL is returned, and errno is set to ENXIO, if there was a
55 * system error (such as running out of memory), if_indextoname returns
56 * NULL and errno would be set to the proper value (e.g., ENOMEM).
57 */
58
59char *
60if_indextoname(unsigned int ifindex, char *ifname)
61{
62 struct ifaddrs *ifaddrs, *ifa;
63 int error = 0;
64
65 if (getifaddrs(&ifaddrs) < 0)
66 return(NULL); /* getifaddrs properly set errno */
67
68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
69 if (ifa->ifa_addr &&
70 ifa->ifa_addr->sa_family == AF_LINK &&
71 ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index)
72 break;
73 }
74
75 if (ifa == NULL) {
76 error = ENXIO;
77 ifname = NULL;
78 }
79 else
80 strlcpy(ifname, ifa->ifa_name, IFNAMSIZ);
81
82 freeifaddrs(ifaddrs);
83
84 errno = error;
85 return(ifname);
86}
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
new file mode 100644
index 0000000000..3675a2a450
--- /dev/null
+++ b/src/lib/libc/net/if_nameindex.c
@@ -0,0 +1,140 @@
1/* $OpenBSD: if_nameindex.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36
37/*
38 * From RFC 2553:
39 *
40 * 4.3 Return All Interface Names and Indexes
41 *
42 * The if_nameindex structure holds the information about a single
43 * interface and is defined as a result of including the <net/if.h>
44 * header.
45 *
46 * struct if_nameindex {
47 * unsigned int if_index;
48 * char *if_name;
49 * };
50 *
51 * The final function returns an array of if_nameindex structures, one
52 * structure per interface.
53 *
54 * struct if_nameindex *if_nameindex(void);
55 *
56 * The end of the array of structures is indicated by a structure with
57 * an if_index of 0 and an if_name of NULL. The function returns a NULL
58 * pointer upon an error, and would set errno to the appropriate value.
59 *
60 * The memory used for this array of structures along with the interface
61 * names pointed to by the if_name members is obtained dynamically.
62 * This memory is freed by the next function.
63 *
64 * 4.4. Free Memory
65 *
66 * The following function frees the dynamic memory that was allocated by
67 * if_nameindex().
68 *
69 * #include <net/if.h>
70 *
71 * void if_freenameindex(struct if_nameindex *ptr);
72 *
73 * The argument to this function must be a pointer that was returned by
74 * if_nameindex().
75 */
76
77struct if_nameindex *
78if_nameindex(void)
79{
80 struct ifaddrs *ifaddrs, *ifa;
81 unsigned int ni;
82 size_t nbytes;
83 struct if_nameindex *ifni, *ifni2;
84 char *cp;
85
86 if (getifaddrs(&ifaddrs) < 0)
87 return(NULL);
88
89 /*
90 * First, find out how many interfaces there are, and how
91 * much space we need for the string names.
92 */
93 ni = 0;
94 nbytes = 0;
95 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
96 if (ifa->ifa_addr &&
97 ifa->ifa_addr->sa_family == AF_LINK) {
98 nbytes += strlen(ifa->ifa_name) + 1;
99 ni++;
100 }
101 }
102
103 /*
104 * Next, allocate a chunk of memory, use the first part
105 * for the array of structures, and the last part for
106 * the strings.
107 */
108 cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
109 ifni = (struct if_nameindex *)cp;
110 if (ifni == NULL)
111 goto out;
112 cp += (ni + 1) * sizeof(struct if_nameindex);
113
114 /*
115 * Now just loop through the list of interfaces again,
116 * filling in the if_nameindex array and making copies
117 * of all the strings.
118 */
119 ifni2 = ifni;
120 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
121 if (ifa->ifa_addr &&
122 ifa->ifa_addr->sa_family == AF_LINK) {
123 ifni2->if_index =
124 ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
125 ifni2->if_name = cp;
126 nbytes = strlen(ifa->ifa_name) + 1;
127 memcpy(cp, ifa->ifa_name, nbytes);
128 ifni2++;
129 cp += nbytes;
130 }
131 }
132 /*
133 * Finally, don't forget to terminate the array.
134 */
135 ifni2->if_index = 0;
136 ifni2->if_name = NULL;
137out:
138 freeifaddrs(ifaddrs);
139 return(ifni);
140}
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c
new file mode 100644
index 0000000000..8bd792b949
--- /dev/null
+++ b/src/lib/libc/net/if_nametoindex.c
@@ -0,0 +1,81 @@
1/* $OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nametoindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <net/if_dl.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2553:
40 *
41 * 4.1 Name-to-Index
42 *
43 *
44 * The first function maps an interface name into its corresponding
45 * index.
46 *
47 * #include <net/if.h>
48 *
49 * unsigned int if_nametoindex(const char *ifname);
50 *
51 * If the specified interface name does not exist, the return value is
52 * 0, and errno is set to ENXIO. If there was a system error (such as
53 * running out of memory), the return value is 0 and errno is set to the
54 * proper value (e.g., ENOMEM).
55 */
56
57unsigned int
58if_nametoindex(const char *ifname)
59{
60 struct ifaddrs *ifaddrs, *ifa;
61 unsigned int ni;
62
63 if (getifaddrs(&ifaddrs) < 0)
64 return(0);
65
66 ni = 0;
67
68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
69 if (ifa->ifa_addr &&
70 ifa->ifa_addr->sa_family == AF_LINK &&
71 strcmp(ifa->ifa_name, ifname) == 0) {
72 ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
73 break;
74 }
75 }
76
77 freeifaddrs(ifaddrs);
78 if (!ni)
79 errno = ENXIO;
80 return(ni);
81}
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3
new file mode 100644
index 0000000000..62f526c09d
--- /dev/null
+++ b/src/lib/libc/net/inet.3
@@ -0,0 +1,349 @@
1.\" $OpenBSD: inet.3,v 1.13 2001/02/17 23:13:26 pjanzen Exp $
2.\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $
3.\"
4.\" Copyright (c) 1983, 1990, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" @(#)inet.3 8.1 (Berkeley) 6/4/93
36.\"
37.Dd June 18, 1997
38.Dt INET 3
39.Os
40.Sh NAME
41.Nm inet_addr ,
42.Nm inet_aton ,
43.Nm inet_lnaof ,
44.Nm inet_makeaddr ,
45.Nm inet_netof ,
46.Nm inet_network ,
47.Nm inet_ntoa ,
48.Nm inet_ntop ,
49.Nm inet_pton
50.Nd Internet address manipulation routines
51.Sh SYNOPSIS
52.Fd #include <sys/socket.h>
53.Fd #include <netinet/in.h>
54.Fd #include <arpa/inet.h>
55.Ft in_addr_t
56.Fn inet_addr "const char *cp"
57.Ft int
58.Fn inet_aton "const char *cp" "struct in_addr *addr"
59.Ft in_addr_t
60.Fn inet_lnaof "struct in_addr in"
61.Ft struct in_addr
62.Fn inet_makeaddr "unsigned long net" "unsigned long lna"
63.Ft in_addr_t
64.Fn inet_netof "struct in_addr in"
65.Ft in_addr_t
66.Fn inet_network "const char *cp"
67.Ft char *
68.Fn inet_ntoa "struct in_addr in"
69.Ft const char *
70.Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size"
71.Ft int
72.Fn inet_pton "int af" "const char *src" "void *dst"
73.Sh DESCRIPTION
74The routines
75.Fn inet_aton ,
76.Fn inet_addr
77and
78.Fn inet_network
79interpret character strings representing
80numbers expressed in the Internet standard
81.Ql \&.
82notation.
83The
84.Fn inet_pton
85function converts a presentation format address (that is, printable form
86as held in a character string) to network format (usually a
87.Li struct in_addr
88or some other internal binary representation, in network byte order).
89It returns 1 if the address was valid for the specified address family, or
900 if the address wasn't parseable in the specified address family, or \-1
91if some system error occurred (in which case
92.Va errno
93will have been set).
94This function is presently valid for
95.Dv AF_INET
96and
97.Dv AF_INET6 .
98The
99.Fn inet_aton
100routine interprets the specified character string as an Internet address,
101placing the address into the structure provided.
102It returns 1 if the string was successfully interpreted,
103or 0 if the string was invalid.
104The
105.Fn inet_addr
106and
107.Fn inet_network
108functions return numbers suitable for use
109as Internet addresses and Internet network
110numbers, respectively.
111.Pp
112The function
113.Fn inet_ntop
114converts an address from network format (usually a
115.Li struct in_addr
116or some other binary form, in network byte order) to presentation format
117(suitable for external display purposes).
118It returns
119.Dv NULL
120if a system
121error occurs (in which case,
122.Va errno
123will have been set), or it returns a pointer to the destination string.
124The routine
125.Fn inet_ntoa
126takes an Internet address and returns an
127.Tn ASCII
128string representing the address in
129.Ql \&.
130notation.
131The routine
132.Fn inet_makeaddr
133takes an Internet network number and a local
134network address and constructs an Internet address
135from it.
136The routines
137.Fn inet_netof
138and
139.Fn inet_lnaof
140break apart Internet host addresses, returning
141the network number and local network address part,
142respectively.
143.Pp
144All Internet addresses are returned in network
145order (bytes ordered from left to right).
146All network numbers and local address parts are
147returned as machine format integer values.
148.Sh INTERNET ADDRESSES (IP VERSION 4)
149Values specified using the
150.Ql \&.
151notation take one
152of the following forms:
153.Bd -literal -offset indent
154a.b.c.d
155a.b.c
156a.b
157a
158.Ed
159.Pp
160When four parts are specified, each is interpreted
161as a byte of data and assigned, from left to right,
162to the four bytes of an Internet address.
163Note that when an Internet address is viewed as a 32-bit
164integer quantity on a system that uses little-endian
165byte order (such as the
166.Tn Intel 386, 486
167and
168.Tn Pentium
169processors) the bytes referred to above appear as
170.Dq Li d.c.b.a .
171That is, little-endian bytes are ordered from right to left.
172.Pp
173When a three part address is specified, the last
174part is interpreted as a 16-bit quantity and placed
175in the rightmost two bytes of the network address.
176This makes the three part address format convenient
177for specifying Class B network addresses as
178.Dq Li 128.net.host .
179.Pp
180When a two part address is supplied, the last part
181is interpreted as a 24-bit quantity and placed in
182the rightmost three bytes of the network address.
183This makes the two part address format convenient
184for specifying Class A network addresses as
185.Dq Li net.host .
186.Pp
187When only one part is given, the value is stored
188directly in the network address without any byte
189rearrangement.
190.Pp
191All numbers supplied as
192.Dq parts
193in a
194.Ql \&.
195notation
196may be decimal, octal, or hexadecimal, as specified
197in the C language (i.e., a leading 0x or 0X implies
198hexadecimal; otherwise, a leading 0 implies octal;
199otherwise, the number is interpreted as decimal).
200.Sh INTERNET ADDRESSES (IP VERSION 6)
201In order to support scoped IPv6 addresses,
202.Xr getaddrinfo 3
203and
204.Xr getnameinfo 3
205are recommended rather than the functions presented here.
206.Pp
207The presentation format of an IPv6 address is given in [RFC1884 2.2]:
208.Pp
209There are three conventional forms for representing IPv6 addresses as
210text strings:
211.Bl -enum
212.It
213The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
214hexadecimal values of the eight 16-bit pieces of the address.
215Examples:
216.Bd -literal -offset indent
217FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2181080:0:0:0:8:800:200C:417A
219.Ed
220.Pp
221Note that it is not necessary to write the leading zeros in an
222individual field, but there must be at least one numeral in
223every field (except for the case described in 2.).
224.It
225Due to the method of allocating certain styles of IPv6
226addresses, it will be common for addresses to contain long
227strings of zero bits.
228In order to make writing addresses
229.Pp
230containing zero bits easier a special syntax is available to
231compress the zeros.
232The use of
233.Dq \&:\&:
234indicates multiple groups
235of 16 bits of zeros.
236The
237.Dq \&:\&:
238can only appear once in an
239address.
240The
241.Dq \&:\&:
242can also be used to compress the leading and/or trailing zeros in an address.
243.Pp
244For example the following addresses:
245.Bd -literal -offset indent
2461080:0:0:0:8:800:200C:417A a unicast address
247FF01:0:0:0:0:0:0:43 a multicast address
2480:0:0:0:0:0:0:1 the loopback address
2490:0:0:0:0:0:0:0 the unspecified addresses
250.Ed
251.Pp
252may be represented as:
253.Bd -literal -offset indent
2541080::8:800:200C:417A a unicast address
255FF01::43 a multicast address
256::1 the loopback address
257:: the unspecified addresses
258.Ed
259.It
260An alternative form that is sometimes more convenient when
261dealing with a mixed environment of IPv4 and IPv6 nodes is
262x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
263of the six high-order 16-bit pieces of the address, and the 'd's
264are the decimal values of the four low-order 8-bit pieces of the
265address (standard IPv4 representation).
266Examples:
267.Bd -literal -offset indent
2680:0:0:0:0:0:13.1.68.3
2690:0:0:0:0:FFFF:129.144.52.38
270.Ed
271.Pp
272or in compressed form:
273.Bd -literal -offset indent
274::13.1.68.3
275::FFFF:129.144.52.38
276.Ed
277.El
278.Sh DIAGNOSTICS
279The constant
280.Dv INADDR_NONE
281is returned by
282.Fn inet_addr
283and
284.Fn inet_network
285for malformed requests.
286.Sh SEE ALSO
287.Xr byteorder 3 ,
288.Xr gethostbyname 3 ,
289.Xr getnetent 3 ,
290.Xr inet_net 3 ,
291.Xr hosts 5 ,
292.Xr networks 5
293.Sh STANDARDS
294The
295.Nm inet_ntop
296and
297.Nm inet_pton
298functions conforms to the IETF IPv6 BSD API and address formatting
299specifications.
300Note that
301.Nm inet_pton
302does not accept 1-, 2-, or 3-part dotted addresses; all four parts
303must be specified.
304This is a narrower input set than that accepted by
305.Nm inet_aton .
306.Sh HISTORY
307The
308.Nm inet_addr ,
309.Nm inet_network ,
310.Nm inet_makeaddr ,
311.Nm inet_lnaof
312and
313.Nm inet_netof
314functions appeared in
315.Bx 4.2 .
316The
317.Nm inet_aton
318and
319.Nm inet_ntoa
320functions appeared in
321.Bx 4.3 .
322The
323.Nm inet_pton
324and
325.Nm inet_ntop
326functions appeared in BIND 4.9.4.
327.Sh BUGS
328The value
329.Dv INADDR_NONE
330(0xffffffff) is a valid broadcast address, but
331.Fn inet_addr
332cannot return that value without indicating failure.
333Also,
334.Fn inet_addr
335should have been designed to return a
336.Li struct in_addr .
337The newer
338.Fn inet_aton
339function does not share these problems, and almost all existing code
340should be modified to use
341.Fn inet_aton
342instead.
343.Pp
344The problem of host byte ordering versus network byte ordering is
345confusing.
346.Pp
347The string returned by
348.Fn inet_ntoa
349resides in a static memory area.
diff --git a/src/lib/libc/net/inet6_option_space.3 b/src/lib/libc/net/inet6_option_space.3
new file mode 100644
index 0000000000..73419d5239
--- /dev/null
+++ b/src/lib/libc/net/inet6_option_space.3
@@ -0,0 +1,452 @@
1.\" $OpenBSD: inet6_option_space.3,v 1.8 2001/06/23 05:57:04 deraadt Exp $
2.\" $KAME: inet6_option_space.3,v 1.7 2000/05/17 14:32:13 itojun Exp $
3.\"
4.\" Copyright (c) 1983, 1987, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.Dd December 10, 1999
36.Dt INET6_OPTION_SPACE 3
37.Os
38.\"
39.Sh NAME
40.Nm inet6_option_space ,
41.Nm inet6_option_init ,
42.Nm inet6_option_append ,
43.Nm inet6_option_alloc ,
44.Nm inet6_option_next ,
45.Nm inet6_option_find
46.Nd IPv6 Hop-by-Hop and Destination Options manipulation
47.\"
48.Sh SYNOPSIS
49.Fd #include <netinet/in.h>
50.Ft "int"
51.Fn inet6_option_space "int nbytes"
52.Ft "int"
53.Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type"
54.Ft "int"
55.Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy"
56.Ft "u_int8_t *"
57.Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy";
58.Ft "int"
59.Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp"
60.Ft "int"
61.Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type"
62.\"
63.Sh DESCRIPTION
64.\"
65Building and parsing the Hop-by-Hop and Destination options is
66complicated due to alignment constranints, padding and
67ancillary data manipulation.
68RFC2292 defines a set of functions to help the application.
69The function prototypes for
70these functions are all in the
71.Aq Li netinet/in.h
72header.
73.\"
74.Ss inet6_option_space
75.Fn inet6_option_space
76returns the number of bytes required to hold an option when it is stored as
77ancillary data, including the
78.Li cmsghdr
79structure at the beginning,
80and any padding at the end
81.Po
82to make its size a multiple of 8 bytes
83.Pc .
84The argument is the size of the structure defining the option,
85which must include any pad bytes at the beginning
86.Po
87the value
88.Li y
89in the alignment term
90.Dq Li xn + y
91.Pc ,
92the type byte, the length byte, and the option data.
93.Pp
94Note: If multiple options are stored in a single ancillary data
95object, which is the recommended technique, this function
96overestimates the amount of space required by the size of
97.Li N-1
98.Li cmsghdr
99structures,
100where
101.Li N
102is the number of options to be stored in the object.
103This is of little consequence, since it is assumed that most
104Hop-by-Hop option headers and Destination option headers carry only
105one option
106.Pq appendix B of [RFC-2460] .
107.\"
108.Ss inet6_option_init
109.Fn inet6_option_init
110is called once per ancillary data object that will
111contain either Hop-by-Hop or Destination options.
112It returns
113.Li 0
114on success or
115.Li -1
116on an error.
117.Pp
118.Fa bp
119is a pointer to previously allocated space that will contain the
120ancillary data object.
121It must be large enough to contain all the
122individual options to be added by later calls to
123.Fn inet6_option_append
124and
125.Fn inet6_option_alloc .
126.Pp
127.Fa cmsgp
128is a pointer to a pointer to a
129.Li cmsghdr
130structure.
131.Fa *cmsgp
132is initialized by this function to point to the
133.Li cmsghdr
134structure constructed by this function in the buffer pointed to by
135.Fa bp .
136.Pp
137.Fa type
138is either
139.Dv IPV6_HOPOPTS
140or
141.Dv IPV6_DSTOPTS .
142This
143.Fa type
144is stored in the
145.Li cmsg_type
146member of the
147.Li cmsghdr
148structure pointed to by
149.Fa *cmsgp .
150.\"
151.Ss inet6_option_append
152This function appends a Hop-by-Hop option or a Destination option
153into an ancillary data object that has been initialized by
154.Fn inet6_option_init .
155This function returns
156.Li 0
157if it succeeds or
158.Li -1
159on an error.
160.Pp
161.Fa cmsg
162is a pointer to the
163.Li cmsghdr
164structure that must have been
165initialized by
166.Fn inet6_option_init .
167.Pp
168.Fa typep
169is a pointer to the 8-bit option type.
170It is assumed that this
171field is immediately followed by the 8-bit option data length field,
172which is then followed immediately by the option data.
173The caller
174initializes these three fields
175.Pq the type-length-value, or TLV
176before calling this function.
177.Pp
178The option type must have a value from
179.Li 2
180to
181.Li 255 ,
182inclusive.
183.Po
184.Li 0
185and
186.Li 1
187are reserved for the
188.Li Pad1
189and
190.Li PadN
191options, respectively.
192.Pc
193.Pp
194The option data length must have a value between
195.Li 0
196and
197.Li 255 ,
198inclusive, and is the length of the option data that follows.
199.Pp
200.Fa multx
201is the value
202.Li x
203in the alignment term
204.Dq Li xn + y .
205It must have a value of
206.Li 1 ,
207.Li 2 ,
208.Li 4 ,
209or
210.Li 8 .
211.Pp
212.Fa plusy
213is the value
214.Li y
215in the alignment term
216.Dq Li xn + y .
217It must have a value between
218.Li 0
219and
220.Li 7 ,
221inclusive.
222.\"
223.Ss inet6_option_alloc
224This function appends a Hop-by-Hop option or a Destination option
225into an ancillary data object that has been initialized by
226.Fn inet6_option_init .
227This function returns a pointer to the 8-bit
228option type field that starts the option on success, or
229.Dv NULL
230on an error.
231.Pp
232The difference between this function and
233.Fn inet6_option_append
234is that the latter copies the contents of a previously built option into
235the ancillary data object while the current function returns a
236pointer to the space in the data object where the option's TLV must
237then be built by the caller.
238.Pp
239.Fa cmsg
240is a pointer to the
241.Li cmsghdr
242structure that must have been
243initialized by
244.Fn inet6_option_init .
245.Pp
246.Fa datalen
247is the value of the option data length byte for this option.
248This value is required as an argument to allow the function to
249determine if padding must be appended at the end of the option.
250.Po
251The
252.Fn inet6_option_append
253function does not need a data length argument
254since the option data length must already be stored by the caller.
255.Pc
256.Pp
257.Fa multx
258is the value
259.Li x
260in the alignment term
261.Dq Li xn + y .
262It must have a value of
263.Li 1 ,
264.Li 2 ,
265.Li 4 ,
266or
267.Li 8 .
268.Pp
269.Fa plusy
270is the value
271.Li y
272in the alignment term
273.Dq Li xn + y .
274It must have a value between
275.Li 0
276and
277.Li 7 ,
278inclusive.
279.\"
280.Ss inet6_option_next
281This function processes the next Hop-by-Hop option or Destination
282option in an ancillary data object.
283If another option remains to be
284processed, the return value of the function is
285.Li 0
286and
287.Fa *tptrp
288points to
289the 8-bit option type field
290.Po
291which is followed by the 8-bit option
292data length, followed by the option data
293.Pc .
294If no more options remain
295to be processed, the return value is
296.Li -1
297and
298.Fa *tptrp
299is
300.Dv NULL .
301If an error occurs, the return value is
302.Li -1
303and
304.Fa *tptrp
305is not
306.Dv NULL .
307.Pp
308.Fa cmsg
309is a pointer to
310.Li cmsghdr
311structure of which
312.Li cmsg_level
313equals
314.Dv IPPROTO_IPV6
315and
316.Li cmsg_type
317equals either
318.Dv IPV6_HOPOPTS
319or
320.Dv IPV6_DSTOPTS .
321.Pp
322.Fa tptrp
323is a pointer to a pointer to an 8-bit byte and
324.Fa *tptrp
325is used
326by the function to remember its place in the ancillary data object
327each time the function is called.
328The first time this function is
329called for a given ancillary data object,
330.Fa *tptrp
331must be set to
332.Dv NULL .
333.Pp
334Each time this function returns success,
335.Fa *tptrp
336points to the 8-bit
337option type field for the next option to be processed.
338.\"
339.Ss inet6_option_find
340This function is similar to the previously described
341.Fn inet6_option_next
342function, except this function lets the caller
343specify the option type to be searched for, instead of always
344returning the next option in the ancillary data object.
345.Fa cmsg
346is a
347pointer to
348.Li cmsghdr
349structure of which
350.Li cmsg_level
351equals
352.Dv IPPROTO_IPV6
353and
354.Li cmsg_type
355equals either
356.Dv IPV6_HOPOPTS
357or
358.Dv IPV6_DSTOPTS .
359.Pp
360.Fa tptrp
361is a pointer to a pointer to an 8-bit byte and
362.Fa *tptrp
363is used
364by the function to remember its place in the ancillary data object
365each time the function is called.
366The first time this function is
367called for a given ancillary data object,
368.Fa *tptrp
369must be set to
370.Dv NULL .
371.Pa
372This function starts searching for an option of the specified type
373beginning after the value of
374.Fa *tptrp .
375If an option of the specified
376type is located, this function returns
377.Li 0
378and
379.Fa *tptrp
380points to the 8-
381bit option type field for the option of the specified type.
382If an
383option of the specified type is not located, the return value is
384.Li -1
385and
386.Fa *tptrp
387is
388.Dv NULL .
389If an error occurs, the return value is
390.Li -1
391and
392.Fa *tptrp
393is not
394.Dv NULL .
395.\"
396.Sh DIAGNOSTICS
397.Fn inet6_option_init
398and
399.Fn inet6_option_append
400return
401.Li 0
402on success or
403.Li -1
404on an error.
405.Pp
406.Fn inet6_option_alloc
407returns
408.Dv NULL
409on an error.
410.Pp
411On errors,
412.Fn inet6_option_next
413and
414.Fn inet6_option_find
415return
416.Li -1
417setting
418.Fa *tptrp
419to non
420.Dv NULL
421value.
422.\"
423.Sh EXAMPLES
424RFC2292 gives comprehensive examples in chapter 6.
425.\"
426.Sh SEE ALSO
427.Rs
428.%A W. Stevens
429.%A M. Thomas
430.%T "Advanced Sockets API for IPv6"
431.%N RFC2292
432.%D February 1998
433.Re
434.Rs
435.%A S. Deering
436.%A R. Hinden
437.%T "Internet Protocol, Version 6 (IPv6) Specification"
438.%N RFC2460
439.%D December 1998
440.Re
441.\"
442.Sh HISTORY
443The implementation first appeared in KAME advanced networking kit.
444.\"
445.Sh STANDARDS
446The functions
447are documented in
448.Dq Advanced Sockets API for IPv6
449.Pq RFC2292 .
450.\"
451.Sh BUGS
452The text was shamelessly copied from RFC2292.
diff --git a/src/lib/libc/net/inet6_rthdr_space.3 b/src/lib/libc/net/inet6_rthdr_space.3
new file mode 100644
index 0000000000..cafe0d2645
--- /dev/null
+++ b/src/lib/libc/net/inet6_rthdr_space.3
@@ -0,0 +1,325 @@
1.\" $OpenBSD: inet6_rthdr_space.3,v 1.8 2001/06/23 05:57:04 deraadt Exp $
2.\" $KAME: inet6_rthdr_space.3,v 1.8 2000/05/17 14:30:15 itojun Exp $
3.\"
4.\" Copyright (c) 1983, 1987, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.Dd December 10, 1999
36.Dt INET6_RTHDR_SPACE 3
37.Os
38.\"
39.Sh NAME
40.Nm inet6_rthdr_space ,
41.Nm inet6_rthdr_init ,
42.Nm inet6_rthdr_add ,
43.Nm inet6_rthdr_lasthop ,
44.Nm inet6_rthdr_reverse ,
45.Nm inet6_rthdr_segments ,
46.Nm inet6_rthdr_getaddr ,
47.Nm inet6_rthdr_getflags
48.Nd IPv6 Routing Header Options manipulation
49.\"
50.Sh SYNOPSIS
51.Fd #include <netinet/in.h>
52.Ft size_t
53.Fn inet6_rthdr_space "int type" "int segments"
54.Ft "struct cmsghdr *"
55.Fn inet6_rthdr_init "void *bp" "int type"
56.Ft int
57.Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags"
58.Ft int
59.Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags"
60.Ft int
61.Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out"
62.Ft int
63.Fn inet6_rthdr_segments "const struct cmsghdr *cmsg"
64.Ft "struct in6_addr *"
65.Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index"
66.Ft int
67.Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index"
68.\"
69.Sh DESCRIPTION
70RFC2292 IPv6 advanced API defines eight
71functions that the application calls to build and examine a Routing
72header.
73Four functions build a Routing header:
74.Bl -hang
75.It Fn inet6_rthdr_space
76return #bytes required for ancillary data
77.It Fn inet6_rthdr_init
78initialize ancillary data for Routing header
79.It Fn inet6_rthdr_add
80add IPv6 address & flags to Routing header
81.It Fn inet6_rthdr_lasthop
82specify the flags for the final hop
83.El
84.Pp
85Four functions deal with a returned Routing header:
86.Bl -hang
87.It Fn inet6_rthdr_reverse
88reverse a Routing header
89.It Fn inet6_rthdr_segments
90return #segments in a Routing header
91.It Fn inet6_rthdr_getaddr
92fetch one address from a Routing header
93.It Fn inet6_rthdr_getflags
94fetch one flag from a Routing header
95.El
96.Pp
97The function prototypes for these functions are all in the
98.Aq Li netinet/in.h
99header.
100.\"
101.Ss inet6_rthdr_space
102This function returns the number of bytes required to hold a Routing
103header of the specified
104.Fa type
105containing the specified number of
106.Fa segments
107.Pq addresses .
108For an IPv6 Type 0 Routing header, the number
109of segments must be between 1 and 23, inclusive.
110The return value
111includes the size of the cmsghdr structure that precedes the Routing
112header, and any required padding.
113.Pp
114If the return value is 0, then either the type of the Routing header
115is not supported by this implementation or the number of segments is
116invalid for this type of Routing header.
117.Pp
118Note: This function returns the size but does not allocate the space
119required for the ancillary data.
120This allows an application to
121allocate a larger buffer, if other ancillary data objects are
122desired, since all the ancillary data objects must be specified to
123.Xr sendmsg 2
124as a single
125.Li msg_control
126buffer.
127.\"
128.Ss inet6_rthdr_init
129This function initializes the buffer pointed to by
130.Fa bp
131to contain a
132.Li cmsghdr
133structure followed by a Routing header of the specified
134.Fa type .
135The
136.Li cmsg_len
137member of the
138.Li cmsghdr
139structure is initialized to the
140size of the structure plus the amount of space required by the
141Routing header.
142The
143.Li cmsg_level
144and
145.Li cmsg_type
146members are also initialized as required.
147.Pp
148The caller must allocate the buffer and its size can be determined by
149calling
150.Fn inet6_rthdr_space .
151.Pp
152Upon success the return value is the pointer to the
153.Li cmsghdr
154structure, and this is then used as the first argument to the next
155two functions.
156Upon an error the return value is
157.Dv NULL .
158.\"
159.Ss inet6_rthdr_add
160This function adds the address pointed to by
161.Fa addr
162to the end of the
163Routing header being constructed and sets the type of this hop to the
164value of
165.Fa flags .
166For an IPv6 Type 0 Routing header,
167.Fa flags
168must be
169either
170.Dv IPV6_RTHDR_LOOSE
171or
172.Dv IPV6_RTHDR_STRICT .
173.Pp
174If successful, the
175.Li cmsg_len
176member of the
177.Li cmsghdr
178structure is
179updated to account for the new address in the Routing header and the
180return value of the function is 0.
181Upon an error the return value of
182the function is -1.
183.\"
184.Ss inet6_rthdr_lasthop
185This function specifies the Strict/Loose flag for the final hop of a
186Routing header.
187For an IPv6 Type 0 Routing header,
188.Fa flags
189must be either
190.Dv IPV6_RTHDR_LOOSE
191or
192.Dv IPV6_RTHDR_STRICT .
193.Pp
194The return value of the function is 0 upon success, or -1 upon an error.
195.Pp
196Notice that a Routing header specifying
197.Li N
198intermediate nodes requires
199.Li N+1
200Strict/Loose flags.
201This requires
202.Li N
203calls to
204.Fn inet6_rthdr_add
205followed by one call to
206.Fn inet6_rthdr_lasthop .
207.\"
208.Ss inet6_rthdr_reverse
209This function takes a Routing header that was received as ancillary
210data
211.Po
212pointed to by the first argument,
213.Fa in
214.Pc
215and writes a new Routing
216header that sends datagrams along the reverse of that route.
217Both
218arguments are allowed to point to the same buffer
219.Pq that is, the reversal can occur in place .
220.Pp
221The return value of the function is 0 on success, or -1 upon an
222error.
223.\"
224.Ss inet6_rthdr_segments
225This function returns the number of segments
226.Pq addresses
227contained in
228the Routing header described by
229.Fa cmsg .
230On success the return value is
231between 1 and 23, inclusive.
232The return value of the function is -1 upon an error.
233.\"
234.Ss inet6_rthdr_getaddr
235This function returns a pointer to the IPv6 address specified by
236.Fa index
237.Po
238which must have a value between 1 and the value returned by
239.Fn inet6_rthdr_segments
240.Pc
241in the Routing header described by
242.Fa cmsg .
243An
244application should first call
245.Fn inet6_rthdr_segments
246to obtain the number of segments in the Routing header.
247.Pp
248Upon an error the return value of the function is
249.Dv NULL .
250.\"
251.Ss inet6_rthdr_getflags
252This function returns the flags value specified by
253.Fa index
254.Po
255which must
256have a value between 0 and the value returned by
257.Fn inet6_rthdr_segments
258.Pc
259in the Routing header described by
260.Fa cmsg .
261For an IPv6 Type 0 Routing header the return value will be either
262.Dv IPV6_RTHDR_LOOSE
263or
264.Dv IPV6_RTHDR_STRICT .
265.Pp
266Upon an error the return value of the function is -1.
267.Pp
268Note: Addresses are indexed starting at 1, and flags starting at 0,
269to maintain consistency with the terminology and figures in RFC2460.
270.\"
271.Sh DIAGNOSTICS
272.Fn inet6_rthdr_space
273returns 0 on errors.
274.Pp
275.Fn inet6_rthdr_add ,
276.Fn inet6_rthdr_lasthop
277and
278.Fn inet6_rthdr_reverse
279return 0 on success, and returns -1 on error.
280.Pp
281.Fn inet6_rthdr_init
282and
283.Fn inet6_rthdr_getaddr
284return
285.Dv NULL
286on error.
287.Pp
288.Fn inet6_rthdr_segments
289and
290.Fn inet6_rthdr_getflags
291return -1 on error.
292.\"
293.Sh EXAMPLES
294RFC2292 gives comprehensive examples in chapter 8.
295.\"
296.Sh SEE ALSO
297.Rs
298.%A W. Stevens
299.%A M. Thomas
300.%T "Advanced Sockets API for IPv6"
301.%N RFC2292
302.%D February 1998
303.Re
304.Rs
305.%A S. Deering
306.%A R. Hinden
307.%T "Internet Protocol, Version 6 (IPv6) Specification"
308.%N RFC2460
309.%D December 1998
310.Re
311.\"
312.Sh HISTORY
313The implementation first appeared in KAME advanced networking kit.
314.\"
315.Sh STANDARDS
316The functions
317are documented in
318.Dq Advanced Sockets API for IPv6
319.Pq RFC2292 .
320.\"
321.Sh BUGS
322The text was shamelessly copied from RFC2292.
323.Pp
324.Fn inet6_rthdr_reverse
325is not implemented yet.
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
new file mode 100644
index 0000000000..6203ccdaac
--- /dev/null
+++ b/src/lib/libc/net/inet_addr.c
@@ -0,0 +1,187 @@
1/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */
2
3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
6 * Copyright (c) 1983, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
61static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/inet.h>
71#include <ctype.h>
72
73/*
74 * Ascii internet address interpretation routine.
75 * The value returned is in network order.
76 */
77in_addr_t
78inet_addr(cp)
79 register const char *cp;
80{
81 struct in_addr val;
82
83 if (inet_aton(cp, &val))
84 return (val.s_addr);
85 return (INADDR_NONE);
86}
87
88/*
89 * Check whether "cp" is a valid ascii representation
90 * of an Internet address and convert to a binary address.
91 * Returns 1 if the address is valid, 0 if not.
92 * This replaces inet_addr, the return value from which
93 * cannot distinguish between failure and a local broadcast address.
94 */
95int
96inet_aton(cp, addr)
97 register const char *cp;
98 struct in_addr *addr;
99{
100 register in_addr_t val;
101 register int base, n;
102 register char c;
103 u_int parts[4];
104 register u_int *pp = parts;
105
106 c = *cp;
107 for (;;) {
108 /*
109 * Collect number up to ``.''.
110 * Values are specified as for C:
111 * 0x=hex, 0=octal, isdigit=decimal.
112 */
113 if (!isdigit(c))
114 return (0);
115 val = 0; base = 10;
116 if (c == '0') {
117 c = *++cp;
118 if (c == 'x' || c == 'X')
119 base = 16, c = *++cp;
120 else
121 base = 8;
122 }
123 for (;;) {
124 if (isascii(c) && isdigit(c)) {
125 val = (val * base) + (c - '0');
126 c = *++cp;
127 } else if (base == 16 && isascii(c) && isxdigit(c)) {
128 val = (val << 4) |
129 (c + 10 - (islower(c) ? 'a' : 'A'));
130 c = *++cp;
131 } else
132 break;
133 }
134 if (c == '.') {
135 /*
136 * Internet format:
137 * a.b.c.d
138 * a.b.c (with c treated as 16 bits)
139 * a.b (with b treated as 24 bits)
140 */
141 if (pp >= parts + 3)
142 return (0);
143 *pp++ = val;
144 c = *++cp;
145 } else
146 break;
147 }
148 /*
149 * Check for trailing characters.
150 */
151 if (c != '\0' && (!isascii(c) || !isspace(c)))
152 return (0);
153 /*
154 * Concoct the address according to
155 * the number of parts specified.
156 */
157 n = pp - parts + 1;
158 switch (n) {
159
160 case 0:
161 return (0); /* initial nondigit */
162
163 case 1: /* a -- 32 bits */
164 break;
165
166 case 2: /* a.b -- 8.24 bits */
167 if ((val > 0xffffff) || (parts[0] > 0xff))
168 return (0);
169 val |= parts[0] << 24;
170 break;
171
172 case 3: /* a.b.c -- 8.8.16 bits */
173 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
174 return (0);
175 val |= (parts[0] << 24) | (parts[1] << 16);
176 break;
177
178 case 4: /* a.b.c.d -- 8.8.8.8 bits */
179 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
180 return (0);
181 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
182 break;
183 }
184 if (addr)
185 addr->s_addr = htonl(val);
186 return (1);
187}
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c
new file mode 100644
index 0000000000..6aed18699b
--- /dev/null
+++ b/src/lib/libc/net/inet_lnaof.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_lnaof.c,v 1.3 1997/04/05 21:13:11 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Return the local network address portion of an
44 * internet address; handles class a/b/c network
45 * number formats.
46 */
47in_addr_t
48inet_lnaof(in)
49 struct in_addr in;
50{
51 register in_addr_t i = ntohl(in.s_addr);
52
53 if (IN_CLASSA(i))
54 return ((i)&IN_CLASSA_HOST);
55 else if (IN_CLASSB(i))
56 return ((i)&IN_CLASSB_HOST);
57 else
58 return ((i)&IN_CLASSC_HOST);
59}
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c
new file mode 100644
index 0000000000..196a589e4c
--- /dev/null
+++ b/src/lib/libc/net/inet_makeaddr.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_makeaddr.c,v 1.3 1997/04/05 21:13:12 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Formulate an Internet address from network + host. Used in
44 * building addresses stored in the ifnet structure.
45 */
46struct in_addr
47inet_makeaddr(net, host)
48 in_addr_t net, host;
49{
50 in_addr_t addr;
51
52 if (net < 128)
53 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
54 else if (net < 65536)
55 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
56 else if (net < 16777216L)
57 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
58 else
59 addr = net | host;
60 addr = htonl(addr);
61 return (*(struct in_addr *)&addr);
62}
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3
new file mode 100644
index 0000000000..5c32aecd86
--- /dev/null
+++ b/src/lib/libc/net/inet_net.3
@@ -0,0 +1,148 @@
1.\" $OpenBSD: inet_net.3,v 1.6 2000/04/21 15:38:17 aaron Exp $
2.\" $NetBSD: inet_net.3,v 1.1 1997/06/18 02:25:27 lukem Exp $
3.\"
4.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" This code is derived from software contributed to The NetBSD Foundation
8.\" by Luke Mewburn.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. All advertising materials mentioning features or use of this software
19.\" must display the following acknowledgement:
20.\" This product includes software developed by the NetBSD
21.\" Foundation, Inc. and its contributors.
22.\" 4. Neither the name of The NetBSD Foundation nor the names of its
23.\" contributors may be used to endorse or promote products derived
24.\" from this software without specific prior written permission.
25.\"
26.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36.\" POSSIBILITY OF SUCH DAMAGE.
37.\"
38.Dd June 18, 1997
39.Dt INET_NET 3
40.Os
41.Sh NAME
42.Nm inet_net_ntop ,
43.Nm inet_net_pton
44.Nd Internet network number manipulation routines
45.Sh SYNOPSIS
46.Fd #include <sys/socket.h>
47.Fd #include <netinet/in.h>
48.Fd #include <arpa/inet.h>
49.Ft char *
50.Fn inet_net_ntop "int af" "const void *src" "int bits" "char *dst" "size_t size"
51.Ft int
52.Fn inet_net_pton "int af" "const char *src" "void *dst" "size_t size"
53.Sh DESCRIPTION
54The
55.Fn inet_net_ntop
56function converts an Internet network number from network format (usually a
57.Li struct in_addr
58or some other binary form, in network byte order) to CIDR presentation format
59(suitable for external display purposes).
60.Fa bits
61is the number of bits in
62.Fa src
63that are the network number.
64It returns
65.Dv NULL
66if a system error occurs (in which case,
67.Va errno
68will have been set), or it returns a pointer to the destination string.
69.Pp
70The
71.Fn inet_net_pton
72function converts a presentation format Internet network number (that is,
73printable form as held in a character string) to network format (usually a
74.Li struct in_addr
75or some other internal binary representation, in network byte order).
76It returns the number of bits (either computed based on the class, or
77specified with /CIDR), or \-1 if a failure occurred
78(in which case
79.Va errno
80will have been set.
81It will be set to
82.Er ENOENT
83if the Internet network number was not valid).
84.Pp
85The only value for
86.Fa af
87currently supported is
88.Dv AF_INET .
89.Fa size
90is the size of the result buffer
91.Fa dst .
92.Sh NETWORK NUMBERS (IP VERSION 4)
93Internet network numbers may be specified in one of the following forms:
94.Bd -literal -offset indent
95a.b.c.d/bits
96a.b.c.d
97a.b.c
98a.b
99a
100.Ed
101.Pp
102When four parts are specified, each is interpreted
103as a byte of data and assigned, from left to right,
104to the four bytes of an Internet network number.
105Note that when an Internet network number is viewed as a 32-bit
106integer quantity on a system that uses little-endian
107byte order (such as the Intel 386, 486, and Pentium processors)
108the bytes referred to above appear as
109.Dq Li d.c.b.a .
110That is, little-endian bytes are ordered from right to left.
111.Pp
112When a three part number is specified, the last
113part is interpreted as a 16-bit quantity and placed
114in the rightmost two bytes of the Internet network number.
115This makes the three part number format convenient
116for specifying Class B network numbers as
117.Dq Li 128.net.host .
118.Pp
119When a two part number is supplied, the last part
120is interpreted as a 24-bit quantity and placed in
121the rightmost three bytes of the Internet network number.
122This makes the two part number format convenient
123for specifying Class A network numbers as
124.Dq Li net.host .
125.Pp
126When only one part is given, the value is stored
127directly in the Internet network number without any byte
128rearrangement.
129.Pp
130All numbers supplied as
131.Dq parts
132in a
133.Ql \&.
134notation
135may be decimal, octal, or hexadecimal, as specified
136in the C language (i.e., a leading 0x or 0X implies
137hexadecimal; otherwise, a leading 0 implies octal;
138otherwise, the number is interpreted as decimal).
139.Sh SEE ALSO
140.Xr byteorder 3 ,
141.Xr inet 3 ,
142.Xr networks 5
143.Sh HISTORY
144The
145.Nm inet_net_ntop
146and
147.Nm inet_net_pton
148functions first appeared in BIND 4.9.4.
diff --git a/src/lib/libc/net/inet_net_ntop.c b/src/lib/libc/net/inet_net_ntop.c
new file mode 100644
index 0000000000..18eea6bb6d
--- /dev/null
+++ b/src/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,153 @@
1/* $OpenBSD: inet_net_ntop.c,v 1.3 2002/08/19 03:01:54 itojun Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.3 2002/08/19 03:01:54 itojun Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <errno.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37
38static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t);
39
40/*
41 * char *
42 * inet_net_ntop(af, src, bits, dst, size)
43 * convert network number from network to presentation format.
44 * generates CIDR style result always.
45 * return:
46 * pointer to dst, or NULL if an error occurred (check errno).
47 * author:
48 * Paul Vixie (ISC), July 1996
49 */
50char *
51inet_net_ntop(af, src, bits, dst, size)
52 int af;
53 const void *src;
54 int bits;
55 char *dst;
56 size_t size;
57{
58 switch (af) {
59 case AF_INET:
60 return (inet_net_ntop_ipv4(src, bits, dst, size));
61 default:
62 errno = EAFNOSUPPORT;
63 return (NULL);
64 }
65}
66
67/*
68 * static char *
69 * inet_net_ntop_ipv4(src, bits, dst, size)
70 * convert IPv4 network number from network to presentation format.
71 * generates CIDR style result always.
72 * return:
73 * pointer to dst, or NULL if an error occurred (check errno).
74 * note:
75 * network byte order assumed. this means 192.5.5.240/28 has
76 * 0x11110000 in its fourth octet.
77 * author:
78 * Paul Vixie (ISC), July 1996
79 */
80static char *
81inet_net_ntop_ipv4(src, bits, dst, size)
82 const u_char *src;
83 int bits;
84 char *dst;
85 size_t size;
86{
87 char *odst = dst;
88 char *t;
89 u_int m;
90 int b;
91 char *ep;
92 int advance;
93
94 ep = dst + size;
95 if (ep <= dst)
96 goto emsgsize;
97
98 if (bits < 0 || bits > 32) {
99 errno = EINVAL;
100 return (NULL);
101 }
102 if (bits == 0) {
103 if (ep - dst < sizeof "0")
104 goto emsgsize;
105 *dst++ = '0';
106 *dst = '\0';
107 }
108
109 /* Format whole octets. */
110 for (b = bits / 8; b > 0; b--) {
111 if (ep - dst < sizeof "255.")
112 goto emsgsize;
113 advance = snprintf(dst, ep - dst, "%u", *src++);
114 if (advance <= 0 || advance >= ep - dst)
115 goto emsgsize;
116 dst += advance;
117 if (b > 1) {
118 if (dst + 1 >= ep)
119 goto emsgsize;
120 *dst++ = '.';
121 *dst = '\0';
122 }
123 }
124
125 /* Format partial octet. */
126 b = bits % 8;
127 if (b > 0) {
128 if (ep - dst < sizeof ".255")
129 goto emsgsize;
130 if (dst != odst)
131 if (dst + 1 >= ep)
132 goto emsgsize;
133 *dst++ = '.';
134 m = ((1 << b) - 1) << (8 - b);
135 advance = snprintf(dst, ep - dst, "%u", *src & m);
136 if (advance <= 0 || advance >= ep - dst)
137 goto emsgsize;
138 dst += advance;
139 }
140
141 /* Format CIDR /width. */
142 if (ep - dst < sizeof "/32")
143 goto emsgsize;
144 advance = snprintf(dst, ep - dst, "/%u", bits);
145 if (advance <= 0 || advance >= ep - dst)
146 goto emsgsize;
147 dst += advance;
148 return (odst);
149
150 emsgsize:
151 errno = EMSGSIZE;
152 return (NULL);
153}
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c
new file mode 100644
index 0000000000..932531eb5d
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,206 @@
1/* $OpenBSD: inet_net_pton.c,v 1.2 2002/02/17 19:42:23 millert Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_pton.c,v 1.2 2002/02/17 19:42:23 millert Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <assert.h>
34#include <ctype.h>
35#include <errno.h>
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39
40static int inet_net_pton_ipv4(const char *, u_char *, size_t);
41
42/*
43 * static int
44 * inet_net_pton(af, src, dst, size)
45 * convert network number from presentation to network format.
46 * accepts hex octets, hex strings, decimal octets, and /CIDR.
47 * "size" is in bytes and describes "dst".
48 * return:
49 * number of bits, either imputed classfully or specified with /CIDR,
50 * or -1 if some failure occurred (check errno). ENOENT means it was
51 * not a valid network specification.
52 * author:
53 * Paul Vixie (ISC), June 1996
54 */
55int
56inet_net_pton(af, src, dst, size)
57 int af;
58 const char *src;
59 void *dst;
60 size_t size;
61{
62 switch (af) {
63 case AF_INET:
64 return (inet_net_pton_ipv4(src, dst, size));
65 default:
66 errno = EAFNOSUPPORT;
67 return (-1);
68 }
69}
70
71/*
72 * static int
73 * inet_net_pton_ipv4(src, dst, size)
74 * convert IPv4 network number from presentation to network format.
75 * accepts hex octets, hex strings, decimal octets, and /CIDR.
76 * "size" is in bytes and describes "dst".
77 * return:
78 * number of bits, either imputed classfully or specified with /CIDR,
79 * or -1 if some failure occurred (check errno). ENOENT means it was
80 * not an IPv4 network specification.
81 * note:
82 * network byte order assumed. this means 192.5.5.240/28 has
83 * 0x11110000 in its fourth octet.
84 * author:
85 * Paul Vixie (ISC), June 1996
86 */
87static int
88inet_net_pton_ipv4(src, dst, size)
89 const char *src;
90 u_char *dst;
91 size_t size;
92{
93 static const char
94 xdigits[] = "0123456789abcdef",
95 digits[] = "0123456789";
96 int n, ch, tmp, dirty, bits;
97 const u_char *odst = dst;
98
99 ch = *src++;
100 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
101 && isascii(src[1]) && isxdigit(src[1])) {
102 /* Hexadecimal: Eat nybble string. */
103 if (size <= 0)
104 goto emsgsize;
105 *dst = 0, dirty = 0;
106 src++; /* skip x or X. */
107 while ((ch = *src++) != '\0' &&
108 isascii(ch) && isxdigit(ch)) {
109 if (isupper(ch))
110 ch = tolower(ch);
111 n = strchr(xdigits, ch) - xdigits;
112 assert(n >= 0 && n <= 15);
113 *dst |= n;
114 if (!dirty++)
115 *dst <<= 4;
116 else if (size-- > 0)
117 *++dst = 0, dirty = 0;
118 else
119 goto emsgsize;
120 }
121 if (dirty)
122 size--;
123 } else if (isascii(ch) && isdigit(ch)) {
124 /* Decimal: eat dotted digit string. */
125 for (;;) {
126 tmp = 0;
127 do {
128 n = strchr(digits, ch) - digits;
129 assert(n >= 0 && n <= 9);
130 tmp *= 10;
131 tmp += n;
132 if (tmp > 255)
133 goto enoent;
134 } while ((ch = *src++) != '\0' &&
135 isascii(ch) && isdigit(ch));
136 if (size-- <= 0)
137 goto emsgsize;
138 *dst++ = (u_char) tmp;
139 if (ch == '\0' || ch == '/')
140 break;
141 if (ch != '.')
142 goto enoent;
143 ch = *src++;
144 if (!isascii(ch) || !isdigit(ch))
145 goto enoent;
146 }
147 } else
148 goto enoent;
149
150 bits = -1;
151 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
152 /* CIDR width specifier. Nothing can follow it. */
153 ch = *src++; /* Skip over the /. */
154 bits = 0;
155 do {
156 n = strchr(digits, ch) - digits;
157 assert(n >= 0 && n <= 9);
158 bits *= 10;
159 bits += n;
160 } while ((ch = *src++) != '\0' &&
161 isascii(ch) && isdigit(ch));
162 if (ch != '\0')
163 goto enoent;
164 if (bits > 32)
165 goto emsgsize;
166 }
167
168 /* Firey death and destruction unless we prefetched EOS. */
169 if (ch != '\0')
170 goto enoent;
171
172 /* If nothing was written to the destination, we found no address. */
173 if (dst == odst)
174 goto enoent;
175 /* If no CIDR spec was given, infer width from net class. */
176 if (bits == -1) {
177 if (*odst >= 240) /* Class E */
178 bits = 32;
179 else if (*odst >= 224) /* Class D */
180 bits = 4;
181 else if (*odst >= 192) /* Class C */
182 bits = 24;
183 else if (*odst >= 128) /* Class B */
184 bits = 16;
185 else /* Class A */
186 bits = 8;
187 /* If imputed mask is narrower than specified octets, widen. */
188 if (bits >= 8 && bits < ((dst - odst) * 8))
189 bits = (dst - odst) * 8;
190 }
191 /* Extend network to cover the actual mask. */
192 while (bits > ((dst - odst) * 8)) {
193 if (size-- <= 0)
194 goto emsgsize;
195 *dst++ = '\0';
196 }
197 return (bits);
198
199 enoent:
200 errno = ENOENT;
201 return (-1);
202
203 emsgsize:
204 errno = EMSGSIZE;
205 return (-1);
206}
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000000..6960bcd0b5
--- /dev/null
+++ b/src/lib/libc/net/inet_neta.c
@@ -0,0 +1,91 @@
1/* $OpenBSD: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$Id: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.4 2002/08/19 03:01:54 itojun Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <errno.h>
34#include <stdio.h>
35#include <string.h>
36
37/*
38 * char *
39 * inet_neta(src, dst, size)
40 * format an in_addr_t network number into presentation format.
41 * return:
42 * pointer to dst, or NULL if an error occurred (check errno).
43 * note:
44 * format of ``src'' is as for inet_network().
45 * author:
46 * Paul Vixie (ISC), July 1996
47 */
48char *
49inet_neta(src, dst, size)
50 in_addr_t src;
51 char *dst;
52 size_t size;
53{
54 char *odst = dst;
55 char *ep;
56 int advance;
57
58 if (src == 0x00000000) {
59 if (size < sizeof "0.0.0.0")
60 goto emsgsize;
61 strlcpy(dst, "0.0.0.0", size);
62 return dst;
63 }
64 ep = dst + size;
65 if (ep <= dst)
66 goto emsgsize;
67 while (src & 0xffffffff) {
68 u_char b = (src & 0xff000000) >> 24;
69
70 src <<= 8;
71 if (b || src) {
72 if (ep - dst < sizeof "255.")
73 goto emsgsize;
74 advance = snprintf(dst, ep - dst, "%u", b);
75 if (advance <= 0 || advance >= ep - dst)
76 goto emsgsize;
77 dst += advance;
78 if (src != 0L) {
79 if (dst + 1 >= ep)
80 goto emsgsize;
81 *dst++ = '.';
82 *dst = '\0';
83 }
84 }
85 }
86 return (odst);
87
88 emsgsize:
89 errno = EMSGSIZE;
90 return (NULL);
91}
diff --git a/src/lib/libc/net/inet_netof.c b/src/lib/libc/net/inet_netof.c
new file mode 100644
index 0000000000..f3b9c01697
--- /dev/null
+++ b/src/lib/libc/net/inet_netof.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_netof.c,v 1.3 1997/04/05 21:13:13 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41
42/*
43 * Return the network number from an internet
44 * address; handles class a/b/c network #'s.
45 */
46in_addr_t
47inet_netof(in)
48 struct in_addr in;
49{
50 register in_addr_t i = ntohl(in.s_addr);
51
52 if (IN_CLASSA(i))
53 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
54 else if (IN_CLASSB(i))
55 return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
56 else
57 return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
58}
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c
new file mode 100644
index 0000000000..8a9a555d62
--- /dev/null
+++ b/src/lib/libc/net/inet_network.c
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_network.c,v 1.7 1997/07/09 01:08:37 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41#include <ctype.h>
42
43/*
44 * Internet network address interpretation routine.
45 * The library routines call this routine to interpret
46 * network numbers.
47 */
48in_addr_t
49inet_network(cp)
50 register const char *cp;
51{
52 register in_addr_t val, base, n;
53 register char c;
54 in_addr_t parts[4], *pp = parts;
55 register int i;
56
57again:
58 val = 0; base = 10;
59 if (*cp == '0')
60 base = 8, cp++;
61 if (*cp == 'x' || *cp == 'X')
62 base = 16, cp++;
63 while ((c = *cp)) {
64 if (isdigit(c)) {
65 val = (val * base) + (c - '0');
66 cp++;
67 continue;
68 }
69 if (base == 16 && isxdigit(c)) {
70 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
71 cp++;
72 continue;
73 }
74 break;
75 }
76 if (*cp == '.') {
77 if (pp >= parts + 3)
78 return (INADDR_NONE);
79 *pp++ = val, cp++;
80 goto again;
81 }
82 if (*cp && !isspace(*cp))
83 return (INADDR_NONE);
84 *pp++ = val;
85 n = pp - parts;
86 for (val = 0, i = 0; i < 4; i++) {
87 val <<= 8;
88 if (i < n)
89 val |= parts[i] & 0xff;
90 }
91 return (val);
92}
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c
new file mode 100644
index 0000000000..377184f366
--- /dev/null
+++ b/src/lib/libc/net/inet_ntoa.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38/*
39 * Convert network-format internet address
40 * to base 256 d.d.d.d representation.
41 */
42#include <sys/types.h>
43#include <netinet/in.h>
44#include <arpa/inet.h>
45#include <stdio.h>
46
47char *
48inet_ntoa(in)
49 struct in_addr in;
50{
51 static char b[18];
52 register char *p;
53
54 p = (char *)&in;
55#define UC(b) (((int)b)&0xff)
56 (void)snprintf(b, sizeof(b),
57 "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
58 return (b);
59}
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000000..adce61c1d4
--- /dev/null
+++ b/src/lib/libc/net/inet_ntop.c
@@ -0,0 +1,213 @@
1/* $OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20#if 0
21static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $";
24#endif
25#endif /* LIBC_SCCS and not lint */
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <arpa/nameser.h>
33#include <string.h>
34#include <errno.h>
35#include <stdio.h>
36
37/*
38 * WARNING: Don't even consider trying to compile this on a system where
39 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
40 */
41
42static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
43static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
44
45/* char *
46 * inet_ntop(af, src, dst, size)
47 * convert a network format address to presentation format.
48 * return:
49 * pointer to presentation format address (`dst'), or NULL (see errno).
50 * author:
51 * Paul Vixie, 1996.
52 */
53const char *
54inet_ntop(af, src, dst, size)
55 int af;
56 const void *src;
57 char *dst;
58 size_t size;
59{
60 switch (af) {
61 case AF_INET:
62 return (inet_ntop4(src, dst, size));
63 case AF_INET6:
64 return (inet_ntop6(src, dst, size));
65 default:
66 errno = EAFNOSUPPORT;
67 return (NULL);
68 }
69 /* NOTREACHED */
70}
71
72/* const char *
73 * inet_ntop4(src, dst, size)
74 * format an IPv4 address, more or less like inet_ntoa()
75 * return:
76 * `dst' (as a const)
77 * notes:
78 * (1) uses no statics
79 * (2) takes a u_char* not an in_addr as input
80 * author:
81 * Paul Vixie, 1996.
82 */
83static const char *
84inet_ntop4(src, dst, size)
85 const u_char *src;
86 char *dst;
87 size_t size;
88{
89 static const char fmt[] = "%u.%u.%u.%u";
90 char tmp[sizeof "255.255.255.255"];
91 int l;
92
93 l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
94 if (l <= 0 || l >= size) {
95 errno = ENOSPC;
96 return (NULL);
97 }
98 strlcpy(dst, tmp, size);
99 return (dst);
100}
101
102/* const char *
103 * inet_ntop6(src, dst, size)
104 * convert IPv6 binary address into presentation (printable) format
105 * author:
106 * Paul Vixie, 1996.
107 */
108static const char *
109inet_ntop6(src, dst, size)
110 const u_char *src;
111 char *dst;
112 size_t size;
113{
114 /*
115 * Note that int32_t and int16_t need only be "at least" large enough
116 * to contain a value of the specified size. On some systems, like
117 * Crays, there is no such thing as an integer variable with 16 bits.
118 * Keep this in mind if you think this function should have been coded
119 * to use pointer overlays. All the world's not a VAX.
120 */
121 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
122 char *tp, *ep;
123 struct { int base, len; } best, cur;
124 u_int words[IN6ADDRSZ / INT16SZ];
125 int i;
126 int advance;
127
128 /*
129 * Preprocess:
130 * Copy the input (bytewise) array into a wordwise array.
131 * Find the longest run of 0x00's in src[] for :: shorthanding.
132 */
133 memset(words, '\0', sizeof words);
134 for (i = 0; i < IN6ADDRSZ; i++)
135 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
136 best.base = -1;
137 cur.base = -1;
138 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
139 if (words[i] == 0) {
140 if (cur.base == -1)
141 cur.base = i, cur.len = 1;
142 else
143 cur.len++;
144 } else {
145 if (cur.base != -1) {
146 if (best.base == -1 || cur.len > best.len)
147 best = cur;
148 cur.base = -1;
149 }
150 }
151 }
152 if (cur.base != -1) {
153 if (best.base == -1 || cur.len > best.len)
154 best = cur;
155 }
156 if (best.base != -1 && best.len < 2)
157 best.base = -1;
158
159 /*
160 * Format the result.
161 */
162 tp = tmp;
163 ep = tmp + sizeof(tmp);
164 for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
165 /* Are we inside the best run of 0x00's? */
166 if (best.base != -1 && i >= best.base &&
167 i < (best.base + best.len)) {
168 if (i == best.base) {
169 if (tp + 1 >= ep)
170 return (NULL);
171 *tp++ = ':';
172 }
173 continue;
174 }
175 /* Are we following an initial run of 0x00s or any real hex? */
176 if (i != 0) {
177 if (tp + 1 >= ep)
178 return (NULL);
179 *tp++ = ':';
180 }
181 /* Is this address an encapsulated IPv4? */
182 if (i == 6 && best.base == 0 &&
183 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
184 if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
185 return (NULL);
186 tp += strlen(tp);
187 break;
188 }
189 advance = snprintf(tp, ep - tp, "%x", words[i]);
190 if (advance <= 0 || advance >= ep - tp)
191 return (NULL);
192 tp += advance;
193 }
194 /* Was it a trailing run of 0x00's? */
195 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
196 if (tp + 1 >= ep)
197 return (NULL);
198 *tp++ = ':';
199 }
200 if (tp + 1 >= ep)
201 return (NULL);
202 *tp++ = '\0';
203
204 /*
205 * Check for overflow, copy, and we're done.
206 */
207 if ((size_t)(tp - tmp) > size) {
208 errno = ENOSPC;
209 return (NULL);
210 }
211 strlcpy(dst, tmp, size);
212 return (dst);
213}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..b04ef05c31
--- /dev/null
+++ b/src/lib/libc/net/inet_pton.c
@@ -0,0 +1,222 @@
1/* $OpenBSD: inet_pton.c,v 1.4 2002/02/16 21:27:23 millert Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20#if 0
21static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.4 2002/02/16 21:27:23 millert Exp $";
24#endif
25#endif /* LIBC_SCCS and not lint */
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <arpa/nameser.h>
33#include <string.h>
34#include <errno.h>
35
36/*
37 * WARNING: Don't even consider trying to compile this on a system where
38 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
39 */
40
41static int inet_pton4(const char *src, u_char *dst);
42static int inet_pton6(const char *src, u_char *dst);
43
44/* int
45 * inet_pton(af, src, dst)
46 * convert from presentation format (which usually means ASCII printable)
47 * to network format (which is usually some kind of binary format).
48 * return:
49 * 1 if the address was valid for the specified address family
50 * 0 if the address wasn't valid (`dst' is untouched in this case)
51 * -1 if some other error occurred (`dst' is untouched in this case, too)
52 * author:
53 * Paul Vixie, 1996.
54 */
55int
56inet_pton(af, src, dst)
57 int af;
58 const char *src;
59 void *dst;
60{
61 switch (af) {
62 case AF_INET:
63 return (inet_pton4(src, dst));
64 case AF_INET6:
65 return (inet_pton6(src, dst));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70 /* NOTREACHED */
71}
72
73/* int
74 * inet_pton4(src, dst)
75 * like inet_aton() but without all the hexadecimal and shorthand.
76 * return:
77 * 1 if `src' is a valid dotted quad, else 0.
78 * notice:
79 * does not touch `dst' unless it's returning 1.
80 * author:
81 * Paul Vixie, 1996.
82 */
83static int
84inet_pton4(src, dst)
85 const char *src;
86 u_char *dst;
87{
88 static const char digits[] = "0123456789";
89 int saw_digit, octets, ch;
90 u_char tmp[INADDRSZ], *tp;
91
92 saw_digit = 0;
93 octets = 0;
94 *(tp = tmp) = 0;
95 while ((ch = *src++) != '\0') {
96 const char *pch;
97
98 if ((pch = strchr(digits, ch)) != NULL) {
99 u_int new = *tp * 10 + (pch - digits);
100
101 if (new > 255)
102 return (0);
103 if (! saw_digit) {
104 if (++octets > 4)
105 return (0);
106 saw_digit = 1;
107 }
108 *tp = new;
109 } else if (ch == '.' && saw_digit) {
110 if (octets == 4)
111 return (0);
112 *++tp = 0;
113 saw_digit = 0;
114 } else
115 return (0);
116 }
117 if (octets < 4)
118 return (0);
119
120 memcpy(dst, tmp, INADDRSZ);
121 return (1);
122}
123
124/* int
125 * inet_pton6(src, dst)
126 * convert presentation level address to network order binary form.
127 * return:
128 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
129 * notice:
130 * (1) does not touch `dst' unless it's returning 1.
131 * (2) :: in a full address is silently ignored.
132 * credit:
133 * inspired by Mark Andrews.
134 * author:
135 * Paul Vixie, 1996.
136 */
137static int
138inet_pton6(src, dst)
139 const char *src;
140 u_char *dst;
141{
142 static const char xdigits_l[] = "0123456789abcdef",
143 xdigits_u[] = "0123456789ABCDEF";
144 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
145 const char *xdigits, *curtok;
146 int ch, saw_xdigit;
147 u_int val;
148
149 memset((tp = tmp), '\0', IN6ADDRSZ);
150 endp = tp + IN6ADDRSZ;
151 colonp = NULL;
152 /* Leading :: requires some special handling. */
153 if (*src == ':')
154 if (*++src != ':')
155 return (0);
156 curtok = src;
157 saw_xdigit = 0;
158 val = 0;
159 while ((ch = *src++) != '\0') {
160 const char *pch;
161
162 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
163 pch = strchr((xdigits = xdigits_u), ch);
164 if (pch != NULL) {
165 val <<= 4;
166 val |= (pch - xdigits);
167 if (val > 0xffff)
168 return (0);
169 saw_xdigit = 1;
170 continue;
171 }
172 if (ch == ':') {
173 curtok = src;
174 if (!saw_xdigit) {
175 if (colonp)
176 return (0);
177 colonp = tp;
178 continue;
179 } else if (*src == '\0') {
180 return (0);
181 }
182 if (tp + INT16SZ > endp)
183 return (0);
184 *tp++ = (u_char) (val >> 8) & 0xff;
185 *tp++ = (u_char) val & 0xff;
186 saw_xdigit = 0;
187 val = 0;
188 continue;
189 }
190 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
191 inet_pton4(curtok, tp) > 0) {
192 tp += INADDRSZ;
193 saw_xdigit = 0;
194 break; /* '\0' was seen by inet_pton4(). */
195 }
196 return (0);
197 }
198 if (saw_xdigit) {
199 if (tp + INT16SZ > endp)
200 return (0);
201 *tp++ = (u_char) (val >> 8) & 0xff;
202 *tp++ = (u_char) val & 0xff;
203 }
204 if (colonp != NULL) {
205 /*
206 * Since some memmove()'s erroneously fail to handle
207 * overlapping regions, we'll do the shift by hand.
208 */
209 const int n = tp - colonp;
210 int i;
211
212 for (i = 1; i <= n; i++) {
213 endp[- i] = colonp[n - i];
214 colonp[n - i] = 0;
215 }
216 tp = endp;
217 }
218 if (tp != endp)
219 return (0);
220 memcpy(dst, tmp, IN6ADDRSZ);
221 return (1);
222}
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c
new file mode 100644
index 0000000000..cbd49f0c22
--- /dev/null
+++ b/src/lib/libc/net/ip6opt.c
@@ -0,0 +1,388 @@
1/* $OpenBSD: ip6opt.c,v 1.1 1999/12/11 08:09:11 itojun Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35
36#include <netinet/in.h>
37#include <netinet/ip6.h>
38
39#include <string.h>
40#include <stdio.h>
41
42static int ip6optlen(u_int8_t *opt, u_int8_t *lim);
43static void inet6_insert_padopt(u_char *p, int len);
44
45/*
46 * This function returns the number of bytes required to hold an option
47 * when it is stored as ancillary data, including the cmsghdr structure
48 * at the beginning, and any padding at the end (to make its size a
49 * multiple of 8 bytes). The argument is the size of the structure
50 * defining the option, which must include any pad bytes at the
51 * beginning (the value y in the alignment term "xn + y"), the type
52 * byte, the length byte, and the option data.
53 */
54int
55inet6_option_space(nbytes)
56 int nbytes;
57{
58 nbytes += 2; /* we need space for nxt-hdr and length fields */
59 return(CMSG_SPACE((nbytes + 7) & ~7));
60}
61
62/*
63 * This function is called once per ancillary data object that will
64 * contain either Hop-by-Hop or Destination options. It returns 0 on
65 * success or -1 on an error.
66 */
67int
68inet6_option_init(bp, cmsgp, type)
69 void *bp;
70 struct cmsghdr **cmsgp;
71 int type;
72{
73 register struct cmsghdr *ch = (struct cmsghdr *)bp;
74
75 /* argument validation */
76 if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
77 return(-1);
78
79 ch->cmsg_level = IPPROTO_IPV6;
80 ch->cmsg_type = type;
81 ch->cmsg_len = CMSG_LEN(0);
82
83 *cmsgp = ch;
84 return(0);
85}
86
87/*
88 * This function appends a Hop-by-Hop option or a Destination option
89 * into an ancillary data object that has been initialized by
90 * inet6_option_init(). This function returns 0 if it succeeds or -1 on
91 * an error.
92 * multx is the value x in the alignment term "xn + y" described
93 * earlier. It must have a value of 1, 2, 4, or 8.
94 * plusy is the value y in the alignment term "xn + y" described
95 * earlier. It must have a value between 0 and 7, inclusive.
96 */
97int
98inet6_option_append(cmsg, typep, multx, plusy)
99 struct cmsghdr *cmsg;
100 const u_int8_t *typep;
101 int multx;
102 int plusy;
103{
104 int padlen, optlen, off;
105 register u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
106 struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
107
108 /* argument validation */
109 if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
110 return(-1);
111 if (plusy < 0 || plusy > 7)
112 return(-1);
113 if (typep[0] > 255)
114 return(-1);
115
116 /*
117 * If this is the first option, allocate space for the
118 * first 2 bytes(for next header and length fields) of
119 * the option header.
120 */
121 if (bp == (u_char *)eh) {
122 bp += 2;
123 cmsg->cmsg_len += 2;
124 }
125
126 /* calculate pad length before the option. */
127 off = bp - (u_char *)eh;
128 padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
129 (off % multx);
130 padlen += plusy;
131 padlen %= multx; /* keep the pad as short as possible */
132 /* insert padding */
133 inet6_insert_padopt(bp, padlen);
134 cmsg->cmsg_len += padlen;
135 bp += padlen;
136
137 /* copy the option */
138 if (typep[0] == IP6OPT_PAD1)
139 optlen = 1;
140 else
141 optlen = typep[1] + 2;
142 memcpy(bp, typep, optlen);
143 bp += optlen;
144 cmsg->cmsg_len += optlen;
145
146 /* calculate pad length after the option and insert the padding */
147 off = bp - (u_char *)eh;
148 padlen = ((off + 7) & ~7) - off;
149 inet6_insert_padopt(bp, padlen);
150 bp += padlen;
151 cmsg->cmsg_len += padlen;
152
153 /* update the length field of the ip6 option header */
154 eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
155
156 return(0);
157}
158
159/*
160 * This function appends a Hop-by-Hop option or a Destination option
161 * into an ancillary data object that has been initialized by
162 * inet6_option_init(). This function returns a pointer to the 8-bit
163 * option type field that starts the option on success, or NULL on an
164 * error.
165 * The difference between this function and inet6_option_append() is
166 * that the latter copies the contents of a previously built option into
167 * the ancillary data object while the current function returns a
168 * pointer to the space in the data object where the option's TLV must
169 * then be built by the caller.
170 *
171 */
172u_int8_t *
173inet6_option_alloc(cmsg, datalen, multx, plusy)
174 struct cmsghdr *cmsg;
175 int datalen;
176 int multx;
177 int plusy;
178{
179 int padlen, off;
180 register u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
181 u_int8_t *retval;
182 struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
183
184 /* argument validation */
185 if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
186 return(NULL);
187 if (plusy < 0 || plusy > 7)
188 return(NULL);
189
190 /*
191 * If this is the first option, allocate space for the
192 * first 2 bytes(for next header and length fields) of
193 * the option header.
194 */
195 if (bp == (u_char *)eh) {
196 bp += 2;
197 cmsg->cmsg_len += 2;
198 }
199
200 /* calculate pad length before the option. */
201 off = bp - (u_char *)eh;
202 padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
203 (off % multx);
204 padlen += plusy;
205 padlen %= multx; /* keep the pad as short as possible */
206 /* insert padding */
207 inet6_insert_padopt(bp, padlen);
208 cmsg->cmsg_len += padlen;
209 bp += padlen;
210
211 /* keep space to store specified length of data */
212 retval = bp;
213 bp += datalen;
214 cmsg->cmsg_len += datalen;
215
216 /* calculate pad length after the option and insert the padding */
217 off = bp - (u_char *)eh;
218 padlen = ((off + 7) & ~7) - off;
219 inet6_insert_padopt(bp, padlen);
220 bp += padlen;
221 cmsg->cmsg_len += padlen;
222
223 /* update the length field of the ip6 option header */
224 eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
225
226 return(retval);
227}
228
229/*
230 * This function processes the next Hop-by-Hop option or Destination
231 * option in an ancillary data object. If another option remains to be
232 * processed, the return value of the function is 0 and *tptrp points to
233 * the 8-bit option type field (which is followed by the 8-bit option
234 * data length, followed by the option data). If no more options remain
235 * to be processed, the return value is -1 and *tptrp is NULL. If an
236 * error occurs, the return value is -1 and *tptrp is not NULL.
237 * (RFC 2292, 6.3.5)
238 */
239int
240inet6_option_next(cmsg, tptrp)
241 const struct cmsghdr *cmsg;
242 u_int8_t **tptrp;
243{
244 struct ip6_ext *ip6e;
245 int hdrlen, optlen;
246 u_int8_t *lim;
247
248 if (cmsg->cmsg_level != IPPROTO_IPV6 ||
249 (cmsg->cmsg_type != IPV6_HOPOPTS &&
250 cmsg->cmsg_type != IPV6_DSTOPTS))
251 return(-1);
252
253 /* message length validation */
254 if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
255 return(-1);
256 ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
257 hdrlen = (ip6e->ip6e_len + 1) << 3;
258 if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
259 return(-1);
260
261 /*
262 * If the caller does not specify the starting point,
263 * simply return the 1st option.
264 * Otherwise, search the option list for the next option.
265 */
266 lim = (u_int8_t *)ip6e + hdrlen;
267 if (*tptrp == NULL)
268 *tptrp = (u_int8_t *)(ip6e + 1);
269 else {
270 if ((optlen = ip6optlen(*tptrp, lim)) == 0)
271 return(-1);
272
273 *tptrp = *tptrp + optlen;
274 }
275 if (*tptrp >= lim) { /* there is no option */
276 *tptrp = NULL;
277 return(-1);
278 }
279 /*
280 * Finally, checks if the next option is safely stored in the
281 * cmsg data.
282 */
283 if (ip6optlen(*tptrp, lim) == 0)
284 return(-1);
285 else
286 return(0);
287}
288
289/*
290 * This function is similar to the inet6_option_next() function,
291 * except this function lets the caller specify the option type to be
292 * searched for, instead of always returning the next option in the
293 * ancillary data object.
294 * Note: RFC 2292 says the type of tptrp is u_int8_t *, but we think
295 * it's a typo. The variable should be type of u_int8_t **.
296 */
297int
298inet6_option_find(cmsg, tptrp, type)
299 const struct cmsghdr *cmsg;
300 u_int8_t **tptrp;
301 int type;
302{
303 struct ip6_ext *ip6e;
304 int hdrlen, optlen;
305 u_int8_t *optp, *lim;
306
307 if (cmsg->cmsg_level != IPPROTO_IPV6 ||
308 (cmsg->cmsg_type != IPV6_HOPOPTS &&
309 cmsg->cmsg_type != IPV6_DSTOPTS))
310 return(-1);
311
312 /* message length validation */
313 if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
314 return(-1);
315 ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
316 hdrlen = (ip6e->ip6e_len + 1) << 3;
317 if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
318 return(-1);
319
320 /*
321 * If the caller does not specify the starting point,
322 * search from the beginning of the option list.
323 * Otherwise, search from *the next option* of the specified point.
324 */
325 lim = (u_int8_t *)ip6e + hdrlen;
326 if (*tptrp == NULL)
327 *tptrp = (u_int8_t *)(ip6e + 1);
328 else {
329 if ((optlen = ip6optlen(*tptrp, lim)) == 0)
330 return(-1);
331
332 *tptrp = *tptrp + optlen;
333 }
334 for (optp = *tptrp; optp < lim; optp += optlen) {
335 if (*optp == type) {
336 *tptrp = optp;
337 return(0);
338 }
339 if ((optlen = ip6optlen(optp, lim)) == 0)
340 return(-1);
341 }
342
343 /* search failed */
344 *tptrp = NULL;
345 return(-1);
346}
347
348/*
349 * Calculate the length of a given IPv6 option. Also checks
350 * if the option is safely stored in user's buffer according to the
351 * calculated length and the limitation of the buffer.
352 */
353static int
354ip6optlen(opt, lim)
355 u_int8_t *opt, *lim;
356{
357 int optlen;
358
359 if (*opt == IP6OPT_PAD1)
360 optlen = 1;
361 else {
362 /* is there enough space to store type and len? */
363 if (opt + 2 > lim)
364 return(0);
365 optlen = *(opt + 1) + 2;
366 }
367 if (opt + optlen <= lim)
368 return(optlen);
369
370 return(0);
371}
372
373static void
374inet6_insert_padopt(u_char *p, int len)
375{
376 switch(len) {
377 case 0:
378 return;
379 case 1:
380 p[0] = IP6OPT_PAD1;
381 return;
382 default:
383 p[0] = IP6OPT_PADN;
384 p[1] = len - 2;
385 memset(&p[2], 0, len - 2);
386 return;
387 }
388}
diff --git a/src/lib/libc/net/ipx.3 b/src/lib/libc/net/ipx.3
new file mode 100644
index 0000000000..21c57a355d
--- /dev/null
+++ b/src/lib/libc/net/ipx.3
@@ -0,0 +1,127 @@
1.\" $OpenBSD: ipx.3,v 1.8 2001/08/02 20:37:35 hugh Exp $
2.\"
3.\" Copyright (c) 1986, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt IPX 3
36.Os
37.Sh NAME
38.Nm ipx_addr ,
39.Nm ipx_ntoa
40.Nd IPX address conversion routines
41.Sh SYNOPSIS
42.Fd #include <sys/types.h>
43.Fd #include <netipx/ipx.h>
44.Ft struct ipx_addr
45.Fn ipx_addr "const char *cp"
46.Ft char *
47.Fn ipx_ntoa "struct ipx_addr ipx"
48.Sh DESCRIPTION
49The routine
50.Fn ipx_addr
51interprets character strings representing
52.Tn IPX
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn ipx_ntoa
57takes
58.Tn IPX
59addresses and returns
60.Tn ASCII
61strings representing the address in a
62notation in common use:
63.Bd -filled -offset indent
64<network number>.<host number>.<port number>
65.Ed
66.Pp
67Trailing zero fields are suppressed, and each number is printed in hexadecimal,
68in a format suitable for input to
69.Fn ipx_addr .
70Any fields lacking super-decimal digits will have a
71trailing
72.Sq H
73appended.
74.Pp
75An effort has been made to ensure that
76.Fn ipx_addr
77be compatible with most formats in common use.
78It will first separate an address into 1 to 3 fields using a single delimiter
79chosen from
80period
81.Pq Ql \&. ,
82colon
83.Pq Ql \&: ,
84or pound-sign
85.Pq Ql # .
86Each field is then examined for byte separators (colon or period).
87If there are byte separators, each subfield separated is taken to be
88a small hexadecimal number, and the entirety is taken as a network-byte-ordered
89quantity to be zero extended in the high-network-order bytes.
90Next, the field is inspected for hyphens, in which case
91the field is assumed to be a number in decimal notation
92with hyphens separating the millenia.
93Next, the field is assumed to be a number:
94It is interpreted
95as hexadecimal if there is a leading
96.Ql 0x
97(as in C),
98a trailing
99.Sq H
100(as in Mesa), or there are any super-decimal digits present.
101It is interpreted as octal is there is a leading
102.Ql 0
103and there are no super-octal digits.
104Otherwise, it is converted as a decimal number.
105.Sh RETURN VALUES
106None.
107(See
108.Sx BUGS . )
109.Sh SEE ALSO
110.Xr ns 4 ,
111.Xr hosts 5 ,
112.Xr networks 5
113.Sh HISTORY
114The precursor
115.Fn ns_addr
116and
117.Fn ns_ntoa
118functions appeared in
119.Bx 4.3 .
120.Sh BUGS
121The string returned by
122.Fn ipx_ntoa
123resides in a static memory area.
124The function
125.Fn ipx_addr
126should diagnose improperly formed input, and there should be an unambiguous
127way to recognize this.
diff --git a/src/lib/libc/net/ipx_addr.c b/src/lib/libc/net/ipx_addr.c
new file mode 100644
index 0000000000..0d225e281b
--- /dev/null
+++ b/src/lib/libc/net/ipx_addr.c
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * J.Q. Johnson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from @(#)ipx_addr.c
37 */
38
39#if defined(LIBC_SCCS) && !defined(lint)
40static char rcsid[] = "$OpenBSD: ipx_addr.c,v 1.5 2001/06/27 00:58:55 lebel Exp $";
41#endif /* LIBC_SCCS and not lint */
42
43#include <sys/param.h>
44#include <netipx/ipx.h>
45#include <stdio.h>
46#include <string.h>
47
48static struct ipx_addr addr, zero_addr;
49
50static void Field(), cvtbase();
51
52struct ipx_addr
53ipx_addr(name)
54 const char *name;
55{
56 char separator;
57 char *hostname, *socketname, *cp;
58 char buf[50];
59
60 strlcpy(buf, name, sizeof(buf));
61
62 /*
63 * First, figure out what he intends as a field separtor.
64 * Despite the way this routine is written, the prefered
65 * form 2-272.AA001234H.01777, i.e. XDE standard.
66 * Great efforts are made to insure backward compatibility.
67 */
68 if ((hostname = strchr(buf, '#')))
69 separator = '#';
70 else {
71 hostname = strchr(buf, '.');
72 if ((cp = strchr(buf, ':')) &&
73 ((hostname && cp < hostname) || (hostname == 0))) {
74 hostname = cp;
75 separator = ':';
76 } else
77 separator = '.';
78 }
79 if (hostname)
80 *hostname++ = 0;
81
82 addr = zero_addr;
83 Field(buf, addr.ipx_net.c_net, 4);
84 if (hostname == 0)
85 return (addr); /* No separator means net only */
86
87 socketname = strchr(hostname, separator);
88 if (socketname) {
89 *socketname++ = 0;
90 Field(socketname, (u_char *)&addr.ipx_port, 2);
91 }
92
93 Field(hostname, addr.ipx_host.c_host, 6);
94
95 return (addr);
96}
97
98static void
99Field(buf, out, len)
100 char *buf;
101 u_char *out;
102 int len;
103{
104 register char *bp = buf;
105 int i, ibase, base16 = 0, base10 = 0, clen = 0;
106 int hb[6], *hp;
107 char *fmt;
108
109 /*
110 * first try 2-273#2-852-151-014#socket
111 */
112 if ((*buf != '-') &&
113 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
114 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
115 cvtbase(1000L, 256, hb, i, out, len);
116 return;
117 }
118 /*
119 * try form 8E1#0.0.AA.0.5E.E6#socket
120 */
121 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
122 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
123 cvtbase(256L, 256, hb, i, out, len);
124 return;
125 }
126 /*
127 * try form 8E1#0:0:AA:0:5E:E6#socket
128 */
129 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
130 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
131 cvtbase(256L, 256, hb, i, out, len);
132 return;
133 }
134 /*
135 * This is REALLY stretching it but there was a
136 * comma notation separting shorts -- definitely non standard
137 */
138 if (1 < (i = sscanf(buf,"%x,%x,%x",
139 &hb[0], &hb[1], &hb[2]))) {
140 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
141 hb[2] = htons(hb[2]);
142 cvtbase(65536L, 256, hb, i, out, len);
143 return;
144 }
145
146 /* Need to decide if base 10, 16 or 8 */
147 while (*bp) switch (*bp++) {
148
149 case '0': case '1': case '2': case '3': case '4': case '5':
150 case '6': case '7': case '-':
151 break;
152
153 case '8': case '9':
154 base10 = 1;
155 break;
156
157 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
158 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
159 base16 = 1;
160 break;
161
162 case 'x': case 'X':
163 *--bp = '0';
164 base16 = 1;
165 break;
166
167 case 'h': case 'H':
168 base16 = 1;
169 /* fall into */
170
171 default:
172 *--bp = 0; /* Ends Loop */
173 }
174 if (base16) {
175 fmt = "%3x";
176 ibase = 4096;
177 } else if (base10 == 0 && *buf == '0') {
178 fmt = "%3o";
179 ibase = 512;
180 } else {
181 fmt = "%3d";
182 ibase = 1000;
183 }
184
185 for (bp = buf; *bp++; ) clen++;
186 if (clen == 0) clen++;
187 if (clen > 18) clen = 18;
188 i = ((clen - 1) / 3) + 1;
189 bp = clen + buf - 3;
190 hp = hb + i - 1;
191
192 while (hp > hb) {
193 (void)sscanf(bp, fmt, hp);
194 bp[0] = 0;
195 hp--;
196 bp -= 3;
197 }
198 (void)sscanf(buf, fmt, hp);
199 cvtbase((long)ibase, 256, hb, i, out, len);
200}
201
202static void
203cvtbase(oldbase,newbase,input,inlen,result,reslen)
204 long oldbase;
205 int newbase;
206 int input[];
207 int inlen;
208 unsigned char result[];
209 int reslen;
210{
211 int d, e;
212 long sum;
213
214 e = 1;
215 while (e > 0 && reslen > 0) {
216 d = 0; e = 0; sum = 0;
217 /* long division: input=input/newbase */
218 while (d < inlen) {
219 sum = sum*oldbase + (long) input[d];
220 e += (sum > 0);
221 input[d++] = sum / newbase;
222 sum %= newbase;
223 }
224 result[--reslen] = sum; /* accumulate remainder */
225 }
226 for (d=0; d < reslen; d++)
227 result[d] = 0;
228}
diff --git a/src/lib/libc/net/ipx_ntoa.c b/src/lib/libc/net/ipx_ntoa.c
new file mode 100644
index 0000000000..598c94d599
--- /dev/null
+++ b/src/lib/libc/net/ipx_ntoa.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: ipx_ntoa.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netipx/ipx.h>
40#include <stdio.h>
41
42char *
43ipx_ntoa(addr)
44 struct ipx_addr addr;
45{
46 static char obuf[] = "xxxx.xx:xx:xx:xx:xx:xx.uuuuu";
47
48 snprintf(obuf, sizeof obuf, "%8xH.%02x:%02x:%02x:%02x:%02x:%02x.%u",
49 ntohl(addr.ipx_net.l_net),
50 addr.ipx_host.c_host[0],
51 addr.ipx_host.c_host[1],
52 addr.ipx_host.c_host[2],
53 addr.ipx_host.c_host[3],
54 addr.ipx_host.c_host[4],
55 addr.ipx_host.c_host[5],
56 ntohs(addr.ipx_port));
57 return (obuf);
58}
diff --git a/src/lib/libc/net/iso_addr.3 b/src/lib/libc/net/iso_addr.3
new file mode 100644
index 0000000000..8655a63973
--- /dev/null
+++ b/src/lib/libc/net/iso_addr.3
@@ -0,0 +1,111 @@
1.\" $OpenBSD: iso_addr.3,v 1.4 1999/07/05 06:08:05 aaron Exp $
2.\"
3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt ISO_ADDR 3
36.Os
37.Sh NAME
38.Nm iso_addr ,
39.Nm iso_ntoa
40.Nd "network address conversion routines for Open System Interconnection"
41.Sh SYNOPSIS
42.Fd #include <sys/types.h>
43.Fd #include <netiso/iso.h>
44.Ft struct iso_addr *
45.Fn iso_addr "char *cp"
46.Ft char *
47.Fn iso_ntoa "struct iso_addr *isoa"
48.Sh DESCRIPTION
49The routine
50.Fn iso_addr
51interprets character strings representing
52.Tn OSI
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn iso_ntoa
57takes
58.Tn OSI
59addresses and returns
60.Tn ASCII
61strings representing NSAPs (network service
62access points) in a
63notation inverse to that accepted by
64.Fn iso_addr .
65.Pp
66Unfortunately, no universal standard exists for representing
67.Tn OSI
68network addresses.
69.Pp
70The format employed by
71.Fn iso_addr
72is a sequence of hexadecimal
73.Dq digits
74(optionally separated by periods),
75of the form:
76.Bd -filled -offset indent
77<hex digits>.<hex digits>.<hex digits>
78.Ed
79.Pp
80Each pair of hexadecimal digits represents a byte
81with the leading digit indicating the higher-ordered bits.
82A period following an even number of bytes has no
83effect (but may be used to increase legibility).
84A period following an odd number of bytes has the
85effect of causing the byte of address being translated
86to have its higher order bits filled with zeros.
87.Sh RETURN VALUES
88.Fn iso_ntoa
89always returns a null terminated string.
90.Fn iso_addr
91always returns a pointer to a
92.Li struct iso_addr .
93(See
94.Sx BUGS . )
95.Sh SEE ALSO
96.Xr iso 4
97.Sh HISTORY
98The
99.Fn iso_addr
100and
101.Fn iso_ntoa
102functions appeared in
103.Bx 4.3 Reno .
104.Sh BUGS
105The returned values
106reside in a static memory area.
107.Pp
108The function
109.Fn iso_addr
110should diagnose improperly formed input, and there should be an unambiguous
111way to recognize this.
diff --git a/src/lib/libc/net/iso_addr.c b/src/lib/libc/net/iso_addr.c
new file mode 100644
index 0000000000..01561e395b
--- /dev/null
+++ b/src/lib/libc/net/iso_addr.c
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: iso_addr.c,v 1.2 1996/08/19 08:29:23 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <netiso/iso.h>
40#include <string.h>
41
42/* States*/
43#define VIRGIN 0
44#define GOTONE 1
45#define GOTTWO 2
46/* Inputs */
47#define DIGIT (4*0)
48#define END (4*1)
49#define DELIM (4*2)
50
51struct iso_addr *
52iso_addr(addr)
53 register const char *addr;
54{
55 static struct iso_addr out_addr;
56 register char *cp = out_addr.isoa_genaddr;
57 char *cplim = cp + sizeof(out_addr.isoa_genaddr);
58 register int byte = 0, state = VIRGIN, new;
59
60 bzero((char *)&out_addr, sizeof(out_addr));
61 do {
62 if ((*addr >= '0') && (*addr <= '9')) {
63 new = *addr - '0';
64 } else if ((*addr >= 'a') && (*addr <= 'f')) {
65 new = *addr - 'a' + 10;
66 } else if ((*addr >= 'A') && (*addr <= 'F')) {
67 new = *addr - 'A' + 10;
68 } else if (*addr == 0)
69 state |= END;
70 else
71 state |= DELIM;
72 addr++;
73 switch (state /* | INPUT */) {
74 case GOTTWO | DIGIT:
75 *cp++ = byte; /*FALLTHROUGH*/
76 case VIRGIN | DIGIT:
77 state = GOTONE; byte = new; continue;
78 case GOTONE | DIGIT:
79 state = GOTTWO; byte = new + (byte << 4); continue;
80 default: /* | DELIM */
81 state = VIRGIN; *cp++ = byte; byte = 0; continue;
82 case GOTONE | END:
83 case GOTTWO | END:
84 *cp++ = byte; /* FALLTHROUGH */
85 case VIRGIN | END:
86 break;
87 }
88 break;
89 } while (cp < cplim);
90 out_addr.isoa_len = cp - out_addr.isoa_genaddr;
91 return (&out_addr);
92}
93static char hexlist[] = "0123456789abcdef";
94
95char *
96iso_ntoa(isoa)
97 const struct iso_addr *isoa;
98{
99 static char obuf[64];
100 register char *out = obuf;
101 register int i;
102 register u_char *in = (u_char *)isoa->isoa_genaddr;
103 u_char *inlim = in + isoa->isoa_len;
104
105 out[1] = 0;
106 while (in < inlim) {
107 i = *in++;
108 *out++ = '.';
109 if (i > 0xf) {
110 out[1] = hexlist[i & 0xf];
111 i >>= 4;
112 out[0] = hexlist[i];
113 out += 2;
114 } else
115 *out++ = hexlist[i];
116 }
117 *out = 0;
118 return(obuf + 1);
119}
diff --git a/src/lib/libc/net/link_addr.3 b/src/lib/libc/net/link_addr.3
new file mode 100644
index 0000000000..29c2449f77
--- /dev/null
+++ b/src/lib/libc/net/link_addr.3
@@ -0,0 +1,131 @@
1.\" $OpenBSD: link_addr.3,v 1.7 2000/04/18 03:01:32 aaron Exp $
2.\"
3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Donn Seeley at BSDI.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.Dd July 28, 1993
38.Dt LINK_ADDR 3
39.Os
40.Sh NAME
41.Nm link_addr ,
42.Nm link_ntoa
43.Nd elementary address specification routines for link level access
44.Sh SYNOPSIS
45.Fd #include <sys/types.h>
46.Fd #include <sys/socket.h>
47.Fd #include <net/if_dl.h>
48.Ft void
49.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
50.Ft char *
51.Fn link_ntoa "const struct sockaddr_dl *sdl"
52.Sh DESCRIPTION
53The
54.Fn link_addr
55function interprets character strings representing
56link-level addresses, returning binary information suitable
57for use in system calls.
58.Fn link_ntoa
59takes
60a link-level
61address and returns an
62.Tn ASCII
63string representing some of the information present,
64including the link level address itself, and the interface name
65or number, if present.
66This facility is experimental and is
67still subject to change.
68.Pp
69For
70.Fn link_addr ,
71the string
72.Fa addr
73may contain
74an optional network interface identifier of the form
75.Dq name unit-number ,
76suitable for the first argument to
77.Xr ifconfig 8 ,
78followed in all cases by a colon and
79an interface address in the form of
80groups of hexadecimal digits
81separated by periods.
82Each group represents a byte of address;
83address bytes are filled left to right from
84low order bytes through high order bytes.
85.Pp
86.\" A regular expression may make this format clearer:
87.\" .Bd -literal -offset indent
88.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
89.\" .Ed
90.\" .Pp
91Thus
92.Li le0:8.0.9.13.d.30
93represents an Ethernet address
94to be transmitted on the first Lance Ethernet interface.
95.Sh RETURN VALUES
96.Fn link_ntoa
97always returns a null-terminated string.
98.Fn link_addr
99has no return value.
100(See
101.Sx BUGS . )
102.Sh SEE ALSO
103.Xr iso 4 ,
104.Xr ifconfig 8
105.Sh HISTORY
106The
107.Fn link_addr
108and
109.Fn link_ntoa
110functions appeared in
111.Bx 4.3 Reno .
112.Sh BUGS
113The returned values for link_ntoa
114reside in a static memory area.
115.Pp
116The function
117.Fn link_addr
118should diagnose improperly formed input, and there should be an unambiguous
119way to recognize this.
120.Pp
121If the
122.Fa sdl_len
123field of the link socket address
124.Fa sdl
125is 0,
126.Fn link_ntoa
127will not insert a colon before the interface address bytes.
128If this translated address is given to
129.Fn link_addr
130without inserting an initial colon,
131the latter will not interpret it correctly.
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c
new file mode 100644
index 0000000000..fb522f3233
--- /dev/null
+++ b/src/lib/libc/net/linkaddr.c
@@ -0,0 +1,158 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: linkaddr.c,v 1.2 1996/08/19 08:29:27 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40#include <net/if_dl.h>
41#include <string.h>
42
43/* States*/
44#define NAMING 0
45#define GOTONE 1
46#define GOTTWO 2
47#define RESET 3
48/* Inputs */
49#define DIGIT (4*0)
50#define END (4*1)
51#define DELIM (4*2)
52#define LETTER (4*3)
53
54void
55link_addr(addr, sdl)
56 register const char *addr;
57 register struct sockaddr_dl *sdl;
58{
59 register char *cp = sdl->sdl_data;
60 char *cplim = sdl->sdl_len + (char *)sdl;
61 register int byte = 0, state = NAMING, new;
62
63 bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
64 sdl->sdl_family = AF_LINK;
65 do {
66 state &= ~LETTER;
67 if ((*addr >= '0') && (*addr <= '9')) {
68 new = *addr - '0';
69 } else if ((*addr >= 'a') && (*addr <= 'f')) {
70 new = *addr - 'a' + 10;
71 } else if ((*addr >= 'A') && (*addr <= 'F')) {
72 new = *addr - 'A' + 10;
73 } else if (*addr == 0) {
74 state |= END;
75 } else if (state == NAMING &&
76 (((*addr >= 'A') && (*addr <= 'Z')) ||
77 ((*addr >= 'a') && (*addr <= 'z'))))
78 state |= LETTER;
79 else
80 state |= DELIM;
81 addr++;
82 switch (state /* | INPUT */) {
83 case NAMING | DIGIT:
84 case NAMING | LETTER:
85 *cp++ = addr[-1];
86 continue;
87 case NAMING | DELIM:
88 state = RESET;
89 sdl->sdl_nlen = cp - sdl->sdl_data;
90 continue;
91 case GOTTWO | DIGIT:
92 *cp++ = byte;
93 /* FALLTHROUGH */
94 case RESET | DIGIT:
95 state = GOTONE;
96 byte = new;
97 continue;
98 case GOTONE | DIGIT:
99 state = GOTTWO;
100 byte = new + (byte << 4);
101 continue;
102 default: /* | DELIM */
103 state = RESET;
104 *cp++ = byte;
105 byte = 0;
106 continue;
107 case GOTONE | END:
108 case GOTTWO | END:
109 *cp++ = byte;
110 /* FALLTHROUGH */
111 case RESET | END:
112 break;
113 }
114 break;
115 } while (cp < cplim);
116 sdl->sdl_alen = cp - LLADDR(sdl);
117 new = cp - (char *)sdl;
118 if (new > sizeof(*sdl))
119 sdl->sdl_len = new;
120 return;
121}
122
123static char hexlist[] = "0123456789abcdef";
124
125char *
126link_ntoa(sdl)
127 register const struct sockaddr_dl *sdl;
128{
129 static char obuf[64];
130 register char *out = obuf;
131 register int i;
132 register u_char *in = (u_char *)LLADDR(sdl);
133 u_char *inlim = in + sdl->sdl_alen;
134 int firsttime = 1;
135
136 if (sdl->sdl_nlen) {
137 bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
138 out += sdl->sdl_nlen;
139 if (sdl->sdl_alen)
140 *out++ = ':';
141 }
142 while (in < inlim) {
143 if (firsttime)
144 firsttime = 0;
145 else
146 *out++ = '.';
147 i = *in++;
148 if (i > 0xf) {
149 out[1] = hexlist[i & 0xf];
150 i >>= 4;
151 out[0] = hexlist[i];
152 out += 2;
153 } else
154 *out++ = hexlist[i];
155 }
156 *out = 0;
157 return (obuf);
158}
diff --git a/src/lib/libc/net/net_addrcmp.3 b/src/lib/libc/net/net_addrcmp.3
new file mode 100644
index 0000000000..f1ce4c8cd1
--- /dev/null
+++ b/src/lib/libc/net/net_addrcmp.3
@@ -0,0 +1,91 @@
1.\" $OpenBSD: net_addrcmp.3,v 1.3 2001/08/07 06:53:27 deraadt Exp $
2.\"
3.\" Copyright (c) 1999 Theo de Raadt
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\"
14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\"
25.Dd July 3, 1999
26.Dt NET_ADDRCMP 3
27.Os
28.Sh NAME
29.Nm net_addrcmp
30.Nd compare socket address structures
31.Sh SYNOPSIS
32.Fd #include <netdb.h>
33.Ft int
34.Fn net_addrcmp "struct sockaddr *sa1" "struct sockaddr *sa2"
35.Sh DESCRIPTION
36The
37.Fn net_addrcmp
38function compares two socket address structures,
39.Fa sa1
40and
41.Fa sa2 .
42.Sh RETURN VALUES
43If
44.Fa sa1
45and
46.Fa sa2
47are for the same address,
48.Fn net_addrcmp
49returns 0.
50.Pp
51The
52.Fa sa_len
53fields are compared first.
54If they do not match,
55.Fn net_addrcmp
56returns \-1 or 1 if
57.Li sa1->sa_len
58is less than or greater than
59.Li sa2->sa_len ,
60respectively.
61.Pp
62Next, the
63.Fa sa_family
64members are compared.
65If they do not match,
66.Fn net_addrcmp
67returns \-1 or 1 if
68.Li sa1->sa_family
69is less than or greater than
70.Li sa2->sa_family ,
71respectively.
72.Pp
73Lastly, if each socket address structure's
74.Fa sa_len
75and
76.Fa sa_family
77fields match,
78the protocol-specific data (the
79.Fa sa_data
80field) is compared.
81If there's a match, both
82.Fa sa1
83and
84.Fa sa2
85must refer to the same address, and 0 is returned; otherwise, a value >0
86or <0 is returned.
87.Sh HISTORY
88A
89.Fn net_addrcmp
90function was added in
91.Ox 2.5 .
diff --git a/src/lib/libc/net/net_addrcmp.c b/src/lib/libc/net/net_addrcmp.c
new file mode 100644
index 0000000000..c77a2fda48
--- /dev/null
+++ b/src/lib/libc/net/net_addrcmp.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 1999 Theo de Raadt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <sys/un.h>
29#include <netinet/in.h>
30#include <netns/ns.h>
31#include <string.h>
32
33int
34net_addrcmp(sa1, sa2)
35 struct sockaddr *sa1;
36 struct sockaddr *sa2;
37{
38
39 if (sa1->sa_len != sa2->sa_len)
40 return (sa1->sa_len < sa2->sa_len) ? -1 : 1;
41 if (sa1->sa_family != sa2->sa_family)
42 return (sa1->sa_family < sa2->sa_family) ? -1 : 1;
43
44 switch(sa1->sa_family) {
45 case AF_INET:
46 return (memcmp(&((struct sockaddr_in *)sa1)->sin_addr,
47 &((struct sockaddr_in *)sa2)->sin_addr,
48 sizeof(struct in_addr)));
49 case AF_INET6:
50 if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
51 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
52 return (((struct sockaddr_in6 *)sa1)->sin6_scope_id <
53 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
54 ? -1 : 1;
55 return memcmp(&((struct sockaddr_in6 *)sa1)->sin6_addr,
56 &((struct sockaddr_in6 *)sa2)->sin6_addr,
57 sizeof(struct in6_addr));
58 case AF_NS:
59 return (memcmp(&((struct sockaddr_ns *)sa1)->sns_addr,
60 &((struct sockaddr_ns *)sa2)->sns_addr,
61 sizeof(struct ns_addr)));
62 case AF_LOCAL:
63 return (strcmp(((struct sockaddr_un *)sa1)->sun_path,
64 ((struct sockaddr_un *)sa1)->sun_path));
65 default:
66 return -1;
67 }
68}
diff --git a/src/lib/libc/net/ns.3 b/src/lib/libc/net/ns.3
new file mode 100644
index 0000000000..14e234c347
--- /dev/null
+++ b/src/lib/libc/net/ns.3
@@ -0,0 +1,131 @@
1.\" $OpenBSD: ns.3,v 1.7 2001/08/02 20:37:35 hugh Exp $
2.\"
3.\" Copyright (c) 1986, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt NS 3
36.Os
37.Sh NAME
38.Nm ns_addr ,
39.Nm ns_ntoa
40.Nd Xerox
41.Tn NS Ns (tm)
42address conversion routines
43.Sh SYNOPSIS
44.Fd #include <sys/types.h>
45.Fd #include <netns/ns.h>
46.Ft struct ns_addr
47.Fn ns_addr "char *cp"
48.Ft char *
49.Fn ns_ntoa "struct ns_addr ns"
50.Sh DESCRIPTION
51The routine
52.Fn ns_addr
53interprets character strings representing
54.Tn XNS
55addresses, returning binary information suitable
56for use in system calls.
57The routine
58.Fn ns_ntoa
59takes
60.Tn XNS
61addresses and returns
62.Tn ASCII
63strings representing the address in a
64notation in common use in the Xerox Development Environment:
65.Bd -filled -offset indent
66<network number>.<host number>.<port number>
67.Ed
68.Pp
69Trailing zero fields are suppressed, and each number is printed in hexadecimal,
70in a format suitable for input to
71.Fn ns_addr .
72Any fields lacking super-decimal digits will have a
73trailing
74.Sq H
75appended.
76.Pp
77Unfortunately, no universal standard exists for representing
78.Tn XNS
79addresses.
80An effort has been made to ensure that
81.Fn ns_addr
82be compatible with most formats in common use.
83It will first separate an address into 1 to 3 fields using a single delimiter
84chosen from
85period
86.Pq Ql \&. ,
87colon
88.Pq Ql \&: ,
89or pound-sign
90.Ql # .
91Each field is then examined for byte separators (colon or period).
92If there are byte separators, each subfield separated is taken to be
93a small hexadecimal number, and the entirety is taken as a network-byte-ordered
94quantity to be zero extended in the high-network-order bytes.
95Next, the field is inspected for hyphens, in which case
96the field is assumed to be a number in decimal notation
97with hyphens separating the millenia.
98Next, the field is assumed to be a number:
99It is interpreted
100as hexadecimal if there is a leading
101.Ql 0x
102(as in C),
103a trailing
104.Sq H
105(as in Mesa), or there are any super-decimal digits present.
106It is interpreted as octal is there is a leading
107.Ql 0
108and there are no super-octal digits.
109Otherwise, it is converted as a decimal number.
110.Sh RETURN VALUES
111None.
112(See
113.Sx BUGS . )
114.Sh SEE ALSO
115.Xr hosts 5 ,
116.Xr networks 5
117.Sh HISTORY
118The
119.Fn ns_addr
120and
121.Fn ns_toa
122functions appeared in
123.Bx 4.3 .
124.Sh BUGS
125The string returned by
126.Fn ns_ntoa
127resides in a static memory area.
128The function
129.Fn ns_addr
130should diagnose improperly formed input, and there should be an unambiguous
131way to recognize this.
diff --git a/src/lib/libc/net/ns_addr.c b/src/lib/libc/net/ns_addr.c
new file mode 100644
index 0000000000..0d1b45858f
--- /dev/null
+++ b/src/lib/libc/net/ns_addr.c
@@ -0,0 +1,227 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * J.Q. Johnson.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char rcsid[] = "$OpenBSD: ns_addr.c,v 1.7 2002/02/16 21:27:23 millert Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/param.h>
42#include <netns/ns.h>
43#include <stdio.h>
44#include <string.h>
45
46static struct ns_addr addr, zero_addr;
47
48static void Field(char *, u_int8_t *, int);
49static void cvtbase(long, int, int[], int, u_int8_t[], int);
50
51struct ns_addr
52ns_addr(name)
53 const char *name;
54{
55 char separator;
56 char *hostname, *socketname, *cp;
57 char buf[50];
58
59 strlcpy(buf, name, sizeof(buf));
60
61 /*
62 * First, figure out what he intends as a field separtor.
63 * Despite the way this routine is written, the prefered
64 * form 2-272.AA001234H.01777, i.e. XDE standard.
65 * Great efforts are made to insure backward compatibility.
66 */
67 if ((hostname = strchr(buf, '#')))
68 separator = '#';
69 else {
70 hostname = strchr(buf, '.');
71 if ((cp = strchr(buf, ':')) &&
72 ((hostname && cp < hostname) || (hostname == 0))) {
73 hostname = cp;
74 separator = ':';
75 } else
76 separator = '.';
77 }
78 if (hostname)
79 *hostname++ = 0;
80
81 addr = zero_addr;
82 Field(buf, addr.x_net.c_net, 4);
83 if (hostname == 0)
84 return (addr); /* No separator means net only */
85
86 socketname = strchr(hostname, separator);
87 if (socketname) {
88 *socketname++ = 0;
89 Field(socketname, (u_char *)&addr.x_port, 2);
90 }
91
92 Field(hostname, (u_char *)addr.x_host.c_host, 6);
93
94 return (addr);
95}
96
97static void
98Field(buf, out, len)
99 char *buf;
100 u_char *out;
101 int len;
102{
103 register char *bp = buf;
104 int i, ibase, base16 = 0, base10 = 0, clen = 0;
105 int hb[6], *hp;
106 char *fmt;
107
108 /*
109 * first try 2-273#2-852-151-014#socket
110 */
111 if ((*buf != '-') &&
112 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
113 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
114 cvtbase(1000L, 256, hb, i, out, len);
115 return;
116 }
117 /*
118 * try form 8E1#0.0.AA.0.5E.E6#socket
119 */
120 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
121 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
122 cvtbase(256L, 256, hb, i, out, len);
123 return;
124 }
125 /*
126 * try form 8E1#0:0:AA:0:5E:E6#socket
127 */
128 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
129 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
130 cvtbase(256L, 256, hb, i, out, len);
131 return;
132 }
133 /*
134 * This is REALLY stretching it but there was a
135 * comma notation separting shorts -- definitely non standard
136 */
137 if (1 < (i = sscanf(buf,"%x,%x,%x",
138 &hb[0], &hb[1], &hb[2]))) {
139 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
140 hb[2] = htons(hb[2]);
141 cvtbase(65536L, 256, hb, i, out, len);
142 return;
143 }
144
145 /* Need to decide if base 10, 16 or 8 */
146 while (*bp) switch (*bp++) {
147
148 case '0': case '1': case '2': case '3': case '4': case '5':
149 case '6': case '7': case '-':
150 break;
151
152 case '8': case '9':
153 base10 = 1;
154 break;
155
156 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
157 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
158 base16 = 1;
159 break;
160
161 case 'x': case 'X':
162 *--bp = '0';
163 base16 = 1;
164 break;
165
166 case 'h': case 'H':
167 base16 = 1;
168 /* fall into */
169
170 default:
171 *--bp = 0; /* Ends Loop */
172 }
173 if (base16) {
174 fmt = "%3x";
175 ibase = 4096;
176 } else if (base10 == 0 && *buf == '0') {
177 fmt = "%3o";
178 ibase = 512;
179 } else {
180 fmt = "%3d";
181 ibase = 1000;
182 }
183
184 for (bp = buf; *bp++; ) clen++;
185 if (clen == 0) clen++;
186 if (clen > 18) clen = 18;
187 i = ((clen - 1) / 3) + 1;
188 bp = clen + buf - 3;
189 hp = hb + i - 1;
190
191 while (hp > hb) {
192 (void)sscanf(bp, fmt, hp);
193 bp[0] = 0;
194 hp--;
195 bp -= 3;
196 }
197 (void)sscanf(buf, fmt, hp);
198 cvtbase((long)ibase, 256, hb, i, out, len);
199}
200
201static void
202cvtbase(oldbase,newbase,input,inlen,result,reslen)
203 long oldbase;
204 int newbase;
205 int input[];
206 int inlen;
207 unsigned char result[];
208 int reslen;
209{
210 int d, e;
211 long sum;
212
213 e = 1;
214 while (e > 0 && reslen > 0) {
215 d = 0; e = 0; sum = 0;
216 /* long division: input=input/newbase */
217 while (d < inlen) {
218 sum = sum*oldbase + (long) input[d];
219 e += (sum > 0);
220 input[d++] = sum / newbase;
221 sum %= newbase;
222 }
223 result[--reslen] = sum; /* accumulate remainder */
224 }
225 for (d=0; d < reslen; d++)
226 result[d] = 0;
227}
diff --git a/src/lib/libc/net/ns_ntoa.c b/src/lib/libc/net/ns_ntoa.c
new file mode 100644
index 0000000000..5ff410e28a
--- /dev/null
+++ b/src/lib/libc/net/ns_ntoa.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: ns_ntoa.c,v 1.10 2002/07/25 21:12:47 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netns/ns.h>
40#include <stdio.h>
41
42static char *spectHex(char *);
43
44char *
45ns_ntoa(struct ns_addr addr)
46{
47 static char obuf[40];
48 union { union ns_net net_e; u_int32_t long_e; } net;
49 in_port_t port = htons(addr.x_port);
50 char *cp, *cp2;
51 u_char *up = addr.x_host.c_host;
52 u_char *uplim = up + 6;
53
54 net.net_e = addr.x_net;
55 snprintf(obuf, sizeof obuf, "%x", ntohl(net.long_e));
56 cp = spectHex(obuf);
57 cp2 = cp + 1;
58 while (*up==0 && up < uplim)
59 up++;
60 if (up == uplim) {
61 if (port) {
62 sprintf(cp, ".0");
63 cp += 2;
64 }
65 } else {
66 sprintf(cp, ".%x", *up++);
67 while (up < uplim) {
68 while (*cp)
69 cp++;
70 sprintf(cp, "%02x", *up++);
71 }
72 cp = spectHex(cp2);
73 }
74 if (port) {
75 sprintf(cp, ".%x", port);
76 spectHex(cp + 1);
77 }
78 return (obuf);
79}
80
81static char *
82spectHex(char *p0)
83{
84 int ok = 0, nonzero = 0;
85 char *p = p0;
86
87 for (; *p; p++) {
88 switch (*p) {
89 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
90 *p += ('A' - 'a');
91 /* fall into . . . */
92 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
93 ok = 1;
94 case '1': case '2': case '3': case '4': case '5':
95 case '6': case '7': case '8': case '9':
96 nonzero = 1;
97 }
98 }
99 if (nonzero && !ok) {
100 *p++ = 'H';
101 *p = 0;
102 }
103 return (p);
104}
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c
new file mode 100644
index 0000000000..22a5f8d66e
--- /dev/null
+++ b/src/lib/libc/net/nsap_addr.c
@@ -0,0 +1,109 @@
1/* $OpenBSD: nsap_addr.c,v 1.4 1997/07/09 01:08:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
23#else
24static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.4 1997/07/09 01:08:45 millert Exp $";
25#endif
26#endif /* LIBC_SCCS and not lint */
27
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/nameser.h>
33#include <ctype.h>
34#include <resolv.h>
35
36static char
37xtob(c)
38 register int c;
39{
40 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
41}
42
43u_int
44inet_nsap_addr(ascii, binary, maxlen)
45 const char *ascii;
46 u_char *binary;
47 int maxlen;
48{
49 register u_char c, nib;
50 u_int len = 0;
51
52 while ((c = *ascii++) != '\0' && len < maxlen) {
53 if (c == '.' || c == '+' || c == '/')
54 continue;
55 if (!isascii(c))
56 return (0);
57 if (islower(c))
58 c = toupper(c);
59 if (isxdigit(c)) {
60 nib = xtob(c);
61 if ((c = *ascii++)) {
62 c = toupper(c);
63 if (isxdigit(c)) {
64 *binary++ = (nib << 4) | xtob(c);
65 len++;
66 } else
67 return (0);
68 }
69 else
70 return (0);
71 }
72 else
73 return (0);
74 }
75 return (len);
76}
77
78char *
79inet_nsap_ntoa(binlen, binary, ascii)
80 int binlen;
81 register const u_char *binary;
82 register char *ascii;
83{
84 register int nib;
85 int i;
86 static char tmpbuf[255*3];
87 char *start;
88
89 if (ascii)
90 start = ascii;
91 else {
92 ascii = tmpbuf;
93 start = tmpbuf;
94 }
95
96 if (binlen > 255)
97 binlen = 255;
98
99 for (i = 0; i < binlen; i++) {
100 nib = *binary >> 4;
101 *ascii++ = nib + (nib < 10 ? '0' : '7');
102 nib = *binary++ & 0x0f;
103 *ascii++ = nib + (nib < 10 ? '0' : '7');
104 if (((i % 2) == 0 && (i + 1) < binlen))
105 *ascii++ = '.';
106 }
107 *ascii = '\0';
108 return (start);
109}
diff --git a/src/lib/libc/net/ntohl.c b/src/lib/libc/net/ntohl.c
new file mode 100644
index 0000000000..7d3e227e60
--- /dev/null
+++ b/src/lib/libc/net/ntohl.c
@@ -0,0 +1,25 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: ntohl.c,v 1.4 1996/12/12 03:19:56 tholo Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef ntohl
14
15u_int32_t
16ntohl(x)
17 u_int32_t x;
18{
19#if BYTE_ORDER == LITTLE_ENDIAN
20 u_char *s = (u_char *)&x;
21 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
22#else
23 return x;
24#endif
25}
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c
new file mode 100644
index 0000000000..4c3ab33f31
--- /dev/null
+++ b/src/lib/libc/net/ntohs.c
@@ -0,0 +1,24 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: ntohs.c,v 1.7 2002/02/19 19:39:36 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <sys/types.h>
11#include <machine/endian.h>
12
13#undef ntohs
14
15u_int16_t
16ntohs(u_int16_t x)
17{
18#if BYTE_ORDER == LITTLE_ENDIAN
19 u_char *s = (u_char *) &x;
20 return (u_int16_t)(s[0] << 8 | s[1]);
21#else
22 return x;
23#endif
24}
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3
new file mode 100644
index 0000000000..7cf5af9519
--- /dev/null
+++ b/src/lib/libc/net/rcmd.3
@@ -0,0 +1,270 @@
1.\" $OpenBSD: rcmd.3,v 1.24 2002/05/06 23:34:33 millert Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt RCMD 3
36.Os
37.Sh NAME
38.Nm rcmd ,
39.Nm rcmd_af ,
40.Nm rresvport ,
41.Nm rresvport_af ,
42.Nm iruserok ,
43.Nm ruserok ,
44.Nm iruserok_sa
45.Nd routines for returning a stream to a remote command
46.Sh SYNOPSIS
47.Fd #include <unistd.h>
48.Ft int
49.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
50.Ft int
51.Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af"
52.Ft int
53.Fn rresvport "int *port"
54.Ft int
55.Fn rresvport_af "int *port" "int af"
56.Ft int
57.Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser"
58.Ft int
59.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
60.Ft int
61.Fn iruserok_sa "const void *sa" "int salen" "int superuser" "const char *ruser"
62.Sh DESCRIPTION
63The
64.Fn rcmd
65function is used by the superuser to execute a command on a remote
66machine using an authentication scheme based on reserved
67port numbers.
68If the calling process is not setuid, the
69.Ev RSH
70environment variable is set, and
71.Fa inport
72is
73.Dq shell/tcp ,
74.Xr rcmdsh 3
75is called instead with the value of
76.Ev RSH .
77Alternately, if the user is not the superuser,
78.Fn rcmd
79will invoke
80.Xr rcmdsh 3
81to run the command via
82.Xr rsh 1 .
83While
84.Fn rcmd
85can handle IPv4 cases only,
86the
87.Fn rcmd_af
88function can handle other cases as well.
89.Pp
90The
91.Fn rresvport
92and
93.Fn rresvport_af
94functions return a descriptor to a socket
95with an address in the privileged port space.
96The
97.Fn iruserok
98and
99.Fn ruserok
100functions are used by servers
101to authenticate clients requesting service with
102.Fn rcmd .
103All four functions are present in the same file and are used
104by the
105.Xr rshd 8
106server (among others).
107.Fn iruserok_sa
108is an address family independent variant of
109.Fn iruserok .
110.Pp
111The
112.Fn rcmd
113function looks up the host
114.Fa *ahost
115using
116.Xr gethostbyname 3 ,
117returning \-1 if the host does not exist.
118Otherwise
119.Fa *ahost
120is set to the standard name of the host
121and a connection is established to a server
122residing at the well-known Internet port
123.Fa inport .
124If the user is not the superuser, the only valid port is
125.Dq shell/tcp
126(usually port 514).
127.Pp
128If the connection succeeds,
129a socket in the Internet domain of type
130.Dv SOCK_STREAM
131is returned to the caller, and given to the remote
132command as stdin and stdout.
133If
134.Fa fd2p
135is non-zero, then an auxiliary channel to a control
136process will be set up, and a descriptor for it will be placed
137in
138.Fa *fd2p .
139The control process will return diagnostic
140output from the command (unit 2) on this channel, and will also
141accept bytes on this channel as being
142.Tn UNIX
143signal numbers, to be
144forwarded to the process group of the command.
145If
146.Fa fd2p
147is
148.Va NULL ,
149then the standard error (unit 2 of the remote command) will be made
150the same as the standard output and no provision is made for sending
151arbitrary signals to the remote process, although you may be able to
152get its attention by using out-of-band data.
153Note that if the user is not the superuser,
154.Fa fd2p
155must be
156.Va NULL .
157.Pp
158.Fn rcmd_af
159takes address family in the last argument.
160If the last argument is
161.Dv PF_UNSPEC ,
162interpretation of
163.Fa *ahost
164will obey the underlying address resolution like DNS.
165.Pp
166The protocol is described in detail in
167.Xr rshd 8 .
168.Pp
169The
170.Fn rresvport
171and
172.Fn rresvport_af
173functions are used to obtain a socket with a privileged
174address bound to it.
175This socket is suitable for use by
176.Fn rcmd
177and several other functions.
178Privileged Internet ports are those in the range 0 to
179.Va IPPORT_RESERVED - 1 ,
180which happens to be 1023.
181Only the superuser is allowed to bind an address of this sort to a socket.
182.Fn rresvport
183and
184.Fn rresvport_af
185need to be seeded with a port number; if that port
186is not available these functions will find another.
187.Pp
188The
189.Fn iruserok
190and
191.Fn ruserok
192functions take a remote host's IP address or name, respectively,
193two user names and a flag indicating whether the local user's
194name is that of the superuser.
195Then, if the user is
196.Em not
197the superuser, it checks the
198.Pa /etc/hosts.equiv
199file.
200If that lookup is not done, or is unsuccessful, the
201.Pa .rhosts
202in the local user's home directory is checked to see if the request for
203service is allowed.
204.Pp
205If this file does not exist, is not a regular file, is owned by anyone
206other than the user or the superuser, or is writeable by anyone other
207than the owner, the check automatically fails.
208Zero is returned if the machine name is listed in the
209.Pa hosts.equiv
210file, or the host and remote user name are found in the
211.Pa .rhosts
212file; otherwise
213.Fn iruserok
214and
215.Fn ruserok
216return \-1.
217If the local domain (as obtained from
218.Xr gethostname 3 )
219is the same as the remote domain, only the machine name need be specified.
220.Pp
221If the IP address of the remote host is known,
222.Fn iruserok
223should be used in preference to
224.Fn ruserok ,
225as it does not require trusting the DNS server for the remote host's domain.
226.Pp
227While
228.Fn iruserok
229can handle IPv4 addresses only,
230.Fn iruserok_sa
231and
232.Fn ruserok
233can handle other address families as well, like IPv6.
234The first argument of
235.Fn iruserok_sa
236is typed as
237.Li "void *"
238to avoid dependency between
239.Aq Pa unistd.h
240and
241.Aq Pa sys/socket.h .
242.Sh DIAGNOSTICS
243The
244.Fn rcmd
245function returns a valid socket descriptor on success.
246It returns \-1 on error and prints a diagnostic message on the standard error.
247.Pp
248The
249.Fn rresvport
250and
251.Fn rresvport_af
252functions return a valid, bound socket descriptor on success.
253It returns \-1 on error with the global value
254.Va errno
255set according to the reason for failure.
256The error code
257.Er EAGAIN
258is overloaded to mean
259.Dq all network ports in use .
260.Sh SEE ALSO
261.Xr rsh 1 ,
262.Xr intro 2 ,
263.Xr bindresvport 3 ,
264.Xr bindresvport_sa 3 ,
265.Xr rcmdsh 3 ,
266.Xr rshd 8
267.Sh HISTORY
268These
269functions appeared in
270.Bx 4.2 .
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c
new file mode 100644
index 0000000000..be68c599d8
--- /dev/null
+++ b/src/lib/libc/net/rcmd.c
@@ -0,0 +1,733 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * This product includes software developed by Theo de Raadt.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: rcmd.c,v 1.43 2002/05/24 21:22:37 deraadt Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/param.h>
41#include <sys/socket.h>
42#include <sys/stat.h>
43
44#include <netinet/in.h>
45#include <arpa/inet.h>
46
47#include <signal.h>
48#include <fcntl.h>
49#include <netdb.h>
50#include <unistd.h>
51#include <pwd.h>
52#include <errno.h>
53#include <stdio.h>
54#include <ctype.h>
55#include <string.h>
56#include <syslog.h>
57#include <stdlib.h>
58#include <netgroup.h>
59
60int __ivaliduser(FILE *, in_addr_t, const char *, const char *);
61int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t,
62 const char *, const char *);
63static int __icheckhost(struct sockaddr *, socklen_t, const char *);
64static char *__gethostloop(struct sockaddr *, socklen_t);
65
66int
67rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
68 char **ahost;
69 in_port_t rport;
70 const char *locuser, *remuser, *cmd;
71 int *fd2p;
72{
73 return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET);
74}
75
76int
77rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af)
78 char **ahost;
79 in_port_t rport;
80 const char *locuser, *remuser, *cmd;
81 int *fd2p;
82 int af;
83{
84 static char hbuf[MAXHOSTNAMELEN];
85 char pbuf[NI_MAXSERV];
86 struct addrinfo hints, *res, *r;
87 int error;
88 struct sockaddr_storage from;
89 fd_set *readsp = NULL;
90 sigset_t oldmask, mask;
91 pid_t pid;
92 int s, lport, timo;
93 char c, *p;
94 int refused;
95
96 /* call rcmdsh() with specified remote shell if appropriate. */
97 if (!issetugid() && (p = getenv("RSH")) && *p) {
98 struct servent *sp = getservbyname("shell", "tcp");
99
100 if (sp && sp->s_port == rport)
101 return (rcmdsh(ahost, rport, locuser, remuser,
102 cmd, p));
103 }
104
105 /* use rsh(1) if non-root and remote port is shell. */
106 if (geteuid()) {
107 struct servent *sp = getservbyname("shell", "tcp");
108
109 if (sp && sp->s_port == rport)
110 return (rcmdsh(ahost, rport, locuser, remuser,
111 cmd, NULL));
112 }
113
114 pid = getpid();
115 snprintf(pbuf, sizeof(pbuf), "%u", ntohs(rport));
116 memset(&hints, 0, sizeof(hints));
117 hints.ai_family = af;
118 hints.ai_socktype = SOCK_STREAM;
119 hints.ai_flags = AI_CANONNAME;
120 error = getaddrinfo(*ahost, pbuf, &hints, &res);
121 if (error) {
122#if 0
123 warnx("%s: %s", *ahost, gai_strerror(error));
124#endif
125 return (-1);
126 }
127 if (res->ai_canonname) {
128 strlcpy(hbuf, res->ai_canonname, sizeof(hbuf));
129 *ahost = hbuf;
130 } else
131 ; /*XXX*/
132
133 r = res;
134 refused = 0;
135 sigemptyset(&mask);
136 sigaddset(&mask, SIGURG);
137 oldmask = sigprocmask(SIG_BLOCK, &mask, &oldmask);
138 for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
139 s = rresvport_af(&lport, r->ai_family);
140 if (s < 0) {
141 if (errno == EAGAIN)
142 (void)fprintf(stderr,
143 "rcmd: socket: All ports in use\n");
144 else
145 (void)fprintf(stderr, "rcmd: socket: %s\n",
146 strerror(errno));
147 if (r->ai_next) {
148 r = r->ai_next;
149 continue;
150 } else {
151 sigprocmask(SIG_SETMASK, &oldmask, NULL);
152 freeaddrinfo(res);
153 return (-1);
154 }
155 }
156 fcntl(s, F_SETOWN, pid);
157 if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
158 break;
159 (void)close(s);
160 if (errno == EADDRINUSE) {
161 lport--;
162 continue;
163 }
164 if (errno == ECONNREFUSED)
165 refused++;
166 if (r->ai_next) {
167 int oerrno = errno;
168 char hbuf[NI_MAXHOST];
169#ifdef NI_WITHSCOPEID
170 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
171#else
172 const int niflags = NI_NUMERICHOST;
173#endif
174
175 hbuf[0] = '\0';
176 if (getnameinfo(r->ai_addr, r->ai_addrlen,
177 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
178 strlcpy(hbuf, "(invalid)", sizeof hbuf);
179 (void)fprintf(stderr, "connect to address %s: ", hbuf);
180 errno = oerrno;
181 perror(0);
182 r = r->ai_next;
183 hbuf[0] = '\0';
184 if (getnameinfo(r->ai_addr, r->ai_addrlen,
185 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
186 strlcpy(hbuf, "(invalid)", sizeof hbuf);
187 (void)fprintf(stderr, "Trying %s...\n", hbuf);
188 continue;
189 }
190 if (refused && timo <= 16) {
191 (void)sleep(timo);
192 timo *= 2;
193 r = res;
194 refused = 0;
195 continue;
196 }
197 (void)fprintf(stderr, "%s: %s\n", res->ai_canonname,
198 strerror(errno));
199 sigprocmask(SIG_SETMASK, &oldmask, NULL);
200 freeaddrinfo(res);
201 return (-1);
202 }
203 /* given "af" can be PF_UNSPEC, we need the real af for "s" */
204 af = r->ai_family;
205 freeaddrinfo(res);
206#if 0
207 /*
208 * try to rresvport() to the same port. This will make rresvport()
209 * fail it's first bind, resulting in it choosing a random port.
210 */
211 lport--;
212#endif
213 if (fd2p == 0) {
214 write(s, "", 1);
215 lport = 0;
216 } else {
217 char num[8];
218 int s2 = rresvport_af(&lport, af), s3;
219 int len = sizeof(from);
220 int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask);
221
222 if (s2 < 0)
223 goto bad;
224 readsp = (fd_set *)malloc(fdssize);
225 if (readsp == NULL)
226 goto bad;
227 listen(s2, 1);
228 (void)snprintf(num, sizeof(num), "%d", lport);
229 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
230 (void)fprintf(stderr,
231 "rcmd: write (setting up stderr): %s\n",
232 strerror(errno));
233 (void)close(s2);
234 goto bad;
235 }
236again:
237 bzero(readsp, fdssize);
238 FD_SET(s, readsp);
239 FD_SET(s2, readsp);
240 errno = 0;
241 if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 ||
242 !FD_ISSET(s2, readsp)) {
243 if (errno != 0)
244 (void)fprintf(stderr,
245 "rcmd: select (setting up stderr): %s\n",
246 strerror(errno));
247 else
248 (void)fprintf(stderr,
249 "select: protocol failure in circuit setup\n");
250 (void)close(s2);
251 goto bad;
252 }
253 s3 = accept(s2, (struct sockaddr *)&from, &len);
254 /*
255 * XXX careful for ftp bounce attacks. If discovered, shut them
256 * down and check for the real auxiliary channel to connect.
257 */
258 switch (from.ss_family) {
259 case AF_INET:
260 case AF_INET6:
261 if (getnameinfo((struct sockaddr *)&from, len,
262 NULL, 0, num, sizeof(num), NI_NUMERICSERV) == 0 &&
263 atoi(num) != 20) {
264 break;
265 }
266 close(s3);
267 goto again;
268 default:
269 break;
270 }
271 (void)close(s2);
272 if (s3 < 0) {
273 (void)fprintf(stderr,
274 "rcmd: accept: %s\n", strerror(errno));
275 lport = 0;
276 goto bad;
277 }
278 *fd2p = s3;
279 switch (from.ss_family) {
280 case AF_INET:
281 case AF_INET6:
282 if (getnameinfo((struct sockaddr *)&from, len,
283 NULL, 0, num, sizeof(num), NI_NUMERICSERV) != 0 ||
284 (atoi(num) >= IPPORT_RESERVED ||
285 atoi(num) < IPPORT_RESERVED / 2)) {
286 (void)fprintf(stderr,
287 "socket: protocol failure in circuit setup.\n");
288 goto bad2;
289 }
290 break;
291 default:
292 break;
293 }
294 }
295 (void)write(s, locuser, strlen(locuser)+1);
296 (void)write(s, remuser, strlen(remuser)+1);
297 (void)write(s, cmd, strlen(cmd)+1);
298 if (read(s, &c, 1) != 1) {
299 (void)fprintf(stderr,
300 "rcmd: %s: %s\n", *ahost, strerror(errno));
301 goto bad2;
302 }
303 if (c != 0) {
304 while (read(s, &c, 1) == 1) {
305 (void)write(STDERR_FILENO, &c, 1);
306 if (c == '\n')
307 break;
308 }
309 goto bad2;
310 }
311 sigprocmask(SIG_SETMASK, &oldmask, NULL);
312 free(readsp);
313 return (s);
314bad2:
315 if (lport)
316 (void)close(*fd2p);
317bad:
318 if (readsp)
319 free(readsp);
320 (void)close(s);
321 sigprocmask(SIG_SETMASK, &oldmask, NULL);
322 return (-1);
323}
324
325int __check_rhosts_file = 1;
326char *__rcmd_errstr;
327
328int
329ruserok(rhost, superuser, ruser, luser)
330 const char *rhost, *ruser, *luser;
331 int superuser;
332{
333 struct addrinfo hints, *res, *r;
334 int error;
335
336 memset(&hints, 0, sizeof(hints));
337 hints.ai_family = PF_UNSPEC;
338 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
339 error = getaddrinfo(rhost, "0", &hints, &res);
340 if (error)
341 return (-1);
342
343 for (r = res; r; r = r->ai_next) {
344 if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser,
345 luser) == 0) {
346 freeaddrinfo(res);
347 return (0);
348 }
349 }
350 freeaddrinfo(res);
351 return (-1);
352}
353
354/*
355 * New .rhosts strategy: We are passed an ip address. We spin through
356 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
357 * has ip addresses, we don't have to trust a nameserver. When it
358 * contains hostnames, we spin through the list of addresses the nameserver
359 * gives us and look for a match.
360 *
361 * Returns 0 if ok, -1 if not ok.
362 */
363int
364iruserok(raddr, superuser, ruser, luser)
365 u_int32_t raddr;
366 int superuser;
367 const char *ruser, *luser;
368{
369 struct sockaddr_in sin;
370
371 memset(&sin, 0, sizeof(sin));
372 sin.sin_family = AF_INET;
373 sin.sin_len = sizeof(struct sockaddr_in);
374 memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr));
375 return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser,
376 luser);
377}
378
379int
380iruserok_sa(raddr, rlen, superuser, ruser, luser)
381 const void *raddr;
382 int rlen;
383 int superuser;
384 const char *ruser, *luser;
385{
386 struct sockaddr *sa;
387 register char *cp;
388 struct stat sbuf;
389 struct passwd *pwd;
390 FILE *hostf;
391 uid_t uid;
392 int first;
393 char pbuf[MAXPATHLEN];
394
395 sa = (struct sockaddr *)raddr;
396 first = 1;
397 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
398again:
399 if (hostf) {
400 if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) {
401 (void)fclose(hostf);
402 return (0);
403 }
404 (void)fclose(hostf);
405 }
406 if (first == 1 && (__check_rhosts_file || superuser)) {
407 first = 0;
408 if ((pwd = getpwnam(luser)) == NULL)
409 return (-1);
410 snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir);
411
412 /*
413 * Change effective uid while opening .rhosts. If root and
414 * reading an NFS mounted file system, can't read files that
415 * are protected read/write owner only.
416 */
417 uid = geteuid();
418 (void)seteuid(pwd->pw_uid);
419 hostf = fopen(pbuf, "r");
420 (void)seteuid(uid);
421
422 if (hostf == NULL)
423 return (-1);
424 /*
425 * If not a regular file, or is owned by someone other than
426 * user or root or if writeable by anyone but the owner, quit.
427 */
428 cp = NULL;
429 if (lstat(pbuf, &sbuf) < 0)
430 cp = ".rhosts lstat failed";
431 else if (!S_ISREG(sbuf.st_mode))
432 cp = ".rhosts not regular file";
433 else if (fstat(fileno(hostf), &sbuf) < 0)
434 cp = ".rhosts fstat failed";
435 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
436 cp = "bad .rhosts owner";
437 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
438 cp = ".rhosts writeable by other than owner";
439 /* If there were any problems, quit. */
440 if (cp) {
441 __rcmd_errstr = cp;
442 (void)fclose(hostf);
443 return (-1);
444 }
445 goto again;
446 }
447 return (-1);
448}
449
450/*
451 * XXX
452 * Don't make static, used by lpd(8).
453 *
454 * Returns 0 if ok, -1 if not ok.
455 */
456int
457__ivaliduser(hostf, raddrl, luser, ruser)
458 FILE *hostf;
459 in_addr_t raddrl;
460 const char *luser, *ruser;
461{
462 struct sockaddr_in sin;
463
464 memset(&sin, 0, sizeof(sin));
465 sin.sin_family = AF_INET;
466 sin.sin_len = sizeof(struct sockaddr_in);
467 memcpy(&sin.sin_addr, &raddrl, sizeof(sin.sin_addr));
468 return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len,
469 luser, ruser);
470}
471
472int
473__ivaliduser_sa(hostf, raddr, salen, luser, ruser)
474 FILE *hostf;
475 struct sockaddr *raddr;
476 socklen_t salen;
477 const char *luser, *ruser;
478{
479 register char *user, *p;
480 char *buf;
481 const char *auser, *ahost;
482 int hostok, userok;
483 char *rhost = (char *)-1;
484 char domain[MAXHOSTNAMELEN];
485 size_t buflen;
486
487 getdomainname(domain, sizeof(domain));
488
489 while ((buf = fgetln(hostf, &buflen))) {
490 p = buf;
491 if (*p == '#')
492 continue;
493 while (*p != '\n' && *p != ' ' && *p != '\t' && p < buf + buflen) {
494 if (!isprint(*p))
495 goto bail;
496 *p = isupper(*p) ? tolower(*p) : *p;
497 p++;
498 }
499 if (p >= buf + buflen)
500 continue;
501 if (*p == ' ' || *p == '\t') {
502 *p++ = '\0';
503 while ((*p == ' ' || *p == '\t') && p < buf + buflen)
504 p++;
505 if (p >= buf + buflen)
506 continue;
507 user = p;
508 while (*p != '\n' && *p != ' ' &&
509 *p != '\t' && p < buf + buflen) {
510 if (!isprint(*p))
511 goto bail;
512 p++;
513 }
514 } else
515 user = p;
516 *p = '\0';
517
518 if (p == buf)
519 continue;
520
521 auser = *user ? user : luser;
522 ahost = buf;
523
524 if (strlen(ahost) >= MAXHOSTNAMELEN)
525 continue;
526
527 /*
528 * innetgr() must lookup a hostname (we do not attempt
529 * to change the semantics so that netgroups may have
530 * #.#.#.# addresses in the list.)
531 */
532 if (ahost[0] == '+')
533 switch (ahost[1]) {
534 case '\0':
535 hostok = 1;
536 break;
537 case '@':
538 if (rhost == (char *)-1)
539 rhost = __gethostloop(raddr, salen);
540 hostok = 0;
541 if (rhost)
542 hostok = innetgr(&ahost[2], rhost,
543 NULL, domain);
544 break;
545 default:
546 hostok = __icheckhost(raddr, salen, &ahost[1]);
547 break;
548 }
549 else if (ahost[0] == '-')
550 switch (ahost[1]) {
551 case '\0':
552 hostok = -1;
553 break;
554 case '@':
555 if (rhost == (char *)-1)
556 rhost = __gethostloop(raddr, salen);
557 hostok = 0;
558 if (rhost)
559 hostok = -innetgr(&ahost[2], rhost,
560 NULL, domain);
561 break;
562 default:
563 hostok = -__icheckhost(raddr, salen, &ahost[1]);
564 break;
565 }
566 else
567 hostok = __icheckhost(raddr, salen, ahost);
568
569
570 if (auser[0] == '+')
571 switch (auser[1]) {
572 case '\0':
573 userok = 1;
574 break;
575 case '@':
576 userok = innetgr(&auser[2], NULL, ruser,
577 domain);
578 break;
579 default:
580 userok = strcmp(ruser, &auser[1]) ? 0 : 1;
581 break;
582 }
583 else if (auser[0] == '-')
584 switch (auser[1]) {
585 case '\0':
586 userok = -1;
587 break;
588 case '@':
589 userok = -innetgr(&auser[2], NULL, ruser,
590 domain);
591 break;
592 default:
593 userok = strcmp(ruser, &auser[1]) ? 0 : -1;
594 break;
595 }
596 else
597 userok = strcmp(ruser, auser) ? 0 : 1;
598
599 /* Check if one component did not match */
600 if (hostok == 0 || userok == 0)
601 continue;
602
603 /* Check if we got a forbidden pair */
604 if (userok <= -1 || hostok <= -1)
605 return (-1);
606
607 /* Check if we got a valid pair */
608 if (hostok >= 1 && userok >= 1)
609 return (0);
610 }
611bail:
612 return (-1);
613}
614
615/*
616 * Returns "true" if match, 0 if no match. If we do not find any
617 * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
618 *
619 * NI_WITHSCOPEID is useful for comparing sin6_scope_id portion
620 * if af == AF_INET6.
621 */
622static int
623__icheckhost(raddr, salen, lhost)
624 struct sockaddr *raddr;
625 socklen_t salen;
626 const char *lhost;
627{
628 struct addrinfo hints, *res, *r;
629 char h1[NI_MAXHOST], h2[NI_MAXHOST];
630 int error;
631#ifdef NI_WITHSCOPEID
632 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
633#else
634 const int niflags = NI_NUMERICHOST;
635#endif
636
637 h1[0] = '\0';
638 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
639 niflags) != 0)
640 return (0);
641
642 /* Resolve laddr into sockaddr */
643 memset(&hints, 0, sizeof(hints));
644 hints.ai_family = raddr->sa_family;
645 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
646 res = NULL;
647 error = getaddrinfo(lhost, "0", &hints, &res);
648 if (error)
649 return (0);
650
651 /*
652 * Try string comparisons between raddr and laddr.
653 */
654 for (r = res; r; r = r->ai_next) {
655 h2[0] = '\0';
656 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
657 NULL, 0, niflags) != 0)
658 continue;
659 if (strcmp(h1, h2) == 0) {
660 freeaddrinfo(res);
661 return (1);
662 }
663 }
664
665 /* No match. */
666 freeaddrinfo(res);
667 return (0);
668}
669
670/*
671 * Return the hostname associated with the supplied address.
672 * Do a reverse lookup as well for security. If a loop cannot
673 * be found, pack the result of inet_ntoa() into the string.
674 *
675 * NI_WITHSCOPEID is useful for comparing sin6_scope_id portion
676 * if af == AF_INET6.
677 */
678static char *
679__gethostloop(raddr, salen)
680 struct sockaddr *raddr;
681 socklen_t salen;
682{
683 static char remotehost[NI_MAXHOST];
684 char h1[NI_MAXHOST], h2[NI_MAXHOST];
685 struct addrinfo hints, *res, *r;
686 int error;
687#ifdef NI_WITHSCOPEID
688 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
689#else
690 const int niflags = NI_NUMERICHOST;
691#endif
692
693 h1[0] = remotehost[0] = '\0';
694 if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost),
695 NULL, 0, NI_NAMEREQD) != 0)
696 return (NULL);
697 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
698 niflags) != 0)
699 return (NULL);
700
701 /*
702 * Look up the name and check that the supplied
703 * address is in the list
704 */
705 memset(&hints, 0, sizeof(hints));
706 hints.ai_family = raddr->sa_family;
707 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
708 hints.ai_flags = AI_CANONNAME;
709 res = NULL;
710 error = getaddrinfo(remotehost, "0", &hints, &res);
711 if (error)
712 return (NULL);
713
714 for (r = res; r; r = r->ai_next) {
715 h2[0] = '\0';
716 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
717 NULL, 0, niflags) != 0)
718 continue;
719 if (strcmp(h1, h2) == 0) {
720 freeaddrinfo(res);
721 return (remotehost);
722 }
723 }
724
725 /*
726 * either the DNS adminstrator has made a configuration
727 * mistake, or someone has attempted to spoof us
728 */
729 syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s",
730 h1, res->ai_canonname ? res->ai_canonname : remotehost);
731 freeaddrinfo(res);
732 return (NULL);
733}
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3
new file mode 100644
index 0000000000..e0c59efb85
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.3
@@ -0,0 +1,97 @@
1.\" $OpenBSD: rcmdsh.3,v 1.8 2000/12/24 00:30:56 aaron Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd September 1, 1996
35.Dt RCMDSH 3
36.Os
37.Sh NAME
38.Nm rcmdsh
39.Nd return a stream to a remote command without superuser
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Ft int
43.Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog"
44.Sh DESCRIPTION
45The
46.Fn rcmdsh
47function is used by normal users to execute a command on a remote machine
48using an authentication scheme based on reserved port numbers using
49.Xr rshd 8
50or the value of
51.Fa rshprog
52(if non-null).
53.Pp
54The
55.Fn rcmdsh
56function looks up the host
57.Fa *ahost
58using
59.Xr gethostbyname 3 ,
60returning \-1 if the host does not exist.
61Otherwise
62.Fa *ahost
63is set to the standard name of the host and a connection is established to
64a server residing at the well-known Internet port
65.Li shell/tcp
66(or whatever port is used by
67.Fa rshprog ) .
68The parameter
69.Fa inport
70is ignored; it is only included to provide an interface similar to
71.Xr rcmd 3 .
72.Pp
73If the connection succeeds, a socket in the
74.Tn UNIX
75domain of type
76.Dv SOCK_STREAM
77is returned to the caller, and given to the remote
78command as stdin and stdout, and stderr.
79.Sh DIAGNOSTICS
80The
81.Fn rcmdsh
82function returns a valid socket descriptor on success.
83It returns \-1 on error and prints a diagnostic message on the standard error.
84.Sh SEE ALSO
85.Xr rsh 1 ,
86.Xr socketpair 2 ,
87.Xr rcmd 3 ,
88.Xr rshd 8
89.Sh BUGS
90If
91.Xr rsh 1
92encounters an error, a file descriptor is still returned instead of \-1.
93.Sh HISTORY
94The
95.Fn rcmdsh
96function first appeared in
97.Ox 2.0 .
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c
new file mode 100644
index 0000000000..a1c7e7d6b8
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.c
@@ -0,0 +1,153 @@
1/* $OpenBSD: rcmdsh.c,v 1.7 2002/03/12 00:05:44 millert Exp $ */
2
3/*
4 * Copyright (c) 2001, MagniComp
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the MagniComp nor the names of its contributors may
16 * be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
28 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/*
32 * This is an rcmd() replacement originally by
33 * Chris Siebenmann <cks@utcc.utoronto.ca>.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: rcmdsh.c,v 1.7 2002/03/12 00:05:44 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <sys/wait.h>
43#include <signal.h>
44#include <errno.h>
45#include <netdb.h>
46#include <stdio.h>
47#include <string.h>
48#include <pwd.h>
49#include <paths.h>
50#include <unistd.h>
51
52/*
53 * This is a replacement rcmd() function that uses the rsh(1)
54 * program in place of a direct rcmd(3) function call so as to
55 * avoid having to be root. Note that rport is ignored.
56 */
57/* ARGSUSED */
58int
59rcmdsh(ahost, rport, locuser, remuser, cmd, rshprog)
60 char **ahost;
61 int rport;
62 const char *locuser, *remuser, *cmd;
63 char *rshprog;
64{
65 struct hostent *hp;
66 int sp[2];
67 pid_t cpid;
68 char *p;
69 struct passwd *pw;
70
71 /* What rsh/shell to use. */
72 if (rshprog == NULL)
73 rshprog = _PATH_RSH;
74
75 /* locuser must exist on this host. */
76 if ((pw = getpwnam(locuser)) == NULL) {
77 (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser);
78 return(-1);
79 }
80
81 /* Validate remote hostname. */
82 if (strcmp(*ahost, "localhost") != 0) {
83 if ((hp = gethostbyname(*ahost)) == NULL) {
84 herror(*ahost);
85 return(-1);
86 }
87 *ahost = hp->h_name;
88 }
89
90 /* Get a socketpair we'll use for stdin and stdout. */
91 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
92 perror("rcmdsh: socketpair");
93 return(-1);
94 }
95
96 cpid = fork();
97 if (cpid < 0) {
98 perror("rcmdsh: fork failed");
99 return(-1);
100 } else if (cpid == 0) {
101 /*
102 * Child. We use sp[1] to be stdin/stdout, and close sp[0].
103 */
104 (void) close(sp[0]);
105 if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) {
106 perror("rcmdsh: dup2 failed");
107 _exit(255);
108 }
109 /* Fork again to lose parent. */
110 cpid = fork();
111 if (cpid < 0) {
112 perror("rcmdsh: fork to lose parent failed");
113 _exit(255);
114 }
115 if (cpid > 0)
116 _exit(0);
117
118 /* In grandchild here. Become local user for rshprog. */
119 if (setuid(pw->pw_uid)) {
120 (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n",
121 pw->pw_uid, strerror(errno));
122 _exit(255);
123 }
124
125 /*
126 * If remote host is "localhost" and local and remote user
127 * are the same, avoid running remote shell for efficiency.
128 */
129 if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) {
130 if (pw->pw_shell[0] == '\0')
131 rshprog = _PATH_BSHELL;
132 else
133 rshprog = pw->pw_shell;
134 p = strrchr(rshprog, '/');
135 execlp(rshprog, p ? p+1 : rshprog, "-c", cmd,
136 (char *) NULL);
137 } else {
138 p = strrchr(rshprog, '/');
139 execlp(rshprog, p ? p+1 : rshprog, *ahost, "-l",
140 remuser, cmd, (char *) NULL);
141 }
142 (void) fprintf(stderr, "rcmdsh: execlp %s failed: %s\n",
143 rshprog, strerror(errno));
144 _exit(255);
145 } else {
146 /* Parent. close sp[1], return sp[0]. */
147 (void) close(sp[1]);
148 /* Reap child. */
149 (void) wait(NULL);
150 return(sp[0]);
151 }
152 /* NOTREACHED */
153}
diff --git a/src/lib/libc/net/recv.c b/src/lib/libc/net/recv.c
new file mode 100644
index 0000000000..d209a07213
--- /dev/null
+++ b/src/lib/libc/net/recv.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: recv.c,v 1.2 1996/08/19 08:29:40 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40
41#include <stddef.h>
42
43ssize_t
44recv(s, buf, len, flags)
45 int s, flags;
46 size_t len;
47 void *buf;
48{
49 return (recvfrom(s, buf, len, flags, NULL, 0));
50}
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
new file mode 100644
index 0000000000..25e196b2cf
--- /dev/null
+++ b/src/lib/libc/net/res_comp.c
@@ -0,0 +1,503 @@
1/* $OpenBSD: res_comp.c,v 1.10 2002/02/19 19:39:36 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
6 * Copyright (c) 1985, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_comp.c,v 1.10 2002/02/19 19:39:36 millert Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/nameser.h>
71
72#include <stdio.h>
73#include <resolv.h>
74#include <ctype.h>
75
76#include <unistd.h>
77#include <string.h>
78
79static int dn_find(u_char *, u_char *, u_char **, u_char **);
80
81/*
82 * Expand compressed domain name 'comp_dn' to full domain name.
83 * 'msg' is a pointer to the begining of the message,
84 * 'eomorig' points to the first location after the message,
85 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
86 * Return size of compressed name or -1 if there was an error.
87 */
88int
89dn_expand(msg, eomorig, comp_dn, exp_dn, length)
90 const u_char *msg, *eomorig, *comp_dn;
91 char *exp_dn;
92 int length;
93{
94 register const u_char *cp;
95 register char *dn;
96 register int n, c;
97 char *eom;
98 int len = -1, checked = 0;
99
100 dn = exp_dn;
101 cp = comp_dn;
102 if (length > MAXHOSTNAMELEN-1)
103 length = MAXHOSTNAMELEN-1;
104 eom = exp_dn + length;
105 /*
106 * fetch next label in domain name
107 */
108 while ((n = *cp++)) {
109 /*
110 * Check for indirection
111 */
112 switch (n & INDIR_MASK) {
113 case 0:
114 if (dn != exp_dn) {
115 if (dn >= eom)
116 return (-1);
117 *dn++ = '.';
118 }
119 if (dn+n >= eom)
120 return (-1);
121 checked += n + 1;
122 while (--n >= 0) {
123 if (((c = *cp++) == '.') || (c == '\\')) {
124 if (dn + n + 2 >= eom)
125 return (-1);
126 *dn++ = '\\';
127 }
128 *dn++ = c;
129 if (cp >= eomorig) /* out of range */
130 return (-1);
131 }
132 break;
133
134 case INDIR_MASK:
135 if (len < 0)
136 len = cp - comp_dn + 1;
137 cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
138 if (cp < msg || cp >= eomorig) /* out of range */
139 return (-1);
140 checked += 2;
141 /*
142 * Check for loops in the compressed name;
143 * if we've looked at the whole message,
144 * there must be a loop.
145 */
146 if (checked >= eomorig - msg)
147 return (-1);
148 break;
149
150 default:
151 return (-1); /* flag error */
152 }
153 }
154 *dn = '\0';
155 if (len < 0)
156 len = cp - comp_dn;
157 return (len);
158}
159
160/*
161 * Compress domain name 'exp_dn' into 'comp_dn'.
162 * Return the size of the compressed name or -1.
163 * 'length' is the size of the array pointed to by 'comp_dn'.
164 * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
165 * is a pointer to the beginning of the message. The list ends with NULL.
166 * 'lastdnptr' is a pointer to the end of the arrary pointed to
167 * by 'dnptrs'. Side effect is to update the list of pointers for
168 * labels inserted into the message as we compress the name.
169 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
170 * is NULL, we don't update the list.
171 */
172int
173dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
174 const char *exp_dn;
175 u_char *comp_dn, **dnptrs, **lastdnptr;
176 int length;
177{
178 register u_char *cp, *dn;
179 register int c, l;
180 u_char **cpp, **lpp, *sp, *eob;
181 u_char *msg;
182
183 dn = (u_char *)exp_dn;
184 cp = comp_dn;
185 eob = cp + length;
186 lpp = cpp = NULL;
187 if (dnptrs != NULL) {
188 if ((msg = *dnptrs++) != NULL) {
189 for (cpp = dnptrs; *cpp != NULL; cpp++)
190 ;
191 lpp = cpp; /* end of list to search */
192 }
193 } else
194 msg = NULL;
195 for (c = *dn++; c != '\0'; ) {
196 /* look to see if we can use pointers */
197 if (msg != NULL) {
198 if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
199 if (cp+1 >= eob)
200 return (-1);
201 *cp++ = (l >> 8) | INDIR_MASK;
202 *cp++ = l % 256;
203 return (cp - comp_dn);
204 }
205 /* not found, save it */
206 if (lastdnptr != NULL && cpp < lastdnptr-1) {
207 *cpp++ = cp;
208 *cpp = NULL;
209 }
210 }
211 sp = cp++; /* save ptr to length byte */
212 do {
213 if (c == '.') {
214 c = *dn++;
215 break;
216 }
217 if (c == '\\') {
218 if ((c = *dn++) == '\0')
219 break;
220 }
221 if (cp >= eob) {
222 if (msg != NULL)
223 *lpp = NULL;
224 return (-1);
225 }
226 *cp++ = c;
227 } while ((c = *dn++) != '\0');
228 /* catch trailing '.'s but not '..' */
229 if ((l = cp - sp - 1) == 0 && c == '\0') {
230 cp--;
231 break;
232 }
233 if (l <= 0 || l > MAXLABEL) {
234 if (msg != NULL)
235 *lpp = NULL;
236 return (-1);
237 }
238 *sp = l;
239 }
240 if (cp >= eob) {
241 if (msg != NULL)
242 *lpp = NULL;
243 return (-1);
244 }
245 *cp++ = '\0';
246 return (cp - comp_dn);
247}
248
249/*
250 * Skip over a compressed domain name. Return the size or -1.
251 */
252int
253__dn_skipname(comp_dn, eom)
254 const u_char *comp_dn, *eom;
255{
256 register const u_char *cp;
257 register int n;
258
259 cp = comp_dn;
260 while (cp < eom && (n = *cp++)) {
261 /*
262 * check for indirection
263 */
264 switch (n & INDIR_MASK) {
265 case 0: /* normal case, n == len */
266 cp += n;
267 continue;
268 case INDIR_MASK: /* indirection */
269 cp++;
270 break;
271 default: /* illegal type */
272 return (-1);
273 }
274 break;
275 }
276 if (cp > eom)
277 return (-1);
278 return (cp - comp_dn);
279}
280
281static int
282mklower(ch)
283 register int ch;
284{
285 if (isascii(ch) && isupper(ch))
286 return (tolower(ch));
287 return (ch);
288}
289
290/*
291 * Search for expanded name from a list of previously compressed names.
292 * Return the offset from msg if found or -1.
293 * dnptrs is the pointer to the first name on the list,
294 * not the pointer to the start of the message.
295 */
296static int
297dn_find(exp_dn, msg, dnptrs, lastdnptr)
298 u_char *exp_dn, *msg;
299 u_char **dnptrs, **lastdnptr;
300{
301 register u_char *dn, *cp, **cpp;
302 register int n;
303 u_char *sp;
304
305 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
306 dn = exp_dn;
307 sp = cp = *cpp;
308 while ((n = *cp++)) {
309 /*
310 * check for indirection
311 */
312 switch (n & INDIR_MASK) {
313 case 0: /* normal case, n == len */
314 while (--n >= 0) {
315 if (*dn == '.')
316 goto next;
317 if (*dn == '\\')
318 dn++;
319 if (mklower(*dn++) != mklower(*cp++))
320 goto next;
321 }
322 if ((n = *dn++) == '\0' && *cp == '\0')
323 return (sp - msg);
324 if (n == '.')
325 continue;
326 goto next;
327
328 case INDIR_MASK: /* indirection */
329 cp = msg + (((n & 0x3f) << 8) | *cp);
330 break;
331
332 default: /* illegal type */
333 return (-1);
334 }
335 }
336 if (*dn == '\0')
337 return (sp - msg);
338 next: ;
339 }
340 return (-1);
341}
342
343/*
344 * Verify that a domain name uses an acceptable character set.
345 */
346
347/*
348 * Note the conspicuous absence of ctype macros in these definitions. On
349 * non-ASCII hosts, we can't depend on string literals or ctype macros to
350 * tell us anything about network-format data. The rest of the BIND system
351 * is not careful about this, but for some reason, we're doing it right here.
352 */
353#define PERIOD 0x2e
354#define hyphenchar(c) ((c) == 0x2d)
355#define bslashchar(c) ((c) == 0x5c)
356#define periodchar(c) ((c) == PERIOD)
357#define asterchar(c) ((c) == 0x2a)
358#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
359 || ((c) >= 0x61 && (c) <= 0x7a))
360#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
361
362#define borderchar(c) (alphachar(c) || digitchar(c))
363#define middlechar(c) (borderchar(c) || hyphenchar(c))
364#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
365
366int
367res_hnok(dn)
368 const char *dn;
369{
370 int pch = PERIOD, ch = *dn++;
371
372 while (ch != '\0') {
373 int nch = *dn++;
374
375 if (periodchar(ch)) {
376 ;
377 } else if (periodchar(pch)) {
378 if (!borderchar(ch))
379 return (0);
380 } else if (periodchar(nch) || nch == '\0') {
381 if (!borderchar(ch))
382 return (0);
383 } else {
384 if (!middlechar(ch))
385 return (0);
386 }
387 pch = ch, ch = nch;
388 }
389 return (1);
390}
391
392/*
393 * hostname-like (A, MX, WKS) owners can have "*" as their first label
394 * but must otherwise be as a host name.
395 */
396int
397res_ownok(dn)
398 const char *dn;
399{
400 if (asterchar(dn[0])) {
401 if (periodchar(dn[1]))
402 return (res_hnok(dn+2));
403 if (dn[1] == '\0')
404 return (1);
405 }
406 return (res_hnok(dn));
407}
408
409/*
410 * SOA RNAMEs and RP RNAMEs can have any printable character in their first
411 * label, but the rest of the name has to look like a host name.
412 */
413int
414res_mailok(dn)
415 const char *dn;
416{
417 int ch, escaped = 0;
418
419 /* "." is a valid missing representation */
420 if (*dn == '\0')
421 return(1);
422
423 /* otherwise <label>.<hostname> */
424 while ((ch = *dn++) != '\0') {
425 if (!domainchar(ch))
426 return (0);
427 if (!escaped && periodchar(ch))
428 break;
429 if (escaped)
430 escaped = 0;
431 else if (bslashchar(ch))
432 escaped = 1;
433 }
434 if (periodchar(ch))
435 return (res_hnok(dn));
436 return(0);
437}
438
439/*
440 * This function is quite liberal, since RFC 1034's character sets are only
441 * recommendations.
442 */
443int
444res_dnok(dn)
445 const char *dn;
446{
447 int ch;
448
449 while ((ch = *dn++) != '\0')
450 if (!domainchar(ch))
451 return (0);
452 return (1);
453}
454
455/*
456 * Routines to insert/extract short/long's.
457 */
458
459u_int16_t
460_getshort(msgp)
461 register const u_char *msgp;
462{
463 register u_int16_t u;
464
465 GETSHORT(u, msgp);
466 return (u);
467}
468
469#ifdef NeXT
470/*
471 * nExt machines have some funky library conventions, which we must maintain.
472 */
473u_int16_t
474res_getshort(msgp)
475 register const u_char *msgp;
476{
477 return (_getshort(msgp));
478}
479#endif
480
481u_int32_t
482_getlong(msgp)
483 register const u_char *msgp;
484{
485 register u_int32_t u;
486
487 GETLONG(u, msgp);
488 return (u);
489}
490
491void
492__putshort(register u_int16_t s, register u_char *msgp)
493{
494 PUTSHORT(s, msgp);
495}
496
497void
498__putlong(l, msgp)
499 register u_int32_t l;
500 register u_char *msgp;
501{
502 PUTLONG(l, msgp);
503}
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c
new file mode 100644
index 0000000000..b0d19c36bb
--- /dev/null
+++ b/src/lib/libc/net/res_data.c
@@ -0,0 +1,117 @@
1/* $OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1995
5 * -
6 * Copyright (c) 1995
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
61#else
62static char rcsid[] = "$OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $";
63#endif
64#endif /* LIBC_SCCS and not lint */
65
66#include <sys/types.h>
67#include <sys/param.h>
68#include <sys/socket.h>
69#include <sys/time.h>
70#include <netinet/in.h>
71#include <arpa/inet.h>
72#include <arpa/nameser.h>
73
74#include <stdio.h>
75#include <ctype.h>
76#include <resolv.h>
77#include <unistd.h>
78#include <stdlib.h>
79#include <string.h>
80
81const char *_res_opcodes[] = {
82 "QUERY",
83 "IQUERY",
84 "CQUERYM",
85 "CQUERYU", /* experimental */
86 "NOTIFY", /* experimental */
87 "5",
88 "6",
89 "7",
90 "8",
91 "UPDATEA",
92 "UPDATED",
93 "UPDATEDA",
94 "UPDATEM",
95 "UPDATEMA",
96 "ZONEINIT",
97 "ZONEREF",
98};
99
100const char *_res_resultcodes[] = {
101 "NOERROR",
102 "FORMERR",
103 "SERVFAIL",
104 "NXDOMAIN",
105 "NOTIMP",
106 "REFUSED",
107 "6",
108 "7",
109 "8",
110 "9",
111 "10",
112 "11",
113 "12",
114 "13",
115 "14",
116 "NOCHANGE",
117};
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
new file mode 100644
index 0000000000..2ea9173fe9
--- /dev/null
+++ b/src/lib/libc/net/res_debug.c
@@ -0,0 +1,1560 @@
1/* $OpenBSD: res_debug.c,v 1.14 2002/07/25 21:55:30 deraadt Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
6 * Copyright (c) 1985, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * Portions Copyright (c) 1995 by International Business Machines, Inc.
56 *
57 * International Business Machines, Inc. (hereinafter called IBM) grants
58 * permission under its copyrights to use, copy, modify, and distribute this
59 * Software with or without fee, provided that the above copyright notice and
60 * all paragraphs of this notice appear in all copies, and that the name of IBM
61 * not be used in connection with the marketing of any product incorporating
62 * the Software or modifications thereof, without specific, written prior
63 * permission.
64 *
65 * To the extent it has a right to do so, IBM grants an immunity from suit
66 * under its patents, if any, for the use, sale or manufacture of products to
67 * the extent that such products are used for performing Domain Name System
68 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
69 * granted for any product per se or for any other function of any product.
70 *
71 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
72 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
73 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
74 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
75 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
76 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
77 * --Copyright--
78 */
79
80#if defined(LIBC_SCCS) && !defined(lint)
81#if 0
82static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
83static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
84#else
85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.14 2002/07/25 21:55:30 deraadt Exp $";
86#endif
87#endif /* LIBC_SCCS and not lint */
88
89#include <sys/param.h>
90#include <sys/types.h>
91#include <sys/socket.h>
92#include <netinet/in.h>
93#include <arpa/inet.h>
94#include <arpa/nameser.h>
95
96#include <ctype.h>
97#include <netdb.h>
98#include <resolv.h>
99#include <stdio.h>
100#include <time.h>
101
102#include <stdlib.h>
103#include <string.h>
104
105extern const char *_res_opcodes[];
106extern const char *_res_resultcodes[];
107
108static const char *loc_ntoal(const u_char *binary, char *ascii, int ascii_len);
109
110/* XXX: we should use getservbyport() instead. */
111static const char *
112dewks(wks)
113 int wks;
114{
115 static char nbuf[20];
116
117 switch (wks) {
118 case 5: return "rje";
119 case 7: return "echo";
120 case 9: return "discard";
121 case 11: return "systat";
122 case 13: return "daytime";
123 case 15: return "netstat";
124 case 17: return "qotd";
125 case 19: return "chargen";
126 case 20: return "ftp-data";
127 case 21: return "ftp";
128 case 23: return "telnet";
129 case 25: return "smtp";
130 case 37: return "time";
131 case 39: return "rlp";
132 case 42: return "name";
133 case 43: return "whois";
134 case 53: return "domain";
135 case 57: return "apts";
136 case 59: return "apfs";
137 case 67: return "bootps";
138 case 68: return "bootpc";
139 case 69: return "tftp";
140 case 77: return "rje";
141 case 79: return "finger";
142 case 87: return "link";
143 case 95: return "supdup";
144 case 100: return "newacct";
145 case 101: return "hostnames";
146 case 102: return "iso-tsap";
147 case 103: return "x400";
148 case 104: return "x400-snd";
149 case 105: return "csnet-ns";
150 case 109: return "pop-2";
151 case 111: return "sunrpc";
152 case 113: return "auth";
153 case 115: return "sftp";
154 case 117: return "uucp-path";
155 case 119: return "nntp";
156 case 121: return "erpc";
157 case 123: return "ntp";
158 case 133: return "statsrv";
159 case 136: return "profile";
160 case 144: return "NeWS";
161 case 161: return "snmp";
162 case 162: return "snmp-trap";
163 case 170: return "print-srv";
164 default:
165 (void) snprintf(nbuf, sizeof nbuf, "%d", wks);
166 return (nbuf);
167 }
168}
169
170/* XXX: we should use getprotobynumber() instead. */
171static const char *
172deproto(protonum)
173 int protonum;
174{
175 static char nbuf[20];
176
177 switch (protonum) {
178 case 1: return "icmp";
179 case 2: return "igmp";
180 case 3: return "ggp";
181 case 5: return "st";
182 case 6: return "tcp";
183 case 7: return "ucl";
184 case 8: return "egp";
185 case 9: return "igp";
186 case 11: return "nvp-II";
187 case 12: return "pup";
188 case 16: return "chaos";
189 case 17: return "udp";
190 default:
191 (void) snprintf(nbuf, sizeof nbuf, "%d", protonum);
192 return (nbuf);
193 }
194}
195
196static const u_char *
197do_rrset(msg, len, cp, cnt, pflag, file, hs)
198 int cnt, pflag, len;
199 const u_char *cp, *msg;
200 const char *hs;
201 FILE *file;
202{
203 int n;
204 int sflag;
205
206 /*
207 * Print answer records.
208 */
209 sflag = (_res.pfcode & pflag);
210 if ((n = ntohs(cnt))) {
211 if ((!_res.pfcode) ||
212 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
213 fprintf(file, "%s", hs);
214 while (--n >= 0) {
215 if ((!_res.pfcode) || sflag) {
216 cp = p_rr(cp, msg, file);
217 } else {
218 unsigned int dlen;
219 cp += __dn_skipname(cp, cp + MAXCDNAME);
220 cp += INT16SZ;
221 cp += INT16SZ;
222 cp += INT32SZ;
223 dlen = _getshort((u_char*)cp);
224 cp += INT16SZ;
225 cp += dlen;
226 }
227 if ((cp - msg) > len)
228 return (NULL);
229 }
230 if ((!_res.pfcode) ||
231 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
232 putc('\n', file);
233 }
234 return (cp);
235}
236
237void
238__p_query(msg)
239 const u_char *msg;
240{
241 __fp_query(msg, stdout);
242}
243
244/*
245 * Print the current options.
246 * This is intended to be primarily a debugging routine.
247 */
248void
249__fp_resstat(statp, file)
250 struct __res_state *statp;
251 FILE *file;
252{
253 register u_long mask;
254
255 fprintf(file, ";; res options:");
256 if (!statp)
257 statp = &_res;
258 for (mask = 1; mask != 0; mask <<= 1)
259 if (statp->options & mask)
260 fprintf(file, " %s", p_option(mask));
261 putc('\n', file);
262}
263
264/*
265 * Print the contents of a query.
266 * This is intended to be primarily a debugging routine.
267 */
268void
269__fp_nquery(msg, len, file)
270 const u_char *msg;
271 int len;
272 FILE *file;
273{
274 register const u_char *cp, *endMark;
275 register const HEADER *hp;
276 register int n;
277
278 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
279 return;
280
281#define TruncTest(x) if (x > endMark) goto trunc
282#define ErrorTest(x) if (x == NULL) goto error
283
284 /*
285 * Print header fields.
286 */
287 hp = (HEADER *)msg;
288 cp = msg + HFIXEDSZ;
289 endMark = msg + len;
290 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
291 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
292 _res_opcodes[hp->opcode],
293 _res_resultcodes[hp->rcode],
294 ntohs(hp->id));
295 putc('\n', file);
296 }
297 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
298 putc(';', file);
299 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
300 fprintf(file, "; flags:");
301 if (hp->qr)
302 fprintf(file, " qr");
303 if (hp->aa)
304 fprintf(file, " aa");
305 if (hp->tc)
306 fprintf(file, " tc");
307 if (hp->rd)
308 fprintf(file, " rd");
309 if (hp->ra)
310 fprintf(file, " ra");
311 if (hp->unused)
312 fprintf(file, " UNUSED-BIT-ON");
313 if (hp->ad)
314 fprintf(file, " ad");
315 if (hp->cd)
316 fprintf(file, " cd");
317 }
318 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
319 fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
320 fprintf(file, ", Ans: %u", ntohs(hp->ancount));
321 fprintf(file, ", Auth: %u", ntohs(hp->nscount));
322 fprintf(file, ", Addit: %u", ntohs(hp->arcount));
323 }
324 if ((!_res.pfcode) || (_res.pfcode &
325 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
326 putc('\n',file);
327 }
328 /*
329 * Print question records.
330 */
331 if ((n = ntohs(hp->qdcount))) {
332 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
333 fprintf(file, ";; QUESTIONS:\n");
334 while (--n >= 0) {
335 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
336 fprintf(file, ";;\t");
337 TruncTest(cp);
338 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
339 cp = p_cdnname(cp, msg, len, file);
340 else {
341 int n;
342 char name[MAXDNAME];
343
344 if ((n = dn_expand(msg, msg+len, cp, name,
345 sizeof name)) < 0)
346 cp = NULL;
347 else
348 cp += n;
349 }
350 ErrorTest(cp);
351 TruncTest(cp);
352 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
353 fprintf(file, ", type = %s",
354 __p_type(_getshort((u_char*)cp)));
355 cp += INT16SZ;
356 TruncTest(cp);
357 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
358 fprintf(file, ", class = %s\n",
359 __p_class(_getshort((u_char*)cp)));
360 cp += INT16SZ;
361 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
362 putc('\n', file);
363 }
364 }
365 /*
366 * Print authoritative answer records
367 */
368 TruncTest(cp);
369 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
370 ";; ANSWERS:\n");
371 ErrorTest(cp);
372
373 /*
374 * print name server records
375 */
376 TruncTest(cp);
377 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
378 ";; AUTHORITY RECORDS:\n");
379 ErrorTest(cp);
380
381 TruncTest(cp);
382 /*
383 * print additional records
384 */
385 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
386 ";; ADDITIONAL RECORDS:\n");
387 ErrorTest(cp);
388 return;
389 trunc:
390 fprintf(file, "\n;; ...truncated\n");
391 return;
392 error:
393 fprintf(file, "\n;; ...malformed\n");
394}
395
396void
397__fp_query(msg, file)
398 const u_char *msg;
399 FILE *file;
400{
401 fp_nquery(msg, PACKETSZ, file);
402}
403
404const u_char *
405__p_cdnname(cp, msg, len, file)
406 const u_char *cp, *msg;
407 int len;
408 FILE *file;
409{
410 char name[MAXDNAME];
411 int n;
412
413 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
414 return (NULL);
415 if (name[0] == '\0')
416 putc('.', file);
417 else
418 fputs(name, file);
419 return (cp + n);
420}
421
422const u_char *
423__p_cdname(cp, msg, file)
424 const u_char *cp, *msg;
425 FILE *file;
426{
427 return (p_cdnname(cp, msg, PACKETSZ, file));
428}
429
430
431/* Return a fully-qualified domain name from a compressed name (with
432 length supplied). */
433
434const u_char *
435__p_fqnname(cp, msg, msglen, name, namelen)
436 const u_char *cp, *msg;
437 int msglen;
438 char *name;
439 int namelen;
440{
441 int n, newlen;
442
443 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
444 return (NULL);
445 newlen = strlen(name);
446 if (newlen == 0 || name[newlen - 1] != '.') {
447 if (newlen+1 >= namelen) /* Lack space for final dot */
448 return (NULL);
449 else
450 strcpy(name + newlen, ".");
451 }
452 return (cp + n);
453}
454
455/* XXX: the rest of these functions need to become length-limited, too. (vix)
456 */
457
458const u_char *
459__p_fqname(cp, msg, file)
460 const u_char *cp, *msg;
461 FILE *file;
462{
463 char name[MAXDNAME];
464 const u_char *n;
465
466 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
467 if (n == NULL)
468 return (NULL);
469 fputs(name, file);
470 return (n);
471}
472
473/*
474 * Print resource record fields in human readable form.
475 */
476const u_char *
477__p_rr(cp, msg, file)
478 const u_char *cp, *msg;
479 FILE *file;
480{
481 int type, class, dlen, n, c;
482 struct in_addr inaddr;
483 const u_char *cp1, *cp2;
484 u_int32_t tmpttl, t;
485 int lcnt;
486 u_int16_t keyflags;
487 char rrname[MAXDNAME]; /* The fqdn of this RR */
488 char base64_key[MAX_KEY_BASE64];
489
490 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
491 h_errno = NETDB_INTERNAL;
492 return (NULL);
493 }
494 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
495 if (!cp)
496 return (NULL); /* compression error */
497 fputs(rrname, file);
498
499 type = _getshort((u_char*)cp);
500 cp += INT16SZ;
501 class = _getshort((u_char*)cp);
502 cp += INT16SZ;
503 tmpttl = _getlong((u_char*)cp);
504 cp += INT32SZ;
505 dlen = _getshort((u_char*)cp);
506 cp += INT16SZ;
507 cp1 = cp;
508 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
509 fprintf(file, "\t%lu", (u_long)tmpttl);
510 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
511 fprintf(file, "\t%s", __p_class(class));
512 fprintf(file, "\t%s", __p_type(type));
513 /*
514 * Print type specific data, if appropriate
515 */
516 switch (type) {
517 case T_A:
518 switch (class) {
519 case C_IN:
520 case C_HS:
521 bcopy(cp, (char *)&inaddr, INADDRSZ);
522 if (dlen == 4) {
523 fprintf(file, "\t%s", inet_ntoa(inaddr));
524 cp += dlen;
525 } else if (dlen == 7) {
526 char *address;
527 u_char protocol;
528 in_port_t port;
529
530 address = inet_ntoa(inaddr);
531 cp += INADDRSZ;
532 protocol = *(u_char*)cp;
533 cp += sizeof (u_char);
534 port = _getshort((u_char*)cp);
535 cp += INT16SZ;
536 fprintf(file, "\t%s\t; proto %u, port %u",
537 address, protocol, port);
538 }
539 break;
540 default:
541 cp += dlen;
542 }
543 break;
544 case T_CNAME:
545 case T_MB:
546 case T_MG:
547 case T_MR:
548 case T_NS:
549 case T_PTR:
550 putc('\t', file);
551 if ((cp = p_fqname(cp, msg, file)) == NULL)
552 return (NULL);
553 break;
554
555 case T_HINFO:
556 case T_ISDN:
557 cp2 = cp + dlen;
558 (void) fputs("\t\"", file);
559 if ((n = (unsigned char) *cp++) != 0) {
560 for (c = n; c > 0 && cp < cp2; c--) {
561 if (strchr("\n\"\\", *cp))
562 (void) putc('\\', file);
563 (void) putc(*cp++, file);
564 }
565 }
566 putc('"', file);
567 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
568 (void) fputs ("\t\"", file);
569 for (c = n; c > 0 && cp < cp2; c--) {
570 if (strchr("\n\"\\", *cp))
571 (void) putc('\\', file);
572 (void) putc(*cp++, file);
573 }
574 putc('"', file);
575 } else if (type == T_HINFO) {
576 (void) fputs("\"?\"", file);
577 fprintf(file, "\n;; *** Warning *** OS-type missing");
578 }
579 break;
580
581 case T_SOA:
582 putc('\t', file);
583 if ((cp = p_fqname(cp, msg, file)) == NULL)
584 return (NULL);
585 putc(' ', file);
586 if ((cp = p_fqname(cp, msg, file)) == NULL)
587 return (NULL);
588 fputs(" (\n", file);
589 t = _getlong((u_char*)cp); cp += INT32SZ;
590 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
591 t = _getlong((u_char*)cp); cp += INT32SZ;
592 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
593 (u_long)t, __p_time(t));
594 t = _getlong((u_char*)cp); cp += INT32SZ;
595 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
596 (u_long)t, __p_time(t));
597 t = _getlong((u_char*)cp); cp += INT32SZ;
598 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
599 (u_long)t, __p_time(t));
600 t = _getlong((u_char*)cp); cp += INT32SZ;
601 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
602 (u_long)t, __p_time(t));
603 break;
604
605 case T_MX:
606 case T_AFSDB:
607 case T_RT:
608 fprintf(file, "\t%u ", _getshort((u_char*)cp));
609 cp += INT16SZ;
610 if ((cp = p_fqname(cp, msg, file)) == NULL)
611 return (NULL);
612 break;
613
614 case T_PX:
615 fprintf(file, "\t%u ", _getshort((u_char*)cp));
616 cp += INT16SZ;
617 if ((cp = p_fqname(cp, msg, file)) == NULL)
618 return (NULL);
619 putc(' ', file);
620 if ((cp = p_fqname(cp, msg, file)) == NULL)
621 return (NULL);
622 break;
623
624 case T_X25:
625 cp2 = cp + dlen;
626 (void) fputs("\t\"", file);
627 if ((n = (unsigned char) *cp++) != 0) {
628 for (c = n; c > 0 && cp < cp2; c--) {
629 if (strchr("\n\"\\", *cp))
630 (void) putc('\\', file);
631 (void) putc(*cp++, file);
632 }
633 }
634 putc('"', file);
635 break;
636
637 case T_TXT:
638 (void) putc('\t', file);
639 cp2 = cp1 + dlen;
640 while (cp < cp2) {
641 putc('"', file);
642 if ((n = (unsigned char) *cp++)) {
643 for (c = n; c > 0 && cp < cp2; c--) {
644 if (strchr("\n\"\\", *cp))
645 (void) putc('\\', file);
646 (void) putc(*cp++, file);
647 }
648 }
649 putc('"', file);
650 if (cp < cp2)
651 putc(' ', file);
652 }
653 break;
654
655 case T_NSAP:
656 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
657 cp += dlen;
658 break;
659
660 case T_AAAA: {
661 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
662
663 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
664 cp += dlen;
665 break;
666 }
667
668 case T_LOC: {
669 char t[255];
670
671 fprintf(file, "\t%s", loc_ntoal(cp, t, sizeof t));
672 cp += dlen;
673 break;
674 }
675
676 case T_NAPTR: {
677 u_int order, preference;
678
679 order = _getshort(cp); cp += INT16SZ;
680 preference = _getshort(cp); cp += INT16SZ;
681 fprintf(file, "\t%u %u ",order, preference);
682 /* Flags */
683 n = *cp++;
684 fprintf(file,"\"%.*s\" ", (int)n, cp);
685 cp += n;
686 /* Service */
687 n = *cp++;
688 fprintf(file,"\"%.*s\" ", (int)n, cp);
689 cp += n;
690 /* Regexp */
691 n = *cp++;
692 fprintf(file,"\"%.*s\" ", (int)n, cp);
693 cp += n;
694 if ((cp = p_fqname(cp, msg, file)) == NULL)
695 return (NULL);
696 break;
697 }
698
699 case T_SRV: {
700 u_int priority, weight, port;
701
702 priority = _getshort(cp); cp += INT16SZ;
703 weight = _getshort(cp); cp += INT16SZ;
704 port = _getshort(cp); cp += INT16SZ;
705 fprintf(file, "\t%u %u %u ", priority, weight, port);
706 if ((cp = p_fqname(cp, msg, file)) == NULL)
707 return (NULL);
708 break;
709 }
710
711 case T_MINFO:
712 case T_RP:
713 putc('\t', file);
714 if ((cp = p_fqname(cp, msg, file)) == NULL)
715 return (NULL);
716 putc(' ', file);
717 if ((cp = p_fqname(cp, msg, file)) == NULL)
718 return (NULL);
719 break;
720
721 case T_UINFO:
722 putc('\t', file);
723 fputs((char *)cp, file);
724 cp += dlen;
725 break;
726
727 case T_UID:
728 case T_GID:
729 if (dlen == 4) {
730 fprintf(file, "\t%u", _getlong((u_char*)cp));
731 cp += INT32SZ;
732 }
733 break;
734
735 case T_WKS:
736 if (dlen < INT32SZ + 1)
737 break;
738 bcopy(cp, (char *)&inaddr, INADDRSZ);
739 cp += INT32SZ;
740 fprintf(file, "\t%s %s ( ",
741 inet_ntoa(inaddr),
742 deproto((int) *cp));
743 cp += sizeof (u_char);
744 n = 0;
745 lcnt = 0;
746 while (cp < cp1 + dlen) {
747 c = *cp++;
748 do {
749 if (c & 0200) {
750 if (lcnt == 0) {
751 fputs("\n\t\t\t", file);
752 lcnt = 5;
753 }
754 fputs(dewks(n), file);
755 putc(' ', file);
756 lcnt--;
757 }
758 c <<= 1;
759 } while (++n & 07);
760 }
761 putc(')', file);
762 break;
763
764 case T_KEY:
765 putc('\t', file);
766 keyflags = _getshort(cp);
767 cp += 2;
768 fprintf(file,"0x%04x", keyflags ); /* flags */
769 fprintf(file," %u", *cp++); /* protocol */
770 fprintf(file," %u (", *cp++); /* algorithm */
771
772 n = b64_ntop(cp, (cp1 + dlen) - cp,
773 base64_key, sizeof base64_key);
774 for (c = 0; c < n; ++c) {
775 if (0 == (c & 0x3F))
776 fprintf(file, "\n\t");
777 putc(base64_key[c], file); /* public key data */
778 }
779
780 fprintf(file, " )");
781 if (n < 0)
782 fprintf(file, "\t; BAD BASE64");
783 fflush(file);
784 cp = cp1 + dlen;
785 break;
786
787 case T_SIG:
788 type = _getshort((u_char*)cp);
789 cp += INT16SZ;
790 fprintf(file, " %s", p_type(type));
791 fprintf(file, "\t%u", *cp++); /* algorithm */
792 /* Check label value and print error if wrong. */
793 n = *cp++;
794 c = dn_count_labels (rrname);
795 if (n != c)
796 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
797 n, c);
798 /* orig ttl */
799 n = _getlong((u_char*)cp);
800 if (n != tmpttl)
801 fprintf(file, " %u", n);
802 cp += INT32SZ;
803 /* sig expire */
804 fprintf(file, " (\n\t%s",
805 __p_secstodate(_getlong((u_char*)cp)));
806 cp += INT32SZ;
807 /* time signed */
808 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
809 cp += INT32SZ;
810 /* sig footprint */
811 fprintf(file," %u ", _getshort((u_char*)cp));
812 cp += INT16SZ;
813 /* signer's name */
814 cp = p_fqname(cp, msg, file);
815 n = b64_ntop(cp, (cp1 + dlen) - cp,
816 base64_key, sizeof base64_key);
817 for (c = 0; c < n; c++) {
818 if (0 == (c & 0x3F))
819 fprintf (file, "\n\t");
820 putc(base64_key[c], file); /* signature */
821 }
822 /* Clean up... */
823 fprintf(file, " )");
824 if (n < 0)
825 fprintf(file, "\t; BAD BASE64");
826 fflush(file);
827 cp = cp1+dlen;
828 break;
829
830#ifdef ALLOW_T_UNSPEC
831 case T_UNSPEC:
832 {
833 int NumBytes = 8;
834 u_char *DataPtr;
835 int i;
836
837 if (dlen < NumBytes) NumBytes = dlen;
838 fprintf(file, "\tFirst %d bytes of hex data:",
839 NumBytes);
840 for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
841 fprintf(file, " %x", *DataPtr);
842 cp += dlen;
843 }
844 break;
845#endif /* ALLOW_T_UNSPEC */
846
847 default:
848 fprintf(file, "\t?%d?", type);
849 cp += dlen;
850 }
851#if 0
852 fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
853#else
854 putc('\n', file);
855#endif
856 if (cp - cp1 != dlen) {
857 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
858 (long)(cp - cp1), dlen);
859 cp = NULL;
860 }
861 return (cp);
862}
863
864/*
865 * Names of RR classes and qclasses. Classes and qclasses are the same, except
866 * that C_ANY is a qclass but not a class. (You can ask for records of class
867 * C_ANY, but you can't have any records of that class in the database.)
868 */
869const struct res_sym __p_class_syms[] = {
870 {C_IN, "IN"},
871 {C_CHAOS, "CHAOS"},
872 {C_HS, "HS"},
873 {C_HS, "HESIOD"},
874 {C_ANY, "ANY"},
875 {C_IN, (char *)0}
876};
877
878/*
879 * Names of RR types and qtypes. Types and qtypes are the same, except
880 * that T_ANY is a qtype but not a type. (You can ask for records of type
881 * T_ANY, but you can't have any records of that type in the database.)
882 */
883const struct res_sym __p_type_syms[] = {
884 {T_A, "A", "address"},
885 {T_NS, "NS", "name server"},
886 {T_MD, "MD", "mail destination (deprecated)"},
887 {T_MF, "MF", "mail forwarder (deprecated)"},
888 {T_CNAME, "CNAME", "canonical name"},
889 {T_SOA, "SOA", "start of authority"},
890 {T_MB, "MB", "mailbox"},
891 {T_MG, "MG", "mail group member"},
892 {T_MR, "MR", "mail rename"},
893 {T_NULL, "NULL", "null"},
894 {T_WKS, "WKS", "well-known service (deprecated)"},
895 {T_PTR, "PTR", "domain name pointer"},
896 {T_HINFO, "HINFO", "host information"},
897 {T_MINFO, "MINFO", "mailbox information"},
898 {T_MX, "MX", "mail exchanger"},
899 {T_TXT, "TXT", "text"},
900 {T_RP, "RP", "responsible person"},
901 {T_AFSDB, "AFSDB", "DCE or AFS server"},
902 {T_X25, "X25", "X25 address"},
903 {T_ISDN, "ISDN", "ISDN address"},
904 {T_RT, "RT", "router"},
905 {T_NSAP, "NSAP", "nsap address"},
906 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
907 {T_SIG, "SIG", "signature"},
908 {T_KEY, "KEY", "key"},
909 {T_PX, "PX", "mapping information"},
910 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
911 {T_AAAA, "AAAA", "IPv6 address"},
912 {T_LOC, "LOC", "location"},
913 {T_NXT, "NXT", "next valid name (unimplemented)"},
914 {T_EID, "EID", "endpoint identifier (unimplemented)"},
915 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
916 {T_SRV, "SRV", "server selection"},
917 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
918 {T_IXFR, "IXFR", "incremental zone transfer"},
919 {T_AXFR, "AXFR", "zone transfer"},
920 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
921 {T_MAILA, "MAILA", "mail agent (deprecated)"},
922 {T_UINFO, "UINFO", "user information (nonstandard)"},
923 {T_UID, "UID", "user ID (nonstandard)"},
924 {T_GID, "GID", "group ID (nonstandard)"},
925 {T_NAPTR, "NAPTR", "URN Naming Authority"},
926#ifdef ALLOW_T_UNSPEC
927 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
928#endif /* ALLOW_T_UNSPEC */
929 {T_ANY, "ANY", "\"any\""},
930 {0, NULL, NULL}
931};
932
933int
934__sym_ston(syms, name, success)
935 const struct res_sym *syms;
936 char *name;
937 int *success;
938{
939 for (; syms->name != 0; syms++) {
940 if (strcasecmp (name, syms->name) == 0) {
941 if (success)
942 *success = 1;
943 return (syms->number);
944 }
945 }
946 if (success)
947 *success = 0;
948 return (syms->number); /* The default value. */
949}
950
951const char *
952__sym_ntos(syms, number, success)
953 const struct res_sym *syms;
954 int number;
955 int *success;
956{
957 static char unname[20];
958
959 for (; syms->name != 0; syms++) {
960 if (number == syms->number) {
961 if (success)
962 *success = 1;
963 return (syms->name);
964 }
965 }
966
967 snprintf(unname, sizeof unname, "%d", number);
968 if (success)
969 *success = 0;
970 return (unname);
971}
972
973
974const char *
975__sym_ntop(syms, number, success)
976 const struct res_sym *syms;
977 int number;
978 int *success;
979{
980 static char unname[20];
981
982 for (; syms->name != 0; syms++) {
983 if (number == syms->number) {
984 if (success)
985 *success = 1;
986 return (syms->humanname);
987 }
988 }
989 snprintf(unname, sizeof unname, "%d", number);
990 if (success)
991 *success = 0;
992 return (unname);
993}
994
995/*
996 * Return a string for the type
997 */
998const char *
999__p_type(type)
1000 int type;
1001{
1002 return (__sym_ntos (__p_type_syms, type, (int *)0));
1003}
1004
1005/*
1006 * Return a mnemonic for class
1007 */
1008const char *
1009__p_class(class)
1010 int class;
1011{
1012 return (__sym_ntos (__p_class_syms, class, (int *)0));
1013}
1014
1015/*
1016 * Return a mnemonic for an option
1017 */
1018const char *
1019__p_option(option)
1020 u_long option;
1021{
1022 static char nbuf[40];
1023
1024 switch (option) {
1025 case RES_INIT: return "init";
1026 case RES_DEBUG: return "debug";
1027 case RES_AAONLY: return "aaonly(unimpl)";
1028 case RES_USEVC: return "usevc";
1029 case RES_PRIMARY: return "primry(unimpl)";
1030 case RES_IGNTC: return "igntc";
1031 case RES_RECURSE: return "recurs";
1032 case RES_DEFNAMES: return "defnam";
1033 case RES_STAYOPEN: return "styopn";
1034 case RES_DNSRCH: return "dnsrch";
1035 case RES_INSECURE1: return "insecure1";
1036 case RES_INSECURE2: return "insecure2";
1037 case RES_USE_INET6: return "inet6";
1038 case RES_USE_EDNS0: return "edns0";
1039 default:
1040 snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option);
1041 return (nbuf);
1042 }
1043}
1044
1045/*
1046 * Return a mnemonic for a time to live
1047 */
1048const char *
1049p_time(value)
1050 u_int32_t value;
1051{
1052 static char nbuf[40];
1053 char *ebuf;
1054 int secs, mins, hours, days;
1055 register char *p;
1056 int tmp;
1057
1058 if (value == 0) {
1059 strlcpy(nbuf, "0 secs", sizeof nbuf);
1060 return (nbuf);
1061 }
1062
1063 secs = value % 60;
1064 value /= 60;
1065 mins = value % 60;
1066 value /= 60;
1067 hours = value % 24;
1068 value /= 24;
1069 days = value;
1070 value = 0;
1071
1072#define PLURALIZE(x) x, (x == 1) ? "" : "s"
1073 p = nbuf;
1074 ebuf = nbuf + sizeof(nbuf);
1075 if (days) {
1076 if ((tmp = snprintf(p, ebuf - p, "%d day%s",
1077 PLURALIZE(days))) >= ebuf - nbuf || tmp < 0)
1078 goto full;
1079 p += tmp;
1080 }
1081 if (hours) {
1082 if (days)
1083 *p++ = ' ';
1084 if (p >= ebuf)
1085 goto full;
1086 if ((tmp = snprintf(p, ebuf - p, "%d hour%s",
1087 PLURALIZE(hours))) >= ebuf - nbuf || tmp < 0)
1088 goto full;
1089 p += tmp;
1090 }
1091 if (mins) {
1092 if (days || hours)
1093 *p++ = ' ';
1094 if (p >= ebuf)
1095 goto full;
1096 if ((tmp = snprintf(p, ebuf - p, "%d min%s",
1097 PLURALIZE(mins))) >= ebuf - nbuf || tmp < 0)
1098 goto full;
1099 p += tmp;
1100 }
1101 if (secs || ! (days || hours || mins)) {
1102 if (days || hours || mins)
1103 *p++ = ' ';
1104 if (p >= ebuf)
1105 goto full;
1106 if ((tmp = snprintf(p, ebuf - p, "%d sec%s",
1107 PLURALIZE(secs))) >= ebuf - nbuf || tmp < 0)
1108 goto full;
1109 }
1110 return (nbuf);
1111full:
1112 p = nbuf + sizeof(nbuf) - 4;
1113 *p++ = '.';
1114 *p++ = '.';
1115 *p++ = '.';
1116 *p++ = '\0';
1117 return (nbuf);
1118}
1119
1120/*
1121 * routines to convert between on-the-wire RR format and zone file format.
1122 * Does not contain conversion to/from decimal degrees; divide or multiply
1123 * by 60*60*1000 for that.
1124 */
1125
1126static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1127 1000000,10000000,100000000,1000000000};
1128
1129/* takes an XeY precision/size value, returns a string representation. */
1130static const char *
1131precsize_ntoa(prec)
1132 u_int8_t prec;
1133{
1134 static char retbuf[sizeof "90000000.00"];
1135 unsigned long val;
1136 int mantissa, exponent;
1137
1138 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1139 exponent = (int)((prec >> 0) & 0x0f) % 10;
1140
1141 val = mantissa * poweroften[exponent];
1142
1143 (void) snprintf(retbuf, sizeof retbuf, "%ld.%.2ld", val/100, val%100);
1144 return (retbuf);
1145}
1146
1147/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1148static u_int8_t
1149precsize_aton(strptr)
1150 char **strptr;
1151{
1152 unsigned int mval = 0, cmval = 0;
1153 u_int8_t retval = 0;
1154 register char *cp;
1155 register int exponent;
1156 register int mantissa;
1157
1158 cp = *strptr;
1159
1160 while (isdigit(*cp))
1161 mval = mval * 10 + (*cp++ - '0');
1162
1163 if (*cp == '.') { /* centimeters */
1164 cp++;
1165 if (isdigit(*cp)) {
1166 cmval = (*cp++ - '0') * 10;
1167 if (isdigit(*cp)) {
1168 cmval += (*cp++ - '0');
1169 }
1170 }
1171 }
1172 cmval = (mval * 100) + cmval;
1173
1174 for (exponent = 0; exponent < 9; exponent++)
1175 if (cmval < poweroften[exponent+1])
1176 break;
1177
1178 mantissa = cmval / poweroften[exponent];
1179 if (mantissa > 9)
1180 mantissa = 9;
1181
1182 retval = (mantissa << 4) | exponent;
1183
1184 *strptr = cp;
1185
1186 return (retval);
1187}
1188
1189/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1190static u_int32_t
1191latlon2ul(latlonstrptr,which)
1192 char **latlonstrptr;
1193 int *which;
1194{
1195 register char *cp;
1196 u_int32_t retval;
1197 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1198
1199 cp = *latlonstrptr;
1200
1201 while (isdigit(*cp))
1202 deg = deg * 10 + (*cp++ - '0');
1203
1204 while (isspace(*cp))
1205 cp++;
1206
1207 if (!(isdigit(*cp)))
1208 goto fndhemi;
1209
1210 while (isdigit(*cp))
1211 min = min * 10 + (*cp++ - '0');
1212
1213 while (isspace(*cp))
1214 cp++;
1215
1216 if (!(isdigit(*cp)))
1217 goto fndhemi;
1218
1219 while (isdigit(*cp))
1220 secs = secs * 10 + (*cp++ - '0');
1221
1222 if (*cp == '.') { /* decimal seconds */
1223 cp++;
1224 if (isdigit(*cp)) {
1225 secsfrac = (*cp++ - '0') * 100;
1226 if (isdigit(*cp)) {
1227 secsfrac += (*cp++ - '0') * 10;
1228 if (isdigit(*cp)) {
1229 secsfrac += (*cp++ - '0');
1230 }
1231 }
1232 }
1233 }
1234
1235 while (!isspace(*cp)) /* if any trailing garbage */
1236 cp++;
1237
1238 while (isspace(*cp))
1239 cp++;
1240
1241 fndhemi:
1242 switch (*cp) {
1243 case 'N': case 'n':
1244 case 'E': case 'e':
1245 retval = ((unsigned)1<<31)
1246 + (((((deg * 60) + min) * 60) + secs) * 1000)
1247 + secsfrac;
1248 break;
1249 case 'S': case 's':
1250 case 'W': case 'w':
1251 retval = ((unsigned)1<<31)
1252 - (((((deg * 60) + min) * 60) + secs) * 1000)
1253 - secsfrac;
1254 break;
1255 default:
1256 retval = 0; /* invalid value -- indicates error */
1257 break;
1258 }
1259
1260 switch (*cp) {
1261 case 'N': case 'n':
1262 case 'S': case 's':
1263 *which = 1; /* latitude */
1264 break;
1265 case 'E': case 'e':
1266 case 'W': case 'w':
1267 *which = 2; /* longitude */
1268 break;
1269 default:
1270 *which = 0; /* error */
1271 break;
1272 }
1273
1274 cp++; /* skip the hemisphere */
1275
1276 while (!isspace(*cp)) /* if any trailing garbage */
1277 cp++;
1278
1279 while (isspace(*cp)) /* move to next field */
1280 cp++;
1281
1282 *latlonstrptr = cp;
1283
1284 return (retval);
1285}
1286
1287/* converts a zone file representation in a string to an RDATA on-the-wire
1288 * representation. */
1289int
1290loc_aton(ascii, binary)
1291 const char *ascii;
1292 u_char *binary;
1293{
1294 const char *maxcp;
1295 u_char *bcp;
1296 char *cp;
1297
1298 u_int32_t latit = 0, longit = 0, alt = 0;
1299 u_int32_t lltemp1 = 0, lltemp2 = 0;
1300 int altmeters = 0, altfrac = 0, altsign = 1;
1301 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1302 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1303 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1304 int which1 = 0, which2 = 0;
1305
1306 cp = (char *)ascii;
1307 maxcp = cp + strlen(ascii);
1308
1309 lltemp1 = latlon2ul(&cp, &which1);
1310
1311 lltemp2 = latlon2ul(&cp, &which2);
1312
1313 switch (which1 + which2) {
1314 case 3: /* 1 + 2, the only valid combination */
1315 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1316 latit = lltemp1;
1317 longit = lltemp2;
1318 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1319 longit = lltemp1;
1320 latit = lltemp2;
1321 } else { /* some kind of brokenness */
1322 return (0);
1323 }
1324 break;
1325 default: /* we didn't get one of each */
1326 return (0);
1327 }
1328
1329 /* altitude */
1330 if (*cp == '-') {
1331 altsign = -1;
1332 cp++;
1333 }
1334
1335 if (*cp == '+')
1336 cp++;
1337
1338 while (isdigit(*cp))
1339 altmeters = altmeters * 10 + (*cp++ - '0');
1340
1341 if (*cp == '.') { /* decimal meters */
1342 cp++;
1343 if (isdigit(*cp)) {
1344 altfrac = (*cp++ - '0') * 10;
1345 if (isdigit(*cp)) {
1346 altfrac += (*cp++ - '0');
1347 }
1348 }
1349 }
1350
1351 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1352
1353 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1354 cp++;
1355
1356 while (isspace(*cp) && (cp < maxcp))
1357 cp++;
1358
1359 if (cp >= maxcp)
1360 goto defaults;
1361
1362 siz = precsize_aton(&cp);
1363
1364 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1365 cp++;
1366
1367 while (isspace(*cp) && (cp < maxcp))
1368 cp++;
1369
1370 if (cp >= maxcp)
1371 goto defaults;
1372
1373 hp = precsize_aton(&cp);
1374
1375 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1376 cp++;
1377
1378 while (isspace(*cp) && (cp < maxcp))
1379 cp++;
1380
1381 if (cp >= maxcp)
1382 goto defaults;
1383
1384 vp = precsize_aton(&cp);
1385
1386 defaults:
1387
1388 bcp = binary;
1389 *bcp++ = (u_int8_t) 0; /* version byte */
1390 *bcp++ = siz;
1391 *bcp++ = hp;
1392 *bcp++ = vp;
1393 PUTLONG(latit,bcp);
1394 PUTLONG(longit,bcp);
1395 PUTLONG(alt,bcp);
1396
1397 return (16); /* size of RR in octets */
1398}
1399
1400const char *
1401loc_ntoa(binary, ascii)
1402 const u_char *binary;
1403 char *ascii;
1404{
1405 return loc_ntoal(binary, ascii, 255);
1406}
1407
1408/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1409static const char *
1410loc_ntoal(binary, ascii, ascii_len)
1411 const u_char *binary;
1412 char *ascii;
1413 int ascii_len;
1414{
1415 static char *error = "?";
1416 register const u_char *cp = binary;
1417
1418 int latdeg, latmin, latsec, latsecfrac;
1419 int longdeg, longmin, longsec, longsecfrac;
1420 char northsouth, eastwest;
1421 int altmeters, altfrac, altsign;
1422
1423 const int referencealt = 100000 * 100;
1424
1425 int32_t latval, longval, altval;
1426 u_int32_t templ;
1427 u_int8_t sizeval, hpval, vpval, versionval;
1428
1429 char *sizestr, *hpstr, *vpstr;
1430
1431 versionval = *cp++;
1432
1433 if (versionval) {
1434 snprintf(ascii, ascii_len, "; error: unknown LOC RR version");
1435 return (ascii);
1436 }
1437
1438 sizeval = *cp++;
1439
1440 hpval = *cp++;
1441 vpval = *cp++;
1442
1443 GETLONG(templ, cp);
1444 latval = (templ - ((unsigned)1<<31));
1445
1446 GETLONG(templ, cp);
1447 longval = (templ - ((unsigned)1<<31));
1448
1449 GETLONG(templ, cp);
1450 if (templ < referencealt) { /* below WGS 84 spheroid */
1451 altval = referencealt - templ;
1452 altsign = -1;
1453 } else {
1454 altval = templ - referencealt;
1455 altsign = 1;
1456 }
1457
1458 if (latval < 0) {
1459 northsouth = 'S';
1460 latval = -latval;
1461 } else
1462 northsouth = 'N';
1463
1464 latsecfrac = latval % 1000;
1465 latval = latval / 1000;
1466 latsec = latval % 60;
1467 latval = latval / 60;
1468 latmin = latval % 60;
1469 latval = latval / 60;
1470 latdeg = latval;
1471
1472 if (longval < 0) {
1473 eastwest = 'W';
1474 longval = -longval;
1475 } else
1476 eastwest = 'E';
1477
1478 longsecfrac = longval % 1000;
1479 longval = longval / 1000;
1480 longsec = longval % 60;
1481 longval = longval / 60;
1482 longmin = longval % 60;
1483 longval = longval / 60;
1484 longdeg = longval;
1485
1486 altfrac = altval % 100;
1487 altmeters = (altval / 100) * altsign;
1488
1489 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1490 sizestr = error;
1491 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1492 hpstr = error;
1493 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1494 vpstr = error;
1495
1496 snprintf(ascii, ascii_len,
1497 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1498 latdeg, latmin, latsec, latsecfrac, northsouth,
1499 longdeg, longmin, longsec, longsecfrac, eastwest,
1500 altmeters, altfrac, sizestr, hpstr, vpstr);
1501
1502 if (sizestr != error)
1503 free(sizestr);
1504 if (hpstr != error)
1505 free(hpstr);
1506 if (vpstr != error)
1507 free(vpstr);
1508
1509 return (ascii);
1510}
1511
1512
1513/* Return the number of DNS hierarchy levels in the name. */
1514int
1515__dn_count_labels(name)
1516 char *name;
1517{
1518 int i, len, count;
1519
1520 len = strlen(name);
1521
1522 for(i = 0, count = 0; i < len; i++) {
1523 if (name[i] == '.')
1524 count++;
1525 }
1526
1527 /* don't count initial wildcard */
1528 if (name[0] == '*')
1529 if (count)
1530 count--;
1531
1532 /* don't count the null label for root. */
1533 /* if terminating '.' not found, must adjust */
1534 /* count to include last label */
1535 if (len > 0 && name[len-1] != '.')
1536 count++;
1537 return (count);
1538}
1539
1540
1541/*
1542 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1543 * SIG records are required to be printed like this, by the Secure DNS RFC.
1544 */
1545char *
1546__p_secstodate (secs)
1547 unsigned long secs;
1548{
1549 static char output[15]; /* YYYYMMDDHHMMSS and null */
1550 time_t clock = secs;
1551 struct tm *time;
1552
1553 time = gmtime(&clock);
1554 time->tm_year += 1900;
1555 time->tm_mon += 1;
1556 snprintf(output, sizeof output, "%04d%02d%02d%02d%02d%02d",
1557 time->tm_year, time->tm_mon, time->tm_mday,
1558 time->tm_hour, time->tm_min, time->tm_sec);
1559 return (output);
1560}
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
new file mode 100644
index 0000000000..c55c7763a4
--- /dev/null
+++ b/src/lib/libc/net/res_init.c
@@ -0,0 +1,639 @@
1/* $OpenBSD: res_init.c,v 1.27 2002/07/25 21:13:45 deraadt Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
6 * Copyright (c) 1985, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#ifndef INET6
59#define INET6
60#endif
61
62#if defined(LIBC_SCCS) && !defined(lint)
63#if 0
64static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
65static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
66#else
67static char rcsid[] = "$OpenBSD: res_init.c,v 1.27 2002/07/25 21:13:45 deraadt Exp $";
68#endif
69#endif /* LIBC_SCCS and not lint */
70
71#include <sys/types.h>
72#include <sys/param.h>
73#include <sys/socket.h>
74#include <sys/time.h>
75#include <netinet/in.h>
76#include <arpa/inet.h>
77#include <arpa/nameser.h>
78
79#include <stdio.h>
80#include <ctype.h>
81#include <resolv.h>
82#include <unistd.h>
83#include <stdlib.h>
84#include <string.h>
85#ifdef INET6
86#include <netdb.h>
87#endif /* INET6 */
88
89/*-------------------------------------- info about "sortlist" --------------
90 * Marc Majka 1994/04/16
91 * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
92 *
93 * NetInfo resolver configuration directory support.
94 *
95 * Allow a NetInfo directory to be created in the hierarchy which
96 * contains the same information as the resolver configuration file.
97 *
98 * - The local domain name is stored as the value of the "domain" property.
99 * - The Internet address(es) of the name server(s) are stored as values
100 * of the "nameserver" property.
101 * - The name server addresses are stored as values of the "nameserver"
102 * property.
103 * - The search list for host-name lookup is stored as values of the
104 * "search" property.
105 * - The sortlist comprised of IP address netmask pairs are stored as
106 * values of the "sortlist" property. The IP address and optional netmask
107 * should be separated by a slash (/) or ampersand (&) character.
108 * - Internal resolver variables can be set from the value of the "options"
109 * property.
110 */
111
112static void res_setoptions(char *, char *);
113
114#ifdef RESOLVSORT
115static const char sort_mask[] = "/&";
116#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
117static u_int32_t net_mask(struct in_addr);
118#endif
119
120/*
121 * Resolver state default settings.
122 */
123
124struct __res_state _res
125# if defined(__BIND_RES_TEXT)
126 = { RES_TIMEOUT, } /* Motorola, et al. */
127# endif
128 ;
129#ifdef INET6
130struct __res_state_ext _res_ext;
131#endif /* INET6 */
132
133/*
134 * Set up default settings. If the configuration file exist, the values
135 * there will have precedence. Otherwise, the server address is set to
136 * INADDR_ANY and the default domain name comes from the gethostname().
137 *
138 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
139 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
140 * since it was noted that INADDR_ANY actually meant ``the first interface
141 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
142 * it had to be "up" in order for you to reach your own name server. It
143 * was later decided that since the recommended practice is to always
144 * install local static routes through 127.0.0.1 for all your network
145 * interfaces, that we could solve this problem without a code change.
146 *
147 * The configuration file should always be used, since it is the only way
148 * to specify a default domain. If you are running a server on your local
149 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
150 * in the configuration file.
151 *
152 * Return 0 if completes successfully, -1 on error
153 */
154int
155res_init()
156{
157 register FILE *fp;
158 register char *cp, **pp;
159 register int n;
160 char buf[BUFSIZ];
161 int nserv = 0; /* number of nameserver records read from file */
162 int haveenv = 0;
163 int havesearch = 0;
164 size_t len;
165#ifdef RESOLVSORT
166 int nsort = 0;
167 char *net;
168#endif
169#ifndef RFC1535
170 int dots;
171#endif
172
173 /*
174 * These three fields used to be statically initialized. This made
175 * it hard to use this code in a shared library. It is necessary,
176 * now that we're doing dynamic initialization here, that we preserve
177 * the old semantics: if an application modifies one of these three
178 * fields of _res before res_init() is called, res_init() will not
179 * alter them. Of course, if an application is setting them to
180 * _zero_ before calling res_init(), hoping to override what used
181 * to be the static default, we can't detect it and unexpected results
182 * will follow. Zero for any of these fields would make no sense,
183 * so one can safely assume that the applications were already getting
184 * unexpected results.
185 *
186 * _res.options is tricky since some apps were known to diddle the bits
187 * before res_init() was first called. We can't replicate that semantic
188 * with dynamic initialization (they may have turned bits off that are
189 * set in RES_DEFAULT). Our solution is to declare such applications
190 * "broken". They could fool us by setting RES_INIT but none do (yet).
191 */
192 if (!_res.retrans)
193 _res.retrans = RES_TIMEOUT;
194 if (!_res.retry)
195 _res.retry = 4;
196 if (!(_res.options & RES_INIT))
197 _res.options = RES_DEFAULT;
198
199#ifdef USELOOPBACK
200 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
201#else
202 _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
203#endif
204 _res.nsaddr.sin_family = AF_INET;
205 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
206 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
207#ifdef INET6
208 if (sizeof(_res_ext.nsaddr) >= _res.nsaddr.sin_len)
209 memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len);
210#endif
211 _res.nscount = 1;
212 _res.ndots = 1;
213 _res.pfcode = 0;
214 strlcpy(_res.lookups, "f", sizeof _res.lookups);
215
216 /* Allow user to override the local domain definition */
217 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
218 strlcpy(_res.defdname, cp, sizeof(_res.defdname));
219 haveenv++;
220
221 /*
222 * Set search list to be blank-separated strings
223 * from rest of env value. Permits users of LOCALDOMAIN
224 * to still have a search list, and anyone to set the
225 * one that they want to use as an individual (even more
226 * important now that the rfc1535 stuff restricts searches)
227 */
228 cp = _res.defdname;
229 pp = _res.dnsrch;
230 *pp++ = cp;
231 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
232 if (*cp == '\n') /* silly backwards compat */
233 break;
234 else if (*cp == ' ' || *cp == '\t') {
235 *cp = 0;
236 n = 1;
237 } else if (n) {
238 *pp++ = cp;
239 n = 0;
240 havesearch = 1;
241 }
242 }
243 /* null terminate last domain if there are excess */
244 while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
245 cp++;
246 *cp = '\0';
247 *pp++ = 0;
248 }
249
250#define MATCH(line, name) \
251 (!strncmp(line, name, sizeof(name) - 1) && \
252 (line[sizeof(name) - 1] == ' ' || \
253 line[sizeof(name) - 1] == '\t'))
254
255 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
256 strlcpy(_res.lookups, "bf", sizeof _res.lookups);
257
258 /* read the config file */
259 buf[0] = '\0';
260 while ((cp = fgetln(fp, &len)) != NULL) {
261 /* skip lines that are too long or zero length */
262 if (len >= sizeof(buf) || len == 0)
263 continue;
264 (void)memcpy(buf, cp, len);
265 buf[len] = '\0';
266 /* skip comments */
267 if ((cp = strpbrk(buf, ";#")) != NULL)
268 *cp = '\0';
269 if (buf[0] == '\0')
270 continue;
271 /* read default domain name */
272 if (MATCH(buf, "domain")) {
273 if (haveenv) /* skip if have from environ */
274 continue;
275 cp = buf + sizeof("domain") - 1;
276 while (*cp == ' ' || *cp == '\t')
277 cp++;
278 if ((*cp == '\0') || (*cp == '\n'))
279 continue;
280 strlcpy(_res.defdname, cp, sizeof(_res.defdname));
281 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
282 *cp = '\0';
283 havesearch = 0;
284 continue;
285 }
286 /* lookup types */
287 if (MATCH(buf, "lookup")) {
288 char *sp = NULL;
289
290 bzero(_res.lookups, sizeof _res.lookups);
291 cp = buf + sizeof("lookup") - 1;
292 for (n = 0;; cp++) {
293 if (n == MAXDNSLUS)
294 break;
295 if ((*cp == '\0') || (*cp == '\n')) {
296 if (sp) {
297 if (*sp=='y' || *sp=='b' || *sp=='f')
298 _res.lookups[n++] = *sp;
299 sp = NULL;
300 }
301 break;
302 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
303 if (sp) {
304 if (*sp=='y' || *sp=='b' || *sp=='f')
305 _res.lookups[n++] = *sp;
306 sp = NULL;
307 }
308 } else if (sp == NULL)
309 sp = cp;
310 }
311 continue;
312 }
313 /* set search list */
314 if (MATCH(buf, "search")) {
315 if (haveenv) /* skip if have from environ */
316 continue;
317 cp = buf + sizeof("search") - 1;
318 while (*cp == ' ' || *cp == '\t')
319 cp++;
320 if ((*cp == '\0') || (*cp == '\n'))
321 continue;
322 strlcpy(_res.defdname, cp, sizeof(_res.defdname));
323 if ((cp = strchr(_res.defdname, '\n')) != NULL)
324 *cp = '\0';
325 /*
326 * Set search list to be blank-separated strings
327 * on rest of line.
328 */
329 cp = _res.defdname;
330 pp = _res.dnsrch;
331 *pp++ = cp;
332 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
333 if (*cp == ' ' || *cp == '\t') {
334 *cp = 0;
335 n = 1;
336 } else if (n) {
337 *pp++ = cp;
338 n = 0;
339 }
340 }
341 /* null terminate last domain if there are excess */
342 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
343 cp++;
344 *cp = '\0';
345 *pp++ = 0;
346 havesearch = 1;
347 continue;
348 }
349 /* read nameservers to query */
350 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
351#ifdef INET6
352 char *q;
353 struct addrinfo hints, *res;
354 char pbuf[NI_MAXSERV];
355#else
356 struct in_addr a;
357#endif /* INET6 */
358
359 cp = buf + sizeof("nameserver") - 1;
360 while (*cp == ' ' || *cp == '\t')
361 cp++;
362#ifdef INET6
363 if ((*cp == '\0') || (*cp == '\n'))
364 continue;
365 for (q = cp; *q; q++) {
366 if (isspace(*q)) {
367 *q = '\0';
368 break;
369 }
370 }
371 memset(&hints, 0, sizeof(hints));
372 hints.ai_flags = AI_NUMERICHOST;
373 hints.ai_socktype = SOCK_DGRAM;
374 snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
375 res = NULL;
376 if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
377 res->ai_next == NULL) {
378 if (res->ai_addrlen <= sizeof(_res_ext.nsaddr_list[nserv])) {
379 memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
380 res->ai_addrlen);
381 } else {
382 memset(&_res_ext.nsaddr_list[nserv], 0,
383 sizeof(_res_ext.nsaddr_list[nserv]));
384 }
385 if (res->ai_addrlen <= sizeof(_res.nsaddr_list[nserv])) {
386 memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
387 res->ai_addrlen);
388 } else {
389 memset(&_res.nsaddr_list[nserv], 0,
390 sizeof(_res.nsaddr_list[nserv]));
391 }
392 nserv++;
393 }
394 if (res)
395 freeaddrinfo(res);
396#else /* INET6 */
397 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
398 _res.nsaddr_list[nserv].sin_addr = a;
399 _res.nsaddr_list[nserv].sin_family = AF_INET;
400 _res.nsaddr_list[nserv].sin_port =
401 htons(NAMESERVER_PORT);
402 _res.nsaddr_list[nserv].sin_len =
403 sizeof(struct sockaddr_in);
404 nserv++;
405 }
406#endif /* INET6 */
407 continue;
408 }
409#ifdef RESOLVSORT
410 if (MATCH(buf, "sortlist")) {
411 struct in_addr a;
412#ifdef INET6
413 struct in6_addr a6;
414 int m, i;
415 u_char *u;
416#endif /* INET6 */
417
418 cp = buf + sizeof("sortlist") - 1;
419 while (nsort < MAXRESOLVSORT) {
420 while (*cp == ' ' || *cp == '\t')
421 cp++;
422 if (*cp == '\0' || *cp == '\n' || *cp == ';')
423 break;
424 net = cp;
425 while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
426 isascii(*cp) && !isspace(*cp))
427 cp++;
428 n = *cp;
429 *cp = 0;
430 if (inet_aton(net, &a)) {
431 _res.sort_list[nsort].addr = a;
432 if (ISSORTMASK(n)) {
433 *cp++ = n;
434 net = cp;
435 while (*cp && *cp != ';' &&
436 isascii(*cp) && !isspace(*cp))
437 cp++;
438 n = *cp;
439 *cp = 0;
440 if (inet_aton(net, &a)) {
441 _res.sort_list[nsort].mask = a.s_addr;
442 } else {
443 _res.sort_list[nsort].mask =
444 net_mask(_res.sort_list[nsort].addr);
445 }
446 } else {
447 _res.sort_list[nsort].mask =
448 net_mask(_res.sort_list[nsort].addr);
449 }
450#ifdef INET6
451 _res_ext.sort_list[nsort].af = AF_INET;
452 _res_ext.sort_list[nsort].addr.ina =
453 _res.sort_list[nsort].addr;
454 _res_ext.sort_list[nsort].mask.ina.s_addr =
455 _res.sort_list[nsort].mask;
456#endif /* INET6 */
457 nsort++;
458 }
459#ifdef INET6
460 else if (inet_pton(AF_INET6, net, &a6) == 1) {
461 _res_ext.sort_list[nsort].af = AF_INET6;
462 _res_ext.sort_list[nsort].addr.in6a = a6;
463 u = (u_char *)&_res_ext.sort_list[nsort].mask.in6a;
464 *cp++ = n;
465 net = cp;
466 while (*cp && *cp != ';' &&
467 isascii(*cp) && !isspace(*cp))
468 cp++;
469 m = n;
470 n = *cp;
471 *cp = 0;
472 switch (m) {
473 case '/':
474 m = atoi(net);
475 break;
476 case '&':
477 if (inet_pton(AF_INET6, net, u) == 1) {
478 m = -1;
479 break;
480 }
481 /*FALLTHRU*/
482 default:
483 m = sizeof(struct in6_addr) * NBBY;
484 break;
485 }
486 if (m >= 0) {
487 for (i = 0; i < sizeof(struct in6_addr); i++) {
488 if (m <= 0) {
489 *u = 0;
490 } else {
491 m -= NBBY;
492 *u = (u_char)~0;
493 if (m < 0)
494 *u <<= -m;
495 }
496 u++;
497 }
498 }
499 nsort++;
500 }
501#endif /* INET6 */
502 *cp = n;
503 }
504 continue;
505 }
506#endif
507 if (MATCH(buf, "options")) {
508 res_setoptions(buf + sizeof("options") - 1, "conf");
509 continue;
510 }
511 }
512 if (nserv > 1)
513 _res.nscount = nserv;
514#ifdef RESOLVSORT
515 _res.nsort = nsort;
516#endif
517 (void) fclose(fp);
518 }
519 if (_res.defdname[0] == 0 &&
520 gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
521 (cp = strchr(buf, '.')) != NULL)
522 {
523 strlcpy(_res.defdname, cp + 1,
524 sizeof(_res.defdname));
525 }
526
527 /* find components of local domain that might be searched */
528 if (havesearch == 0) {
529 pp = _res.dnsrch;
530 *pp++ = _res.defdname;
531 *pp = NULL;
532
533#ifndef RFC1535
534 dots = 0;
535 for (cp = _res.defdname; *cp; cp++)
536 dots += (*cp == '.');
537
538 cp = _res.defdname;
539 while (pp < _res.dnsrch + MAXDFLSRCH) {
540 if (dots < LOCALDOMAINPARTS)
541 break;
542 cp = strchr(cp, '.') + 1; /* we know there is one */
543 *pp++ = cp;
544 dots--;
545 }
546 *pp = NULL;
547#ifdef DEBUG
548 if (_res.options & RES_DEBUG) {
549 printf(";; res_init()... default dnsrch list:\n");
550 for (pp = _res.dnsrch; *pp; pp++)
551 printf(";;\t%s\n", *pp);
552 printf(";;\t..END..\n");
553 }
554#endif /* DEBUG */
555#endif /* !RFC1535 */
556 }
557
558 if (issetugid())
559 _res.options |= RES_NOALIASES;
560 else if ((cp = getenv("RES_OPTIONS")) != NULL)
561 res_setoptions(cp, "env");
562 _res.options |= RES_INIT;
563 return (0);
564}
565
566/* ARGSUSED */
567static void
568res_setoptions(options, source)
569 char *options, *source;
570{
571 char *cp = options;
572 char *endp;
573 long l;
574
575#ifdef DEBUG
576 if (_res.options & RES_DEBUG)
577 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
578 options, source);
579#endif
580 while (*cp) {
581 /* skip leading and inner runs of spaces */
582 while (*cp == ' ' || *cp == '\t')
583 cp++;
584 /* search for and process individual options */
585 if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
586 char *p = cp + sizeof("ndots:") - 1;
587 l = strtol(p, &endp, 10);
588 if (l >= 0 && endp != p &&
589 (*endp = '\0' || isspace(*endp))) {
590 if (l <= RES_MAXNDOTS)
591 _res.ndots = l;
592 else
593 _res.ndots = RES_MAXNDOTS;
594#ifdef DEBUG
595 if (_res.options & RES_DEBUG)
596 printf(";;\tndots=%u\n", _res.ndots);
597#endif
598 }
599 } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
600#ifdef DEBUG
601 if (!(_res.options & RES_DEBUG)) {
602 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
603 options, source);
604 _res.options |= RES_DEBUG;
605 }
606 printf(";;\tdebug\n");
607#endif
608 } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
609 _res.options |= RES_USE_INET6;
610 } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
611 _res.options |= RES_INSECURE1;
612 } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
613 _res.options |= RES_INSECURE2;
614 } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
615 _res.options |= RES_USE_EDNS0;
616 } else {
617 /* XXX - print a warning here? */
618 }
619 /* skip to next run of spaces */
620 while (*cp && *cp != ' ' && *cp != '\t')
621 cp++;
622 }
623}
624
625#ifdef RESOLVSORT
626/* XXX - should really support CIDR which means explicit masks always. */
627static u_int32_t
628net_mask(in) /* XXX - should really use system's version of this */
629 struct in_addr in;
630{
631 register u_int32_t i = ntohl(in.s_addr);
632
633 if (IN_CLASSA(i))
634 return (htonl(IN_CLASSA_NET));
635 else if (IN_CLASSB(i))
636 return (htonl(IN_CLASSB_NET));
637 return (htonl(IN_CLASSC_NET));
638}
639#endif
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
new file mode 100644
index 0000000000..6cd6a00dbe
--- /dev/null
+++ b/src/lib/libc/net/res_mkquery.c
@@ -0,0 +1,242 @@
1/* $OpenBSD: res_mkquery.c,v 1.12 2002/08/28 03:19:38 itojun Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
6 * Copyright (c) 1985, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.12 2002/08/28 03:19:38 itojun Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/nameser.h>
71
72#include <stdio.h>
73#include <netdb.h>
74#include <resolv.h>
75#include <string.h>
76
77/*
78 * Form all types of queries.
79 * Returns the size of the result or -1.
80 */
81/* ARGSUSED */
82int
83res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
84 int op; /* opcode of query */
85 const char *dname; /* domain name */
86 int class, type; /* class and type of query */
87 const u_char *data; /* resource record data */
88 int datalen; /* length of data */
89 const u_char *newrr_in; /* new rr for modify or append */
90 u_char *buf; /* buffer to put query */
91 int buflen; /* size of buffer */
92{
93 register HEADER *hp;
94 register u_char *cp, *ep;
95 register int n;
96 u_char *dnptrs[20], **dpp, **lastdnptr;
97
98 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
99 h_errno = NETDB_INTERNAL;
100 return (-1);
101 }
102#ifdef DEBUG
103 if (_res.options & RES_DEBUG)
104 printf(";; res_mkquery(%d, %s, %d, %d)\n",
105 op, dname, class, type);
106#endif
107 /*
108 * Initialize header fields.
109 *
110 * A special random number generator is used to create non predictable
111 * and non repeating ids over a long period. It also avoids reuse
112 * by switching between two distinct number cycles.
113 */
114
115 if ((buf == NULL) || (buflen < HFIXEDSZ))
116 return (-1);
117 bzero(buf, HFIXEDSZ);
118 hp = (HEADER *) buf;
119 _res.id = res_randomid();
120 hp->id = htons(_res.id);
121 hp->opcode = op;
122 hp->rd = (_res.options & RES_RECURSE) != 0;
123 hp->rcode = NOERROR;
124 cp = buf + HFIXEDSZ;
125 ep = buf + buflen;
126 dpp = dnptrs;
127 *dpp++ = buf;
128 *dpp++ = NULL;
129 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
130 /*
131 * perform opcode specific processing
132 */
133 switch (op) {
134 case QUERY: /*FALLTHROUGH*/
135 case NS_NOTIFY_OP:
136 if (ep - cp < QFIXEDSZ)
137 return (-1);
138 if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
139 lastdnptr)) < 0)
140 return (-1);
141 cp += n;
142 __putshort(type, cp);
143 cp += INT16SZ;
144 __putshort(class, cp);
145 cp += INT16SZ;
146 hp->qdcount = htons(1);
147 if (op == QUERY || data == NULL)
148 break;
149 /*
150 * Make an additional record for completion domain.
151 */
152 if (ep - cp < RRFIXEDSZ)
153 return (-1);
154 n = dn_comp((char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs,
155 lastdnptr);
156 if (n < 0)
157 return (-1);
158 cp += n;
159 __putshort(T_NULL, cp);
160 cp += INT16SZ;
161 __putshort(class, cp);
162 cp += INT16SZ;
163 __putlong(0, cp);
164 cp += INT32SZ;
165 __putshort(0, cp);
166 cp += INT16SZ;
167 hp->arcount = htons(1);
168 break;
169
170 case IQUERY:
171 /*
172 * Initialize answer section
173 */
174 if (ep - cp < 1 + RRFIXEDSZ + datalen)
175 return (-1);
176 *cp++ = '\0'; /* no domain name */
177 __putshort(type, cp);
178 cp += INT16SZ;
179 __putshort(class, cp);
180 cp += INT16SZ;
181 __putlong(0, cp);
182 cp += INT32SZ;
183 __putshort(datalen, cp);
184 cp += INT16SZ;
185 if (datalen) {
186 bcopy(data, cp, datalen);
187 cp += datalen;
188 }
189 hp->ancount = htons(1);
190 break;
191
192 default:
193 return (-1);
194 }
195 return (cp - buf);
196}
197
198/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
199int
200res_opt(n0, buf, buflen, anslen)
201 int n0;
202 u_char *buf; /* buffer to put query */
203 int buflen; /* size of buffer */
204 int anslen; /* answer buffer length */
205{
206 register HEADER *hp;
207 register u_char *cp, *ep;
208
209 hp = (HEADER *) buf;
210 cp = buf + n0;
211 ep = buf + buflen;
212
213 if (ep - cp < 1 + RRFIXEDSZ)
214 return -1;
215
216 *cp++ = 0; /* "." */
217
218 __putshort(T_OPT, cp); /* TYPE */
219 cp += INT16SZ;
220 if (anslen > 0xffff)
221 anslen = 0xffff; /* limit to 16bit value */
222 __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
223 cp += INT16SZ;
224 *cp++ = NOERROR; /* extended RCODE */
225 *cp++ = 0; /* EDNS version */
226 if (_res.options & RES_USE_DNSSEC) {
227#ifdef DEBUG
228 if (_res.options & RES_DEBUG)
229 printf(";; res_opt()... ENDS0 DNSSEC OK\n");
230#endif /* DEBUG */
231 __putshort(DNS_MESSAGEEXTFLAG_DO, cp); /* EDNS Z field */
232 cp += INT16SZ;
233 } else {
234 __putshort(0, cp); /* EDNS Z field */
235 cp += INT16SZ;
236 }
237 __putshort(0, cp); /* RDLEN */
238 cp += INT16SZ;
239 hp->arcount = htons(ntohs(hp->arcount) + 1);
240
241 return cp - buf;
242}
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
new file mode 100644
index 0000000000..9c1aef1218
--- /dev/null
+++ b/src/lib/libc/net/res_query.c
@@ -0,0 +1,405 @@
1/* $OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $ */
2
3/*
4 * ++Copyright++ 1988, 1993
5 * -
6 * Copyright (c) 1988, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $";
64#endif
65#endif /* LIBC_SCCS and not lint */
66
67#include <sys/types.h>
68#include <sys/param.h>
69#include <netinet/in.h>
70#include <arpa/inet.h>
71#include <arpa/nameser.h>
72
73#include <stdio.h>
74#include <netdb.h>
75#include <resolv.h>
76#include <ctype.h>
77#include <errno.h>
78#include <stdlib.h>
79#include <string.h>
80#include <unistd.h>
81
82#if PACKETSZ > 1024
83#define MAXPACKET PACKETSZ
84#else
85#define MAXPACKET 1024
86#endif
87
88const char *hostalias(const char *);
89int h_errno;
90extern int res_opt(int, u_char *, int, int);
91
92/*
93 * Formulate a normal query, send, and await answer.
94 * Returned answer is placed in supplied buffer "answer".
95 * Perform preliminary check of answer, returning success only
96 * if no error is indicated and the answer count is nonzero.
97 * Return the size of the response on success, -1 on error.
98 * Error number is left in h_errno.
99 *
100 * Caller must parse answer and determine whether it answers the question.
101 */
102int
103res_query(name, class, type, answer, anslen)
104 const char *name; /* domain name */
105 int class, type; /* class and type of query */
106 u_char *answer; /* buffer to put answer */
107 int anslen; /* size of answer buffer */
108{
109 u_char buf[MAXPACKET];
110 register HEADER *hp = (HEADER *) answer;
111 int n;
112
113 hp->rcode = NOERROR; /* default */
114
115 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
116 h_errno = NETDB_INTERNAL;
117 return (-1);
118 }
119#ifdef DEBUG
120 if (_res.options & RES_DEBUG)
121 printf(";; res_query(%s, %d, %d)\n", name, class, type);
122#endif
123
124 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
125 buf, sizeof(buf));
126 if (n > 0 && ((_res.options & RES_USE_EDNS0) ||
127 (_res.options & RES_USE_DNSSEC))) {
128 n = res_opt(n, buf, sizeof(buf), anslen);
129 }
130
131 if (n <= 0) {
132#ifdef DEBUG
133 if (_res.options & RES_DEBUG)
134 printf(";; res_query: mkquery failed\n");
135#endif
136 h_errno = NO_RECOVERY;
137 return (n);
138 }
139 n = res_send(buf, n, answer, anslen);
140 if (n < 0) {
141#ifdef DEBUG
142 if (_res.options & RES_DEBUG)
143 printf(";; res_query: send error\n");
144#endif
145 h_errno = TRY_AGAIN;
146 return (n);
147 }
148
149 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
150#ifdef DEBUG
151 if (_res.options & RES_DEBUG)
152 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
153 ntohs(hp->ancount));
154#endif
155 switch (hp->rcode) {
156 case NXDOMAIN:
157 h_errno = HOST_NOT_FOUND;
158 break;
159 case SERVFAIL:
160 h_errno = TRY_AGAIN;
161 break;
162 case NOERROR:
163 h_errno = NO_DATA;
164 break;
165 case FORMERR:
166 case NOTIMP:
167 case REFUSED:
168 default:
169 h_errno = NO_RECOVERY;
170 break;
171 }
172 return (-1);
173 }
174 return (n);
175}
176
177/*
178 * Formulate a normal query, send, and retrieve answer in supplied buffer.
179 * Return the size of the response on success, -1 on error.
180 * If enabled, implement search rules until answer or unrecoverable failure
181 * is detected. Error code, if any, is left in h_errno.
182 */
183int
184res_search(name, class, type, answer, anslen)
185 const char *name; /* domain name */
186 int class, type; /* class and type of query */
187 u_char *answer; /* buffer to put answer */
188 int anslen; /* size of answer */
189{
190 register const char *cp, * const *domain;
191 HEADER *hp = (HEADER *) answer;
192 u_int dots;
193 int trailing_dot, ret, saved_herrno;
194 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
195
196 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
197 h_errno = NETDB_INTERNAL;
198 return (-1);
199 }
200 errno = 0;
201 h_errno = HOST_NOT_FOUND; /* default, if we never query */
202 dots = 0;
203 for (cp = name; *cp; cp++)
204 dots += (*cp == '.');
205 trailing_dot = 0;
206 if (cp > name && *--cp == '.')
207 trailing_dot++;
208
209 /*
210 * if there aren't any dots, it could be a user-level alias
211 */
212 if (!dots && (cp = __hostalias(name)) != NULL)
213 return (res_query(cp, class, type, answer, anslen));
214
215 /*
216 * If there are dots in the name already, let's just give it a try
217 * 'as is'. The threshold can be set with the "ndots" option.
218 */
219 saved_herrno = -1;
220 if (dots >= _res.ndots) {
221 ret = res_querydomain(name, NULL, class, type, answer, anslen);
222 if (ret > 0)
223 return (ret);
224 saved_herrno = h_errno;
225 tried_as_is++;
226 }
227
228 /*
229 * We do at least one level of search if
230 * - there is no dot and RES_DEFNAME is set, or
231 * - there is at least one dot, there is no trailing dot,
232 * and RES_DNSRCH is set.
233 */
234 if ((!dots && (_res.options & RES_DEFNAMES)) ||
235 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
236 int done = 0;
237
238 for (domain = (const char * const *)_res.dnsrch;
239 *domain && !done;
240 domain++) {
241
242 ret = res_querydomain(name, *domain, class, type,
243 answer, anslen);
244 if (ret > 0)
245 return (ret);
246
247 /*
248 * If no server present, give up.
249 * If name isn't found in this domain,
250 * keep trying higher domains in the search list
251 * (if that's enabled).
252 * On a NO_DATA error, keep trying, otherwise
253 * a wildcard entry of another type could keep us
254 * from finding this entry higher in the domain.
255 * If we get some other error (negative answer or
256 * server failure), then stop searching up,
257 * but try the input name below in case it's
258 * fully-qualified.
259 */
260 if (errno == ECONNREFUSED) {
261 h_errno = TRY_AGAIN;
262 return (-1);
263 }
264
265 switch (h_errno) {
266 case NO_DATA:
267 got_nodata++;
268 /* FALLTHROUGH */
269 case HOST_NOT_FOUND:
270 /* keep trying */
271 break;
272 case TRY_AGAIN:
273 if (hp->rcode == SERVFAIL) {
274 /* try next search element, if any */
275 got_servfail++;
276 break;
277 }
278 /* FALLTHROUGH */
279 default:
280 /* anything else implies that we're done */
281 done++;
282 }
283
284 /* if we got here for some reason other than DNSRCH,
285 * we only wanted one iteration of the loop, so stop.
286 */
287 if (!(_res.options & RES_DNSRCH))
288 done++;
289 }
290 }
291
292 /* if we have not already tried the name "as is", do that now.
293 * note that we do this regardless of how many dots were in the
294 * name or whether it ends with a dot.
295 */
296 if (!tried_as_is) {
297 ret = res_querydomain(name, NULL, class, type, answer, anslen);
298 if (ret > 0)
299 return (ret);
300 }
301
302 /* if we got here, we didn't satisfy the search.
303 * if we did an initial full query, return that query's h_errno
304 * (note that we wouldn't be here if that query had succeeded).
305 * else if we ever got a nodata, send that back as the reason.
306 * else send back meaningless h_errno, that being the one from
307 * the last DNSRCH we did.
308 */
309 if (saved_herrno != -1)
310 h_errno = saved_herrno;
311 else if (got_nodata)
312 h_errno = NO_DATA;
313 else if (got_servfail)
314 h_errno = TRY_AGAIN;
315 return (-1);
316}
317
318/*
319 * Perform a call on res_query on the concatenation of name and domain,
320 * removing a trailing dot from name if domain is NULL.
321 */
322int
323res_querydomain(name, domain, class, type, answer, anslen)
324 const char *name, *domain;
325 int class, type; /* class and type of query */
326 u_char *answer; /* buffer to put answer */
327 int anslen; /* size of answer */
328{
329 char nbuf[MAXDNAME*2+1+1];
330 const char *longname = nbuf;
331 int n;
332
333 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
334 h_errno = NETDB_INTERNAL;
335 return (-1);
336 }
337#ifdef DEBUG
338 if (_res.options & RES_DEBUG)
339 printf(";; res_querydomain(%s, %s, %d, %d)\n",
340 name, domain?domain:"<Nil>", class, type);
341#endif
342 if (domain == NULL) {
343 /*
344 * Check for trailing '.';
345 * copy without '.' if present.
346 */
347 n = strlen(name) - 1;
348 if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) {
349 bcopy(name, nbuf, n);
350 nbuf[n] = '\0';
351 } else
352 longname = name;
353 } else
354 snprintf(nbuf, sizeof nbuf, "%.*s.%.*s",
355 MAXDNAME, name, MAXDNAME, domain);
356
357 return (res_query(longname, class, type, answer, anslen));
358}
359
360const char *
361hostalias(name)
362 register const char *name;
363{
364 register char *cp1, *cp2;
365 FILE *fp;
366 char *file;
367 char buf[BUFSIZ];
368 static char abuf[MAXDNAME];
369 size_t len;
370
371 if (_res.options & RES_NOALIASES)
372 return (NULL);
373 file = getenv("HOSTALIASES");
374 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
375 return (NULL);
376 setbuf(fp, NULL);
377 while ((cp1 = fgetln(fp, &len)) != NULL) {
378 if (cp1[len-1] == '\n')
379 len--;
380 if (len >= sizeof(buf) || len == 0)
381 continue;
382 (void)memcpy(buf, cp1, len);
383 buf[len] = '\0';
384
385 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
386 ;
387 if (!*cp1)
388 break;
389 *cp1 = '\0';
390 if (!strcasecmp(buf, name)) {
391 while (isspace(*++cp1))
392 ;
393 if (!*cp1)
394 break;
395 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
396 ;
397 *cp2 = '\0';
398 strlcpy(abuf, cp1, sizeof(abuf));
399 fclose(fp);
400 return (abuf);
401 }
402 }
403 fclose(fp);
404 return (NULL);
405}
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c
new file mode 100644
index 0000000000..c739e4a952
--- /dev/null
+++ b/src/lib/libc/net/res_random.c
@@ -0,0 +1,229 @@
1/* $OpenBSD: res_random.c,v 1.12 2002/06/27 10:14:02 itojun Exp $ */
2
3/*
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
8 * such a mathematical system to generate more random (yet non-repeating)
9 * ids to solve the resolver/named problem. But Niels designed the
10 * actual system based on the constraints.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Niels Provos.
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * seed = random 15bit
40 * n = prime, g0 = generator to n,
41 * j = random so that gcd(j,n-1) == 1
42 * g = g0^j mod n will be a generator again.
43 *
44 * X[0] = random seed.
45 * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
46 * with a = 7^(even random) mod m,
47 * b = random with gcd(b,m) == 1
48 * m = 31104 and a maximal period of m-1.
49 *
50 * The transaction id is determined by:
51 * id[n] = seed xor (g^X[n] mod n)
52 *
53 * Effectivly the id is restricted to the lower 15 bits, thus
54 * yielding two different cycles by toggling the msb on and off.
55 * This avoids reuse issues caused by reseeding.
56 *
57 * The 16 bit space is very small and brute force attempts are
58 * entirly feasible, we skip a random number of transaction ids
59 * so that an attacker will not get sequential ids.
60 */
61
62#include <sys/types.h>
63#include <netinet/in.h>
64#include <sys/time.h>
65#include <resolv.h>
66
67#include <unistd.h>
68#include <stdlib.h>
69#include <string.h>
70
71#define RU_OUT 180 /* Time after wich will be reseeded */
72#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
73#define RU_GEN 2 /* Starting generator */
74#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
75#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
76#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
77
78#define PFAC_N 3
79const static u_int16_t pfacts[PFAC_N] = {
80 2,
81 3,
82 2729
83};
84
85static u_int16_t ru_x;
86static u_int16_t ru_seed, ru_seed2;
87static u_int16_t ru_a, ru_b;
88static u_int16_t ru_g;
89static u_int16_t ru_counter = 0;
90static u_int16_t ru_msb = 0;
91static long ru_reseed;
92static u_int32_t tmp; /* Storage for unused random */
93static struct timeval tv;
94
95static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
96static void res_initid(void);
97
98/*
99 * Do a fast modular exponation, returned value will be in the range
100 * of 0 - (mod-1)
101 */
102
103static u_int16_t
104pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
105{
106 u_int16_t s, t, u;
107
108 s = 1;
109 t = gen;
110 u = exp;
111
112 while (u) {
113 if (u & 1)
114 s = (s*t) % mod;
115 u >>= 1;
116 t = (t*t) % mod;
117 }
118 return (s);
119}
120
121/*
122 * Initializes the seed and chooses a suitable generator. Also toggles
123 * the msb flag. The msb flag is used to generate two distinct
124 * cycles of random numbers and thus avoiding reuse of ids.
125 *
126 * This function is called from res_randomid() when needed, an
127 * application does not have to worry about it.
128 */
129static void
130res_initid()
131{
132 u_int16_t j, i;
133 int noprime = 1;
134
135 tmp = arc4random();
136 ru_x = (tmp & 0xFFFF) % RU_M;
137
138 /* 15 bits of random seed */
139 ru_seed = (tmp >> 16) & 0x7FFF;
140 tmp = arc4random();
141 ru_seed2 = tmp & 0x7FFF;
142
143 tmp = arc4random();
144
145 /* Determine the LCG we use */
146 ru_b = (tmp & 0xfffe) | 1;
147 ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
148 while (ru_b % 3 == 0)
149 ru_b += 2;
150
151 tmp = arc4random();
152 j = tmp % RU_N;
153 tmp = tmp >> 16;
154
155 /*
156 * Do a fast gcd(j,RU_N-1), so we can find a j with
157 * gcd(j, RU_N-1) == 1, giving a new generator for
158 * RU_GEN^j mod RU_N
159 */
160
161 while (noprime) {
162 for (i=0; i<PFAC_N; i++)
163 if (j%pfacts[i] == 0)
164 break;
165
166 if (i>=PFAC_N)
167 noprime = 0;
168 else
169 j = (j+1) % RU_N;
170 }
171
172 ru_g = pmod(RU_GEN,j,RU_N);
173 ru_counter = 0;
174
175 gettimeofday(&tv, NULL);
176 ru_reseed = tv.tv_sec + RU_OUT;
177 ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
178}
179
180u_int
181res_randomid()
182{
183 int i, n;
184
185 gettimeofday(&tv, NULL);
186 if (ru_counter >= RU_MAX || tv.tv_sec > ru_reseed)
187 res_initid();
188
189 if (!tmp)
190 tmp = arc4random();
191
192 /* Skip a random number of ids */
193 n = tmp & 0x7; tmp = tmp >> 3;
194 if (ru_counter + n >= RU_MAX)
195 res_initid();
196
197 for (i=0; i<=n; i++)
198 /* Linear Congruential Generator */
199 ru_x = (ru_a*ru_x + ru_b) % RU_M;
200
201 ru_counter += i;
202
203 return (ru_seed ^ pmod(ru_g,ru_seed2 ^ ru_x,RU_N)) | ru_msb;
204}
205
206#if 0
207void
208main(int argc, char **argv)
209{
210 int i, n;
211 u_int16_t wert;
212
213 res_initid();
214
215 printf("Generator: %u\n", ru_g);
216 printf("Seed: %u\n", ru_seed);
217 printf("Reseed at %ld\n", ru_reseed);
218 printf("Ru_X: %u\n", ru_x);
219 printf("Ru_A: %u\n", ru_a);
220 printf("Ru_B: %u\n", ru_b);
221
222 n = atoi(argv[1]);
223 for (i=0;i<n;i++) {
224 wert = res_randomid();
225 printf("%06d\n", wert);
226 }
227}
228#endif
229
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
new file mode 100644
index 0000000000..81bf23ba9f
--- /dev/null
+++ b/src/lib/libc/net/res_send.c
@@ -0,0 +1,893 @@
1/* $OpenBSD: res_send.c,v 1.11 2002/02/16 21:27:23 millert Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
6 * Copyright (c) 1985, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#ifndef INET6
59#define INET6
60#endif
61
62#if defined(LIBC_SCCS) && !defined(lint)
63#if 0
64static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
65static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
66#else
67static char rcsid[] = "$OpenBSD: res_send.c,v 1.11 2002/02/16 21:27:23 millert Exp $";
68#endif
69#endif /* LIBC_SCCS and not lint */
70
71 /* change this to "0"
72 * if you talk to a lot
73 * of multi-homed SunOS
74 * ("broken") name servers.
75 */
76#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
77
78/*
79 * Send query to name server and wait for reply.
80 */
81
82#include <sys/types.h>
83#include <sys/param.h>
84#include <sys/time.h>
85#include <sys/socket.h>
86#include <sys/uio.h>
87#include <netinet/in.h>
88#include <arpa/nameser.h>
89#include <arpa/inet.h>
90
91#include <stdio.h>
92#include <netdb.h>
93#include <errno.h>
94#include <resolv.h>
95#include <stdlib.h>
96#include <string.h>
97#include <unistd.h>
98
99static int s = -1; /* socket used for communications */
100static int connected = 0; /* is the socket connected */
101static int vc = 0; /* is the socket a virtual ciruit? */
102static int af = 0; /* address family of socket */
103
104#ifndef FD_SET
105/* XXX - should be in portability.h */
106#define NFDBITS 32
107#define FD_SETSIZE 32
108#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
109#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
110#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
111#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
112#endif
113
114#define CAN_RECONNECT 1
115
116#ifndef DEBUG
117# define Dprint(cond, args) /*empty*/
118# define DprintQ(cond, args, query, size) /*empty*/
119# define Aerror(file, string, error, address) /*empty*/
120# define Perror(file, string, error) /*empty*/
121#else
122# define Dprint(cond, args) if (cond) {fprintf args;} else {}
123# define DprintQ(cond, args, query, size) if (cond) {\
124 fprintf args;\
125 __fp_nquery(query, size, stdout);\
126 } else {}
127static char abuf[NI_MAXHOST];
128static char pbuf[NI_MAXSERV];
129static void Aerror(FILE *, char *, int, struct sockaddr *);
130static void Perror(FILE *, char *, int);
131
132 static void
133 Aerror(file, string, error, address)
134 FILE *file;
135 char *string;
136 int error;
137 struct sockaddr *address;
138 {
139 int save = errno;
140
141 if (_res.options & RES_DEBUG) {
142 if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
143 pbuf, sizeof(pbuf),
144 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) {
145 strncpy(abuf, "?", sizeof(abuf));
146 strncpy(pbuf, "?", sizeof(pbuf));
147 }
148 fprintf(file, "res_send: %s ([%s].%s): %s\n",
149 string, abuf, pbuf, strerror(error));
150 }
151 errno = save;
152 }
153 static void
154 Perror(file, string, error)
155 FILE *file;
156 char *string;
157 int error;
158 {
159 int save = errno;
160
161 if (_res.options & RES_DEBUG) {
162 fprintf(file, "res_send: %s: %s\n",
163 string, strerror(error));
164 }
165 errno = save;
166 }
167#endif
168
169static res_send_qhook Qhook = NULL;
170static res_send_rhook Rhook = NULL;
171
172void
173res_send_setqhook(hook)
174 res_send_qhook hook;
175{
176
177 Qhook = hook;
178}
179
180void
181res_send_setrhook(hook)
182 res_send_rhook hook;
183{
184
185 Rhook = hook;
186}
187
188#ifdef INET6
189static struct sockaddr * get_nsaddr(size_t);
190
191/*
192 * pick appropriate nsaddr_list for use. see res_init() for initialization.
193 */
194static struct sockaddr *
195get_nsaddr(n)
196 size_t n;
197{
198
199 if (!_res.nsaddr_list[n].sin_family) {
200 /*
201 * - _res_ext.nsaddr_list[n] holds an address that is larger
202 * than struct sockaddr, and
203 * - user code did not update _res.nsaddr_list[n].
204 */
205 return (struct sockaddr *)&_res_ext.nsaddr_list[n];
206 } else {
207 /*
208 * - user code updated _res.nsaddr_list[n], or
209 * - _res.nsaddr_list[n] has the same content as
210 * _res_ext.nsaddr_list[n].
211 */
212 return (struct sockaddr *)&_res.nsaddr_list[n];
213 }
214}
215#else
216#define get_nsaddr(n) ((struct sockaddr *)&_res.nsaddr_list[(n)])
217#endif
218
219/* int
220 * res_isourserver(ina)
221 * looks up "ina" in _res.ns_addr_list[]
222 * returns:
223 * 0 : not found
224 * >0 : found
225 * author:
226 * paul vixie, 29may94
227 */
228int
229res_isourserver(inp)
230 const struct sockaddr_in *inp;
231{
232#ifdef INET6
233 const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
234 const struct sockaddr_in6 *srv6;
235#endif
236 const struct sockaddr_in *srv;
237 int ns, ret;
238
239 ret = 0;
240 switch (inp->sin_family) {
241#ifdef INET6
242 case AF_INET6:
243 for (ns = 0; ns < _res.nscount; ns++) {
244 srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
245 if (srv6->sin6_family == in6p->sin6_family &&
246 srv6->sin6_port == in6p->sin6_port &&
247 srv6->sin6_scope_id == in6p->sin6_scope_id &&
248 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
249 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
250 &in6p->sin6_addr))) {
251 ret++;
252 break;
253 }
254 }
255 break;
256#endif
257 case AF_INET:
258 for (ns = 0; ns < _res.nscount; ns++) {
259 srv = (struct sockaddr_in *)get_nsaddr(ns);
260 if (srv->sin_family == inp->sin_family &&
261 srv->sin_port == inp->sin_port &&
262 (srv->sin_addr.s_addr == INADDR_ANY ||
263 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
264 ret++;
265 break;
266 }
267 }
268 break;
269 }
270 return (ret);
271}
272
273/* int
274 * res_nameinquery(name, type, class, buf, eom)
275 * look for (name,type,class) in the query section of packet (buf,eom)
276 * returns:
277 * -1 : format error
278 * 0 : not found
279 * >0 : found
280 * author:
281 * paul vixie, 29may94
282 */
283int
284res_nameinquery(name, type, class, buf, eom)
285 const char *name;
286 register int type, class;
287 const u_char *buf, *eom;
288{
289 register const u_char *cp = buf + HFIXEDSZ;
290 int qdcount = ntohs(((HEADER*)buf)->qdcount);
291
292 while (qdcount-- > 0) {
293 char tname[MAXDNAME+1];
294 register int n, ttype, tclass;
295
296 n = dn_expand(buf, eom, cp, tname, sizeof tname);
297 if (n < 0)
298 return (-1);
299 cp += n;
300 ttype = _getshort(cp); cp += INT16SZ;
301 tclass = _getshort(cp); cp += INT16SZ;
302 if (ttype == type &&
303 tclass == class &&
304 strcasecmp(tname, name) == 0)
305 return (1);
306 }
307 return (0);
308}
309
310/* int
311 * res_queriesmatch(buf1, eom1, buf2, eom2)
312 * is there a 1:1 mapping of (name,type,class)
313 * in (buf1,eom1) and (buf2,eom2)?
314 * returns:
315 * -1 : format error
316 * 0 : not a 1:1 mapping
317 * >0 : is a 1:1 mapping
318 * author:
319 * paul vixie, 29may94
320 */
321int
322res_queriesmatch(buf1, eom1, buf2, eom2)
323 const u_char *buf1, *eom1;
324 const u_char *buf2, *eom2;
325{
326 register const u_char *cp = buf1 + HFIXEDSZ;
327 int qdcount = ntohs(((HEADER*)buf1)->qdcount);
328
329 if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
330 return (0);
331 while (qdcount-- > 0) {
332 char tname[MAXDNAME+1];
333 register int n, ttype, tclass;
334
335 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
336 if (n < 0)
337 return (-1);
338 cp += n;
339 ttype = _getshort(cp); cp += INT16SZ;
340 tclass = _getshort(cp); cp += INT16SZ;
341 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
342 return (0);
343 }
344 return (1);
345}
346
347int
348res_send(buf, buflen, ans, anssiz)
349 const u_char *buf;
350 int buflen;
351 u_char *ans;
352 int anssiz;
353{
354 HEADER *hp = (HEADER *) buf;
355 HEADER *anhp = (HEADER *) ans;
356 int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
357 register int n;
358 u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
359
360 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
361 /* errno should have been set by res_init() in this case. */
362 return (-1);
363 }
364 DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
365 (stdout, ";; res_send()\n"), buf, buflen);
366 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
367 gotsomewhere = 0;
368 connreset = 0;
369 terrno = ETIMEDOUT;
370 badns = 0;
371
372 /*
373 * Send request, RETRY times, or until successful
374 */
375 for (try = 0; try < _res.retry; try++) {
376 for (ns = 0; ns < _res.nscount; ns++) {
377 struct sockaddr *nsap = get_nsaddr(ns);
378 socklen_t salen;
379
380 if (nsap->sa_len)
381 salen = nsap->sa_len;
382#ifdef INET6
383 else if (nsap->sa_family == AF_INET6)
384 salen = sizeof(struct sockaddr_in6);
385#endif
386 else if (nsap->sa_family == AF_INET)
387 salen = sizeof(struct sockaddr_in);
388 else
389 salen = 0; /*unknown, die on connect*/
390
391 same_ns:
392 if (badns & (1 << ns)) {
393 res_close();
394 goto next_ns;
395 }
396
397 if (Qhook) {
398 int done = 0, loops = 0;
399
400 do {
401 res_sendhookact act;
402
403 act = (*Qhook)((struct sockaddr_in **)&nsap,
404 &buf, &buflen,
405 ans, anssiz, &resplen);
406 switch (act) {
407 case res_goahead:
408 done = 1;
409 break;
410 case res_nextns:
411 res_close();
412 goto next_ns;
413 case res_done:
414 return (resplen);
415 case res_modified:
416 /* give the hook another try */
417 if (++loops < 42) /*doug adams*/
418 break;
419 /*FALLTHROUGH*/
420 case res_error:
421 /*FALLTHROUGH*/
422 default:
423 return (-1);
424 }
425 } while (!done);
426 }
427
428 Dprint((_res.options & RES_DEBUG) &&
429 getnameinfo(nsap, salen, abuf, sizeof(abuf),
430 NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0,
431 (stdout, ";; Querying server (# %d) address = %s\n",
432 ns + 1, abuf));
433
434 if (v_circuit) {
435 int truncated;
436 struct iovec iov[2];
437 u_short len;
438 u_char *cp;
439
440 /*
441 * Use virtual circuit;
442 * at most one attempt per server.
443 */
444 try = _res.retry;
445 truncated = 0;
446 if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
447 if (s >= 0)
448 res_close();
449
450 af = nsap->sa_family;
451 s = socket(af, SOCK_STREAM, 0);
452 if (s < 0) {
453 terrno = errno;
454 Perror(stderr, "socket(vc)", errno);
455#if 0
456 return (-1);
457#else
458 badns |= (1 << ns);
459 res_close();
460 goto next_ns;
461#endif
462 }
463 errno = 0;
464 if (connect(s, nsap, salen) < 0) {
465 terrno = errno;
466 Aerror(stderr, "connect/vc",
467 errno, nsap);
468 badns |= (1 << ns);
469 res_close();
470 goto next_ns;
471 }
472 vc = 1;
473 }
474 /*
475 * Send length & message
476 */
477 putshort((u_short)buflen, (u_char*)&len);
478 iov[0].iov_base = (caddr_t)&len;
479 iov[0].iov_len = INT16SZ;
480 iov[1].iov_base = (caddr_t)buf;
481 iov[1].iov_len = buflen;
482 if (writev(s, iov, 2) != (INT16SZ + buflen)) {
483 terrno = errno;
484 Perror(stderr, "write failed", errno);
485 badns |= (1 << ns);
486 res_close();
487 goto next_ns;
488 }
489 /*
490 * Receive length & response
491 */
492read_len:
493 cp = ans;
494 len = INT16SZ;
495 while ((n = read(s, (char *)cp, (int)len)) > 0) {
496 cp += n;
497 if ((len -= n) <= 0)
498 break;
499 }
500 if (n <= 0) {
501 terrno = errno;
502 Perror(stderr, "read failed", errno);
503 res_close();
504 /*
505 * A long running process might get its TCP
506 * connection reset if the remote server was
507 * restarted. Requery the server instead of
508 * trying a new one. When there is only one
509 * server, this means that a query might work
510 * instead of failing. We only allow one reset
511 * per query to prevent looping.
512 */
513 if (terrno == ECONNRESET && !connreset) {
514 connreset = 1;
515 res_close();
516 goto same_ns;
517 }
518 res_close();
519 goto next_ns;
520 }
521 resplen = _getshort(ans);
522 if (resplen > anssiz) {
523 Dprint(_res.options & RES_DEBUG,
524 (stdout, ";; response truncated\n")
525 );
526 truncated = 1;
527 len = anssiz;
528 } else
529 len = resplen;
530 cp = ans;
531 while (len != 0 &&
532 (n = read(s, (char *)cp, (int)len)) > 0) {
533 cp += n;
534 len -= n;
535 }
536 if (n <= 0) {
537 terrno = errno;
538 Perror(stderr, "read(vc)", errno);
539 res_close();
540 goto next_ns;
541 }
542 if (truncated) {
543 /*
544 * Flush rest of answer
545 * so connection stays in synch.
546 */
547 anhp->tc = 1;
548 len = resplen - anssiz;
549 while (len != 0) {
550 char junk[PACKETSZ];
551
552 n = (len > sizeof(junk)
553 ? sizeof(junk)
554 : len);
555 if ((n = read(s, junk, n)) > 0)
556 len -= n;
557 else
558 break;
559 }
560 }
561 /*
562 * The calling applicating has bailed out of
563 * a previous call and failed to arrange to have
564 * the circuit closed or the server has got
565 * itself confused. Anyway drop the packet and
566 * wait for the correct one.
567 */
568 if (hp->id != anhp->id) {
569 DprintQ((_res.options & RES_DEBUG) ||
570 (_res.pfcode & RES_PRF_REPLY),
571 (stdout, ";; old answer (unexpected):\n"),
572 ans, (resplen>anssiz)?anssiz:resplen);
573 goto read_len;
574 }
575 } else {
576 /*
577 * Use datagrams.
578 */
579 struct timeval timeout;
580 fd_set *dsmaskp;
581 struct sockaddr_storage from;
582 int fromlen;
583
584 if ((s < 0) || vc || (af != nsap->sa_family)) {
585 if (vc)
586 res_close();
587 af = nsap->sa_family;
588 s = socket(af, SOCK_DGRAM, 0);
589 if (s < 0) {
590#if !CAN_RECONNECT
591 bad_dg_sock:
592#endif
593 terrno = errno;
594 Perror(stderr, "socket(dg)", errno);
595#if 0
596 return (-1);
597#else
598 badns |= (1 << ns);
599 res_close();
600 goto next_ns;
601#endif
602 }
603#ifdef IPV6_MINMTU
604 if (af == AF_INET6) {
605 const int yes = 1;
606 (void)setsockopt(s, IPPROTO_IPV6,
607 IPV6_USE_MIN_MTU, &yes,
608 sizeof(yes));
609 }
610#endif
611 connected = 0;
612 }
613 /*
614 * On a 4.3BSD+ machine (client and server,
615 * actually), sending to a nameserver datagram
616 * port with no nameserver will cause an
617 * ICMP port unreachable message to be returned.
618 * If our datagram socket is "connected" to the
619 * server, we get an ECONNREFUSED error on the next
620 * socket operation, and select returns if the
621 * error message is received. We can thus detect
622 * the absence of a nameserver without timing out.
623 * If we have sent queries to at least two servers,
624 * however, we don't want to remain connected,
625 * as we wish to receive answers from the first
626 * server to respond.
627 */
628 if (!(_res.options & RES_INSECURE1) &&
629 (_res.nscount == 1 || (try == 0 && ns == 0))) {
630 /*
631 * Connect only if we are sure we won't
632 * receive a response from another server.
633 */
634 if (!connected) {
635 if (connect(s, nsap, salen) < 0) {
636 Aerror(stderr,
637 "connect(dg)",
638 errno, nsap);
639 badns |= (1 << ns);
640 res_close();
641 goto next_ns;
642 }
643 connected = 1;
644 }
645 if (send(s, (char*)buf, buflen, 0) != buflen) {
646 Perror(stderr, "send", errno);
647 badns |= (1 << ns);
648 res_close();
649 goto next_ns;
650 }
651 } else {
652 /*
653 * Disconnect if we want to listen
654 * for responses from more than one server.
655 */
656 if (connected) {
657#if CAN_RECONNECT
658#ifdef INET6
659 /* XXX: any errornous address */
660#endif /* INET6 */
661 struct sockaddr_in no_addr;
662
663 no_addr.sin_family = AF_INET;
664 no_addr.sin_addr.s_addr = INADDR_ANY;
665 no_addr.sin_port = 0;
666 (void) connect(s,
667 (struct sockaddr *)
668 &no_addr,
669 sizeof(no_addr));
670#else
671 int s1 = socket(af, SOCK_DGRAM,0);
672 if (s1 < 0)
673 goto bad_dg_sock;
674 (void) dup2(s1, s);
675 (void) close(s1);
676 Dprint(_res.options & RES_DEBUG,
677 (stdout, ";; new DG socket\n"))
678#endif
679#ifdef IPV6_MINMTU
680 if (af == AF_INET6) {
681 const int yes = 1;
682 (void)setsockopt(s, IPPROTO_IPV6,
683 IPV6_USE_MIN_MTU, &yes,
684 sizeof(yes));
685 }
686#endif
687 connected = 0;
688 errno = 0;
689 }
690 if (sendto(s, (char*)buf, buflen, 0,
691 nsap, salen) != buflen) {
692 Aerror(stderr, "sendto", errno, nsap);
693 badns |= (1 << ns);
694 res_close();
695 goto next_ns;
696 }
697 }
698
699 /*
700 * Wait for reply
701 */
702 timeout.tv_sec = (_res.retrans << try);
703 if (try > 0)
704 timeout.tv_sec /= _res.nscount;
705 if ((long) timeout.tv_sec <= 0)
706 timeout.tv_sec = 1;
707 timeout.tv_usec = 0;
708 wait:
709 dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
710 sizeof(fd_mask));
711 if (dsmaskp == NULL) {
712 res_close();
713 goto next_ns;
714 }
715 FD_SET(s, dsmaskp);
716 n = select(s+1, dsmaskp, (fd_set *)NULL,
717 (fd_set *)NULL, &timeout);
718 free(dsmaskp);
719 if (n < 0) {
720 if (errno == EINTR)
721 goto wait;
722 Perror(stderr, "select", errno);
723 res_close();
724 goto next_ns;
725 }
726 if (n == 0) {
727 /*
728 * timeout
729 */
730 Dprint(_res.options & RES_DEBUG,
731 (stdout, ";; timeout\n"));
732 gotsomewhere = 1;
733 res_close();
734 goto next_ns;
735 }
736 errno = 0;
737 fromlen = sizeof(from);
738 resplen = recvfrom(s, (char*)ans, anssiz, 0,
739 (struct sockaddr *)&from, &fromlen);
740 if (resplen <= 0) {
741 Perror(stderr, "recvfrom", errno);
742 res_close();
743 goto next_ns;
744 }
745 gotsomewhere = 1;
746 if (hp->id != anhp->id) {
747 /*
748 * response from old query, ignore it.
749 * XXX - potential security hazard could
750 * be detected here.
751 */
752 DprintQ((_res.options & RES_DEBUG) ||
753 (_res.pfcode & RES_PRF_REPLY),
754 (stdout, ";; old answer:\n"),
755 ans, (resplen>anssiz)?anssiz:resplen);
756 goto wait;
757 }
758#if CHECK_SRVR_ADDR
759 if (!(_res.options & RES_INSECURE1) &&
760 !res_isourserver((struct sockaddr_in *)&from)) {
761 /*
762 * response from wrong server? ignore it.
763 * XXX - potential security hazard could
764 * be detected here.
765 */
766 DprintQ((_res.options & RES_DEBUG) ||
767 (_res.pfcode & RES_PRF_REPLY),
768 (stdout, ";; not our server:\n"),
769 ans, (resplen>anssiz)?anssiz:resplen);
770 goto wait;
771 }
772#endif
773 if (!(_res.options & RES_INSECURE2) &&
774 !res_queriesmatch(buf, buf + buflen,
775 ans, ans + anssiz)) {
776 /*
777 * response contains wrong query? ignore it.
778 * XXX - potential security hazard could
779 * be detected here.
780 */
781 DprintQ((_res.options & RES_DEBUG) ||
782 (_res.pfcode & RES_PRF_REPLY),
783 (stdout, ";; wrong query name:\n"),
784 ans, (resplen>anssiz)?anssiz:resplen);
785 goto wait;
786 }
787 if (anhp->rcode == SERVFAIL ||
788 anhp->rcode == NOTIMP ||
789 anhp->rcode == REFUSED) {
790 DprintQ(_res.options & RES_DEBUG,
791 (stdout, "server rejected query:\n"),
792 ans, (resplen>anssiz)?anssiz:resplen);
793 badns |= (1 << ns);
794 res_close();
795 /* don't retry if called from dig */
796 if (!_res.pfcode)
797 goto next_ns;
798 }
799 if (!(_res.options & RES_IGNTC) && anhp->tc) {
800 /*
801 * get rest of answer;
802 * use TCP with same server.
803 */
804 Dprint(_res.options & RES_DEBUG,
805 (stdout, ";; truncated answer\n"));
806 v_circuit = 1;
807 res_close();
808 goto same_ns;
809 }
810 } /*if vc/dg*/
811 Dprint((_res.options & RES_DEBUG) ||
812 ((_res.pfcode & RES_PRF_REPLY) &&
813 (_res.pfcode & RES_PRF_HEAD1)),
814 (stdout, ";; got answer:\n"));
815 DprintQ((_res.options & RES_DEBUG) ||
816 (_res.pfcode & RES_PRF_REPLY),
817 (stdout, "%s", ""),
818 ans, (resplen>anssiz)?anssiz:resplen);
819 /*
820 * If using virtual circuits, we assume that the first server
821 * is preferred over the rest (i.e. it is on the local
822 * machine) and only keep that one open.
823 * If we have temporarily opened a virtual circuit,
824 * or if we haven't been asked to keep a socket open,
825 * close the socket.
826 */
827 if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
828 !(_res.options & RES_STAYOPEN)) {
829 res_close();
830 }
831 if (Rhook) {
832 int done = 0, loops = 0;
833
834 do {
835 res_sendhookact act;
836
837 act = (*Rhook)((struct sockaddr_in *)nsap,
838 buf, buflen,
839 ans, anssiz, &resplen);
840 switch (act) {
841 case res_goahead:
842 case res_done:
843 done = 1;
844 break;
845 case res_nextns:
846 res_close();
847 goto next_ns;
848 case res_modified:
849 /* give the hook another try */
850 if (++loops < 42) /*doug adams*/
851 break;
852 /*FALLTHROUGH*/
853 case res_error:
854 /*FALLTHROUGH*/
855 default:
856 return (-1);
857 }
858 } while (!done);
859
860 }
861 return (resplen);
862 next_ns: ;
863 } /*foreach ns*/
864 } /*foreach retry*/
865 res_close();
866 if (!v_circuit) {
867 if (!gotsomewhere)
868 errno = ECONNREFUSED; /* no nameservers found */
869 else
870 errno = ETIMEDOUT; /* no answer obtained */
871 } else
872 errno = terrno;
873 return (-1);
874}
875
876/*
877 * This routine is for closing the socket if a virtual circuit is used and
878 * the program wants to close it. This provides support for endhostent()
879 * which expects to close the socket.
880 *
881 * This routine is not expected to be user visible.
882 */
883void
884res_close()
885{
886 if (s >= 0) {
887 (void) close(s);
888 s = -1;
889 connected = 0;
890 vc = 0;
891 af = 0;
892 }
893}
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
new file mode 100644
index 0000000000..4d5402ed2d
--- /dev/null
+++ b/src/lib/libc/net/resolver.3
@@ -0,0 +1,345 @@
1.\" $OpenBSD: resolver.3,v 1.15 2001/04/03 20:09:08 aaron Exp $
2.\"
3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd June 4, 1993
35.Dt RESOLVER 3
36.Os
37.Sh NAME
38.Nm res_query ,
39.Nm res_search ,
40.Nm res_mkquery ,
41.Nm res_send ,
42.Nm res_init ,
43.Nm dn_comp ,
44.Nm dn_expand
45.Nd resolver routines
46.Sh SYNOPSIS
47.Fd #include <sys/types.h>
48.Fd #include <netinet/in.h>
49.Fd #include <arpa/nameser.h>
50.Fd #include <resolv.h>
51.Ft int
52.Fo res_query
53.Fa "char *dname"
54.Fa "int class"
55.Fa "int type"
56.Fa "u_char *answer"
57.Fa "int anslen"
58.Fc
59.Ft int
60.Fo res_search
61.Fa "char *dname"
62.Fa "int class"
63.Fa "int type"
64.Fa "u_char *answer"
65.Fa "int anslen"
66.Fc
67.Ft int
68.Fo res_mkquery
69.Fa "int op"
70.Fa "char *dname"
71.Fa "int class"
72.Fa "int type"
73.Fa "char *data"
74.Fa "int datalen"
75.Fa "struct rrec *newrr"
76.Fa "char *buf"
77.Fa "int buflen"
78.Fc
79.Ft int
80.Fo res_send
81.Fa "char *msg"
82.Fa "int msglen"
83.Fa "char *answer"
84.Fa "int anslen"
85.Fc
86.Ft int
87.Fn res_init "void"
88.Ft int
89.Fo dn_comp
90.Fa "char *exp_dn"
91.Fa "char *comp_dn"
92.Fa "int length"
93.Fa "char **dnptrs"
94.Fa "char **lastdnptr"
95.Fc
96.Ft int
97.Fo dn_expand
98.Fa "u_char *msg"
99.Fa "u_char *eomorig"
100.Fa "u_char *comp_dn"
101.Fa "u_char *exp_dn"
102.Fa "int length"
103.Fc
104.Sh DESCRIPTION
105These routines are used for making, sending, and interpreting
106query and reply messages with Internet domain name servers.
107.Pp
108Global configuration and state information that is used by the
109resolver routines is kept in the structure
110.Li _res .
111Most of the values have reasonable defaults and can be ignored.
112Options stored in
113.Li _res.options
114are defined in
115.Aq Pa resolv.h
116and are as follows.
117Options are stored as a simple bit mask containing the bitwise
118.Tn OR
119of the options enabled.
120.Bl -tag -width RES_USE_INET6
121.It Dv RES_INIT
122True if the initial name server address and default domain name are
123initialized (i.e.,
124.Fn res_init
125has been called).
126.It Dv RES_DEBUG
127Print debugging messages.
128.It Dv RES_AAONLY
129Accept authoritative answers only.
130With this option,
131.Fn res_send
132should continue until it finds an authoritative answer or finds an error.
133Currently this is not implemented.
134.It Dv RES_USEVC
135Use
136.Tn TCP
137connections for queries instead of
138.Tn UDP
139datagrams.
140.It Dv RES_STAYOPEN
141Used with
142.Dv RES_USEVC
143to keep the
144.Tn TCP
145connection open between queries.
146This is useful only in programs that regularly do many queries.
147.Tn UDP
148should be the normal mode used.
149.It Dv RES_IGNTC
150Unused currently (ignore truncation errors, i.e., don't retry with
151.Tn TCP ) .
152.It Dv RES_RECURSE
153Set the recursion-desired bit in queries.
154This is the default.
155.Pf ( Fn res_send
156does not do iterative queries and expects the name server
157to handle recursion.)
158.It Dv RES_DEFNAMES
159If set,
160.Fn res_search
161will append the default domain name to single-component names
162(those that do not contain a dot).
163This option is enabled by default.
164.It Dv RES_DNSRCH
165If this option is set,
166.Fn res_search
167will search for host names in the current domain and in parent domains; see
168.Xr hostname 7 .
169This is used by the standard host lookup routine
170.Xr gethostbyname 3 .
171This option is enabled by default.
172.It Dv RES_USE_INET6
173Enables support for IPv6-only applications.
174This causes IPv4 addresses to be returned as an IPv4 mapped address.
175For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1.
176The option is not meaningful on
177.Ox .
178.El
179.Pp
180The
181.Fn res_init
182routine reads the configuration file (if any; see
183.Xr resolv.conf 5 )
184to get the default domain name, search list, and the Internet address
185of the local name server(s).
186If no server is configured, the host running
187the resolver is tried.
188The current domain name is defined by the hostname
189if not specified in the configuration file;
190it can be overridden by the environment variable
191.Ev LOCALDOMAIN .
192This environment variable may contain several blank-separated
193tokens if you wish to override the
194.Fa search list
195on a per-process basis.
196This is similar to the
197.Fa search
198command in the configuration file.
199Another environment variable
200.Ev RES_OPTIONS
201can be set to override certain internal resolver options which
202are otherwise set by changing fields in the
203.Fa _res
204structure or are inherited from the configuration file's
205.Fa options
206command.
207The syntax of the
208.Ev RES_OPTIONS
209environment variable is explained in
210.Xr resolv.conf 5 .
211Initialization normally occurs on the first call
212to one of the following routines.
213.Pp
214The
215.Fn res_query
216function provides an interface to the server query mechanism.
217It constructs a query, sends it to the local server,
218awaits a response, and makes preliminary checks on the reply.
219The query requests information of the specified
220.Fa type
221and
222.Fa class
223for the specified fully qualified domain name
224.Fa dname .
225The reply message is left in the
226.Fa answer
227buffer with length
228.Fa anslen
229supplied by the caller.
230.Pp
231The
232.Fn res_search
233routine makes a query and awaits a response like
234.Fn res_query ,
235but in addition, it implements the default and search rules controlled by the
236.Dv RES_DEFNAMES
237and
238.Dv RES_DNSRCH
239options.
240It returns the first successful reply.
241.Pp
242The remaining routines are lower-level routines used by
243.Fn res_query .
244The
245.Fn res_mkquery
246function constructs a standard query message and places it in
247.Fa buf .
248It returns the size of the query, or \-1 if the query is larger than
249.Fa buflen .
250The query type
251.Fa op
252is usually
253.Dv QUERY ,
254but can be any of the query types defined in
255.Aq Pa arpa/nameser.h .
256The domain name for the query is given by
257.Fa dname .
258.Fa newrr
259is currently unused but is intended for making update messages.
260.Pp
261The
262.Fn res_send
263routine sends a pre-formatted query and returns an answer.
264It will call
265.Fn res_init
266if
267.Dv RES_INIT
268is not set, send the query to the local name server, and
269handle timeouts and retries.
270The length of the reply message is returned, or \-1 if there were errors.
271.Pp
272The
273.Fn dn_comp
274function compresses the domain name
275.Fa exp_dn
276and stores it in
277.Fa comp_dn .
278The size of the compressed name is returned or \-1 if there were errors.
279The size of the array pointed to by
280.Fa comp_dn
281is given by
282.Fa length .
283The compression uses an array of pointers
284.Fa dnptrs
285to previously compressed names in the current message.
286The first pointer points
287to the beginning of the message and the list ends with
288.Dv NULL .
289The limit to the array is specified by
290.Fa lastdnptr .
291A side effect of
292.Fn dn_comp
293is to update the list of pointers for labels inserted into the message
294as the name is compressed.
295If
296.Em dnptr
297is
298.Dv NULL ,
299names are not compressed.
300If
301.Fa lastdnptr
302is
303.Dv NULL ,
304the list of labels is not updated.
305.Pp
306The
307.Fn dn_expand
308entry expands the compressed domain name
309.Fa comp_dn
310to a full domain name
311The compressed name is contained in a query or reply message;
312.Fa msg
313is a pointer to the beginning of the message.
314The uncompressed name is placed in the buffer indicated by
315.Fa exp_dn
316which is of size
317.Fa length .
318The size of compressed name is returned or \-1 if there was an error.
319.Sh FILES
320.Bl -tag -width Pa
321/etc/resolv.conf
322configuration file
323see
324.Xr resolv.conf 5 .
325.El
326.Sh SEE ALSO
327.Xr gethostbyname 3 ,
328.Xr resolv.conf 5 ,
329.Xr hostname 7 ,
330.Xr named 8
331.Pp
332.%T RFC1032 ,
333.%T RFC1033 ,
334.%T RFC1034 ,
335.%T RFC1035 ,
336.%T RFC1535 ,
337.%T RFC974
338.Rs
339.%T "Name Server Operations Guide for BIND"
340.Re
341.Sh HISTORY
342The
343.Nm
344function appeared in
345.Bx 4.3 .
diff --git a/src/lib/libc/net/rresvport.c b/src/lib/libc/net/rresvport.c
new file mode 100644
index 0000000000..c807adfb83
--- /dev/null
+++ b/src/lib/libc/net/rresvport.c
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * This product includes software developed by Theo de Raadt.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: rresvport.c,v 1.5 2000/01/26 03:43:20 deraadt Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#include <sys/param.h>
41#include <sys/socket.h>
42#include <sys/stat.h>
43
44#include <netinet/in.h>
45#include <arpa/inet.h>
46
47#include <signal.h>
48#include <fcntl.h>
49#include <netdb.h>
50#include <unistd.h>
51#include <pwd.h>
52#include <errno.h>
53#include <stdio.h>
54#include <ctype.h>
55#include <string.h>
56#include <syslog.h>
57#include <stdlib.h>
58#include <netgroup.h>
59
60int
61rresvport(alport)
62 int *alport;
63{
64 return rresvport_af(alport, AF_INET);
65}
66
67
68int
69rresvport_af(alport, af)
70 int *alport;
71 int af;
72{
73 struct sockaddr_storage ss;
74 struct sockaddr *sa;
75 u_int16_t *portp;
76 int s;
77
78 bzero(&ss, sizeof ss);
79 sa = (struct sockaddr *)&ss;
80
81 switch (af) {
82 case AF_INET:
83 sa->sa_len = sizeof(struct sockaddr_in);
84 portp = &((struct sockaddr_in *)sa)->sin_port;
85 break;
86 case AF_INET6:
87 sa->sa_len = sizeof(struct sockaddr_in6);
88 portp = &((struct sockaddr_in6 *)sa)->sin6_port;
89 break;
90 default:
91 errno = EPFNOSUPPORT;
92 return (-1);
93 }
94 sa->sa_family = af;
95
96 s = socket(af, SOCK_STREAM, 0);
97 if (s < 0)
98 return (-1);
99
100 *portp = htons(*alport);
101 if (*alport < IPPORT_RESERVED - 1) {
102 if (bind(s, sa, sa->sa_len) >= 0)
103 return (s);
104 if (errno != EADDRINUSE) {
105 (void)close(s);
106 return (-1);
107 }
108 }
109
110 *portp = 0;
111 sa->sa_family = af;
112 if (bindresvport_sa(s, sa) == -1) {
113 (void)close(s);
114 return (-1);
115 }
116 *alport = ntohs(*portp);
117 return (s);
118}
diff --git a/src/lib/libc/net/rthdr.c b/src/lib/libc/net/rthdr.c
new file mode 100644
index 0000000000..7a87b322d1
--- /dev/null
+++ b/src/lib/libc/net/rthdr.c
@@ -0,0 +1,310 @@
1/* $OpenBSD: rthdr.c,v 1.3 2002/06/27 10:14:02 itojun Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35
36#include <netinet/in.h>
37#include <netinet/ip6.h>
38
39#include <string.h>
40#include <stdio.h>
41
42size_t
43inet6_rthdr_space(type, seg)
44 int type, seg;
45{
46 switch(type) {
47 case IPV6_RTHDR_TYPE_0:
48 if (seg < 1 || seg > 23)
49 return(0);
50 return(CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1)
51 + sizeof(struct ip6_rthdr0)));
52 default:
53#ifdef DEBUG
54 fprintf(stderr, "inet6_rthdr_space: unknown type(%d)\n", type);
55#endif
56 return(0);
57 }
58}
59
60struct cmsghdr *
61inet6_rthdr_init(bp, type)
62 void *bp;
63 int type;
64{
65 register struct cmsghdr *ch = (struct cmsghdr *)bp;
66 register struct ip6_rthdr *rthdr;
67
68 rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
69
70 ch->cmsg_level = IPPROTO_IPV6;
71 ch->cmsg_type = IPV6_RTHDR;
72
73 switch(type) {
74 case IPV6_RTHDR_TYPE_0:
75 ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) - sizeof(struct in6_addr));
76 bzero(rthdr, sizeof(struct ip6_rthdr0));
77 rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
78 return(ch);
79 default:
80#ifdef DEBUG
81 fprintf(stderr, "inet6_rthdr_init: unknown type(%d)\n", type);
82#endif
83 return(NULL);
84 }
85}
86
87int
88inet6_rthdr_add(cmsg, addr, flags)
89 struct cmsghdr *cmsg;
90 const struct in6_addr *addr;
91 u_int flags;
92{
93 register struct ip6_rthdr *rthdr;
94
95 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
96
97 switch(rthdr->ip6r_type) {
98 case IPV6_RTHDR_TYPE_0:
99 {
100 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
101 if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
102#ifdef DEBUG
103 fprintf(stderr, "inet6_rthdr_add: unsupported flag(%u)\n", flags);
104#endif
105 return(-1);
106 }
107 if (rt0->ip6r0_segleft == 23) {
108#ifdef DEBUG
109 fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
110#endif
111 return(-1);
112 }
113 if (flags == IPV6_RTHDR_STRICT) {
114 int c, b;
115 c = rt0->ip6r0_segleft / 8;
116 b = rt0->ip6r0_segleft % 8;
117 rt0->ip6r0_slmap[c] |= (1 << (7 - b));
118 }
119 rt0->ip6r0_segleft++;
120 bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
121 sizeof(struct in6_addr));
122 rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
123 cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
124 break;
125 }
126 default:
127#ifdef DEBUG
128 fprintf(stderr, "inet6_rthdr_add: unknown type(%u)\n",
129 rthdr->ip6r_type);
130#endif
131 return(-1);
132 }
133
134 return(0);
135}
136
137int
138inet6_rthdr_lasthop(cmsg, flags)
139 struct cmsghdr *cmsg;
140 unsigned int flags;
141{
142 register struct ip6_rthdr *rthdr;
143
144 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
145
146 switch(rthdr->ip6r_type) {
147 case IPV6_RTHDR_TYPE_0:
148 {
149 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
150 if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
151#ifdef DEBUG
152 fprintf(stderr, "inet6_rthdr_lasthop: unsupported flag(%u)\n", flags);
153#endif
154 return(-1);
155 }
156 if (rt0->ip6r0_segleft > 23) {
157#ifdef DEBUG
158 fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
159#endif
160 return(-1);
161 }
162 if (flags == IPV6_RTHDR_STRICT) {
163 int c, b;
164 c = rt0->ip6r0_segleft / 8;
165 b = rt0->ip6r0_segleft % 8;
166 rt0->ip6r0_slmap[c] |= (1 << (7 - b));
167 }
168 break;
169 }
170 default:
171#ifdef DEBUG
172 fprintf(stderr, "inet6_rthdr_lasthop: unknown type(%u)\n",
173 rthdr->ip6r_type);
174#endif
175 return(-1);
176 }
177
178 return(0);
179}
180
181#if 0
182int
183inet6_rthdr_reverse(in, out)
184 const struct cmsghdr *in;
185 struct cmsghdr *out;
186{
187#ifdef DEBUG
188 fprintf(stderr, "inet6_rthdr_reverse: not implemented yet\n");
189#endif
190 return -1;
191}
192#endif
193
194int
195inet6_rthdr_segments(cmsg)
196 const struct cmsghdr *cmsg;
197{
198 register struct ip6_rthdr *rthdr;
199
200 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
201
202 switch(rthdr->ip6r_type) {
203 case IPV6_RTHDR_TYPE_0:
204 {
205 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
206
207 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
208#ifdef DEBUG
209 fprintf(stderr, "inet6_rthdr_segments: invalid size(%u)\n",
210 rt0->ip6r0_len);
211#endif
212 return -1;
213 }
214
215 return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
216 }
217
218 default:
219#ifdef DEBUG
220 fprintf(stderr, "inet6_rthdr_segments: unknown type(%u)\n",
221 rthdr->ip6r_type);
222#endif
223 return -1;
224 }
225}
226
227struct in6_addr *
228inet6_rthdr_getaddr(cmsg, index)
229 struct cmsghdr *cmsg;
230 int index;
231{
232 register struct ip6_rthdr *rthdr;
233
234 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
235
236 switch(rthdr->ip6r_type) {
237 case IPV6_RTHDR_TYPE_0:
238 {
239 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
240 int naddr;
241
242 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
243#ifdef DEBUG
244 fprintf(stderr, "inet6_rthdr_getaddr: invalid size(%u)\n",
245 rt0->ip6r0_len);
246#endif
247 return NULL;
248 }
249 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
250 if (index <= 0 || naddr < index) {
251#ifdef DEBUG
252 fprintf(stderr, "inet6_rthdr_getaddr: invalid index(%d)\n", index);
253#endif
254 return NULL;
255 }
256 return &rt0->ip6r0_addr[index - 1];
257 }
258
259 default:
260#ifdef DEBUG
261 fprintf(stderr, "inet6_rthdr_getaddr: unknown type(%u)\n",
262 rthdr->ip6r_type);
263#endif
264 return NULL;
265 }
266}
267
268int
269inet6_rthdr_getflags(cmsg, index)
270 const struct cmsghdr *cmsg;
271 int index;
272{
273 register struct ip6_rthdr *rthdr;
274
275 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
276
277 switch(rthdr->ip6r_type) {
278 case IPV6_RTHDR_TYPE_0:
279 {
280 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
281 int naddr;
282
283 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
284#ifdef DEBUG
285 fprintf(stderr, "inet6_rthdr_getflags: invalid size(%u)\n",
286 rt0->ip6r0_len);
287#endif
288 return -1;
289 }
290 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
291 if (index < 0 || naddr < index) {
292#ifdef DEBUG
293 fprintf(stderr, "inet6_rthdr_getflags: invalid index(%d)\n", index);
294#endif
295 return -1;
296 }
297 if (rt0->ip6r0_slmap[index / 8] & (0x80 >> (index % 8)))
298 return IPV6_RTHDR_STRICT;
299 else
300 return IPV6_RTHDR_LOOSE;
301 }
302
303 default:
304#ifdef DEBUG
305 fprintf(stderr, "inet6_rthdr_getflags: unknown type(%u)\n",
306 rthdr->ip6r_type);
307#endif
308 return -1;
309 }
310}
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c
new file mode 100644
index 0000000000..8495931ca3
--- /dev/null
+++ b/src/lib/libc/net/send.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: send.c,v 1.2 1996/08/19 08:29:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/socket.h>
40
41#include <stddef.h>
42
43ssize_t
44send(s, msg, len, flags)
45 int s, flags;
46 size_t len;
47 const void *msg;
48{
49 return (sendto(s, msg, len, flags, NULL, 0));
50}
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/net/sethostent.c
new file mode 100644
index 0000000000..5392a2f11b
--- /dev/null
+++ b/src/lib/libc/net/sethostent.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/param.h>
39#include <netinet/in.h>
40#include <arpa/nameser.h>
41#include <netdb.h>
42#include <resolv.h>
43
44void
45sethostent(stayopen)
46 int stayopen;
47{
48
49 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
50 return;
51 if (stayopen)
52 _res.options |= RES_STAYOPEN | RES_USEVC;
53}
54
55void
56endhostent()
57{
58 _res.options &= ~(RES_STAYOPEN | RES_USEVC);
59 res_close();
60}
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c
new file mode 100644
index 0000000000..6d0f069ef6
--- /dev/null
+++ b/src/lib/libc/net/vars6.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: vars6.c,v 1.1 1999/12/11 08:09:11 itojun Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <netinet/in.h>
34
35/*
36 * Definitions of some costant IPv6 addresses.
37 */
38const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
39const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
40const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
41const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
42
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000000..4b4c88b9af
--- /dev/null
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,56 @@
1# $OpenBDS: Makefile.inc,v 1.6 1996/08/21 03:47:21 tholo Exp $
2
3# stdlib sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \
7 cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c l64a.c \
8 malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c rand.c \
9 random.c realpath.c setenv.c strtod.c strtol.c strtoll.c strtoul.c \
10 strtoull.c system.c tfind.c tsearch.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13
14.if (${MACHINE_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c
16LSRCS+= abs.c
17.elif (${MACHINE_ARCH} == "i386")
18SRCS+= abs.S div.S labs.S ldiv.S
19LSRCS+= abs.c div.c labs.c ldiv.c
20.elif (${MACHINE_ARCH} == "ns32k")
21SRCS+= abs.S div.c labs.c ldiv.c
22LSRCS+= abs.c
23.elif (${MACHINE_ARCH} == "tahoe")
24SRCS+= abs.S div.c labs.c ldiv.c
25LSRCS+= abs.c
26.elif (${MACHINE_ARCH} == "vax")
27SRCS+= abs.c div.c labs.c ldiv.c
28.elif (${MACHINE_ARCH} == "alpha")
29# XXX should be .S's
30SRCS+= abs.c div.c labs.c ldiv.c
31.else
32SRCS+= abs.c div.c labs.c ldiv.c
33.endif
34
35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
36 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \
37 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
39
40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
41MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
42MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
43MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
44MLINKS+=radixsort.3 sradixsort.3
45MLINKS+=rand.3 srand.3 rand.3 rand_r.3
46MLINKS+=random.3 initstate.3 random.3 setstate.3
47MLINKS+=random.3 srandom.3 random.3 srandomdev.3
48MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
49MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
50MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
51MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3
52MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3
53MLINKS+=tsearch.3 tfind.3
54MLINKS+=tsearch.3 tdelete.3
55MLINKS+=tsearch.3 twalk.3
56MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_rand48.c b/src/lib/libc/stdlib/_rand48.c
new file mode 100644
index 0000000000..fed7372f68
--- /dev/null
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: _rand48.c,v 1.2 1996/08/19 08:33:19 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20unsigned short __rand48_seed[3] = {
21 RAND48_SEED_0,
22 RAND48_SEED_1,
23 RAND48_SEED_2
24};
25unsigned short __rand48_mult[3] = {
26 RAND48_MULT_0,
27 RAND48_MULT_1,
28 RAND48_MULT_2
29};
30unsigned short __rand48_add = RAND48_ADD;
31
32void
33__dorand48(unsigned short xseed[3])
34{
35 unsigned long accu;
36 unsigned short temp[2];
37
38 accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
39 (unsigned long) __rand48_add;
40 temp[0] = (unsigned short) accu; /* lower 16 bits */
41 accu >>= sizeof(unsigned short) * 8;
42 accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
43 (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
44 temp[1] = (unsigned short) accu; /* middle 16 bits */
45 accu >>= sizeof(unsigned short) * 8;
46 accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
47 xseed[0] = temp[0];
48 xseed[1] = temp[1];
49 xseed[2] = (unsigned short) accu;
50}
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..787634303c
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,144 @@
1.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. The name of the author may not be used to endorse or promote products
13.\" derived from this software without specific prior written permission.
14.\"
15.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $OpenBSD: a64l.3,v 1.5 2000/04/20 13:50:01 aaron Exp $
27.\"
28.Dd August 17, 1997
29.Dt A64L 3
30.Os
31.Sh NAME
32.Nm a64l ,
33.Nm l64a
34.Nd convert between 32-bit integer and radix-64 ASCII string
35.Sh SYNOPSIS
36.Fd #include <stdlib.h>
37.Ft long
38.Fn a64l "const char *s"
39.Ft char *
40.Fn l64a "long l"
41.Sh DESCRIPTION
42The
43.Fn a64l
44and
45.Fn l64a
46functions are used to maintain numbers stored in radix-64
47.Tn ASCII
48characters.
49This is a notation by which 32-bit integers
50can be represented by up to six characters; each character represents a
51.Dq digit
52in a radix-64 notation.
53.Pp
54The characters used to represent digits are
55.Ql \&.
56for 0,
57.Ql /
58for 1,
59.Ql 0
60through
61.Ql 9
62for 2-11,
63.Ql A
64through
65.Ql Z
66for 12-37, and
67.Ql a
68through
69.Ql z
70for 38-63.
71.Pp
72The
73.Fn a64l
74function takes a pointer to a null-terminated radix-64 representation
75and returns a corresponding 32-bit value.
76If the string pointed to by
77.Fa s
78contains more than six characters,
79.Fn a64l
80will use the first six.
81.Fn a64l
82scans the character string from left to right, decoding
83each character as a 6-bit radix-64 number.
84If a long integer is
85larger than 32 bits, the return value will be sign-extended.
86.Pp
87.Fn l64a
88takes a long integer argument
89.Fa l
90and returns a pointer to the corresponding radix-64 representation.
91.Sh RETURN VALUES
92On success,
93.Fn a64l
94returns a 32-bit representation of
95.Fa s .
96If
97.Fa s
98is a null pointer or if it contains digits other than those described above.
99.Fn a64l
100returns \-1 and sets the global variable
101.Va errno
102to
103.Er EINVAL .
104.Pp
105On success,
106.Fn l64a
107returns a pointer to a string containing the radix-64 representation of
108.Fa l .
109If
110.Fa l
111is 0,
112.Fn l64a
113returns a pointer to the empty string.
114If
115.Fa l
116is negative,
117.Fn l64a
118returns a null pointer and sets the global variable
119.Va errno
120to
121.Er EINVAL .
122.Sh WARNINGS
123The value returned by
124.Fn l64a
125is a pointer into a static buffer, the contents of which
126will be overwritten by subsequent calls.
127.Pp
128The value returned by
129.Fn a64l
130may be incorrect if the value is too large; for that reason, only strings
131that resulted from a call to
132.Fn l64a
133should be used to call
134.Fn a64l .
135.Pp
136If a long integer is larger than 32 bits, only the low-order
13732 bits are used.
138.Sh STANDARDS
139The
140.Fn a64l
141and
142.Fn l64a
143functions conform to
144.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
new file mode 100644
index 0000000000..a68f0a6dcd
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: a64l.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13long
14a64l(s)
15 const char *s;
16{
17 long value, digit, shift;
18 int i;
19
20 if (s == NULL) {
21 errno = EINVAL;
22 return(-1L);
23 }
24
25 value = 0;
26 shift = 0;
27 for (i = 0; *s && i < 6; i++, s++) {
28 if (*s >= '.' && *s <= '/')
29 digit = *s - '.';
30 else if (*s >= '0' && *s <= '9')
31 digit = *s - '0' + 2;
32 else if (*s >= 'A' && *s <= 'Z')
33 digit = *s - 'A' + 12;
34 else if (*s >= 'a' && *s <= 'z')
35 digit = *s - 'a' + 38;
36 else {
37 errno = EINVAL;
38 return(-1L);
39 }
40
41 value |= digit << shift;
42 shift += 6;
43 }
44
45 return(value);
46}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000000..743d42dd8a
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.3
@@ -0,0 +1,67 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: abort.3,v 1.6 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABORT 3
40.Os
41.Sh NAME
42.Nm abort
43.Nd cause abnormal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn abort void
48.Sh DESCRIPTION
49The
50.Fn abort
51function causes abnormal program termination to occur, unless the signal
52.Dv SIGABRT
53is being caught and the signal handler does not return.
54.Pp
55Any open streams are flushed and closed.
56.Sh RETURN VALUES
57The
58.Fn abort
59function never returns.
60.Sh SEE ALSO
61.Xr sigaction 2 ,
62.Xr exit 3
63.Sh STANDARDS
64The
65.Fn abort
66function conforms to
67.St -p1003.1-90 .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000000..41a9f0f48b
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abort.c,v 1.7 2001/08/12 12:03:01 heko Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <signal.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include "thread_private.h"
42
43void (*__cleanup)();
44
45void
46abort()
47{
48 static int cleanup_called = 0;
49 sigset_t mask;
50
51
52 sigfillset(&mask);
53 /*
54 * don't block SIGABRT to give any handler a chance; we ignore
55 * any errors -- X311J doesn't allow abort to return anyway.
56 */
57 sigdelset(&mask, SIGABRT);
58#ifdef _THREAD_SAFE
59 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
60#else /* _THREAD_SAFE */
61 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
62#endif /* _THREAD_SAFE */
63
64 /*
65 * POSIX requires we flush stdio buffers on abort
66 */
67 if (cleanup_called == 0 && __cleanup != NULL) {
68 cleanup_called = 1;
69 (*__cleanup)();
70 }
71
72 (void)kill(getpid(), SIGABRT);
73
74 /*
75 * if SIGABRT ignored, or caught and the handler returns, do
76 * it again, only harder.
77 */
78 (void)signal(SIGABRT, SIG_DFL);
79#ifdef _THREAD_SAFE
80 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
81#else /* _THREAD_SAFE */
82 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
83#endif /* _THREAD_SAFE */
84 (void)kill(getpid(), SIGABRT);
85 exit(1);
86}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000000..0f7c097ade
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: abs.3,v 1.5 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt ABS 3
40.Os
41.Sh NAME
42.Nm abs
43.Nd integer absolute value function
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn abs "int j"
48.Sh DESCRIPTION
49The
50.Fn abs
51function computes the absolute value of the integer
52.Fa j .
53.Sh RETURN VALUES
54The
55.Fn abs
56function returns the absolute value.
57.Sh SEE ALSO
58.Xr cabs 3 ,
59.Xr floor 3 ,
60.Xr hypot 3 ,
61.Xr labs 3 ,
62.Xr math 3
63.Sh STANDARDS
64The
65.Fn abs
66function conforms to
67.St -ansiC .
68.Sh BUGS
69The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
new file mode 100644
index 0000000000..7c79e4073c
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: abs.c,v 1.2 1996/08/19 08:33:21 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41abs(j)
42 int j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
new file mode 100644
index 0000000000..431443a6e6
--- /dev/null
+++ b/src/lib/libc/stdlib/alloca.3
@@ -0,0 +1,84 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: alloca.3,v 1.9 2001/12/06 04:21:27 deraadt Exp $
33.\"
34.Dd May 2, 1991
35.Dt ALLOCA 3
36.Os
37.Sh NAME
38.Nm alloca
39.Nd memory allocator
40.Sh SYNOPSIS
41.Fd #include <stdlib.h>
42.Ft void *
43.Fn alloca "size_t size"
44.Sh DESCRIPTION
45The
46.Fn alloca
47function allocates
48.Fa size
49bytes of space in the stack frame of the caller.
50This temporary space is automatically freed on return.
51.Sh RETURN VALUES
52The
53.Fn alloca
54function returns a pointer to the beginning of the allocated space.
55.Sh SEE ALSO
56.Xr pagesize 1 ,
57.Xr brk 2 ,
58.Xr calloc 3 ,
59.Xr malloc 3 ,
60.Xr realloc 3
61.Sh BUGS
62The
63.Fn alloca
64function is machine dependent; its use is discouraged.
65.\" .Sh HISTORY
66.\" The
67.\" .Fn alloca
68.\" function appeared in
69.\" .Bx ?? .
70.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
71.\" The first man page (or link to a man page that I can find at the
72.\" moment is 4.3...
73.Pp
74The
75.Fn alloca
76function is slightly unsafe because it cannot ensure that the pointer
77returned points to a valid and usable block of memory.
78The allocation made may exceed the bounds of the stack, or even go
79further into other objects in memory, and
80.Fn alloca
81cannot determine such an error.
82Avoid
83.Fn alloca
84with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000000..5d79ede649
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.3
@@ -0,0 +1,75 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atexit.3,v 1.4 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATEXIT 3
40.Os
41.Sh NAME
42.Nm atexit
43.Nd register a function to be called on exit
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn atexit "void (*function)(void)"
48.Sh DESCRIPTION
49The
50.Fn atexit
51function registers the given
52.Fa function
53to be called at program exit, whether via
54.Xr exit 3
55or via return from the program's
56.Fn main .
57Functions so registered are called in reverse order;
58no arguments are passed.
59At least 32 functions can always be registered,
60and more are allowed as long as sufficient memory can be allocated.
61.Sh RETURN VALUES
62.Rv -std atexit
63.Sh ERRORS
64.Bl -tag -width Er
65.It Bq Er ENOMEM
66No memory was available to add the function to the list.
67The existing list of functions is unmodified.
68.El
69.Sh SEE ALSO
70.Xr exit 3
71.Sh STANDARDS
72The
73.Fn atexit
74function conforms to
75.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000000..92c4884f28
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#if defined(LIBC_SCCS) && !defined(lint)
32static char *rcsid = "$OpenBSD: atexit.c,v 1.5 2002/08/30 07:58:07 dhartmei Exp $";
33#endif /* LIBC_SCCS and not lint */
34
35#include <sys/types.h>
36#include <sys/mman.h>
37#include <stdlib.h>
38#include "atexit.h"
39
40int __atexit_invalid = 1;
41struct atexit *__atexit;
42
43/*
44 * Register a function to be performed at exit.
45 */
46int
47atexit(fn)
48 void (*fn)();
49{
50 register struct atexit *p = __atexit;
51 register int pgsize = getpagesize();
52
53 if (pgsize < sizeof(*p))
54 return (-1);
55 if (p != NULL) {
56 if (p->ind + 1 >= p->max)
57 p = NULL;
58 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
59 return (-1);
60 }
61 if (p == NULL) {
62 if (__atexit_invalid) {
63 /* malloc.c wants the first mmap() for sbrk()
64 games ('nice hack'), so enforce
65 malloc_init() with a dummy call. */
66 free(malloc(1));
67 __atexit_invalid = 0;
68 }
69 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
70 MAP_ANON | MAP_PRIVATE, -1, 0);
71 if (p == MAP_FAILED)
72 return (-1);
73 p->ind = 0;
74 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
75 sizeof(p->fns[0]);
76 p->next = __atexit;
77 __atexit = p;
78 }
79 p->fns[p->ind++] = fn;
80 if (mprotect(p, pgsize, PROT_READ))
81 return (-1);
82 return (0);
83}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000000..28bf3a7f27
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.h
@@ -0,0 +1,41 @@
1/* $OpenBSD: atexit.h,v 1.5 2002/08/30 07:58:07 dhartmei Exp $ */
2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33struct atexit {
34 struct atexit *next; /* next in list */
35 int ind; /* next index in this table */
36 int max; /* max entries >= ATEXIT_SIZE */
37 void (*fns[1])(); /* the table itself */
38};
39
40extern int __atexit_invalid;
41extern struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
new file mode 100644
index 0000000000..0bd85dbe82
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atof.3,v 1.3 1999/06/29 18:36:18 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOF 3
40.Os
41.Sh NAME
42.Nm atof
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn atof "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atof
53function converts the initial portion of the string pointed to by
54.Fa nptr
55to
56.Li double
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtod(nptr, (char **)NULL);
62.Ed
63.Sh SEE ALSO
64.Xr atoi 3 ,
65.Xr atol 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atof
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
new file mode 100644
index 0000000000..30bac19899
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atof.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40double
41atof(ascii)
42 const char *ascii;
43{
44 return(strtod(ascii, (char **)NULL));
45}
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
new file mode 100644
index 0000000000..69b94be70c
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.3
@@ -0,0 +1,85 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atoi.3,v 1.5 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd June 4, 1993
39.Dt ATOI 3
40.Os
41.Sh NAME
42.Nm atoi
43.Nd convert
44.Tn ASCII
45string to integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft int
49.Fn atoi "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atoi
53function converts the initial portion of the string pointed to by
54.Fa nptr
55to
56.Li integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61(int)strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh CAVEATS
64.Nm
65does no overflow checking, handles unsigned numbers poorly,
66and handles strings containing trailing extra characters
67(like
68.Dq "123abc" Ns )
69poorly.
70Careful use of
71.Xr strtol 3
72and
73.Xr strtoul 3
74can alleviate these problems.
75.Sh SEE ALSO
76.Xr atof 3 ,
77.Xr atol 3 ,
78.Xr strtod 3 ,
79.Xr strtol 3 ,
80.Xr strtoul 3
81.Sh STANDARDS
82The
83.Fn atoi
84function conforms to
85.St -ansiC .
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
new file mode 100644
index 0000000000..a74d6e1351
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atoi.c,v 1.2 1996/08/19 08:33:24 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40int
41atoi(str)
42 const char *str;
43{
44 return((int)strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
new file mode 100644
index 0000000000..53a518997f
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: atol.3,v 1.4 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt ATOL 3
40.Os
41.Sh NAME
42.Nm atol
43.Nd convert
44.Tn ASCII
45string to long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft long
49.Fn atol "const char *nptr"
50.Sh DESCRIPTION
51The
52.Fn atol
53function converts the initial portion of the string pointed to by
54.Fa nptr
55to
56.Li long integer
57representation.
58.Pp
59It is equivalent to:
60.Bd -literal -offset indent
61strtol(nptr, (char **)NULL, 10);
62.Ed
63.Sh SEE ALSO
64.Xr atof 3 ,
65.Xr atoi 3 ,
66.Xr strtod 3 ,
67.Xr strtol 3 ,
68.Xr strtoul 3
69.Sh STANDARDS
70The
71.Fn atol
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
new file mode 100644
index 0000000000..528a932214
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: atol.c,v 1.2 1996/08/19 08:33:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41atol(str)
42 const char *str;
43{
44 return(strtol(str, (char **)NULL, 10));
45}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
new file mode 100644
index 0000000000..9bb9d4ece4
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,88 @@
1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: bsearch.3,v 1.5 2000/04/20 13:50:01 aaron Exp $
37.\"
38.Dd April 19, 1994
39.Dt BSEARCH 3
40.Os
41.Sh NAME
42.Nm bsearch
43.Nd binary search of a sorted table
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar) (const void *, const void *)"
48.Sh DESCRIPTION
49The
50.Fn bsearch
51function searches an array of
52.Fa nmemb
53objects, the initial member of which is
54pointed to by
55.Fa base ,
56for a member that matches the object pointed to by
57.Fa key .
58The size of each member of the array is specified by
59.Fa size .
60.Pp
61The contents of the array should be in ascending sorted order according
62to the comparison function referenced by
63.Fa compar .
64The
65.Fa compar
66routine is expected to have two arguments which point to the
67.Fa key
68object and to an array member, in that order, and should return an integer
69less than, equal to, or greater than zero if the
70.Fa key
71object is found, respectively, to be less than, to match, or be
72greater than the array member.
73.Sh RETURN VALUES
74The
75.Fn bsearch
76function returns a pointer to a matching member of the array, or a null
77pointer if no match is found.
78If two members compare as equal, which member is matched is unspecified.
79.Sh SEE ALSO
80.Xr db 3 ,
81.Xr lsearch 3 ,
82.Xr qsort 3 ,
83.Xr tsearch 3
84.Sh STANDARDS
85The
86.Fn bsearch
87function conforms to
88.St -ansiC .
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000000..1903202b6c
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bsearch.c,v 1.3 2002/02/16 21:27:24 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Perform a binary search.
42 *
43 * The code below is a bit sneaky. After a comparison fails, we
44 * divide the work in half by moving either left or right. If lim
45 * is odd, moving left simply involves halving lim: e.g., when lim
46 * is 5 we look at item 2, so we change lim to 2 so that we will
47 * look at items 0 & 1. If lim is even, the same applies. If lim
48 * is odd, moving right again involes halving lim, this time moving
49 * the base up one item past p: e.g., when lim is 5 we change base
50 * to item 3 and make lim 2 so that we will look at items 3 and 4.
51 * If lim is even, however, we have to shrink it by one before
52 * halving: e.g., when lim is 4, we still looked at item 2, so we
53 * have to make lim 3, then halve, obtaining 1, so that we will only
54 * look at item 3.
55 */
56void *
57bsearch(key, base0, nmemb, size, compar)
58 register const void *key;
59 const void *base0;
60 size_t nmemb;
61 register size_t size;
62 register int (*compar)(const void *, const void *);
63{
64 register const char *base = base0;
65 register int lim, cmp;
66 register const void *p;
67
68 for (lim = nmemb; lim != 0; lim >>= 1) {
69 p = base + (lim >> 1) * size;
70 cmp = (*compar)(key, p);
71 if (cmp == 0)
72 return ((void *)p);
73 if (cmp > 0) { /* key > p: move right */
74 base = (char *)p + size;
75 lim--;
76 } /* else move left */
77 }
78 return (NULL);
79}
diff --git a/src/lib/libc/stdlib/calloc.c b/src/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000000..c75b256d14
--- /dev/null
+++ b/src/lib/libc/stdlib/calloc.c
@@ -0,0 +1,59 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: calloc.c,v 1.7 2002/07/31 09:19:04 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40#include <limits.h>
41#include <errno.h>
42
43void *
44calloc(num, size)
45 size_t num;
46 register size_t size;
47{
48 register void *p;
49
50 if (num && size && SIZE_T_MAX / num < size) {
51 errno = ENOMEM;
52 return NULL;
53 }
54 size *= num;
55 p = malloc(size);
56 if (p)
57 memset(p, 0, size);
58 return(p);
59}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..3af32039a9
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $ */
2
3/*
4 * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by SigmaSoft, Th. Lockert.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char rcsid[] = "$OpenBSD: cfree.c,v 1.1 1996/08/21 03:47:22 tholo Exp $";
35#endif /* LIBC_SCCS and not lint */
36
37#include <sys/cdefs.h>
38
39#ifdef __indr_reference
40__indr_reference(free, cfree);
41#else
42
43void
44cfree(p)
45 void *p;
46{
47 free(p);
48}
49#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
new file mode 100644
index 0000000000..1f651d7fd3
--- /dev/null
+++ b/src/lib/libc/stdlib/div.3
@@ -0,0 +1,67 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: div.3,v 1.5 2000/04/20 13:50:02 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt DIV 3
38.Os
39.Sh NAME
40.Nm div
41.Nd return quotient and remainder from division
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Ft div_t
45.Fn div "int num" "int denom"
46.Sh DESCRIPTION
47The
48.Fn div
49function computes the value
50.Fa num Ns No / Ns Fa denom
51and returns the quotient and remainder in a structure named
52.Fa div_t
53that contains two
54.Li int
55members named
56.Fa quot
57and
58.Fa rem .
59.Sh SEE ALSO
60.Xr ldiv 3 ,
61.Xr math 3 ,
62.Xr qdiv 3
63.Sh STANDARDS
64The
65.Fn div
66function conforms to
67.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
new file mode 100644
index 0000000000..c1fae29008
--- /dev/null
+++ b/src/lib/libc/stdlib/div.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: div.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* div_t */
42
43div_t
44div(num, denom)
45 int num, denom;
46{
47 div_t r;
48
49 r.quot = num / denom;
50 r.rem = num % denom;
51 /*
52 * The ANSI standard says that |r.quot| <= |n/d|, where
53 * n/d is to be computed in infinite precision. In other
54 * words, we should always truncate the quotient towards
55 * 0, never -infinity.
56 *
57 * Machine division and remainer may work either way when
58 * one or both of n or d is negative. If only one is
59 * negative and r.quot has been truncated towards -inf,
60 * r.rem will have the same sign as denom and the opposite
61 * sign of num; if both are negative and r.quot has been
62 * truncated towards -inf, r.rem will be positive (will
63 * have the opposite sign of num). These are considered
64 * `wrong'.
65 *
66 * If both are num and denom are positive, r will always
67 * be positive.
68 *
69 * This all boils down to:
70 * if num >= 0, but r.rem < 0, we got the wrong answer.
71 * In that case, to get the right answer, add 1 to r.quot and
72 * subtract denom from r.rem.
73 */
74 if (num >= 0 && r.rem < 0) {
75 r.quot++;
76 r.rem -= denom;
77 }
78 return (r);
79}
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
new file mode 100644
index 0000000000..02886d5b62
--- /dev/null
+++ b/src/lib/libc/stdlib/drand48.c
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: drand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22double
23drand48(void)
24{
25 return erand48(__rand48_seed);
26}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
new file mode 100644
index 0000000000..b92dacffcc
--- /dev/null
+++ b/src/lib/libc/stdlib/erand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: erand48.c,v 1.2 1996/08/19 08:33:29 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20double
21erand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ldexp((double) xseed[0], -48) +
25 ldexp((double) xseed[1], -32) +
26 ldexp((double) xseed[2], -16);
27}
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
new file mode 100644
index 0000000000..bcfdfd38f5
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.3
@@ -0,0 +1,92 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: exit.3,v 1.6 2001/07/27 23:48:12 mpech Exp $
37.\"
38.Dd June 29, 1991
39.Dt EXIT 3
40.Os
41.Sh NAME
42.Nm exit
43.Nd perform normal program termination
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void
47.Fn exit "int status"
48.Sh DESCRIPTION
49The
50.Fn exit
51function terminates a process.
52.Pp
53Before termination it performs the following functions in the
54order listed:
55.Bl -enum -offset indent
56.It
57Call the functions registered with the
58.Xr atexit 3
59function, in the reverse order of their registration.
60.It
61Flush all open output streams.
62.It
63Close all open streams.
64.It
65Unlink all files created with the
66.Xr tmpfile 3
67function.
68.El
69Following this,
70.Fn exit
71calls
72.Xr _exit 2 .
73Note that typically
74.Xr exit 2
75only passes the lower 8 bits of
76.Fa status
77on to the parent, thus negative values have less meaning.
78.Sh RETURN VALUES
79The
80.Fn exit
81function never returns.
82.Sh SEE ALSO
83.Xr _exit 2 ,
84.Xr atexit 3 ,
85.Xr intro 3 ,
86.Xr sysexits 3 ,
87.Xr tmpfile 3
88.Sh STANDARDS
89The
90.Fn exit
91function conforms to
92.St -ansiC .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000000..c69639125e
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.c
@@ -0,0 +1,79 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: exit.c,v 1.7 2002/08/30 07:58:07 dhartmei Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/mman.h>
40#include <stdlib.h>
41#include <unistd.h>
42#include "atexit.h"
43#include "thread_private.h"
44
45void (*__cleanup)();
46
47/*
48 * This variable is zero until a process has created a thread.
49 * It is used to avoid calling locking functions in libc when they
50 * are not required. By default, libc is intended to be(come)
51 * thread-safe, but without a (significant) penalty to non-threaded
52 * processes.
53 */
54int __isthreaded = 0;
55
56/*
57 * Exit, flushing stdio buffers if necessary.
58 */
59void
60exit(status)
61 int status;
62{
63 register struct atexit *p, *q;
64 register int n, pgsize = getpagesize();
65
66 if (!__atexit_invalid) {
67 p = __atexit;
68 while (p != NULL) {
69 for (n = p->ind; --n >= 0;)
70 (*p->fns[n])();
71 q = p;
72 p = p->next;
73 munmap(q, pgsize);
74 }
75 }
76 if (__cleanup)
77 (*__cleanup)();
78 _exit(status);
79}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000000..b2aa0080d6
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.3
@@ -0,0 +1,146 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: getenv.3,v 1.7 2000/04/20 13:50:02 aaron Exp $
37.\"
38.Dd December 11, 1993
39.Dt GETENV 3
40.Os
41.Sh NAME
42.Nm getenv ,
43.Nm putenv ,
44.Nm setenv ,
45.Nm unsetenv
46.Nd environment variable functions
47.Sh SYNOPSIS
48.Fd #include <stdlib.h>
49.Ft char *
50.Fn getenv "const char *name"
51.Ft int
52.Fn setenv "const char *name" "const char *value" "int overwrite"
53.Ft int
54.Fn putenv "const char *string"
55.Ft void
56.Fn unsetenv "const char *name"
57.Sh DESCRIPTION
58These functions set, unset, and fetch environment variables from the host
59.Em environment list .
60For compatibility with differing environment conventions, the given arguments
61.Fa name
62and
63.Fa value
64may be appended and prepended, respectively, with an equal sign
65.Dq Li \&= .
66.Pp
67The
68.Fn getenv
69function obtains the current value of the environment variable,
70.Fa name .
71If the variable
72.Fa name
73is not in the current environment, a null pointer is returned.
74.Pp
75The
76.Fn setenv
77function inserts or resets the environment variable
78.Fa name
79in the current environment list.
80If the variable
81.Fa name
82does not exist in the list, it is inserted with the given
83.Fa value .
84If the variable does exist, the argument
85.Fa overwrite
86is tested; if
87.Fa overwrite
88is zero, the variable is not reset, otherwise it is reset to the given
89.Fa value .
90.Pp
91The
92.Fn putenv
93function takes an argument of the form
94.Ar name Ns No = Ns Ar value
95and is equivalent to:
96.Bd -literal -offset indent
97setenv(name, value, 1);
98.Ed
99.Pp
100The
101.Fn unsetenv
102function deletes all instances of the variable name pointed to by
103.Fa name
104from the list.
105.Sh RETURN VALUES
106The functions
107.Fn setenv
108and
109.Fn putenv
110return zero if successful; otherwise the global variable
111.Va errno
112is set to indicate the error and \-1 is returned.
113.Pp
114If
115.Fn getenv
116is successful, the string returned should be considered read-only.
117.Sh ERRORS
118.Bl -tag -width [ENOMEM]
119.It Bq Er ENOMEM
120The function
121.Fn setenv
122or
123.Fn putenv
124failed because they were unable to allocate memory for the environment.
125.El
126.Sh SEE ALSO
127.Xr csh 1 ,
128.Xr sh 1 ,
129.Xr execve 2 ,
130.Xr environ 7
131.Sh STANDARDS
132The
133.Fn getenv
134function conforms to
135.St -ansiC .
136.Sh HISTORY
137The functions
138.Fn setenv
139and
140.Fn unsetenv
141appeared in
142.At v7 .
143The
144.Fn putenv
145function appeared in
146.Bx 4.3 Reno .
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
new file mode 100644
index 0000000000..4db86df915
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 1987, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getenv.c,v 1.4 1998/07/16 18:02:33 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * __findenv --
43 * Returns pointer to value associated with name, if any, else NULL.
44 * Sets offset to be the offset of the name/value combination in the
45 * environmental array, for use by setenv(3) and unsetenv(3).
46 * Explicitly removes '=' in argument name.
47 *
48 * This routine *should* be a static; don't use it.
49 */
50char *
51__findenv(name, offset)
52 register const char *name;
53 int *offset;
54{
55 extern char **environ;
56 register int len, i;
57 register const char *np;
58 register char **p, *cp;
59
60 if (name == NULL || environ == NULL)
61 return (NULL);
62 for (np = name; *np && *np != '='; ++np)
63 ;
64 len = np - name;
65 for (p = environ; (cp = *p) != NULL; ++p) {
66 for (np = name, i = len; i && *cp; i--)
67 if (*cp++ != *np++)
68 break;
69 if (i == 0 && *cp++ == '=') {
70 *offset = p - environ;
71 return (cp);
72 }
73 }
74 return (NULL);
75}
76
77/*
78 * getenv --
79 * Returns ptr to value associated with name, if any, else NULL.
80 */
81char *
82getenv(name)
83 const char *name;
84{
85 int offset;
86 char *__findenv();
87
88 return(__findenv(name, &offset));
89}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
new file mode 100644
index 0000000000..4acbe69606
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.3
@@ -0,0 +1,254 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: getopt.3,v 1.17 2002/08/19 22:29:52 miod Exp $
33.\"
34.Dd April 19, 1994
35.Dt GETOPT 3
36.Os
37.Sh NAME
38.Nm getopt
39.Nd get option character from command line argument list
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Vt extern char *optarg;
43.Vt extern int optind;
44.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset;
47.Ft int
48.Fn getopt "int argc" "char * const *argv" "const char *optstring"
49.Sh DESCRIPTION
50The
51.Fn getopt
52function incrementally parses a command line argument list
53.Fa argv
54and returns the next known option character.
55An option character is
56.Dq known
57if it has been specified in the string of accepted option characters,
58.Fa optstring .
59.Pp
60The option string
61.Fa optstring
62may contain the following elements: individual characters and
63characters followed by a colon to indicate an option argument
64is to follow.
65For example, an option string
66.Qq x
67recognizes an option
68.Fl x ,
69and an option string
70.Qq Li x:
71recognizes an option and argument
72.Fl x Ar argument .
73It does not matter to
74.Fn getopt
75if a following argument has leading whitespace.
76.Pp
77On return from
78.Fn getopt ,
79.Va optarg
80points to an option argument, if it is anticipated,
81and the variable
82.Va optind
83contains the index to the next
84.Fa argv
85argument for a subsequent call
86to
87.Fn getopt .
88The variable
89.Va optopt
90saves the last known option character returned by
91.Fn getopt .
92.Pp
93The variables
94.Va opterr
95and
96.Va optind
97are both initialized to 1.
98The
99.Va optind
100variable may be set to another value before a set of calls to
101.Fn getopt
102in order to skip over more or less argv entries.
103.Pp
104In order to use
105.Fn getopt
106to evaluate multiple sets of arguments, or to evaluate a single set of
107arguments multiple times,
108the variable
109.Va optreset
110must be set to 1 before the second and each additional set of calls to
111.Fn getopt ,
112and the variable
113.Va optind
114must be reinitialized.
115.Pp
116The
117.Fn getopt
118function returns \-1 when the argument list is exhausted.
119The interpretation of options in the argument list may be cancelled
120by the option
121.Ql --
122(double dash) which causes
123.Fn getopt
124to signal the end of argument processing and returns \-1.
125When all options have been processed (i.e., up to the first non-option
126argument),
127.Fn getopt
128returns \-1.
129.Sh EXAMPLES
130.Bd -literal -compact
131int bflag, ch, fd;
132
133bflag = 0;
134while ((ch = getopt(argc, argv, "bf:")) != -1) {
135 switch (ch) {
136 case 'b':
137 bflag = 1;
138 break;
139 case 'f':
140 if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
141 (void)fprintf(stderr,
142 "myname: %s: %s\en", optarg, strerror(errno));
143 exit(1);
144 }
145 break;
146 case '?':
147 default:
148 usage();
149 }
150}
151argc -= optind;
152argv += optind;
153.Ed
154.Sh SEE ALSO
155.Xr getopt 1 ,
156.Xr getsubopt 3
157.Sh DIAGNOSTICS
158If the
159.Fn getopt
160function encounters a character not found in the string
161.Va optstring
162or detects
163a missing option argument it writes an error message to
164.Em stderr
165and returns
166.Ql ? .
167Setting
168.Va opterr
169to a zero will disable these error messages.
170If
171.Va optstring
172has a leading
173.Ql \&:
174then a missing option argument causes a
175.Ql \&:
176to be returned in addition to suppressing any error messages.
177.Pp
178Option arguments are allowed to begin with
179.Ql - ;
180this is reasonable but reduces the amount of error checking possible.
181.Sh EXTENSIONS
182The
183.Va optreset
184variable was added to make it possible to call the
185.Fn getopt
186function multiple times.
187This is an extension to the
188.St -p1003.2
189specification.
190.Sh HISTORY
191The
192.Fn getopt
193function appeared in
194.Bx 4.3 .
195.Sh BUGS
196The
197.Fn getopt
198function was once specified to return
199.Dv EOF
200instead of \-1.
201This was changed by
202.St -p1003.2-92
203to decouple
204.Fn getopt
205from
206.Pa <stdio.h> .
207.Pp
208A single dash
209.Pq Ql -
210may be specified as a character in
211.Fa optstring ,
212however it should
213.Em never
214have an argument associated with it.
215This allows
216.Fn getopt
217to be used with programs that expect
218.Ql -
219as an option flag.
220This practice is wrong, and should not be used in any current development.
221It is provided for backward compatibility
222.Em only .
223By default, a single dash causes
224.Fn getopt
225to return \-1.
226This is, we believe, compatible with System V.
227.Pp
228It is also possible to handle digits as option letters.
229This allows
230.Fn getopt
231to be used with programs that expect a number
232.Pq Dq Li \&-\&3
233as an option.
234This practice is wrong, and should not be used in any current development.
235It is provided for backward compatibility
236.Em only .
237The following code fragment works in most cases.
238.Bd -literal -offset indent
239long length;
240char *p;
241
242while ((c = getopt(argc, argv, "0123456789")) != -1) {
243 switch (c) {
244 case '0': case '1': case '2': case '3': case '4':
245 case '5': case '6': case '7': case '8': case '9':
246 p = argv[optind - 1];
247 if (p[0] == '-' && p[1] == ch && !p[2])
248 length = ch - '0';
249 else
250 length = strtol(argv[optind] + 1, NULL, 10);
251 break;
252 }
253}
254.Ed
diff --git a/src/lib/libc/stdlib/getopt.c b/src/lib/libc/stdlib/getopt.c
new file mode 100644
index 0000000000..b7f6163662
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 1987, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: getopt.c,v 1.2 1996/08/19 08:33:32 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
42int opterr = 1, /* if error message should be printed */
43 optind = 1, /* index into parent argv vector */
44 optopt, /* character checked for validity */
45 optreset; /* reset getopt */
46char *optarg; /* argument associated with option */
47
48#define BADCH (int)'?'
49#define BADARG (int)':'
50#define EMSG ""
51
52/*
53 * getopt --
54 * Parse argc/argv argument vector.
55 */
56int
57getopt(nargc, nargv, ostr)
58 int nargc;
59 char * const *nargv;
60 const char *ostr;
61{
62 extern char *__progname;
63 static char *place = EMSG; /* option letter processing */
64 char *oli; /* option letter list index */
65
66 if (optreset || !*place) { /* update scanning pointer */
67 optreset = 0;
68 if (optind >= nargc || *(place = nargv[optind]) != '-') {
69 place = EMSG;
70 return (-1);
71 }
72 if (place[1] && *++place == '-') { /* found "--" */
73 ++optind;
74 place = EMSG;
75 return (-1);
76 }
77 } /* option letter okay? */
78 if ((optopt = (int)*place++) == (int)':' ||
79 !(oli = strchr(ostr, optopt))) {
80 /*
81 * if the user didn't specify '-' as an option,
82 * assume it means -1.
83 */
84 if (optopt == (int)'-')
85 return (-1);
86 if (!*place)
87 ++optind;
88 if (opterr && *ostr != ':')
89 (void)fprintf(stderr,
90 "%s: illegal option -- %c\n", __progname, optopt);
91 return (BADCH);
92 }
93 if (*++oli != ':') { /* don't need argument */
94 optarg = NULL;
95 if (!*place)
96 ++optind;
97 }
98 else { /* need an argument */
99 if (*place) /* no white space */
100 optarg = place;
101 else if (nargc <= ++optind) { /* no arg */
102 place = EMSG;
103 if (*ostr == ':')
104 return (BADARG);
105 if (opterr)
106 (void)fprintf(stderr,
107 "%s: option requires an argument -- %c\n",
108 __progname, optopt);
109 return (BADCH);
110 }
111 else /* white space */
112 optarg = nargv[optind];
113 place = EMSG;
114 ++optind;
115 }
116 return (optopt); /* dump back option letter */
117}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..8a17da4ea5
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,147 @@
1.\" $OpenBSD: getsubopt.3,v 1.5 2000/12/15 14:31:17 aaron Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt GETSUBOPT 3
38.Os
39.Sh NAME
40.Nm getsubopt
41.Nd get sub options from an argument
42.Sh SYNOPSIS
43.Fd #include <stdlib.h>
44.Vt extern char *suboptarg;
45.Ft int
46.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
47.Sh DESCRIPTION
48The
49.Fn getsubopt
50function parses a string containing tokens delimited by one or more
51tab, space or comma
52.Pq Ql \&,
53characters.
54It is intended for use in parsing groups of option arguments provided
55as part of a utility command line.
56.Pp
57The argument
58.Fa optionp
59is a pointer to a pointer to the string.
60The argument
61.Fa tokens
62is a pointer to a null-terminated array of pointers to strings.
63.Pp
64The
65.Fn getsubopt
66function returns the zero-based offset of the pointer in the
67.Fa tokens
68array referencing a string which matches the first token
69in the string, or, \-1 if the string contains no tokens or
70.Fa tokens
71does not contain a matching string.
72.Pp
73If the token is of the form
74.Ar name Ns No = Ns Ar value ,
75the location referenced by
76.Fa valuep
77will be set to point to the start of the
78.Dq value
79portion of the token.
80.Pp
81On return from
82.Fn getsubopt ,
83.Fa optionp
84will be set to point to the start of the next token in the string,
85or the null at the end of the string if no more tokens are present.
86The external variable
87.Fa suboptarg
88will be set to point to the start of the current token, or
89.Dv NULL
90if no tokens were present.
91The argument
92.Fa valuep
93will be set to point to the value portion of the token, or
94.Dv NULL
95if no value portion was present.
96.Sh EXAMPLES
97.Bd -literal -compact
98char *tokens[] = {
99 #define ONE 0
100 "one",
101 #define TWO 1
102 "two",
103 NULL
104};
105
106\&...
107
108extern char *optarg, *suboptarg;
109char *options, *value;
110
111while ((ch = getopt(argc, argv, "ab:")) != \-1) {
112 switch(ch) {
113 case 'a':
114 /* process ``a'' option */
115 break;
116 case 'b':
117 options = optarg;
118 while (*options) {
119 switch(getsubopt(&options, tokens, &value)) {
120 case ONE:
121 /* process ``one'' sub option */
122 break;
123 case TWO:
124 /* process ``two'' sub option */
125 if (!value)
126 error("no value for two");
127 i = atoi(value);
128 break;
129 case \-1:
130 if (suboptarg)
131 error("illegal sub option %s",
132 suboptarg);
133 else
134 error("missing sub option");
135 break;
136 }
137 break;
138 }
139.Ed
140.Sh SEE ALSO
141.Xr getopt 3 ,
142.Xr strsep 3
143.Sh HISTORY
144The
145.Fn getsubopt
146function first appeared in
147.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/getsubopt.c b/src/lib/libc/stdlib/getsubopt.c
new file mode 100644
index 0000000000..1667a31d7d
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$OpenBSD: getsubopt.c,v 1.1 1997/08/20 04:02:17 millert Exp $";
41#endif
42#endif /* not lint */
43
44#include <unistd.h>
45#include <stdlib.h>
46#include <string.h>
47
48/*
49 * The SVID interface to getsubopt provides no way of figuring out which
50 * part of the suboptions list wasn't matched. This makes error messages
51 * tricky... The extern variable suboptarg is a pointer to the token
52 * which didn't match.
53 */
54char *suboptarg;
55
56int
57getsubopt(optionp, tokens, valuep)
58 register char **optionp, **valuep;
59 register char * const *tokens;
60{
61 register int cnt;
62 register char *p;
63
64 suboptarg = *valuep = NULL;
65
66 if (!optionp || !*optionp)
67 return(-1);
68
69 /* skip leading white-space, commas */
70 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
71
72 if (!*p) {
73 *optionp = p;
74 return(-1);
75 }
76
77 /* save the start of the token, and skip the rest of the token. */
78 for (suboptarg = p;
79 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
80
81 if (*p) {
82 /*
83 * If there's an equals sign, set the value pointer, and
84 * skip over the value part of the token. Terminate the
85 * token.
86 */
87 if (*p == '=') {
88 *p = '\0';
89 for (*valuep = ++p;
90 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
91 if (*p)
92 *p++ = '\0';
93 } else
94 *p++ = '\0';
95 /* Skip any whitespace or commas after this token. */
96 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
97 }
98
99 /* set optionp for next round. */
100 *optionp = p;
101
102 for (cnt = 0; *tokens; ++tokens, ++cnt)
103 if (!strcmp(suboptarg, *tokens))
104 return(cnt);
105 return(-1);
106}
diff --git a/src/lib/libc/stdlib/heapsort.c b/src/lib/libc/stdlib/heapsort.c
new file mode 100644
index 0000000000..2770e5b977
--- /dev/null
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,183 @@
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: heapsort.c,v 1.3 2002/02/16 21:27:24 millert Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42#include <errno.h>
43#include <stdlib.h>
44
45/*
46 * Swap two areas of size number of bytes. Although qsort(3) permits random
47 * blocks of memory to be sorted, sorting pointers is almost certainly the
48 * common case (and, were it not, could easily be made so). Regardless, it
49 * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
50 * arithmetic gets lost in the time required for comparison function calls.
51 */
52#define SWAP(a, b, count, size, tmp) { \
53 count = size; \
54 do { \
55 tmp = *a; \
56 *a++ = *b; \
57 *b++ = tmp; \
58 } while (--count); \
59}
60
61/* Copy one block of size size to another. */
62#define COPY(a, b, count, size, tmp1, tmp2) { \
63 count = size; \
64 tmp1 = a; \
65 tmp2 = b; \
66 do { \
67 *tmp1++ = *tmp2++; \
68 } while (--count); \
69}
70
71/*
72 * Build the list into a heap, where a heap is defined such that for
73 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
74 *
75 * There two cases. If j == nmemb, select largest of Ki and Kj. If
76 * j < nmemb, select largest of Ki, Kj and Kj+1.
77 */
78#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
79 for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
80 par_i = child_i) { \
81 child = base + child_i * size; \
82 if (child_i < nmemb && compar(child, child + size) < 0) { \
83 child += size; \
84 ++child_i; \
85 } \
86 par = base + par_i * size; \
87 if (compar(child, par) <= 0) \
88 break; \
89 SWAP(par, child, count, size, tmp); \
90 } \
91}
92
93/*
94 * Select the top of the heap and 'heapify'. Since by far the most expensive
95 * action is the call to the compar function, a considerable optimization
96 * in the average case can be achieved due to the fact that k, the displaced
97 * elememt, is ususally quite small, so it would be preferable to first
98 * heapify, always maintaining the invariant that the larger child is copied
99 * over its parent's record.
100 *
101 * Then, starting from the *bottom* of the heap, finding k's correct place,
102 * again maintianing the invariant. As a result of the invariant no element
103 * is 'lost' when k is assigned its correct place in the heap.
104 *
105 * The time savings from this optimization are on the order of 15-20% for the
106 * average case. See Knuth, Vol. 3, page 158, problem 18.
107 *
108 * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
109 */
110#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
111 for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
112 child = base + child_i * size; \
113 if (child_i < nmemb && compar(child, child + size) < 0) { \
114 child += size; \
115 ++child_i; \
116 } \
117 par = base + par_i * size; \
118 COPY(par, child, count, size, tmp1, tmp2); \
119 } \
120 for (;;) { \
121 child_i = par_i; \
122 par_i = child_i / 2; \
123 child = base + child_i * size; \
124 par = base + par_i * size; \
125 if (child_i == 1 || compar(k, par) < 0) { \
126 COPY(child, k, count, size, tmp1, tmp2); \
127 break; \
128 } \
129 COPY(child, par, count, size, tmp1, tmp2); \
130 } \
131}
132
133/*
134 * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
135 * and worst. While heapsort is faster than the worst case of quicksort,
136 * the BSD quicksort does median selection so that the chance of finding
137 * a data set that will trigger the worst case is nonexistent. Heapsort's
138 * only advantage over quicksort is that it requires little additional memory.
139 */
140int
141heapsort(vbase, nmemb, size, compar)
142 void *vbase;
143 size_t nmemb, size;
144 int (*compar)(const void *, const void *);
145{
146 register int cnt, i, j, l;
147 register char tmp, *tmp1, *tmp2;
148 char *base, *k, *p, *t;
149
150 if (nmemb <= 1)
151 return (0);
152
153 if (!size) {
154 errno = EINVAL;
155 return (-1);
156 }
157
158 if ((k = malloc(size)) == NULL)
159 return (-1);
160
161 /*
162 * Items are numbered from 1 to nmemb, so offset from size bytes
163 * below the starting address.
164 */
165 base = (char *)vbase - size;
166
167 for (l = nmemb / 2 + 1; --l;)
168 CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
169
170 /*
171 * For each element of the heap, save the largest element into its
172 * final slot, save the displaced element (k), then recreate the
173 * heap.
174 */
175 while (nmemb > 1) {
176 COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
177 COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
178 --nmemb;
179 SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
180 }
181 free(k);
182 return (0);
183}
diff --git a/src/lib/libc/stdlib/jrand48.c b/src/lib/libc/stdlib/jrand48.c
new file mode 100644
index 0000000000..99cddb71e5
--- /dev/null
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: jrand48.c,v 1.2 1996/08/19 08:33:33 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20long
21jrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 16) + (long) xseed[1];
25}
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
new file mode 100644
index 0000000000..4e99391254
--- /dev/null
+++ b/src/lib/libc/stdlib/l64a.c
@@ -0,0 +1,46 @@
1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 */
5
6#if defined(LIBC_SCCS) && !defined(lint)
7static char *rcsid = "$OpenBSD: l64a.c,v 1.3 1997/08/17 22:58:34 millert Exp $";
8#endif /* LIBC_SCCS and not lint */
9
10#include <errno.h>
11#include <stdlib.h>
12
13char *
14l64a(value)
15 long value;
16{
17 static char buf[8];
18 char *s = buf;
19 int digit;
20 int i;
21
22 if (value < 0) {
23 errno = EINVAL;
24 return(NULL);
25 }
26
27 for (i = 0; value != 0 && i < 6; i++) {
28 digit = value & 0x3f;
29
30 if (digit < 2)
31 *s = digit + '.';
32 else if (digit < 12)
33 *s = digit + '0' - 2;
34 else if (digit < 38)
35 *s = digit + 'A' - 12;
36 else
37 *s = digit + 'a' - 38;
38
39 value >>= 6;
40 s++;
41 }
42
43 *s = '\0';
44
45 return(buf);
46}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
new file mode 100644
index 0000000000..fe39ca24dc
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.3
@@ -0,0 +1,64 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: labs.3,v 1.5 2000/04/20 13:50:02 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt LABS 3
40.Os
41.Sh NAME
42.Nm labs
43.Nd return the absolute value of a long integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft long
47.Fn labs "long j"
48.Sh DESCRIPTION
49The
50.Fn labs
51function returns the absolute value of the long integer
52.Fa j .
53.Sh SEE ALSO
54.Xr abs 3 ,
55.Xr cabs 3 ,
56.Xr floor 3 ,
57.Xr math 3
58.Sh STANDARDS
59The
60.Fn labs
61function conforms to
62.St -ansiC .
63.Sh BUGS
64The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/labs.c b/src/lib/libc/stdlib/labs.c
new file mode 100644
index 0000000000..f20e2c29be
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: labs.c,v 1.2 1996/08/19 08:33:34 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40long
41labs(j)
42 long j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
new file mode 100644
index 0000000000..44bd74e48a
--- /dev/null
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lcong48.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25lcong48(unsigned short p[7])
26{
27 __rand48_seed[0] = p[0];
28 __rand48_seed[1] = p[1];
29 __rand48_seed[2] = p[2];
30 __rand48_mult[0] = p[3];
31 __rand48_mult[1] = p[4];
32 __rand48_mult[2] = p[5];
33 __rand48_add = p[6];
34}
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
new file mode 100644
index 0000000000..b5301b1b21
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: ldiv.3,v 1.5 2000/04/20 13:50:02 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt LDIV 3
40.Os
41.Sh NAME
42.Nm ldiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft ldiv_t
47.Fn ldiv "long num" "long denom"
48.Sh DESCRIPTION
49The
50.Fn ldiv
51function computes the value
52.Fa num Ns No / Ns Fa denom
53and returns the quotient and remainder in a structure named
54.Li ldiv_t
55that contains two
56.Li long integer
57members named
58.Fa quot
59and
60.Fa rem .
61.Sh SEE ALSO
62.Xr div 3 ,
63.Xr math 3 ,
64.Xr qdiv 3
65.Sh STANDARDS
66The
67.Fn ldiv
68function conforms to
69.St -ansiC .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
new file mode 100644
index 0000000000..908c2bf0aa
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: ldiv.c,v 1.2 1996/08/19 08:33:35 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* ldiv_t */
42
43ldiv_t
44ldiv(num, denom)
45 long num, denom;
46{
47 ldiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c
new file mode 100644
index 0000000000..6b7524a51b
--- /dev/null
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: lrand48.c,v 1.2 1996/08/19 08:33:36 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23lrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1);
27}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
new file mode 100644
index 0000000000..8f05c38e86
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.3
@@ -0,0 +1,419 @@
1.\"
2.\" Copyright (c) 1980, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
4.\"
5.\" This code is derived from software contributed to Berkeley by
6.\" the American National Standards Committee X3, on Information
7.\" Processing Systems.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.\" $OpenBSD: malloc.3,v 1.24 2001/12/05 09:49:39 deraadt Exp $
38.\"
39.Dd August 27, 1996
40.Dt MALLOC 3
41.Os
42.Sh NAME
43.Nm malloc ,
44.Nm calloc ,
45.Nm realloc ,
46.Nm free ,
47.Nm cfree
48.Nd memory allocation and deallocation
49.Sh SYNOPSIS
50.Fd #include <stdlib.h>
51.Ft void *
52.Fn malloc "size_t size"
53.Ft void *
54.Fn calloc "size_t nmemb" "size_t size"
55.Ft void *
56.Fn realloc "void *ptr" "size_t size"
57.Ft void
58.Fn free "void *ptr"
59.Ft void
60.Fn cfree "void *ptr"
61.Ft char *
62.Va malloc_options
63.Sh DESCRIPTION
64The
65.Fn malloc
66function allocates uninitialized space for an object whose
67size is specified by
68.Fa size .
69The
70.Fn malloc
71function maintains multiple lists of free blocks according to size, allocating
72space from the appropriate list.
73.Pp
74The allocated space is
75suitably aligned (after possible pointer
76coercion) for storage of any type of object.
77If the space is of
78.Em pagesize
79or larger, the memory returned will be page-aligned.
80.Pp
81Allocation of a zero size object returns a pointer to a zero size object.
82This zero size object is access protected, so any access to it will
83generate an exception (SIGSEGV).
84Many zero-sized objects can be placed consecutively in shared
85protected pages.
86The minimum size of the protection on each object is suitably aligned and
87sized as previously stated, but the protection may extend further depending
88on where in a protected zone the object lands.
89.Pp
90The
91.Fn calloc
92function allocates space for an array of
93.Fa nmemb
94objects, each of whose size is
95.Fa size .
96The space is initialized to all bits zero.
97.Pp
98The
99.Fn free
100function causes the space pointed to by
101.Fa ptr
102to be deallocated, that is, at least made available for further allocation,
103but if possible, it will passed back to the kernel with
104.Xr sbrk 2 .
105If
106.Fa ptr
107is a null pointer, no action occurs.
108.Pp
109A
110.Fn cfree
111function is also provided for compatibility with old systems and other
112.Nm malloc
113libraries; it is simply an alias for
114.Fn free .
115.Pp
116The
117.Fn realloc
118function changes the size of the object pointed to by
119.Fa ptr
120to
121.Fa size
122bytes and returns a pointer to the (possibly moved) object.
123The contents of the object are unchanged up to the lesser
124of the new and old sizes.
125If the new size is larger, the value of the newly allocated portion
126of the object is indeterminate and uninitialized.
127If
128.Fa ptr
129is a null pointer, the
130.Fn realloc
131function behaves like the
132.Fn malloc
133function for the specified size.
134If the space cannot be allocated, the object
135pointed to by
136.Fa ptr
137is unchanged.
138If
139.Fa size
140is zero and
141.Fa ptr
142is not a null pointer, the object it points to is freed and a new zero size
143object is returned.
144.Pp
145When using
146.Fn realloc
147one must be careful to avoid the following idiom:
148.Pp
149.Bd -literal -offset indent
150if ((p = realloc(p, nsize)) == NULL)
151 return NULL;
152.Ed
153.Pp
154In most cases, this will result in a leak of memory.
155As stated earlier, a return value of
156.Dv NULL
157indicates that the old object still remains allocated.
158Better code looks like this:
159.Bd -literal -offset indent
160if ((p2 = realloc(p, nsize)) == NULL) {
161 if (p)
162 free(p);
163 p = NULL;
164 return NULL;
165}
166p = p2;
167.Ed
168.Pp
169Malloc will first look for a symbolic link called
170.Pa /etc/malloc.conf
171and next check the environment for a variable called
172.Ev MALLOC_OPTIONS
173and finally for the global variable
174.Va malloc_options
175and scan them for flags in that order.
176Flags are single letters, uppercase means on, lowercase means off.
177.Bl -tag -width indent
178.It Cm A
179.Dq Abort .
180.Fn malloc
181will coredump the process, rather than tolerate failure.
182This is a very handy debugging aid, since the core file will represent the
183time of failure, rather than when the null pointer was accessed.
184.Pp
185.It Cm D
186.Dq Dump .
187.Fn malloc
188will dump statistics in a file called
189.Pa malloc.out
190at exit.
191This option requires the library to have been compiled with -DMALLOC_STATS in
192order to have any effect.
193.Pp
194.It Cm J
195.Dq Junk .
196Fill some junk into the area allocated.
197Currently junk is bytes of 0xd0; this is pronounced
198.Dq Duh .
199\&:-)
200.Pp
201.It Cm H
202.Dq Hint .
203Pass a hint to the kernel about pages we don't use.
204If the machine is paging a lot this may help a bit.
205.Pp
206.It Cm N
207Do not output warning messages when encountering possible corruption
208or bad pointers.
209.Pp
210.It Cm R
211.Dq realloc .
212Always reallocate when
213.Fn realloc
214is called, even if the initial allocation was big enough.
215This can substantially aid in compacting memory.
216.\".Pp
217.\".It Cm U
218.\".Dq utrace .
219.\"Generate entries for
220.\".Xr ktrace 1
221.\"for all operations.
222.\"Consult the source for this one.
223.Pp
224.It Cm X
225.Dq xmalloc .
226rather than return failure,
227.Xr abort 3
228the program with a diagnostic message on stderr.
229It is the intention that this option be set at compile time by
230including in the source:
231.Bd -literal -offset indent
232extern char *malloc_options;
233malloc_options = "X";
234.Ed
235.Pp
236.It Cm Z
237.Dq Zero .
238Fill some junk into the area allocated (see
239.Cm J ) ,
240except for the exact length the user asked for, which is zeroed.
241.Pp
242.It Cm <
243.Dq Half the cache size .
244Reduce the size of the cache by a factor of two.
245.Pp
246.It Cm >
247.Dq Double the cache size .
248Double the size of the cache by a factor of two.
249.El
250.Pp
251So to set a systemwide reduction of cache size and coredumps on problems
252one would:
253.Li ln -s 'A<' /etc/malloc.conf
254.Pp
255The
256.Cm J
257and
258.Cm Z
259is mostly for testing and debugging.
260If a program changes behavior if either of these options are used,
261it is buggy.
262.Pp
263The default cache size is 16 pages.
264.Sh ENVIRONMENT
265See above.
266.Sh RETURN VALUES
267The
268.Fn malloc
269and
270.Fn calloc
271functions return a pointer to the allocated space if successful; otherwise,
272a null pointer is returned and
273.Va errno
274is set to
275.Er ENOMEM .
276.Pp
277The
278.Fn free
279and
280.Fn cfree
281functions return no value.
282.Pp
283The
284.Fn realloc
285function returns a pointer to the (possibly moved) allocated space
286if successful; otherwise, a null pointer is returned and
287.Va errno
288is set to
289.Er ENOMEM .
290.Sh DIAGNOSTICS
291If
292.Fn malloc ,
293.Fn calloc ,
294.Fn realloc ,
295or
296.Fn free
297detect an error or warning condition,
298a message will be printed to file descriptor
2992 (not using stdio).
300Errors will always result in the process being
301.Xr abort 3 'ed.
302If the
303.Cm A
304option has been specified, warnings will also
305.Xr abort 3
306the process.
307.Pp
308Here is a brief description of the error messages and what they mean:
309.Bl -tag -width Fl
310.It Dq (ES): mumble mumble mumble
311.Fn malloc
312has been compiled with
313.Dv \&-DEXTRA_SANITY
314and something looks fishy in there.
315Consult sources and/or wizards.
316.It Dq allocation failed
317If the
318.Cm A
319option is specified it is an error for
320.Fn malloc ,
321.Fn calloc ,
322or
323.Fn realloc
324to return
325.Dv NULL .
326.It Dq mmap(2) failed, check limits.
327This is a rather weird condition that is most likely to indicate a
328seriously overloaded system or a
329.Xr ulimit 1
330restriction.
331.It Dq freelist is destroyed.
332.Fn malloc Ns 's
333internal freelist has been stomped on.
334.El
335.Pp
336Here is a brief description of the warning messages and what they mean:
337.Bl -tag -width Fl
338.It Dq chunk/page is already free.
339A pointer to a free chunk is attempted freed again.
340.It Dq junk pointer, too high to make sense.
341The pointer doesn't make sense.
342It's above the area of memory that
343.Fn malloc
344knows something about.
345This could be a pointer from some
346.Xr mmap 2 'ed
347memory.
348.It Dq junk pointer, too low to make sense.
349The pointer doesn't make sense.
350It's below the area of memory that
351.Fn malloc
352knows something about.
353This pointer probably came from your data or bss segments.
354.It Dq malloc() has never been called.
355Nothing has ever been allocated, yet something is being freed or
356realloc'ed.
357.It Dq modified (chunk-/page-) pointer.
358The pointer passed to free or realloc has been modified.
359.It Dq pointer to wrong page.
360The pointer that
361.Fn malloc
362is trying to free is not pointing to
363a sensible page.
364.It Dq recursive call.
365An attempt was made to call recursively into these functions, i.e., from a
366signal handler.
367This behavior is not supported.
368In particular, signal handlers should
369.Em not
370use any of the
371.Fn malloc
372functions nor utilize any other functions which may call
373.Fn malloc
374(e.g.,
375.Xr stdio 3
376routines).
377.It Dq unknown char in MALLOC_OPTIONS
378We found something we didn't understand.
379.El
380.Sh FILES
381.Bl -tag -width "/etc/malloc.conf"
382.It Pa /etc/malloc.conf
383symbolic link to filename containing option flags
384.El
385.Sh SEE ALSO
386.Xr brk 2 ,
387.Xr alloca 3 ,
388.Xr getpagesize 3 ,
389.Xr memory 3
390.Pa /usr/share/doc/papers/malloc.ascii.gz
391.Sh STANDARDS
392The
393.Fn malloc
394function conforms to
395.St -ansiC .
396.Sh HISTORY
397The present implementation of
398.Fn malloc
399started out as a filesystem on a drum
400attached to a 20-bit binary challenged computer built with discrete germanium
401transistors, and it has since graduated to handle primary storage rather than
402secondary.
403.Pp
404The main difference from other
405.Fn malloc
406implementations are believed to be that
407the free pages are not accessed until allocated.
408Most
409.Fn malloc
410implementations will store a data structure containing a,
411possibly double-, linked list in the free chunks of memory, used to tie
412all the free memory together.
413That is a quite suboptimal thing to do.
414Every time the free-list is traversed, all the otherwise unused, and very
415likely paged out, pages get faulted into primary memory, just to see what
416lies after them in the list.
417.Pp
418On systems which are paging, this can make a factor five in difference on the
419page-faults of a process.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000000..4e90ce402e
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1305 @@
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 */
9
10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.48 2002/05/27 03:13:23 deraadt Exp $";
12#endif /* LIBC_SCCS and not lint */
13
14/*
15 * Defining MALLOC_EXTRA_SANITY will enable extra checks which are
16 * related to internal conditions and consistency in malloc.c. This has
17 * a noticeable runtime performance hit, and generally will not do you
18 * any good unless you fiddle with the internals of malloc or want
19 * to catch random pointer corruption as early as possible.
20 */
21#ifndef MALLOC_EXTRA_SANITY
22#undef MALLOC_EXTRA_SANITY
23#endif
24
25/*
26 * Defining MALLOC_STATS will enable you to call malloc_dump() and set
27 * the [dD] options in the MALLOC_OPTIONS environment variable.
28 * It has no run-time performance hit, but does pull in stdio...
29 */
30#ifndef MALLOC_STATS
31#undef MALLOC_STATS
32#endif
33
34/*
35 * What to use for Junk. This is the byte value we use to fill with
36 * when the 'J' option is enabled.
37 */
38#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
39
40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/mman.h>
43#include <sys/uio.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <unistd.h>
48#include <fcntl.h>
49#include <errno.h>
50
51/*
52 * The basic parameters you can tweak.
53 *
54 * malloc_pageshift pagesize = 1 << malloc_pageshift
55 * It's probably best if this is the native
56 * page size, but it shouldn't have to be.
57 *
58 * malloc_minsize minimum size of an allocation in bytes.
59 * If this is too small it's too much work
60 * to manage them. This is also the smallest
61 * unit of alignment used for the storage
62 * returned by malloc/realloc.
63 *
64 */
65
66#if defined(__OpenBSD__) && defined(__sparc__)
67# define malloc_pageshift 13U
68#endif /* __OpenBSD__ */
69
70#ifdef _THREAD_SAFE
71# include "thread_private.h"
72# if 0
73 /* kernel threads */
74# include <pthread.h>
75 static pthread_mutex_t malloc_lock;
76# define THREAD_LOCK() pthread_mutex_lock(&malloc_lock)
77# define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock)
78# define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0);
79# else
80 /* user threads */
81# include "spinlock.h"
82 static spinlock_t malloc_lock = _SPINLOCK_INITIALIZER;
83# define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&malloc_lock)
84# define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&malloc_lock)
85# define THREAD_LOCK_INIT()
86 /*
87 * Malloc can't use the wrapped write() if it fails very early, so
88 * we use the unwrapped syscall _thread_sys_write()
89 */
90# define write _thread_sys_write
91 ssize_t write(int, const void *, size_t);
92# undef malloc
93# undef realloc
94# undef free
95# endif
96#else
97 /* no threads */
98# define THREAD_LOCK()
99# define THREAD_UNLOCK()
100# define THREAD_LOCK_INIT()
101#endif
102
103/*
104 * No user serviceable parts behind this point.
105 *
106 * This structure describes a page worth of chunks.
107 */
108
109struct pginfo {
110 struct pginfo *next; /* next on the free list */
111 void *page; /* Pointer to the page */
112 u_short size; /* size of this page's chunks */
113 u_short shift; /* How far to shift for this size chunks */
114 u_short free; /* How many free chunks */
115 u_short total; /* How many chunk */
116 u_long bits[1]; /* Which chunks are free */
117};
118
119/*
120 * This structure describes a number of free pages.
121 */
122
123struct pgfree {
124 struct pgfree *next; /* next run of free pages */
125 struct pgfree *prev; /* prev run of free pages */
126 void *page; /* pointer to free pages */
127 void *end; /* pointer to end of free pages */
128 u_long size; /* number of bytes free */
129};
130
131/*
132 * How many bits per u_long in the bitmap.
133 * Change only if not 8 bits/byte
134 */
135#define MALLOC_BITS (8*sizeof(u_long))
136
137/*
138 * Magic values to put in the page_directory
139 */
140#define MALLOC_NOT_MINE ((struct pginfo*) 0)
141#define MALLOC_FREE ((struct pginfo*) 1)
142#define MALLOC_FIRST ((struct pginfo*) 2)
143#define MALLOC_FOLLOW ((struct pginfo*) 3)
144#define MALLOC_MAGIC ((struct pginfo*) 4)
145
146#ifndef malloc_pageshift
147#define malloc_pageshift (PGSHIFT)
148#endif
149
150#ifndef malloc_minsize
151#define malloc_minsize 16U
152#endif
153
154#ifndef malloc_pageshift
155#error "malloc_pageshift undefined"
156#endif
157
158#if !defined(malloc_pagesize)
159#define malloc_pagesize (1UL<<malloc_pageshift)
160#endif
161
162#if ((1UL<<malloc_pageshift) != malloc_pagesize)
163#error "(1UL<<malloc_pageshift) != malloc_pagesize"
164#endif
165
166#ifndef malloc_maxsize
167#define malloc_maxsize ((malloc_pagesize)>>1)
168#endif
169
170/* A mask for the offset inside a page. */
171#define malloc_pagemask ((malloc_pagesize)-1)
172
173#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
174#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
175
176/* fd of /dev/zero */
177#ifdef USE_DEV_ZERO
178static int fdzero;
179#define MMAP_FD fdzero
180#define INIT_MMAP() \
181 { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
182 wrterror("open of /dev/zero"); }
183#else
184#define MMAP_FD (-1)
185#define INIT_MMAP()
186#endif
187
188/* Set when initialization has been done */
189static unsigned int malloc_started;
190
191/* Number of free pages we cache */
192static unsigned int malloc_cache = 16;
193
194/* The offset from pagenumber to index into the page directory */
195static u_long malloc_origo;
196
197/* The last index in the page directory we care about */
198static u_long last_index;
199
200/* Pointer to page directory. Allocated "as if with" malloc */
201static struct pginfo **page_dir;
202
203/* How many slots in the page directory */
204static size_t malloc_ninfo;
205
206/* Free pages line up here */
207static struct pgfree free_list;
208
209/* Abort(), user doesn't handle problems. */
210static int malloc_abort;
211
212/* Are we trying to die ? */
213static int suicide;
214
215#ifdef MALLOC_STATS
216/* dump statistics */
217static int malloc_stats;
218#endif
219
220/* avoid outputting warnings? */
221static int malloc_silent;
222
223/* always realloc ? */
224static int malloc_realloc;
225
226#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
227/* pass the kernel a hint on free pages ? */
228static int malloc_hint;
229#endif
230
231/* xmalloc behaviour ? */
232static int malloc_xmalloc;
233
234/* zero fill ? */
235static int malloc_zero;
236
237/* junk fill ? */
238static int malloc_junk;
239
240#ifdef __FreeBSD__
241/* utrace ? */
242static int malloc_utrace;
243
244struct ut { void *p; size_t s; void *r; };
245
246void utrace(struct ut *, int);
247
248#define UTRACE(a, b, c) \
249 if (malloc_utrace) \
250 {struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
251#else /* !__FreeBSD__ */
252#define UTRACE(a,b,c)
253#endif
254
255/* my last break. */
256static void *malloc_brk;
257
258/* one location cache for free-list holders */
259static struct pgfree *px;
260
261/* compile-time options */
262char *malloc_options;
263
264/* Name of the current public function */
265static char *malloc_func;
266
267/* Macro for mmap */
268#define MMAP(size) \
269 mmap((void *)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
270 MMAP_FD, (off_t)0);
271
272/*
273 * Necessary function declarations
274 */
275static int extend_pgdir(u_long index);
276static void *imalloc(size_t size);
277static void ifree(void *ptr);
278static void *irealloc(void *ptr, size_t size);
279static void *malloc_bytes(size_t size);
280
281#ifdef MALLOC_STATS
282void
283malloc_dump(fd)
284 FILE *fd;
285{
286 struct pginfo **pd;
287 struct pgfree *pf;
288 int j;
289
290 pd = page_dir;
291
292 /* print out all the pages */
293 for(j=0;j<=last_index;j++) {
294 fprintf(fd, "%08lx %5d ", (j+malloc_origo) << malloc_pageshift, j);
295 if (pd[j] == MALLOC_NOT_MINE) {
296 for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
297 ;
298 j--;
299 fprintf(fd, ".. %5d not mine\n", j);
300 } else if (pd[j] == MALLOC_FREE) {
301 for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
302 ;
303 j--;
304 fprintf(fd, ".. %5d free\n", j);
305 } else if (pd[j] == MALLOC_FIRST) {
306 for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
307 ;
308 j--;
309 fprintf(fd, ".. %5d in use\n", j);
310 } else if (pd[j] < MALLOC_MAGIC) {
311 fprintf(fd, "(%p)\n", pd[j]);
312 } else {
313 fprintf(fd, "%p %d (of %d) x %d @ %p --> %p\n",
314 pd[j], pd[j]->free, pd[j]->total,
315 pd[j]->size, pd[j]->page, pd[j]->next);
316 }
317 }
318
319 for(pf=free_list.next; pf; pf=pf->next) {
320 fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n",
321 pf, pf->page, pf->end, pf->size, pf->prev, pf->next);
322 if (pf == pf->next) {
323 fprintf(fd, "Free_list loops.\n");
324 break;
325 }
326 }
327
328 /* print out various info */
329 fprintf(fd, "Minsize\t%d\n", malloc_minsize);
330 fprintf(fd, "Maxsize\t%d\n", malloc_maxsize);
331 fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize);
332 fprintf(fd, "Pageshift\t%d\n", malloc_pageshift);
333 fprintf(fd, "FirstPage\t%ld\n", malloc_origo);
334 fprintf(fd, "LastPage\t%ld %lx\n", last_index+malloc_pageshift,
335 (last_index + malloc_pageshift) << malloc_pageshift);
336 fprintf(fd, "Break\t%ld\n", (u_long)sbrk(0) >> malloc_pageshift);
337}
338#endif /* MALLOC_STATS */
339
340extern char *__progname;
341
342static void
343wrterror(p)
344 char *p;
345{
346 char *q = " error: ";
347 struct iovec iov[4];
348
349 iov[0].iov_base = __progname;
350 iov[0].iov_len = strlen(__progname);
351 iov[1].iov_base = malloc_func;
352 iov[1].iov_len = strlen(malloc_func);
353 iov[2].iov_base = q;
354 iov[2].iov_len = strlen(q);
355 iov[3].iov_base = p;
356 iov[3].iov_len = strlen(p);
357 writev(STDERR_FILENO, iov, 4);
358
359 suicide = 1;
360#ifdef MALLOC_STATS
361 if (malloc_stats)
362 malloc_dump(stderr);
363#endif /* MALLOC_STATS */
364 abort();
365}
366
367static void
368wrtwarning(p)
369 char *p;
370{
371 char *q = " warning: ";
372 struct iovec iov[4];
373
374 if (malloc_abort)
375 wrterror(p);
376 else if (malloc_silent)
377 return;
378
379 iov[0].iov_base = __progname;
380 iov[0].iov_len = strlen(__progname);
381 iov[1].iov_base = malloc_func;
382 iov[1].iov_len = strlen(malloc_func);
383 iov[2].iov_base = q;
384 iov[2].iov_len = strlen(q);
385 iov[3].iov_base = p;
386 iov[3].iov_len = strlen(p);
387 writev(STDERR_FILENO, iov, 4);
388}
389
390#ifdef MALLOC_STATS
391static void
392malloc_exit()
393{
394 FILE *fd = fopen("malloc.out", "a");
395 char *q = "malloc() warning: Couldn't dump stats.\n";
396 if (fd) {
397 malloc_dump(fd);
398 fclose(fd);
399 } else
400 write(2, q, strlen(q));
401}
402#endif /* MALLOC_STATS */
403
404
405/*
406 * Allocate a number of pages from the OS
407 */
408static void *
409map_pages(pages)
410 int pages;
411{
412 caddr_t result, tail;
413
414 result = (caddr_t)pageround((u_long)sbrk(0));
415 tail = result + (pages << malloc_pageshift);
416
417 if (brk(tail)) {
418#ifdef MALLOC_EXTRA_SANITY
419 wrterror("(ES): map_pages fails\n");
420#endif /* MALLOC_EXTRA_SANITY */
421 return 0;
422 }
423
424 last_index = ptr2index(tail) - 1;
425 malloc_brk = tail;
426
427 if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
428 return 0;
429
430 return result;
431}
432
433/*
434 * Extend page directory
435 */
436static int
437extend_pgdir(index)
438 u_long index;
439{
440 struct pginfo **new, **old;
441 size_t i, oldlen;
442
443 /* Make it this many pages */
444 i = index * sizeof *page_dir;
445 i /= malloc_pagesize;
446 i += 2;
447
448 /* remember the old mapping size */
449 oldlen = malloc_ninfo * sizeof *page_dir;
450
451 /*
452 * NOTE: we allocate new pages and copy the directory rather than tempt
453 * fate by trying to "grow" the region.. There is nothing to prevent
454 * us from accidently re-mapping space that's been allocated by our caller
455 * via dlopen() or other mmap().
456 *
457 * The copy problem is not too bad, as there is 4K of page index per
458 * 4MB of malloc arena.
459 *
460 * We can totally avoid the copy if we open a file descriptor to associate
461 * the anon mappings with. Then, when we remap the pages at the new
462 * address, the old pages will be "magically" remapped.. But this means
463 * keeping open a "secret" file descriptor.....
464 */
465
466 /* Get new pages */
467 new = (struct pginfo**) MMAP(i * malloc_pagesize);
468 if (new == MAP_FAILED)
469 return 0;
470
471 /* Copy the old stuff */
472 memcpy(new, page_dir,
473 malloc_ninfo * sizeof *page_dir);
474
475 /* register the new size */
476 malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
477
478 /* swap the pointers */
479 old = page_dir;
480 page_dir = new;
481
482 /* Now free the old stuff */
483 munmap(old, oldlen);
484 return 1;
485}
486
487/*
488 * Initialize the world
489 */
490static void
491malloc_init ()
492{
493 char *p, b[64];
494 int i, j;
495 int save_errno = errno;
496
497 THREAD_LOCK_INIT();
498
499 INIT_MMAP();
500
501#ifdef MALLOC_EXTRA_SANITY
502 malloc_junk = 1;
503#endif /* MALLOC_EXTRA_SANITY */
504
505 for (i = 0; i < 3; i++) {
506 if (i == 0) {
507 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
508 if (j <= 0)
509 continue;
510 b[j] = '\0';
511 p = b;
512 } else if (i == 1) {
513 if (issetugid() == 0)
514 p = getenv("MALLOC_OPTIONS");
515 else
516 continue;
517 } else if (i == 2) {
518 p = malloc_options;
519 }
520 for (; p && *p; p++) {
521 switch (*p) {
522 case '>': malloc_cache <<= 1; break;
523 case '<': malloc_cache >>= 1; break;
524 case 'a': malloc_abort = 0; break;
525 case 'A': malloc_abort = 1; break;
526#ifdef MALLOC_STATS
527 case 'd': malloc_stats = 0; break;
528 case 'D': malloc_stats = 1; break;
529#endif /* MALLOC_STATS */
530#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
531 case 'h': malloc_hint = 0; break;
532 case 'H': malloc_hint = 1; break;
533#endif /* __FreeBSD__ */
534 case 'r': malloc_realloc = 0; break;
535 case 'R': malloc_realloc = 1; break;
536 case 'j': malloc_junk = 0; break;
537 case 'J': malloc_junk = 1; break;
538 case 'n': malloc_silent = 0; break;
539 case 'N': malloc_silent = 1; break;
540#ifdef __FreeBSD__
541 case 'u': malloc_utrace = 0; break;
542 case 'U': malloc_utrace = 1; break;
543#endif /* __FreeBSD__ */
544 case 'x': malloc_xmalloc = 0; break;
545 case 'X': malloc_xmalloc = 1; break;
546 case 'z': malloc_zero = 0; break;
547 case 'Z': malloc_zero = 1; break;
548 default:
549 j = malloc_abort;
550 malloc_abort = 0;
551 wrtwarning("unknown char in MALLOC_OPTIONS\n");
552 malloc_abort = j;
553 break;
554 }
555 }
556 }
557
558 UTRACE(0, 0, 0);
559
560 /*
561 * We want junk in the entire allocation, and zero only in the part
562 * the user asked for.
563 */
564 if (malloc_zero)
565 malloc_junk=1;
566
567#ifdef MALLOC_STATS
568 if (malloc_stats)
569 atexit(malloc_exit);
570#endif /* MALLOC_STATS */
571
572 /* Allocate one page for the page directory */
573 page_dir = (struct pginfo **) MMAP(malloc_pagesize);
574
575 if (page_dir == MAP_FAILED)
576 wrterror("mmap(2) failed, check limits.\n");
577
578 /*
579 * We need a maximum of malloc_pageshift buckets, steal these from the
580 * front of the page_directory;
581 */
582 malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
583 malloc_origo -= malloc_pageshift;
584
585 malloc_ninfo = malloc_pagesize / sizeof *page_dir;
586
587 /* Been here, done that */
588 malloc_started++;
589
590 /* Recalculate the cache size in bytes, and make sure it's nonzero */
591
592 if (!malloc_cache)
593 malloc_cache++;
594
595 malloc_cache <<= malloc_pageshift;
596
597 /*
598 * This is a nice hack from Kaleb Keithly (kaleb@x.org).
599 * We can sbrk(2) further back when we keep this on a low address.
600 */
601 px = (struct pgfree *) imalloc (sizeof *px);
602 errno = save_errno;
603}
604
605/*
606 * Allocate a number of complete pages
607 */
608static void *
609malloc_pages(size)
610 size_t size;
611{
612 void *p, *delay_free = 0;
613 int i;
614 struct pgfree *pf;
615 u_long index;
616
617 size = pageround(size);
618
619 p = 0;
620 /* Look for free pages before asking for more */
621 for(pf = free_list.next; pf; pf = pf->next) {
622
623#ifdef MALLOC_EXTRA_SANITY
624 if (pf->size & malloc_pagemask)
625 wrterror("(ES): junk length entry on free_list\n");
626 if (!pf->size)
627 wrterror("(ES): zero length entry on free_list\n");
628 if (pf->page == pf->end)
629 wrterror("(ES): zero entry on free_list\n");
630 if (pf->page > pf->end)
631 wrterror("(ES): sick entry on free_list\n");
632 if ((void*)pf->page >= (void*)sbrk(0))
633 wrterror("(ES): entry on free_list past brk\n");
634 if (page_dir[ptr2index(pf->page)] != MALLOC_FREE)
635 wrterror("(ES): non-free first page on free-list\n");
636 if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
637 wrterror("(ES): non-free last page on free-list\n");
638#endif /* MALLOC_EXTRA_SANITY */
639
640 if (pf->size < size)
641 continue;
642
643 if (pf->size == size) {
644 p = pf->page;
645 if (pf->next)
646 pf->next->prev = pf->prev;
647 pf->prev->next = pf->next;
648 delay_free = pf;
649 break;
650 }
651
652 p = pf->page;
653 pf->page = (char *)pf->page + size;
654 pf->size -= size;
655 break;
656 }
657
658#ifdef MALLOC_EXTRA_SANITY
659 if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
660 wrterror("(ES): allocated non-free page on free-list\n");
661#endif /* MALLOC_EXTRA_SANITY */
662
663 size >>= malloc_pageshift;
664
665 /* Map new pages */
666 if (!p)
667 p = map_pages(size);
668
669 if (p) {
670
671 index = ptr2index(p);
672 page_dir[index] = MALLOC_FIRST;
673 for (i=1;i<size;i++)
674 page_dir[index+i] = MALLOC_FOLLOW;
675
676 if (malloc_junk)
677 memset(p, SOME_JUNK, size << malloc_pageshift);
678 }
679
680 if (delay_free) {
681 if (!px)
682 px = delay_free;
683 else
684 ifree(delay_free);
685 }
686
687 return p;
688}
689
690/*
691 * Allocate a page of fragments
692 */
693
694static __inline__ int
695malloc_make_chunks(bits)
696 int bits;
697{
698 struct pginfo *bp;
699 void *pp;
700 int i, k, l;
701
702 /* Allocate a new bucket */
703 pp = malloc_pages((size_t)malloc_pagesize);
704 if (!pp)
705 return 0;
706
707 /* Find length of admin structure */
708 l = sizeof *bp - sizeof(u_long);
709 l += sizeof(u_long) *
710 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
711
712 /* Don't waste more than two chunks on this */
713 /*
714 * If we are to allocate a memory protected page for the malloc(0)
715 * case (when bits=0), it must be from a different page than the
716 * pginfo page.
717 * --> Treat it like the big chunk alloc, get a second data page.
718 */
719 if (bits != 0 && (1UL<<(bits)) <= l+l) {
720 bp = (struct pginfo *)pp;
721 } else {
722 bp = (struct pginfo *)imalloc(l);
723 if (!bp) {
724 ifree(pp);
725 return 0;
726 }
727 }
728
729 /* memory protect the page allocated in the malloc(0) case */
730 if (bits == 0) {
731
732 bp->size = 0;
733 bp->shift = 1;
734 i = malloc_minsize-1;
735 while (i >>= 1)
736 bp->shift++;
737 bp->total = bp->free = malloc_pagesize >> bp->shift;
738 bp->page = pp;
739
740 k = mprotect(pp, malloc_pagesize, PROT_NONE);
741 if (k < 0) {
742 ifree(pp);
743 ifree(bp);
744 return 0;
745 }
746 } else {
747 bp->size = (1UL<<bits);
748 bp->shift = bits;
749 bp->total = bp->free = malloc_pagesize >> bits;
750 bp->page = pp;
751 }
752
753 /* set all valid bits in the bitmap */
754 k = bp->total;
755 i = 0;
756
757 /* Do a bunch at a time */
758 for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
759 bp->bits[i / MALLOC_BITS] = ~0UL;
760
761 for(; i < k; i++)
762 bp->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
763
764 if (bp == bp->page) {
765 /* Mark the ones we stole for ourselves */
766 for(i=0;l > 0;i++) {
767 bp->bits[i/MALLOC_BITS] &= ~(1UL<<(i%MALLOC_BITS));
768 bp->free--;
769 bp->total--;
770 l -= (1 << bits);
771 }
772 }
773
774 /* MALLOC_LOCK */
775
776 page_dir[ptr2index(pp)] = bp;
777
778 bp->next = page_dir[bits];
779 page_dir[bits] = bp;
780
781 /* MALLOC_UNLOCK */
782
783 return 1;
784}
785
786/*
787 * Allocate a fragment
788 */
789static void *
790malloc_bytes(size)
791 size_t size;
792{
793 int i,j;
794 u_long u;
795 struct pginfo *bp;
796 int k;
797 u_long *lp;
798
799 /* Don't bother with anything less than this */
800 /* unless we have a malloc(0) requests */
801 if (size != 0 && size < malloc_minsize)
802 size = malloc_minsize;
803
804 /* Find the right bucket */
805 if (size == 0)
806 j=0;
807 else {
808 j = 1;
809 i = size-1;
810 while (i >>= 1)
811 j++;
812 }
813
814 /* If it's empty, make a page more of that size chunks */
815 if (!page_dir[j] && !malloc_make_chunks(j))
816 return 0;
817
818 bp = page_dir[j];
819
820 /* Find first word of bitmap which isn't empty */
821 for (lp = bp->bits; !*lp; lp++)
822 ;
823
824 /* Find that bit, and tweak it */
825 u = 1;
826 k = 0;
827 while (!(*lp & u)) {
828 u += u;
829 k++;
830 }
831 *lp ^= u;
832
833 /* If there are no more free, remove from free-list */
834 if (!--bp->free) {
835 page_dir[j] = bp->next;
836 bp->next = 0;
837 }
838
839 /* Adjust to the real offset of that chunk */
840 k += (lp-bp->bits)*MALLOC_BITS;
841 k <<= bp->shift;
842
843 if (malloc_junk && bp->size != 0)
844 memset((char *)bp->page + k, SOME_JUNK, bp->size);
845
846 return (u_char *)bp->page + k;
847}
848
849/*
850 * Allocate a piece of memory
851 */
852static void *
853imalloc(size)
854 size_t size;
855{
856 void *result;
857
858 if (!malloc_started)
859 malloc_init();
860
861 if (suicide)
862 abort();
863
864 if ((size + malloc_pagesize) < size) /* Check for overflow */
865 result = 0;
866 else if (size <= malloc_maxsize)
867 result = malloc_bytes(size);
868 else
869 result = malloc_pages(size);
870
871 if (malloc_abort && !result)
872 wrterror("allocation failed.\n");
873
874 if (malloc_zero && result)
875 memset(result, 0, size);
876
877 return result;
878}
879
880/*
881 * Change the size of an allocation.
882 */
883static void *
884irealloc(ptr, size)
885 void *ptr;
886 size_t size;
887{
888 void *p;
889 u_long osize, index;
890 struct pginfo **mp;
891 int i;
892
893 if (suicide)
894 abort();
895
896 if (!malloc_started) {
897 wrtwarning("malloc() has never been called.\n");
898 return 0;
899 }
900
901 index = ptr2index(ptr);
902
903 if (index < malloc_pageshift) {
904 wrtwarning("junk pointer, too low to make sense.\n");
905 return 0;
906 }
907
908 if (index > last_index) {
909 wrtwarning("junk pointer, too high to make sense.\n");
910 return 0;
911 }
912
913 mp = &page_dir[index];
914
915 if (*mp == MALLOC_FIRST) { /* Page allocation */
916
917 /* Check the pointer */
918 if ((u_long)ptr & malloc_pagemask) {
919 wrtwarning("modified (page-) pointer.\n");
920 return 0;
921 }
922
923 /* Find the size in bytes */
924 for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
925 osize += malloc_pagesize;
926
927 if (!malloc_realloc && /* unless we have to, */
928 size <= osize && /* .. or are too small, */
929 size > (osize - malloc_pagesize)) { /* .. or can free a page, */
930 return ptr; /* don't do anything. */
931 }
932
933 } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
934
935 /* Check the pointer for sane values */
936 if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) {
937 wrtwarning("modified (chunk-) pointer.\n");
938 return 0;
939 }
940
941 /* Find the chunk index in the page */
942 i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
943
944 /* Verify that it isn't a free chunk already */
945 if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
946 wrtwarning("chunk is already free.\n");
947 return 0;
948 }
949
950 osize = (*mp)->size;
951
952 if (!malloc_realloc && /* Unless we have to, */
953 size < osize && /* ..or are too small, */
954 (size > osize/2 || /* ..or could use a smaller size, */
955 osize == malloc_minsize)) { /* ..(if there is one) */
956 return ptr; /* ..Don't do anything */
957 }
958
959 } else {
960 wrtwarning("pointer to wrong page.\n");
961 return 0;
962 }
963
964 p = imalloc(size);
965
966 if (p) {
967 /* copy the lesser of the two sizes, and free the old one */
968 /* Don't move from/to 0 sized region !!! */
969 if (osize != 0 && size != 0) {
970 if (osize < size)
971 memcpy(p, ptr, osize);
972 else
973 memcpy(p, ptr, size);
974 }
975 ifree(ptr);
976 }
977 return p;
978}
979
980/*
981 * Free a sequence of pages
982 */
983
984static __inline__ void
985free_pages(ptr, index, info)
986 void *ptr;
987 int index;
988 struct pginfo *info;
989{
990 int i;
991 struct pgfree *pf, *pt=0;
992 u_long l;
993 void *tail;
994
995 if (info == MALLOC_FREE) {
996 wrtwarning("page is already free.\n");
997 return;
998 }
999
1000 if (info != MALLOC_FIRST) {
1001 wrtwarning("pointer to wrong page.\n");
1002 return;
1003 }
1004
1005 if ((u_long)ptr & malloc_pagemask) {
1006 wrtwarning("modified (page-) pointer.\n");
1007 return;
1008 }
1009
1010 /* Count how many pages and mark them free at the same time */
1011 page_dir[index] = MALLOC_FREE;
1012 for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
1013 page_dir[index + i] = MALLOC_FREE;
1014
1015 l = i << malloc_pageshift;
1016
1017 if (malloc_junk)
1018 memset(ptr, SOME_JUNK, l);
1019
1020#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
1021 if (malloc_hint)
1022 madvise(ptr, l, MADV_FREE);
1023#endif
1024
1025 tail = (char *)ptr+l;
1026
1027 /* add to free-list */
1028 if (!px)
1029 px = imalloc(sizeof *px); /* This cannot fail... */
1030 px->page = ptr;
1031 px->end = tail;
1032 px->size = l;
1033 if (!free_list.next) {
1034
1035 /* Nothing on free list, put this at head */
1036 px->next = free_list.next;
1037 px->prev = &free_list;
1038 free_list.next = px;
1039 pf = px;
1040 px = 0;
1041
1042 } else {
1043
1044 /* Find the right spot, leave pf pointing to the modified entry. */
1045 tail = (char *)ptr+l;
1046
1047 for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
1048 ; /* Race ahead here */
1049
1050 if (pf->page > tail) {
1051 /* Insert before entry */
1052 px->next = pf;
1053 px->prev = pf->prev;
1054 pf->prev = px;
1055 px->prev->next = px;
1056 pf = px;
1057 px = 0;
1058 } else if (pf->end == ptr ) {
1059 /* Append to the previous entry */
1060 pf->end = (char *)pf->end + l;
1061 pf->size += l;
1062 if (pf->next && pf->end == pf->next->page ) {
1063 /* And collapse the next too. */
1064 pt = pf->next;
1065 pf->end = pt->end;
1066 pf->size += pt->size;
1067 pf->next = pt->next;
1068 if (pf->next)
1069 pf->next->prev = pf;
1070 }
1071 } else if (pf->page == tail) {
1072 /* Prepend to entry */
1073 pf->size += l;
1074 pf->page = ptr;
1075 } else if (!pf->next) {
1076 /* Append at tail of chain */
1077 px->next = 0;
1078 px->prev = pf;
1079 pf->next = px;
1080 pf = px;
1081 px = 0;
1082 } else {
1083 wrterror("freelist is destroyed.\n");
1084 }
1085 }
1086
1087 /* Return something to OS ? */
1088 if (!pf->next && /* If we're the last one, */
1089 pf->size > malloc_cache && /* ..and the cache is full, */
1090 pf->end == malloc_brk && /* ..and none behind us, */
1091 malloc_brk == sbrk(0)) { /* ..and it's OK to do... */
1092
1093 /*
1094 * Keep the cache intact. Notice that the '>' above guarantees that
1095 * the pf will always have at least one page afterwards.
1096 */
1097 pf->end = (char *)pf->page + malloc_cache;
1098 pf->size = malloc_cache;
1099
1100 brk(pf->end);
1101 malloc_brk = pf->end;
1102
1103 index = ptr2index(pf->end);
1104 last_index = index - 1;
1105
1106 for(i=index;i <= last_index;)
1107 page_dir[i++] = MALLOC_NOT_MINE;
1108
1109 /* XXX: We could realloc/shrink the pagedir here I guess. */
1110 }
1111 if (pt)
1112 ifree(pt);
1113}
1114
1115/*
1116 * Free a chunk, and possibly the page it's on, if the page becomes empty.
1117 */
1118
1119/* ARGSUSED */
1120static __inline__ void
1121free_bytes(ptr, index, info)
1122 void *ptr;
1123 int index;
1124 struct pginfo *info;
1125{
1126 int i;
1127 struct pginfo **mp;
1128 void *vp;
1129
1130 /* Find the chunk number on the page */
1131 i = ((u_long)ptr & malloc_pagemask) >> info->shift;
1132
1133 if ((u_long)ptr & ((1UL<<(info->shift))-1)) {
1134 wrtwarning("modified (chunk-) pointer.\n");
1135 return;
1136 }
1137
1138 if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) {
1139 wrtwarning("chunk is already free.\n");
1140 return;
1141 }
1142
1143 if (malloc_junk && info->size != 0)
1144 memset(ptr, SOME_JUNK, info->size);
1145
1146 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
1147 info->free++;
1148
1149 if (info->size != 0)
1150 mp = page_dir + info->shift;
1151 else
1152 mp = page_dir;
1153
1154 if (info->free == 1) {
1155
1156 /* Page became non-full */
1157
1158 /* Insert in address order */
1159 while (*mp && (*mp)->next && (*mp)->next->page < info->page)
1160 mp = &(*mp)->next;
1161 info->next = *mp;
1162 *mp = info;
1163 return;
1164 }
1165
1166 if (info->free != info->total)
1167 return;
1168
1169 /* Find & remove this page in the queue */
1170 while (*mp != info) {
1171 mp = &((*mp)->next);
1172#ifdef MALLOC_EXTRA_SANITY
1173 if (!*mp)
1174 wrterror("(ES): Not on queue\n");
1175#endif /* MALLOC_EXTRA_SANITY */
1176 }
1177 *mp = info->next;
1178
1179 /* Free the page & the info structure if need be */
1180 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
1181
1182 /* If the page was mprotected, unprotect it before releasing it */
1183 if (info->size == 0) {
1184 mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
1185 /* Do we have to care if mprotect succeeds here ? */
1186 }
1187
1188 vp = info->page; /* Order is important ! */
1189 if(vp != (void*)info)
1190 ifree(info);
1191 ifree(vp);
1192}
1193
1194static void
1195ifree(ptr)
1196 void *ptr;
1197{
1198 struct pginfo *info;
1199 int index;
1200
1201 /* This is legal */
1202 if (!ptr)
1203 return;
1204
1205 if (!malloc_started) {
1206 wrtwarning("malloc() has never been called.\n");
1207 return;
1208 }
1209
1210 /* If we're already sinking, don't make matters any worse. */
1211 if (suicide)
1212 return;
1213
1214 index = ptr2index(ptr);
1215
1216 if (index < malloc_pageshift) {
1217 wrtwarning("junk pointer, too low to make sense.\n");
1218 return;
1219 }
1220
1221 if (index > last_index) {
1222 wrtwarning("junk pointer, too high to make sense.\n");
1223 return;
1224 }
1225
1226 info = page_dir[index];
1227
1228 if (info < MALLOC_MAGIC)
1229 free_pages(ptr, index, info);
1230 else
1231 free_bytes(ptr, index, info);
1232 return;
1233}
1234
1235/*
1236 * These are the public exported interface routines.
1237 */
1238
1239static int malloc_active;
1240
1241void *
1242malloc(size_t size)
1243{
1244 register void *r;
1245
1246 malloc_func = " in malloc():";
1247 THREAD_LOCK();
1248 if (malloc_active++) {
1249 wrtwarning("recursive call.\n");
1250 malloc_active--;
1251 THREAD_UNLOCK();
1252 return (0);
1253 }
1254 r = imalloc(size);
1255 UTRACE(0, size, r);
1256 malloc_active--;
1257 THREAD_UNLOCK();
1258 if (malloc_xmalloc && !r)
1259 wrterror("out of memory.\n");
1260 return (r);
1261}
1262
1263void
1264free(void *ptr)
1265{
1266 malloc_func = " in free():";
1267 THREAD_LOCK();
1268 if (malloc_active++) {
1269 wrtwarning("recursive call.\n");
1270 malloc_active--;
1271 THREAD_UNLOCK();
1272 return;
1273 }
1274 ifree(ptr);
1275 UTRACE(ptr, 0, 0);
1276 malloc_active--;
1277 THREAD_UNLOCK();
1278 return;
1279}
1280
1281void *
1282realloc(void *ptr, size_t size)
1283{
1284 register void *r;
1285
1286 malloc_func = " in realloc():";
1287 THREAD_LOCK();
1288 if (malloc_active++) {
1289 wrtwarning("recursive call.\n");
1290 malloc_active--;
1291 THREAD_UNLOCK();
1292 return (0);
1293 }
1294 if (!ptr) {
1295 r = imalloc(size);
1296 } else {
1297 r = irealloc(ptr, size);
1298 }
1299 UTRACE(ptr, size, r);
1300 malloc_active--;
1301 THREAD_UNLOCK();
1302 if (malloc_xmalloc && !r)
1303 wrterror("out of memory.\n");
1304 return (r);
1305}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000000..959a173a03
--- /dev/null
+++ b/src/lib/libc/stdlib/memory.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: memory.3,v 1.5 2000/04/20 13:50:02 aaron Exp $
33.\"
34.Dd May 2, 1991
35.Dt MEMORY 3
36.Os
37.Sh NAME
38.Nm malloc ,
39.Nm free ,
40.Nm realloc ,
41.Nm calloc ,
42.Nm alloca
43.Nd general memory allocation operations
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft void *
47.Fn malloc "size_t size"
48.Ft void
49.Fn free "void *ptr"
50.Ft void *
51.Fn realloc "void *ptr" "size_t size"
52.Ft void *
53.Fn calloc "size_t nelem" "size_t elsize"
54.Ft void *
55.Fn alloca "size_t size"
56.Sh DESCRIPTION
57These functions allocate and free memory for the calling process.
58They are described in the individual man pages.
59.Sh SEE ALSO
60.Xr alloca 3 ,
61.Xr calloc 3 ,
62.Xr free 3 ,
63.Xr malloc 3 ,
64.Xr realloc 3
65.Sh STANDARDS
66These functions, with the exception of
67.Fn alloca ,
68conform to
69.St -ansiC .
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000000..4ae6488af2
--- /dev/null
+++ b/src/lib/libc/stdlib/merge.c
@@ -0,0 +1,347 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: merge.c,v 1.5 2002/02/17 19:42:24 millert Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Hybrid exponential search/linear search merge sort with hybrid
43 * natural/pairwise first pass. Requires about .3% more comparisons
44 * for random data than LSMS with pairwise first pass alone.
45 * It works for objects as small as two bytes.
46 */
47
48#define NATURAL
49#define THRESHOLD 16 /* Best choice for natural merge cut-off. */
50
51/* #define NATURAL to get hybrid natural merge.
52 * (The default is pairwise merging.)
53 */
54
55#include <sys/types.h>
56
57#include <errno.h>
58#include <stdlib.h>
59#include <string.h>
60
61static void setup(u_char *, u_char *, size_t, size_t, int (*)());
62static void insertionsort(u_char *, size_t, size_t, int (*)());
63
64#define ISIZE sizeof(int)
65#define PSIZE sizeof(u_char *)
66#define ICOPY_LIST(src, dst, last) \
67 do \
68 *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \
69 while(src < last)
70#define ICOPY_ELT(src, dst, i) \
71 do \
72 *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \
73 while (i -= ISIZE)
74
75#define CCOPY_LIST(src, dst, last) \
76 do \
77 *dst++ = *src++; \
78 while (src < last)
79#define CCOPY_ELT(src, dst, i) \
80 do \
81 *dst++ = *src++; \
82 while (i -= 1)
83
84/*
85 * Find the next possible pointer head. (Trickery for forcing an array
86 * to do double duty as a linked list when objects do not align with word
87 * boundaries.
88 */
89/* Assumption: PSIZE is a power of 2. */
90#define EVAL(p) (u_char **) \
91 ((u_char *)0 + \
92 (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
93
94/*
95 * Arguments are as for qsort.
96 */
97int
98mergesort(base, nmemb, size, cmp)
99 void *base;
100 size_t nmemb;
101 register size_t size;
102 int (*cmp)(const void *, const void *);
103{
104 register int i, sense;
105 int big, iflag;
106 register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
107 u_char *list2, *list1, *p2, *p, *last, **p1;
108
109 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
110 errno = EINVAL;
111 return (-1);
112 }
113
114 /*
115 * XXX
116 * Stupid subtraction for the Cray.
117 */
118 iflag = 0;
119 if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
120 iflag = 1;
121
122 if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
123 return (-1);
124
125 list1 = base;
126 setup(list1, list2, nmemb, size, cmp);
127 last = list2 + nmemb * size;
128 i = big = 0;
129 while (*EVAL(list2) != last) {
130 l2 = list1;
131 p1 = EVAL(list1);
132 for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
133 p2 = *EVAL(p2);
134 f1 = l2;
135 f2 = l1 = list1 + (p2 - list2);
136 if (p2 != last)
137 p2 = *EVAL(p2);
138 l2 = list1 + (p2 - list2);
139 while (f1 < l1 && f2 < l2) {
140 if ((*cmp)(f1, f2) <= 0) {
141 q = f2;
142 b = f1, t = l1;
143 sense = -1;
144 } else {
145 q = f1;
146 b = f2, t = l2;
147 sense = 0;
148 }
149 if (!big) { /* here i = 0 */
150 while ((b += size) < t && cmp(q, b) >sense)
151 if (++i == 6) {
152 big = 1;
153 goto EXPONENTIAL;
154 }
155 } else {
156EXPONENTIAL: for (i = size; ; i <<= 1)
157 if ((p = (b + i)) >= t) {
158 if ((p = t - size) > b &&
159 (*cmp)(q, p) <= sense)
160 t = p;
161 else
162 b = p;
163 break;
164 } else if ((*cmp)(q, p) <= sense) {
165 t = p;
166 if (i == size)
167 big = 0;
168 goto FASTCASE;
169 } else
170 b = p;
171 while (t > b+size) {
172 i = (((t - b) / size) >> 1) * size;
173 if ((*cmp)(q, p = b + i) <= sense)
174 t = p;
175 else
176 b = p;
177 }
178 goto COPY;
179FASTCASE: while (i > size)
180 if ((*cmp)(q,
181 p = b + (i >>= 1)) <= sense)
182 t = p;
183 else
184 b = p;
185COPY: b = t;
186 }
187 i = size;
188 if (q == f1) {
189 if (iflag) {
190 ICOPY_LIST(f2, tp2, b);
191 ICOPY_ELT(f1, tp2, i);
192 } else {
193 CCOPY_LIST(f2, tp2, b);
194 CCOPY_ELT(f1, tp2, i);
195 }
196 } else {
197 if (iflag) {
198 ICOPY_LIST(f1, tp2, b);
199 ICOPY_ELT(f2, tp2, i);
200 } else {
201 CCOPY_LIST(f1, tp2, b);
202 CCOPY_ELT(f2, tp2, i);
203 }
204 }
205 }
206 if (f2 < l2) {
207 if (iflag)
208 ICOPY_LIST(f2, tp2, l2);
209 else
210 CCOPY_LIST(f2, tp2, l2);
211 } else if (f1 < l1) {
212 if (iflag)
213 ICOPY_LIST(f1, tp2, l1);
214 else
215 CCOPY_LIST(f1, tp2, l1);
216 }
217 *p1 = l2;
218 }
219 tp2 = list1; /* swap list1, list2 */
220 list1 = list2;
221 list2 = tp2;
222 last = list2 + nmemb*size;
223 }
224 if (base == list2) {
225 memmove(list2, list1, nmemb*size);
226 list2 = list1;
227 }
228 free(list2);
229 return (0);
230}
231
232#define swap(a, b) { \
233 s = b; \
234 i = size; \
235 do { \
236 tmp = *a; *a++ = *s; *s++ = tmp; \
237 } while (--i); \
238 a -= size; \
239 }
240#define reverse(bot, top) { \
241 s = top; \
242 do { \
243 i = size; \
244 do { \
245 tmp = *bot; *bot++ = *s; *s++ = tmp; \
246 } while (--i); \
247 s -= size2; \
248 } while(bot < s); \
249}
250
251/*
252 * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of
253 * increasing order, list2 in a corresponding linked list. Checks for runs
254 * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL
255 * is defined. Otherwise simple pairwise merging is used.)
256 */
257void
258setup(list1, list2, n, size, cmp)
259 size_t n, size;
260 int (*cmp)(const void *, const void *);
261 u_char *list1, *list2;
262{
263 int i, length, size2, tmp, sense;
264 u_char *f1, *f2, *s, *l2, *last, *p2;
265
266 size2 = size*2;
267 if (n <= 5) {
268 insertionsort(list1, n, size, cmp);
269 *EVAL(list2) = (u_char*) list2 + n*size;
270 return;
271 }
272 /*
273 * Avoid running pointers out of bounds; limit n to evens
274 * for simplicity.
275 */
276 i = 4 + (n & 1);
277 insertionsort(list1 + (n - i) * size, i, size, cmp);
278 last = list1 + size * (n - i);
279 *EVAL(list2 + (last - list1)) = list2 + n * size;
280
281#ifdef NATURAL
282 p2 = list2;
283 f1 = list1;
284 sense = (cmp(f1, f1 + size) > 0);
285 for (; f1 < last; sense = !sense) {
286 length = 2;
287 /* Find pairs with same sense. */
288 for (f2 = f1 + size2; f2 < last; f2 += size2) {
289 if ((cmp(f2, f2+ size) > 0) != sense)
290 break;
291 length += 2;
292 }
293 if (length < THRESHOLD) { /* Pairwise merge */
294 do {
295 p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
296 if (sense > 0)
297 swap (f1, f1 + size);
298 } while ((f1 += size2) < f2);
299 } else { /* Natural merge */
300 l2 = f2;
301 for (f2 = f1 + size2; f2 < l2; f2 += size2) {
302 if ((cmp(f2-size, f2) > 0) != sense) {
303 p2 = *EVAL(p2) = f2 - list1 + list2;
304 if (sense > 0)
305 reverse(f1, f2-size);
306 f1 = f2;
307 }
308 }
309 if (sense > 0)
310 reverse (f1, f2-size);
311 f1 = f2;
312 if (f2 < last || cmp(f2 - size, f2) > 0)
313 p2 = *EVAL(p2) = f2 - list1 + list2;
314 else
315 p2 = *EVAL(p2) = list2 + n*size;
316 }
317 }
318#else /* pairwise merge only. */
319 for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
320 p2 = *EVAL(p2) = p2 + size2;
321 if (cmp (f1, f1 + size) > 0)
322 swap(f1, f1 + size);
323 }
324#endif /* NATURAL */
325}
326
327/*
328 * This is to avoid out-of-bounds addresses in sorting the
329 * last 4 elements.
330 */
331static void
332insertionsort(a, n, size, cmp)
333 u_char *a;
334 size_t n, size;
335 int (*cmp)(const void *, const void *);
336{
337 u_char *ai, *s, *t, *u, tmp;
338 int i;
339
340 for (ai = a+size; --n >= 1; ai += size)
341 for (t = ai; t > a; t -= size) {
342 u = t - size;
343 if (cmp(u, t) <= 0)
344 break;
345 swap(u, t);
346 }
347}
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
new file mode 100644
index 0000000000..cd34260b5c
--- /dev/null
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: mrand48.c,v 1.2 1996/08/19 08:33:39 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21
22long
23mrand48(void)
24{
25 __dorand48(__rand48_seed);
26 return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1];
27}
diff --git a/src/lib/libc/stdlib/multibyte.c b/src/lib/libc/stdlib/multibyte.c
new file mode 100644
index 0000000000..6f08bbe342
--- /dev/null
+++ b/src/lib/libc/stdlib/multibyte.c
@@ -0,0 +1,124 @@
1/*
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: multibyte.c,v 1.3 2002/02/19 19:39:37 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40/*
41 * Stub multibyte character functions.
42 * This cheezy implementation is fixed to the native single-byte
43 * character set.
44 */
45
46int
47mblen(s, n)
48 const char *s;
49 size_t n;
50{
51 if (s == NULL || *s == '\0')
52 return 0;
53 if (n == 0)
54 return -1;
55 return 1;
56}
57
58/*ARGSUSED*/
59int
60mbtowc(pwc, s, n)
61 wchar_t *pwc;
62 const char *s;
63 size_t n;
64{
65 if (s == NULL)
66 return 0;
67 if (n == 0)
68 return -1;
69 if (pwc)
70 *pwc = (wchar_t) *s;
71 return (*s != '\0');
72}
73
74/*ARGSUSED*/
75int
76wctomb(char *s, wchar_t wchar)
77{
78 if (s == NULL)
79 return 0;
80
81 *s = (char) wchar;
82 return 1;
83}
84
85/*ARGSUSED*/
86size_t
87mbstowcs(pwcs, s, n)
88 wchar_t *pwcs;
89 const char *s;
90 size_t n;
91{
92 int count = 0;
93
94 if (n != 0) {
95 do {
96 if ((*pwcs++ = (wchar_t) *s++) == 0)
97 break;
98 count++;
99 } while (--n != 0);
100 }
101
102 return count;
103}
104
105/*ARGSUSED*/
106size_t
107wcstombs(s, pwcs, n)
108 char *s;
109 const wchar_t *pwcs;
110 size_t n;
111{
112 int count = 0;
113
114 if (n != 0) {
115 do {
116 if ((*s++ = (char) *pwcs++) == 0)
117 break;
118 count++;
119 } while (--n != 0);
120 }
121
122 return count;
123}
124
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
new file mode 100644
index 0000000000..b1ec2cebb1
--- /dev/null
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: nrand48.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20long
21nrand48(unsigned short xseed[3])
22{
23 __dorand48(xseed);
24 return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
25}
diff --git a/src/lib/libc/stdlib/putenv.c b/src/lib/libc/stdlib/putenv.c
new file mode 100644
index 0000000000..d8c4886d4b
--- /dev/null
+++ b/src/lib/libc/stdlib/putenv.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: putenv.c,v 1.2 1996/08/10 05:03:00 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41int
42putenv(str)
43 const char *str;
44{
45 char *p, *equal;
46 int rval;
47
48 if ((p = strdup(str)) == NULL)
49 return (-1);
50 if ((equal = strchr(p, '=')) == NULL) {
51 (void)free(p);
52 return (-1);
53 }
54 *equal = '\0';
55 rval = setenv(p, equal + 1, 1);
56 (void)free(p);
57 return (rval);
58}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
new file mode 100644
index 0000000000..ef0307ab25
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.3
@@ -0,0 +1,60 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qabs.3,v 1.5 2000/04/20 13:50:02 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt QABS 3
40.Os
41.Sh NAME
42.Nm qabs
43.Nd return the absolute value of a quad integer
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft quad_t
47.Fn qabs "quad_t j"
48.Sh DESCRIPTION
49The
50.Fn qabs
51function returns the absolute value of the quad integer
52.Fa j .
53.Sh SEE ALSO
54.Xr abs 3 ,
55.Xr cabs 3 ,
56.Xr floor 3 ,
57.Xr labs 3 ,
58.Xr math 3
59.Sh BUGS
60The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c
new file mode 100644
index 0000000000..ccc42cbec6
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.c
@@ -0,0 +1,45 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qabs.c,v 1.2 1996/08/19 08:33:40 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39
40quad_t
41qabs(j)
42 quad_t j;
43{
44 return(j < 0 ? -j : j);
45}
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
new file mode 100644
index 0000000000..4db47d9b4a
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -0,0 +1,64 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qdiv.3,v 1.4 2000/12/24 00:31:00 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt QDIV 3
40.Os
41.Sh NAME
42.Nm qdiv
43.Nd return quotient and remainder from division
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft qdiv_t
47.Fn qdiv "quad_t num" "quad_t denom"
48.Sh DESCRIPTION
49The
50.Fn qdiv
51function computes the value
52.Fa num Ns No / Ns Fa denom
53and returns the quotient and remainder in a structure named
54.Li qdiv_t
55that contains two
56.Li quad integer
57members named
58.Fa quot
59and
60.Fa rem .
61.Sh SEE ALSO
62.Xr div 3 ,
63.Xr ldiv 3 ,
64.Xr math 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
new file mode 100644
index 0000000000..07e84cd649
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: qdiv.c,v 1.2 1996/08/19 08:33:41 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <stdlib.h> /* qdiv_t */
42
43qdiv_t
44qdiv(num, denom)
45 quad_t num, denom;
46{
47 qdiv_t r;
48
49 /* see div.c for comments */
50
51 r.quot = num / denom;
52 r.rem = num % denom;
53 if (num >= 0 && r.rem < 0) {
54 r.quot++;
55 r.rem -= denom;
56 }
57 return (r);
58}
diff --git a/src/lib/libc/stdlib/qsort.3 b/src/lib/libc/stdlib/qsort.3
new file mode 100644
index 0000000000..6c4eba46bf
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.3
@@ -0,0 +1,233 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: qsort.3,v 1.9 2002/02/23 19:51:46 miod Exp $
37.\"
38.Dd June 4, 1993
39.Dt QSORT 3
40.Os
41.Sh NAME
42.Nm qsort ,
43.Nm heapsort ,
44.Nm mergesort
45.Nd sort functions
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft void
49.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
50.Ft int
51.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
52.Ft int
53.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
54.Sh DESCRIPTION
55The
56.Fn qsort
57function is a modified partition-exchange sort, or quicksort.
58The
59.Fn heapsort
60function is a modified selection sort.
61The
62.Fn mergesort
63function is a modified merge sort with exponential search
64intended for sorting data with pre-existing order.
65.Pp
66The
67.Fn qsort
68and
69.Fn heapsort
70functions sort an array of
71.Fa nmemb
72objects, the initial member of which is pointed to by
73.Fa base .
74The size of each object is specified by
75.Fa size .
76.Fn mergesort
77behaves similarly, but
78.Em requires
79that
80.Fa size
81be greater than
82.Dq "sizeof(void *) / 2" .
83.Pp
84The contents of the array
85.Fa base
86are sorted in ascending order according to
87a comparison function pointed to by
88.Fa compar ,
89which requires two arguments pointing to the objects being
90compared.
91.Pp
92The comparison function must return an integer less than, equal to, or
93greater than zero if the first argument is considered to be respectively
94less than, equal to, or greater than the second.
95.Pp
96The functions
97.Fn qsort
98and
99.Fn heapsort
100are
101.Em not
102stable, that is, if two members compare as equal, their order in
103the sorted array is undefined.
104The function
105.Fn mergesort
106is stable.
107.Pp
108The
109.Fn qsort
110function is an implementation of C.A.R. Hoare's
111.Dq quicksort
112algorithm,
113a variant of partition-exchange sorting; in particular, see D.E. Knuth's
114Algorithm Q.
115.Fn qsort
116takes O N lg N average time.
117This implementation uses median selection to avoid its
118O N**2 worst-case behavior.
119.Pp
120The
121.Fn heapsort
122function is an implementation of J.W.J. William's
123.Dq heapsort
124algorithm,
125a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
126.Fn heapsort
127takes O N lg N worst-case time.
128This implementation of
129.Fn qsort
130is implemented without recursive function calls.
131.Pp
132The function
133.Fn mergesort
134requires additional memory of size
135.Fa nmemb *
136.Fa size
137bytes; it should be used only when space is not at a premium.
138.Fn mergesort
139is optimized for data with pre-existing order; its worst case
140time is O N lg N; its best case is O N.
141.Pp
142Normally,
143.Fn qsort
144is faster than
145.Fn mergesort ,
146which is faster than
147.Fn heapsort .
148Memory availability and pre-existing order in the data can make this untrue.
149.Sh RETURN VALUES
150The
151.Fn qsort
152function returns no value.
153.Pp
154Upon successful completion,
155.Fn heapsort
156and
157.Fn mergesort
158return 0.
159Otherwise, they return \-1 and the global variable
160.Va errno
161is set to indicate the error.
162.Sh ERRORS
163The
164.Fn heapsort
165and
166.Fn mergesort
167functions succeed unless:
168.Bl -tag -width Er
169.It Bq Er EINVAL
170The
171.Fa size
172argument is zero, or the
173.Fa size
174argument to
175.Fn mergesort
176is less than
177.Dq "sizeof(void *) / 2" .
178.It Bq Er ENOMEM
179.Fn heapsort
180or
181.Fn mergesort
182were unable to allocate memory.
183.El
184.Sh COMPATIBILITY
185Previous versions of
186.Fn qsort
187did not permit the comparison routine itself to call
188.Fn qsort 3 .
189This is no longer true.
190.Sh SEE ALSO
191.Xr sort 1 ,
192.Xr radixsort 3
193.Rs
194.%A Hoare, C.A.R.
195.%D 1962
196.%T "Quicksort"
197.%J "The Computer Journal"
198.%V 5:1
199.%P pp. 10-15
200.Re
201.Rs
202.%A Williams, J.W.J
203.%D 1964
204.%T "Heapsort"
205.%J "Communications of the ACM"
206.%V 7:1
207.%P pp. 347-348
208.Re
209.Rs
210.%A Knuth, D.E.
211.%D 1968
212.%B "The Art of Computer Programming"
213.%V Vol. 3
214.%T "Sorting and Searching"
215.%P pp. 114-123, 145-149
216.Re
217.Rs
218.%A Mcilroy, P.M.
219.%T "Optimistic Sorting and Information Theoretic Complexity"
220.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
221.%V January 1992
222.Re
223.Rs
224.%A Bentley, J.L.
225.%T "Engineering a Sort Function"
226.%J "bentley@research.att.com"
227.%V January 1992
228.Re
229.Sh STANDARDS
230The
231.Fn qsort
232function conforms to
233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000000..9b8bb5801b
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.c
@@ -0,0 +1,175 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: qsort.c,v 1.7 2002/02/17 19:42:24 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static __inline char *med3(char *, char *, char *, int (*)());
42static __inline void swapfunc(char *, char *, int, int);
43
44#define min(a, b) (a) < (b) ? a : b
45
46/*
47 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
48 */
49#define swapcode(TYPE, parmi, parmj, n) { \
50 long i = (n) / sizeof (TYPE); \
51 register TYPE *pi = (TYPE *) (parmi); \
52 register TYPE *pj = (TYPE *) (parmj); \
53 do { \
54 register TYPE t = *pi; \
55 *pi++ = *pj; \
56 *pj++ = t; \
57 } while (--i > 0); \
58}
59
60#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
61 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
62
63static __inline void
64swapfunc(a, b, n, swaptype)
65 char *a, *b;
66 int n, swaptype;
67{
68 if (swaptype <= 1)
69 swapcode(long, a, b, n)
70 else
71 swapcode(char, a, b, n)
72}
73
74#define swap(a, b) \
75 if (swaptype == 0) { \
76 long t = *(long *)(a); \
77 *(long *)(a) = *(long *)(b); \
78 *(long *)(b) = t; \
79 } else \
80 swapfunc(a, b, es, swaptype)
81
82#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
83
84static __inline char *
85med3(a, b, c, cmp)
86 char *a, *b, *c;
87 int (*cmp)();
88{
89 return cmp(a, b) < 0 ?
90 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
91 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
92}
93
94void
95qsort(aa, n, es, cmp)
96 void *aa;
97 size_t n, es;
98 int (*cmp)();
99{
100 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
101 int d, r, swaptype, swap_cnt;
102 register char *a = aa;
103
104loop: SWAPINIT(a, es);
105 swap_cnt = 0;
106 if (n < 7) {
107 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es)
110 swap(pl, pl - es);
111 return;
112 }
113 pm = (char *)a + (n / 2) * es;
114 if (n > 7) {
115 pl = (char *)a;
116 pn = (char *)a + (n - 1) * es;
117 if (n > 40) {
118 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp);
120 pm = med3(pm - d, pm, pm + d, cmp);
121 pn = med3(pn - 2 * d, pn - d, pn, cmp);
122 }
123 pm = med3(pl, pm, pn, cmp);
124 }
125 swap(a, pm);
126 pa = pb = (char *)a + es;
127
128 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) {
132 swap_cnt = 1;
133 swap(pa, pb);
134 pa += es;
135 }
136 pb += es;
137 }
138 while (pb <= pc && (r = cmp(pc, a)) >= 0) {
139 if (r == 0) {
140 swap_cnt = 1;
141 swap(pc, pd);
142 pd -= es;
143 }
144 pc -= es;
145 }
146 if (pb > pc)
147 break;
148 swap(pb, pc);
149 swap_cnt = 1;
150 pb += es;
151 pc -= es;
152 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es)
157 swap(pl, pl - es);
158 return;
159 }
160
161 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es);
165 vecswap(pb, pn - r, r);
166 if ((r = pb - pa) > es)
167 qsort(a, r / es, es, cmp);
168 if ((r = pd - pc) > es) {
169 /* Iterate rather than recurse to save stack space */
170 a = pn - r;
171 n = r / es;
172 goto loop;
173 }
174/* qsort(pn - r, r / es, es, cmp);*/
175}
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
new file mode 100644
index 0000000000..f70990fa8e
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,156 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: radixsort.3,v 1.7 2001/08/06 10:42:26 mpech Exp $
33.\"
34.Dd January 27, 1994
35.Dt RADIXSORT 3
36.Os
37.Sh NAME
38.Nm radixsort
39.Nd radix sort
40.Sh SYNOPSIS
41.Fd #include <limits.h>
42.Fd #include <stdlib.h>
43.Ft int
44.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
45.Ft int
46.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
47.Sh DESCRIPTION
48The
49.Fn radixsort
50and
51.Fn sradixsort
52functions are implementations of radix sort.
53.Pp
54These functions sort an array of pointers to byte strings, the initial
55member of which is referenced by
56.Fa base .
57The byte strings may contain any values; the end of each string
58is denoted by the user-specified value
59.Fa endbyte .
60.Pp
61Applications may specify a sort order by providing the
62.Fa table
63argument.
64If non-null,
65.Fa table
66must reference an array of
67.Dv UCHAR_MAX
68+ 1 bytes which contains the sort weight of each possible byte value.
69The end-of-string byte must have a sort weight of 0 or 255
70(for sorting in reverse order).
71More than one byte may have the same sort weight.
72The
73.Fa table
74argument is useful for applications which wish to sort different characters
75equally, for example, providing a table with the same weights
76for A-Z as for a-z will result in a case-insensitive sort.
77If
78.Fa table
79is
80.Dv NULL ,
81the contents of the array are sorted in ascending order according to the
82.Tn ASCII
83order of the byte strings they reference and
84.Fa endbyte
85has a sorting weight of 0.
86.Pp
87The
88.Fn sradixsort
89function is stable, that is, if two elements compare as equal, their
90order in the sorted array is unchanged.
91The
92.Fn sradixsort
93function uses additional memory sufficient to hold
94.Fa nmemb
95pointers.
96.Pp
97The
98.Fn radixsort
99function is not stable, but uses no additional memory.
100.Pp
101These functions are variants of most-significant-byte radix sorting; in
102particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
103They take linear time relative to the number of bytes in the strings.
104.Sh RETURN VALUES
105Upon successful completion 0 is returned.
106Otherwise, \-1 is returned and the global variable
107.Va errno
108is set to indicate the error.
109.Sh ERRORS
110.Bl -tag -width Er
111.It Bq Er EINVAL
112The value of the
113.Fa endbyte
114element of
115.Fa table
116is not 0 or 255.
117.El
118.Pp
119Additionally, the
120.Fn sradixsort
121function may fail and set
122.Va errno
123for any of the errors specified for the library routine
124.Xr malloc 3 .
125.Sh SEE ALSO
126.Xr sort 1 ,
127.Xr qsort 3
128.Rs
129.%A Knuth, D.E.
130.%D 1968
131.%B "The Art of Computer Programming"
132.%T "Sorting and Searching"
133.%V Vol. 3
134.%P pp. 170-178
135.Re
136.Rs
137.%A Paige, R.
138.%D 1987
139.%T "Three Partition Refinement Algorithms"
140.%J "SIAM J. Comput."
141.%V Vol. 16
142.%N No. 6
143.Re
144.Rs
145.%A McIlroy, P.
146.%D 1993
147.%B "Engineering Radix Sort"
148.%T "Computing Systems"
149.%V Vol. 6:1
150.%P pp. 5-27
151.Re
152.Sh HISTORY
153The
154.Fn radixsort
155function first appeared in
156.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000000..e03b479715
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -0,0 +1,317 @@
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Peter McIlroy and by Dan Bernstein at New York University,
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: radixsort.c,v 1.5 2002/02/17 19:42:24 millert Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41/*
42 * Radixsort routines.
43 *
44 * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack.
45 * Use radixsort(a, n, trace, endchar) for this case.
46 *
47 * For stable sorting (using N extra pointers) use sradixsort(), which calls
48 * r_sort_b().
49 *
50 * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic,
51 * "Engineering Radix Sort".
52 */
53
54#include <sys/types.h>
55#include <stdlib.h>
56#include <errno.h>
57
58typedef struct {
59 const u_char **sa;
60 int sn, si;
61} stack;
62
63static __inline void simplesort
64(const u_char **, int, int, const u_char *, u_int);
65static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
66static void r_sort_b(const u_char **,
67 const u_char **, int, int, const u_char *, u_int);
68
69#define THRESHOLD 20 /* Divert to simplesort(). */
70#define SIZE 512 /* Default stack size. */
71
72#define SETUP { \
73 if (tab == NULL) { \
74 tr = tr0; \
75 for (c = 0; c < endch; c++) \
76 tr0[c] = c + 1; \
77 tr0[c] = 0; \
78 for (c++; c < 256; c++) \
79 tr0[c] = c; \
80 endch = 0; \
81 } else { \
82 endch = tab[endch]; \
83 tr = tab; \
84 if (endch != 0 && endch != 255) { \
85 errno = EINVAL; \
86 return (-1); \
87 } \
88 } \
89}
90
91int
92radixsort(a, n, tab, endch)
93 const u_char **a, *tab;
94 int n;
95 u_int endch;
96{
97 const u_char *tr;
98 int c;
99 u_char tr0[256];
100
101 SETUP;
102 r_sort_a(a, n, 0, tr, endch);
103 return (0);
104}
105
106int
107sradixsort(a, n, tab, endch)
108 const u_char **a, *tab;
109 int n;
110 u_int endch;
111{
112 const u_char *tr, **ta;
113 int c;
114 u_char tr0[256];
115
116 SETUP;
117 if (n < THRESHOLD)
118 simplesort(a, n, 0, tr, endch);
119 else {
120 if ((ta = malloc(n * sizeof(a))) == NULL)
121 return (-1);
122 r_sort_b(a, ta, n, 0, tr, endch);
123 free(ta);
124 }
125 return (0);
126}
127
128#define empty(s) (s >= sp)
129#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
130#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
131#define swap(a, b, t) t = a, a = b, b = t
132
133/* Unstable, in-place sort. */
134void
135r_sort_a(a, n, i, tr, endch)
136 const u_char **a;
137 int n, i;
138 const u_char *tr;
139 u_int endch;
140{
141 static int count[256], nc, bmin;
142 register int c;
143 register const u_char **ak, *r;
144 stack s[SIZE], *sp, *sp0, *sp1, temp;
145 int *cp, bigc;
146 const u_char **an, *t, **aj, **top[256];
147
148 /* Set up stack. */
149 sp = s;
150 push(a, n, i);
151 while (!empty(s)) {
152 pop(a, n, i);
153 if (n < THRESHOLD) {
154 simplesort(a, n, i, tr, endch);
155 continue;
156 }
157 an = a + n;
158
159 /* Make character histogram. */
160 if (nc == 0) {
161 bmin = 255; /* First occupied bin, excluding eos. */
162 for (ak = a; ak < an;) {
163 c = tr[(*ak++)[i]];
164 if (++count[c] == 1 && c != endch) {
165 if (c < bmin)
166 bmin = c;
167 nc++;
168 }
169 }
170 if (sp + nc > s + SIZE) { /* Get more stack. */
171 r_sort_a(a, n, i, tr, endch);
172 continue;
173 }
174 }
175
176 /*
177 * Set top[]; push incompletely sorted bins onto stack.
178 * top[] = pointers to last out-of-place element in bins.
179 * count[] = counts of elements in bins.
180 * Before permuting: top[c-1] + count[c] = top[c];
181 * during deal: top[c] counts down to top[c-1].
182 */
183 sp0 = sp1 = sp; /* Stack position of biggest bin. */
184 bigc = 2; /* Size of biggest bin. */
185 if (endch == 0) /* Special case: set top[eos]. */
186 top[0] = ak = a + count[0];
187 else {
188 ak = a;
189 top[255] = an;
190 }
191 for (cp = count + bmin; nc > 0; cp++) {
192 while (*cp == 0) /* Find next non-empty pile. */
193 cp++;
194 if (*cp > 1) {
195 if (*cp > bigc) {
196 bigc = *cp;
197 sp1 = sp;
198 }
199 push(ak, *cp, i+1);
200 }
201 top[cp-count] = ak += *cp;
202 nc--;
203 }
204 swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */
205
206 /*
207 * Permute misplacements home. Already home: everything
208 * before aj, and in bin[c], items from top[c] on.
209 * Inner loop:
210 * r = next element to put in place;
211 * ak = top[r[i]] = location to put the next element.
212 * aj = bottom of 1st disordered bin.
213 * Outer loop:
214 * Once the 1st disordered bin is done, ie. aj >= ak,
215 * aj<-aj + count[c] connects the bins in a linked list;
216 * reset count[c].
217 */
218 for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0)
219 for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);)
220 swap(*ak, r, t);
221 }
222}
223
224/* Stable sort, requiring additional memory. */
225void
226r_sort_b(a, ta, n, i, tr, endch)
227 const u_char **a, **ta;
228 int n, i;
229 const u_char *tr;
230 u_int endch;
231{
232 static int count[256], nc, bmin;
233 register int c;
234 register const u_char **ak, **ai;
235 stack s[512], *sp, *sp0, *sp1, temp;
236 const u_char **top[256];
237 int *cp, bigc;
238
239 sp = s;
240 push(a, n, i);
241 while (!empty(s)) {
242 pop(a, n, i);
243 if (n < THRESHOLD) {
244 simplesort(a, n, i, tr, endch);
245 continue;
246 }
247
248 if (nc == 0) {
249 bmin = 255;
250 for (ak = a + n; --ak >= a;) {
251 c = tr[(*ak)[i]];
252 if (++count[c] == 1 && c != endch) {
253 if (c < bmin)
254 bmin = c;
255 nc++;
256 }
257 }
258 if (sp + nc > s + SIZE) {
259 r_sort_b(a, ta, n, i, tr, endch);
260 continue;
261 }
262 }
263
264 sp0 = sp1 = sp;
265 bigc = 2;
266 if (endch == 0) {
267 top[0] = ak = a + count[0];
268 count[0] = 0;
269 } else {
270 ak = a;
271 top[255] = a + n;
272 count[255] = 0;
273 }
274 for (cp = count + bmin; nc > 0; cp++) {
275 while (*cp == 0)
276 cp++;
277 if ((c = *cp) > 1) {
278 if (c > bigc) {
279 bigc = c;
280 sp1 = sp;
281 }
282 push(ak, c, i+1);
283 }
284 top[cp-count] = ak += c;
285 *cp = 0; /* Reset count[]. */
286 nc--;
287 }
288 swap(*sp0, *sp1, temp);
289
290 for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */
291 *--ak = *--ai;
292 for (ak = ta+n; --ak >= ta;) /* Deal to piles. */
293 *--top[tr[(*ak)[i]]] = *ak;
294 }
295}
296
297static __inline void
298simplesort(a, n, b, tr, endch) /* insertion sort */
299 register const u_char **a;
300 int n, b;
301 register const u_char *tr;
302 u_int endch;
303{
304 register u_char ch;
305 const u_char **ak, **ai, *s, *t;
306
307 for (ak = a+1; --n >= 1; ak++)
308 for (ai = ak; ai > a; ai--) {
309 for (s = ai[0] + b, t = ai[-1] + b;
310 (ch = tr[*s]) != endch; s++, t++)
311 if (ch != tr[*t])
312 break;
313 if (ch >= tr[*t])
314 break;
315 swap(ai[0], ai[-1], s);
316 }
317}
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
new file mode 100644
index 0000000000..8899c2e104
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.3
@@ -0,0 +1,102 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: rand.3,v 1.8 2001/05/13 23:38:02 millert Exp $
37.\"
38.Dd June 29, 1991
39.Dt RAND 3
40.Os
41.Sh NAME
42.Nm rand ,
43.Nm srand
44.Nd bad random number generator
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn srand "unsigned int seed"
49.Ft int
50.Fn rand void
51.Ft int
52.Fn rand_r "unsigned int *seed"
53.Sh DESCRIPTION
54.Bf -symbolic
55These interfaces are obsoleted by
56.Xr random 3 .
57.Ef
58.Pp
59The
60.Fn rand
61function computes a sequence of pseudo-random integers in the range
62of 0 to
63.Dv RAND_MAX
64(as defined by the header file
65.Aq Pa stdlib.h ) .
66.Pp
67The
68.Fn srand
69function sets its argument as the seed for a new sequence of
70pseudo-random numbers to be returned by
71.Fn rand .
72These sequences are repeatable by calling
73.Fn srand
74with the same seed value.
75.Pp
76If no seed value is provided, the functions are automatically
77seeded with a value of 1.
78.Pp
79The
80.Fn rand_r
81is a thread-safe version of
82.Fn rand .
83Storage for the seed must be provided through the
84.Fa seed
85argument, and needs to have been initialized by the caller.
86.Sh SEE ALSO
87.Xr arc4random 3 ,
88.Xr rand48 3 ,
89.Xr random 3
90.Sh STANDARDS
91The
92.Fn rand
93and
94.Fn srand
95functions conform to
96.St -ansiC .
97.Pp
98The
99.Fn rand_r
100function conforms to ISO/IEC 9945-1 ANSI/IEEE
101.Pq Dq Tn POSIX
102Std 1003.1c Draft 10.
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000000..bb180886c0
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.c
@@ -0,0 +1,65 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: rand.c,v 1.6 1998/12/07 21:47:22 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <stdlib.h>
40
41static u_int next = 1;
42
43int
44rand_r(seed)
45u_int *seed;
46{
47
48 *seed = *seed * 1103515245 + 12345;
49 return (*seed % ((u_int)RAND_MAX + 1));
50}
51
52int
53rand()
54{
55
56 return (rand_r(&next));
57}
58
59void
60srand(seed)
61u_int seed;
62{
63
64 next = seed;
65}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
new file mode 100644
index 0000000000..31a4fdf4dd
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.3
@@ -0,0 +1,165 @@
1\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved.
3.\"
4.\" You may redistribute unmodified or modified versions of this source
5.\" code provided that the above copyright notice and this and the
6.\" following conditions are retained.
7.\"
8.\" This software is provided ``as is'', and comes with no warranties
9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software.
11.\"
12.\" $OpenBSD: rand48.3,v 1.8 2001/08/06 10:42:26 mpech Exp $
13.\"
14.Dd October 8, 1993
15.Dt RAND48 3
16.Os
17.Sh NAME
18.Nm drand48 ,
19.Nm erand48 ,
20.Nm lrand48 ,
21.Nm nrand48 ,
22.Nm mrand48 ,
23.Nm jrand48 ,
24.Nm srand48 ,
25.Nm seed48 ,
26.Nm lcong48
27.Nd pseudo random number generators and initialization routines
28.Sh SYNOPSIS
29.Fd #include <stdlib.h>
30.Ft double
31.Fn drand48 void
32.Ft double
33.Fn erand48 "unsigned short xseed[3]"
34.Ft long
35.Fn lrand48 void
36.Ft long
37.Fn nrand48 "unsigned short xseed[3]"
38.Ft long
39.Fn mrand48 void
40.Ft long
41.Fn jrand48 "unsigned short xseed[3]"
42.Ft void
43.Fn srand48 "long seed"
44.Ft "unsigned short *"
45.Fn seed48 "unsigned short xseed[3]"
46.Ft void
47.Fn lcong48 "unsigned short p[7]"
48.Sh DESCRIPTION
49The
50.Fn rand48
51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size.
53The particular formula employed is
54r(n+1) = (a * r(n) + c) mod m
55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11.
58The modulus is always fixed at m = 2 ** 48.
59r(n) is called the seed of the random number generator.
60.Pp
61For all the six generator routines described next, the first
62computational step is to perform a single iteration of the algorithm.
63.Pp
64.Fn drand48
65and
66.Fn erand48
67return values of type double.
68The full 48 bits of r(n+1) are
69loaded into the mantissa of the returned value, with the exponent set
70such that the values produced lie in the interval [0.0, 1.0).
71.Pp
72.Fn lrand48
73and
74.Fn nrand48
75return values of type long in the range
76[0, 2**31-1].
77The high-order (31) bits of
78r(n+1) are loaded into the lower bits of the returned value, with
79the topmost (sign) bit set to zero.
80.Pp
81.Fn mrand48
82and
83.Fn jrand48
84return values of type long in the range
85[-2**31, 2**31-1].
86The high-order (32) bits of r(n+1) are loaded into the returned value.
87.Pp
88.Fn drand48 ,
89.Fn lrand48 ,
90and
91.Fn mrand48
92use an internal buffer to store r(n).
93For these functions
94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
95.Pp
96On the other hand,
97.Fn erand48 ,
98.Fn nrand48 ,
99and
100.Fn jrand48
101use a user-supplied buffer to store the seed r(n),
102which consists of an array of 3 shorts, where the zeroth member
103holds the least significant bits.
104.Pp
105All functions share the same multiplicand and addend.
106.Pp
107.Fn srand48
108is used to initialize the internal buffer r(n) of
109.Fn drand48 ,
110.Fn lrand48 ,
111and
112.Fn mrand48
113such that the 32 bits of the seed value are copied into the upper 32 bits
114of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
115Additionally, the constant multiplicand and addend of the algorithm are
116reset to the default values given above.
117.Pp
118.Fn seed48
119also initializes the internal buffer r(n) of
120.Fn drand48 ,
121.Fn lrand48 ,
122and
123.Fn mrand48 ,
124but here all 48 bits of the seed can be specified in an array of 3 shorts,
125where the zeroth member specifies the lowest bits.
126Again, the constant multiplicand and addend of the algorithm are
127reset to the default values given above.
128.Fn seed48
129returns a pointer to an array of 3 shorts which contains the old seed.
130This array is statically allocated, so its contents are lost after
131each new call to
132.Fn seed48 .
133.Pp
134Finally,
135.Fn lcong48
136allows full control over the multiplicand and addend used in
137.Fn drand48 ,
138.Fn erand48 ,
139.Fn lrand48 ,
140.Fn nrand48 ,
141.Fn mrand48 ,
142and
143.Fn jrand48 ,
144and the seed used in
145.Fn drand48 ,
146.Fn lrand48 ,
147and
148.Fn mrand48 .
149An array of 7 shorts is passed as parameter; the first three shorts are
150used to initialize the seed; the second three are used to initialize the
151multiplicand; and the last short is used to initialize the addend.
152It is thus not possible to use values greater than 0xffff as the addend.
153.Pp
154Note that all three methods of seeding the random number generator
155always also set the multiplicand and addend for any of the six
156generator calls.
157.Pp
158For a more powerful random number generator, see
159.Xr random 3
160.Sh AUTHORS
161Martin Birgmeier
162.Sh SEE ALSO
163.Xr arc4random 3 ,
164.Xr rand 3 ,
165.Xr random 3
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
new file mode 100644
index 0000000000..afa49f65f3
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
14 */
15
16#ifndef _RAND48_H_
17#define _RAND48_H_
18
19#include <math.h>
20#include <stdlib.h>
21
22void __dorand48(unsigned short[3]);
23
24#define RAND48_SEED_0 (0x330e)
25#define RAND48_SEED_1 (0xabcd)
26#define RAND48_SEED_2 (0x1234)
27#define RAND48_MULT_0 (0xe66d)
28#define RAND48_MULT_1 (0xdeec)
29#define RAND48_MULT_2 (0x0005)
30#define RAND48_ADD (0x000b)
31
32#endif /* _RAND48_H_ */
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
new file mode 100644
index 0000000000..3d4545651b
--- /dev/null
+++ b/src/lib/libc/stdlib/random.3
@@ -0,0 +1,190 @@
1.\" Copyright (c) 1983, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: random.3,v 1.14 2001/09/06 15:04:34 mpech Exp $
33.\"
34.Dd April 19, 1991
35.Dt RANDOM 3
36.Os
37.Sh NAME
38.Nm random ,
39.Nm srandom ,
40.Nm srandomdev ,
41.Nm initstate ,
42.Nm setstate
43.Nd better random number generator; routines for changing generators
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft long
47.Fn random void
48.Ft void
49.Fn srandom "unsigned int seed"
50.Ft void
51.Fn srandomdev void
52.Ft char *
53.Fn initstate "unsigned int seed" "char *state" "size_t n"
54.Ft char *
55.Fn setstate "const char *state"
56.Sh DESCRIPTION
57The
58.Fn random
59function uses a non-linear additive feedback random number generator employing
60a default table of size 31 long integers to return successive pseudo-random
61numbers in the range from 0 to (2**31)\-1.
62The period of this random number generator is very large, approximately
6316*((2**31)\-1.
64.Pp
65The
66.Fn random
67and
68.Fn srandom
69functions have (almost) the same calling sequence and initialization
70properties as
71.Xr rand 3 Ns / Xr srand 3 .
72The difference is that
73.Xr rand
74produces a much less random sequence \(em in fact, the low dozen bits
75generated by rand go through a cyclic pattern.
76All the bits generated by
77.Fn random
78are usable.
79For example,
80.Sq Li random()&01
81will produce a random binary
82value.
83.Pp
84Like
85.Xr rand 3 ,
86.Fn random
87will by default produce a sequence of numbers that can be duplicated
88by calling
89.Fn srandom
90with
91.Ql 1
92as the seed.
93.Pp
94The
95.Fn srandomdev
96routine initialize a state array using the
97.Xr arandom 4
98random number device which returns good random numbers,
99suitable for cryptographic use.
100Note that this particular seeding procedure can generate
101states which are impossible to reproduce by calling
102.Fn srandom
103with any value, since the succeeding terms in the
104state buffer are no longer derived from the LC algorithm applied to
105a fixed seed.
106.Pp
107The
108.Fn initstate
109routine allows a state array, passed in as an argument, to be initialized
110for future use.
111The size of the state array (in bytes) is used by
112.Fn initstate
113to decide how sophisticated a random number generator it should use \(em the
114more state, the better the random numbers will be.
115(Current "optimal" values for the amount of state information are
1168, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
117the nearest known amount.
118Using less than 8 bytes will cause an error.)
119The seed for the initialization (which specifies a starting point for
120the random number sequence, and provides for restarting at the same
121point) is also an argument.
122The
123.Fn initstate
124function returns a pointer to the previous state information array.
125.Pp
126Once a state has been initialized, the
127.Fn setstate
128routine provides for rapid switching between states.
129The
130.Fn setstate
131function returns a pointer to the previous state array; its
132argument state array is used for further random number generation
133until the next call to
134.Fn initstate
135or
136.Fn setstate .
137.Pp
138Once a state array has been initialized, it may be restarted at a
139different point either by calling
140.Fn initstate
141(with the desired seed, the state array, and its size) or by calling
142both
143.Fn setstate
144(with the state array) and
145.Fn srandom
146(with the desired seed).
147The advantage of calling both
148.Fn setstate
149and
150.Fn srandom
151is that the size of the state array does not have to be remembered after
152it is initialized.
153.Pp
154With 256 bytes of state information, the period of the random number
155generator is greater than 2**69
156which should be sufficient for most purposes.
157.Sh AUTHORS
158.An Earl T. Cohen
159.Sh DIAGNOSTICS
160If
161.Fn initstate
162is called with less than 8 bytes of state information, or if
163.Fn setstate
164detects that the state information has been garbled, error
165messages are printed on the standard error output.
166.Sh SEE ALSO
167.Xr arc4random 3 ,
168.Xr drand48 3 ,
169.Xr rand 3 ,
170.Xr random 4
171.Sh STANDARDS
172The
173.Fn random ,
174.Fn srandom ,
175.Fn initstate ,
176and
177.Fn setstate
178functions conform to
179.St -xpg4.2 .
180.Pp
181The
182.Fn srandomdev
183function is an extension.
184.Sh HISTORY
185These
186functions appeared in
187.Bx 4.2 .
188.Sh BUGS
189About 2/3 the speed of
190.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
new file mode 100644
index 0000000000..5ce7c90ee9
--- /dev/null
+++ b/src/lib/libc/stdlib/random.c
@@ -0,0 +1,417 @@
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: random.c,v 1.9 2000/04/04 14:27:00 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/time.h>
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44
45/*
46 * random.c:
47 *
48 * An improved random number generation package. In addition to the standard
49 * rand()/srand() like interface, this package also has a special state info
50 * interface. The initstate() routine is called with a seed, an array of
51 * bytes, and a count of how many bytes are being passed in; this array is
52 * then initialized to contain information for random number generation with
53 * that much state information. Good sizes for the amount of state
54 * information are 32, 64, 128, and 256 bytes. The state can be switched by
55 * calling the setstate() routine with the same array as was initiallized
56 * with initstate(). By default, the package runs with 128 bytes of state
57 * information and generates far better random numbers than a linear
58 * congruential generator. If the amount of state information is less than
59 * 32 bytes, a simple linear congruential R.N.G. is used.
60 *
61 * Internally, the state information is treated as an array of longs; the
62 * zeroeth element of the array is the type of R.N.G. being used (small
63 * integer); the remainder of the array is the state information for the
64 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
65 * state information, which will allow a degree seven polynomial. (Note:
66 * the zeroeth word of state information also has some other information
67 * stored in it -- see setstate() for details).
68 *
69 * The random number generation technique is a linear feedback shift register
70 * approach, employing trinomials (since there are fewer terms to sum up that
71 * way). In this approach, the least significant bit of all the numbers in
72 * the state table will act as a linear feedback shift register, and will
73 * have period 2^deg - 1 (where deg is the degree of the polynomial being
74 * used, assuming that the polynomial is irreducible and primitive). The
75 * higher order bits will have longer periods, since their values are also
76 * influenced by pseudo-random carries out of the lower bits. The total
77 * period of the generator is approximately deg*(2**deg - 1); thus doubling
78 * the amount of state information has a vast influence on the period of the
79 * generator. Note: the deg*(2**deg - 1) is an approximation only good for
80 * large deg, when the period of the shift register is the dominant factor.
81 * With deg equal to seven, the period is actually much longer than the
82 * 7*(2**7 - 1) predicted by this formula.
83 */
84
85/*
86 * For each of the currently supported random number generators, we have a
87 * break value on the amount of state information (you need at least this
88 * many bytes of state info to support this random number generator), a degree
89 * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
90 * the separation between the two lower order coefficients of the trinomial.
91 */
92#define TYPE_0 0 /* linear congruential */
93#define BREAK_0 8
94#define DEG_0 0
95#define SEP_0 0
96
97#define TYPE_1 1 /* x**7 + x**3 + 1 */
98#define BREAK_1 32
99#define DEG_1 7
100#define SEP_1 3
101
102#define TYPE_2 2 /* x**15 + x + 1 */
103#define BREAK_2 64
104#define DEG_2 15
105#define SEP_2 1
106
107#define TYPE_3 3 /* x**31 + x**3 + 1 */
108#define BREAK_3 128
109#define DEG_3 31
110#define SEP_3 3
111
112#define TYPE_4 4 /* x**63 + x + 1 */
113#define BREAK_4 256
114#define DEG_4 63
115#define SEP_4 1
116
117/*
118 * Array versions of the above information to make code run faster --
119 * relies on fact that TYPE_i == i.
120 */
121#define MAX_TYPES 5 /* max number of types above */
122
123static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
124static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
125
126/*
127 * Initially, everything is set up as if from:
128 *
129 * initstate(1, &randtbl, 128);
130 *
131 * Note that this initialization takes advantage of the fact that srandom()
132 * advances the front and rear pointers 10*rand_deg times, and hence the
133 * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
134 * element of the state information, which contains info about the current
135 * position of the rear pointer is just
136 *
137 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
138 */
139
140static long randtbl[DEG_3 + 1] = {
141 TYPE_3,
142 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
143 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
144 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
145 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
146 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
147 0xf3bec5da,
148};
149
150/*
151 * fptr and rptr are two pointers into the state info, a front and a rear
152 * pointer. These two pointers are always rand_sep places aparts, as they
153 * cycle cyclically through the state information. (Yes, this does mean we
154 * could get away with just one pointer, but the code for random() is more
155 * efficient this way). The pointers are left positioned as they would be
156 * from the call
157 *
158 * initstate(1, randtbl, 128);
159 *
160 * (The position of the rear pointer, rptr, is really 0 (as explained above
161 * in the initialization of randtbl) because the state table pointer is set
162 * to point to randtbl[1] (as explained below).
163 */
164static long *fptr = &randtbl[SEP_3 + 1];
165static long *rptr = &randtbl[1];
166
167/*
168 * The following things are the pointer to the state information table, the
169 * type of the current generator, the degree of the current polynomial being
170 * used, and the separation between the two pointers. Note that for efficiency
171 * of random(), we remember the first location of the state information, not
172 * the zeroeth. Hence it is valid to access state[-1], which is used to
173 * store the type of the R.N.G. Also, we remember the last location, since
174 * this is more efficient than indexing every time to find the address of
175 * the last element to see if the front and rear pointers have wrapped.
176 */
177static long *state = &randtbl[1];
178static int rand_type = TYPE_3;
179static int rand_deg = DEG_3;
180static int rand_sep = SEP_3;
181static long *end_ptr = &randtbl[DEG_3 + 1];
182
183/*
184 * srandom:
185 *
186 * Initialize the random number generator based on the given seed. If the
187 * type is the trivial no-state-information type, just remember the seed.
188 * Otherwise, initializes state[] based on the given "seed" via a linear
189 * congruential generator. Then, the pointers are set to known locations
190 * that are exactly rand_sep places apart. Lastly, it cycles the state
191 * information a given number of times to get rid of any initial dependencies
192 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
193 * for default usage relies on values produced by this routine.
194 */
195void
196srandom(x)
197 u_int x;
198{
199 register long int test;
200 register int i;
201 ldiv_t val;
202
203 if (rand_type == TYPE_0)
204 state[0] = x;
205 else {
206 state[0] = x;
207 for (i = 1; i < rand_deg; i++) {
208 /*
209 * Implement the following, without overflowing 31 bits:
210 *
211 * state[i] = (16807 * state[i - 1]) % 2147483647;
212 *
213 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
214 */
215 val = ldiv(state[i-1], 127773);
216 test = 16807 * val.rem - 2836 * val.quot;
217 state[i] = test + (test < 0 ? 2147483647 : 0);
218 }
219 fptr = &state[rand_sep];
220 rptr = &state[0];
221 for (i = 0; i < 10 * rand_deg; i++)
222 (void)random();
223 }
224}
225
226/*
227 * srandomdev:
228 *
229 * Many programs choose the seed value in a totally predictable manner.
230 * This often causes problems. We seed the generator using the much more
231 * secure arandom(4) interface. Note that this particular seeding
232 * procedure can generate states which are impossible to reproduce by
233 * calling srandom() with any value, since the succeeding terms in the
234 * state buffer are no longer derived from the LC algorithm applied to
235 * a fixed seed.
236 */
237void
238srandomdev()
239{
240 int fd;
241 size_t len;
242
243 if (rand_type == TYPE_0)
244 len = sizeof(state[0]);
245 else
246 len = rand_deg * sizeof(state[0]);
247
248 if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
249 read(fd, (void *) state, len) == (ssize_t) len) {
250 close(fd);
251 } else {
252 struct timeval tv;
253 u_int junk;
254
255 /* XXX - this could be better */
256 gettimeofday(&tv, NULL);
257 srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
258 if (fd != -1)
259 close(fd);
260 return;
261 }
262
263 if (rand_type != TYPE_0) {
264 fptr = &state[rand_sep];
265 rptr = &state[0];
266 }
267}
268
269/*
270 * initstate:
271 *
272 * Initialize the state information in the given array of n bytes for future
273 * random number generation. Based on the number of bytes we are given, and
274 * the break values for the different R.N.G.'s, we choose the best (largest)
275 * one we can and set things up for it. srandom() is then called to
276 * initialize the state information.
277 *
278 * Note that on return from srandom(), we set state[-1] to be the type
279 * multiplexed with the current value of the rear pointer; this is so
280 * successive calls to initstate() won't lose this information and will be
281 * able to restart with setstate().
282 *
283 * Note: the first thing we do is save the current state, if any, just like
284 * setstate() so that it doesn't matter when initstate is called.
285 *
286 * Returns a pointer to the old state.
287 */
288char *
289initstate(seed, arg_state, n)
290 u_int seed; /* seed for R.N.G. */
291 char *arg_state; /* pointer to state array */
292 size_t n; /* # bytes of state info */
293{
294 register char *ostate = (char *)(&state[-1]);
295
296 if (rand_type == TYPE_0)
297 state[-1] = rand_type;
298 else
299 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
300 if (n < BREAK_0)
301 return(NULL);
302 if (n < BREAK_1) {
303 rand_type = TYPE_0;
304 rand_deg = DEG_0;
305 rand_sep = SEP_0;
306 } else if (n < BREAK_2) {
307 rand_type = TYPE_1;
308 rand_deg = DEG_1;
309 rand_sep = SEP_1;
310 } else if (n < BREAK_3) {
311 rand_type = TYPE_2;
312 rand_deg = DEG_2;
313 rand_sep = SEP_2;
314 } else if (n < BREAK_4) {
315 rand_type = TYPE_3;
316 rand_deg = DEG_3;
317 rand_sep = SEP_3;
318 } else {
319 rand_type = TYPE_4;
320 rand_deg = DEG_4;
321 rand_sep = SEP_4;
322 }
323 state = &(((long *)arg_state)[1]); /* first location */
324 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
325 srandom(seed);
326 if (rand_type == TYPE_0)
327 state[-1] = rand_type;
328 else
329 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
330 return(ostate);
331}
332
333/*
334 * setstate:
335 *
336 * Restore the state from the given state array.
337 *
338 * Note: it is important that we also remember the locations of the pointers
339 * in the current state information, and restore the locations of the pointers
340 * from the old state information. This is done by multiplexing the pointer
341 * location into the zeroeth word of the state information.
342 *
343 * Note that due to the order in which things are done, it is OK to call
344 * setstate() with the same state as the current state.
345 *
346 * Returns a pointer to the old state information.
347 */
348char *
349setstate(arg_state)
350 const char *arg_state;
351{
352 register long *new_state = (long *)arg_state;
353 register int type = new_state[0] % MAX_TYPES;
354 register int rear = new_state[0] / MAX_TYPES;
355 char *ostate = (char *)(&state[-1]);
356
357 if (rand_type == TYPE_0)
358 state[-1] = rand_type;
359 else
360 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
361 switch(type) {
362 case TYPE_0:
363 case TYPE_1:
364 case TYPE_2:
365 case TYPE_3:
366 case TYPE_4:
367 rand_type = type;
368 rand_deg = degrees[type];
369 rand_sep = seps[type];
370 break;
371 default:
372 return(NULL);
373 }
374 state = &new_state[1];
375 if (rand_type != TYPE_0) {
376 rptr = &state[rear];
377 fptr = &state[(rear + rand_sep) % rand_deg];
378 }
379 end_ptr = &state[rand_deg]; /* set end_ptr too */
380 return(ostate);
381}
382
383/*
384 * random:
385 *
386 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
387 * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
388 * the same in all the other cases due to all the global variables that have
389 * been set up. The basic operation is to add the number at the rear pointer
390 * into the one at the front pointer. Then both pointers are advanced to
391 * the next location cyclically in the table. The value returned is the sum
392 * generated, reduced to 31 bits by throwing away the "least random" low bit.
393 *
394 * Note: the code takes advantage of the fact that both the front and
395 * rear pointers can't wrap on the same call by not testing the rear
396 * pointer if the front one has wrapped.
397 *
398 * Returns a 31-bit random number.
399 */
400long
401random()
402{
403 long i;
404
405 if (rand_type == TYPE_0)
406 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
407 else {
408 *fptr += *rptr;
409 i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
410 if (++fptr >= end_ptr) {
411 fptr = state;
412 ++rptr;
413 } else if (++rptr >= end_ptr)
414 rptr = state;
415 }
416 return(i);
417}
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000000..56fbea9ede
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.3
@@ -0,0 +1,124 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Jan-Simon Pendry.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: realpath.3,v 1.8 2001/04/23 15:30:25 aaron Exp $
36.\"
37.Dd February 16, 1994
38.Dt REALPATH 3
39.Os
40.Sh NAME
41.Nm realpath
42.Nd returns the canonicalized absolute pathname
43.Sh SYNOPSIS
44.Fd #include <sys/param.h>
45.Fd #include <stdlib.h>
46.Ft "char *"
47.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]"
48.Sh DESCRIPTION
49The
50.Fn realpath
51function resolves all symbolic links, extra
52.Dq /
53characters and references to
54.Pa /./
55and
56.Pa /../
57in
58.Fa pathname ,
59and copies the resulting absolute pathname into the memory referenced by
60.Fa resolvedname .
61The
62.Fa resolvedname
63argument
64.Em must
65refer to a buffer capable of storing at least
66.Dv MAXPATHLEN
67characters.
68.Pp
69The
70.Fn realpath
71function will resolve both absolute and relative paths
72and return the absolute pathname corresponding to
73.Fa pathname .
74All but the last component of
75.Fa pathname
76must exist when
77.Fn realpath
78is called.
79.Sh "RETURN VALUES"
80The
81.Fn realpath
82function returns
83.Fa resolvedname
84on success.
85If an error occurs,
86.Fn realpath
87returns
88.Dv NULL ,
89and
90.Fa resolvedname
91contains the pathname which caused the problem.
92.Sh ERRORS
93The function
94.Fn realpath
95may fail and set the external variable
96.Va errno
97for any of the errors specified for the library functions
98.Xr chdir 2 ,
99.Xr close 2 ,
100.Xr fchdir 2 ,
101.Xr lstat 2 ,
102.Xr open 2 ,
103.Xr readlink 2 ,
104and
105.Xr getcwd 3 .
106.Sh CAVEATS
107This implementation of
108.Fn realpath
109differs slightly from the Solaris implementation.
110The
111.Bx 4.4
112version always returns absolute pathnames,
113whereas the Solaris implementation will,
114under certain circumstances, return a relative
115.Fa resolvedname
116when given a relative
117.Fa pathname .
118.Sh SEE ALSO
119.Xr getcwd 3
120.Sh HISTORY
121The
122.Fn realpath
123function call first appeared in
124.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
new file mode 100644
index 0000000000..d01b19e0f2
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.c
@@ -0,0 +1,166 @@
1/*
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/param.h>
42#include <sys/stat.h>
43
44#include <errno.h>
45#include <fcntl.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50/*
51 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
52 *
53 * Find the real name of path, by removing all ".", ".." and symlink
54 * components. Returns (resolved) on success, or (NULL) on failure,
55 * in which case the path which caused trouble is left in (resolved).
56 */
57char *
58realpath(path, resolved)
59 const char *path;
60 char *resolved;
61{
62 struct stat sb;
63 int fd, n, rootd, serrno;
64 char *p, *q, wbuf[MAXPATHLEN];
65 int symlinks = 0;
66
67 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strlcpy(resolved, ".", MAXPATHLEN);
70 return (NULL);
71 }
72
73 /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
74 if (path[0] == '.' && path[1] == '\0')
75 path = "";
76
77 /*
78 * Find the dirname and basename from the path to be resolved.
79 * Change directory to the dirname component.
80 * lstat the basename part.
81 * if it is a symlink, read in the value and loop.
82 * if it is a directory, then change to that directory.
83 * get the current directory name and append the basename.
84 */
85 strlcpy(resolved, path, MAXPATHLEN);
86loop:
87 q = strrchr(resolved, '/');
88 if (q != NULL) {
89 p = q + 1;
90 if (q == resolved)
91 q = "/";
92 else {
93 do {
94 --q;
95 } while (q > resolved && *q == '/');
96 q[1] = '\0';
97 q = resolved;
98 }
99 if (chdir(q) < 0)
100 goto err1;
101 } else
102 p = resolved;
103
104 /* Deal with the last component. */
105 if (*p != '\0' && lstat(p, &sb) == 0) {
106 if (S_ISLNK(sb.st_mode)) {
107 if (++symlinks > MAXSYMLINKS) {
108 errno = ELOOP;
109 goto err1;
110 }
111 n = readlink(p, resolved, MAXPATHLEN-1);
112 if (n < 0)
113 goto err1;
114 resolved[n] = '\0';
115 goto loop;
116 }
117 if (S_ISDIR(sb.st_mode)) {
118 if (chdir(p) < 0)
119 goto err1;
120 p = "";
121 }
122 }
123
124 /*
125 * Save the last component name and get the full pathname of
126 * the current directory.
127 */
128 (void)strlcpy(wbuf, p, sizeof wbuf);
129 if (getcwd(resolved, MAXPATHLEN) == 0)
130 goto err1;
131
132 /*
133 * Join the two strings together, ensuring that the right thing
134 * happens if the last component is empty, or the dirname is root.
135 */
136 if (resolved[0] == '/' && resolved[1] == '\0')
137 rootd = 1;
138 else
139 rootd = 0;
140
141 if (*wbuf) {
142 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
143 errno = ENAMETOOLONG;
144 goto err1;
145 }
146 if (rootd == 0)
147 (void)strcat(resolved, "/");
148 (void)strcat(resolved, wbuf);
149 }
150
151 /* Go back to where we came from. */
152 if (fchdir(fd) < 0) {
153 serrno = errno;
154 goto err2;
155 }
156
157 /* It's okay if the close fails, what's an fd more or less? */
158 (void)close(fd);
159 return (resolved);
160
161err1: serrno = errno;
162 (void)fchdir(fd);
163err2: (void)close(fd);
164 errno = serrno;
165 return (NULL);
166}
diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c
new file mode 100644
index 0000000000..c4dcd0ead8
--- /dev/null
+++ b/src/lib/libc/stdlib/seed48.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: seed48.c,v 1.2 1996/08/19 08:33:48 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24unsigned short *
25seed48(unsigned short xseed[3])
26{
27 static unsigned short sseed[3];
28
29 sseed[0] = __rand48_seed[0];
30 sseed[1] = __rand48_seed[1];
31 sseed[2] = __rand48_seed[2];
32 __rand48_seed[0] = xseed[0];
33 __rand48_seed[1] = xseed[1];
34 __rand48_seed[2] = xseed[2];
35 __rand48_mult[0] = RAND48_MULT_0;
36 __rand48_mult[1] = RAND48_MULT_1;
37 __rand48_mult[2] = RAND48_MULT_2;
38 __rand48_add = RAND48_ADD;
39 return sseed;
40}
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
new file mode 100644
index 0000000000..fc7c67a5db
--- /dev/null
+++ b/src/lib/libc/stdlib/setenv.c
@@ -0,0 +1,121 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: setenv.c,v 1.4 2001/07/09 06:57:45 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * setenv --
43 * Set the value of the environmental variable "name" to be
44 * "value". If rewrite is set, replace any current value.
45 */
46int
47setenv(name, value, rewrite)
48 register const char *name;
49 register const char *value;
50 int rewrite;
51{
52 extern char **environ;
53 static int alloced; /* if allocated space before */
54 register char *C;
55 int l_value, offset;
56 char *__findenv();
57
58 if (*value == '=') /* no `=' in value */
59 ++value;
60 l_value = strlen(value);
61 if ((C = __findenv(name, &offset))) { /* find if already exists */
62 if (!rewrite)
63 return (0);
64 if (strlen(C) >= l_value) { /* old larger; copy over */
65 while ((*C++ = *value++))
66 ;
67 return (0);
68 }
69 } else { /* create new slot */
70 register int cnt;
71 register char **P;
72
73 for (P = environ, cnt = 0; *P; ++P, ++cnt);
74 if (alloced) { /* just increase size */
75 P = (char **)realloc((void *)environ,
76 (size_t)(sizeof(char *) * (cnt + 2)));
77 if (!P)
78 return (-1);
79 environ = P;
80 }
81 else { /* get new space */
82 alloced = 1; /* copy old entries into it */
83 P = (char **)malloc((size_t)(sizeof(char *) *
84 (cnt + 2)));
85 if (!P)
86 return (-1);
87 bcopy(environ, P, cnt * sizeof(char *));
88 environ = P;
89 }
90 environ[cnt + 1] = NULL;
91 offset = cnt;
92 }
93 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
94 if (!(environ[offset] = /* name + `=' + value */
95 malloc((size_t)((int)(C - name) + l_value + 2))))
96 return (-1);
97 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
98 ;
99 for (*C++ = '='; (*C++ = *value++); )
100 ;
101 return (0);
102}
103
104/*
105 * unsetenv(name) --
106 * Delete environmental variable "name".
107 */
108void
109unsetenv(name)
110 const char *name;
111{
112 extern char **environ;
113 register char **P;
114 int offset;
115 char *__findenv();
116
117 while (__findenv(name, &offset)) /* if set multiple times */
118 for (P = &environ[offset];; ++P)
119 if (!(*P = *(P + 1)))
120 break;
121}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
new file mode 100644
index 0000000000..fcff8a172e
--- /dev/null
+++ b/src/lib/libc/stdlib/srand48.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 */
13
14#if defined(LIBC_SCCS) && !defined(lint)
15static char rcsid[] = "$OpenBSD: srand48.c,v 1.2 1996/08/19 08:33:49 tholo Exp $";
16#endif /* LIBC_SCCS and not lint */
17
18#include "rand48.h"
19
20extern unsigned short __rand48_seed[3];
21extern unsigned short __rand48_mult[3];
22extern unsigned short __rand48_add;
23
24void
25srand48(long seed)
26{
27 __rand48_seed[0] = RAND48_SEED_0;
28 __rand48_seed[1] = (unsigned short) seed;
29 __rand48_seed[2] = (unsigned short) (seed >> 16);
30 __rand48_mult[0] = RAND48_MULT_0;
31 __rand48_mult[1] = RAND48_MULT_1;
32 __rand48_mult[2] = RAND48_MULT_2;
33 __rand48_add = RAND48_ADD;
34}
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
new file mode 100644
index 0000000000..4e04f6738e
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.3
@@ -0,0 +1,117 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtod.3,v 1.7 2000/04/20 13:50:03 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRTOD 3
40.Os
41.Sh NAME
42.Nm strtod
43.Nd convert
44.Tn ASCII
45string to double
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Ft double
49.Fn strtod "const char *nptr" "char **endptr"
50.Sh DESCRIPTION
51The
52.Fn strtod
53function converts the initial portion of the string pointed to by
54.Fa nptr
55to
56.Li double
57representation.
58.Pp
59The expected form of the string is an optional plus
60.Pq Ql +
61or minus sign
62.Pq Ql -
63followed by a sequence of digits optionally containing
64a decimal-point character, optionally followed by an exponent.
65An exponent consists of an
66.Sq E
67or
68.Sq e ,
69followed by an optional plus or minus sign, followed by a sequence of digits.
70.Pp
71Leading whitespace characters in the string (as defined by the
72.Xr isspace 3
73function) are skipped.
74.Sh RETURN VALUES
75The
76.Fn strtod
77function returns the converted value, if any.
78.Pp
79If
80.Fa endptr
81is not
82.Dv NULL ,
83a pointer to the character after the last character used
84in the conversion is stored in the location referenced by
85.Fa endptr .
86.Pp
87If no conversion is performed, zero is returned and the value of
88.Fa nptr
89is stored in the location referenced by
90.Fa endptr .
91.Pp
92If the correct value would cause overflow, plus or minus
93.Dv HUGE_VAL
94is returned (according to the sign of the value), and
95.Er ERANGE
96is stored in
97.Va errno .
98If the correct value would cause underflow, zero is returned and
99.Er ERANGE
100is stored in
101.Va errno .
102.Sh ERRORS
103.Bl -tag -width Er
104.It Bq Er ERANGE
105Overflow or underflow occurred.
106.El
107.Sh SEE ALSO
108.Xr atof 3 ,
109.Xr atoi 3 ,
110.Xr atol 3 ,
111.Xr strtol 3 ,
112.Xr strtoul 3
113.Sh STANDARDS
114The
115.Fn strtod
116function conforms to
117.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
new file mode 100644
index 0000000000..ce7ce9fe56
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.c
@@ -0,0 +1,2528 @@
1/****************************************************************
2 *
3 * The author of this software is David M. Gay.
4 *
5 * Copyright (c) 1991 by AT&T.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose without fee is hereby granted, provided that this entire notice
9 * is included in all copies of any software which is or includes a copy
10 * or modification of this software and in all copies of the supporting
11 * documentation for such software.
12 *
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17 *
18 ***************************************************************/
19
20/* Please send bug reports to
21 David M. Gay
22 AT&T Bell Laboratories, Room 2C-463
23 600 Mountain Avenue
24 Murray Hill, NJ 07974-2070
25 U.S.A.
26 dmg@research.att.com or research!dmg
27 */
28
29/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
30 *
31 * This strtod returns a nearest machine number to the input decimal
32 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
33 * broken by the IEEE round-even rule. Otherwise ties are broken by
34 * biased rounding (add half and chop).
35 *
36 * Inspired loosely by William D. Clinger's paper "How to Read Floating
37 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
38 *
39 * Modifications:
40 *
41 * 1. We only require IEEE, IBM, or VAX double-precision
42 * arithmetic (not IEEE double-extended).
43 * 2. We get by with floating-point arithmetic in a case that
44 * Clinger missed -- when we're computing d * 10^n
45 * for a small integer d and the integer n is not too
46 * much larger than 22 (the maximum integer k for which
47 * we can represent 10^k exactly), we may be able to
48 * compute (d*10^k) * 10^(e-k) with just one roundoff.
49 * 3. Rather than a bit-at-a-time adjustment of the binary
50 * result in the hard case, we use floating-point
51 * arithmetic to determine the adjustment to within
52 * one bit; only in really hard cases do we need to
53 * compute a second residual.
54 * 4. Because of 3., we don't need a large table of powers of 10
55 * for ten-to-e (just some small tables, e.g. of 10^k
56 * for 0 <= k <= 22).
57 */
58
59/*
60 * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
61 * significant byte has the lowest address.
62 * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
63 * significant byte has the lowest address.
64 * #define Long int on machines with 32-bit ints and 64-bit longs.
65 * #define Sudden_Underflow for IEEE-format machines without gradual
66 * underflow (i.e., that flush to zero on underflow).
67 * #define IBM for IBM mainframe-style floating-point arithmetic.
68 * #define VAX for VAX-style floating-point arithmetic.
69 * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
70 * #define No_leftright to omit left-right logic in fast floating-point
71 * computation of dtoa.
72 * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
73 * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
74 * that use extended-precision instructions to compute rounded
75 * products and quotients) with IBM.
76 * #define ROUND_BIASED for IEEE-format with biased rounding.
77 * #define Inaccurate_Divide for IEEE-format with correctly rounded
78 * products but inaccurate quotients, e.g., for Intel i860.
79 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
80 * integer arithmetic. Whether this speeds things up or slows things
81 * down depends on the machine and the number being converted.
82 * #define KR_headers for old-style C function headers.
83 * #define Bad_float_h if your system lacks a float.h or if it does not
84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
86 * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
87 * if memory is available and otherwise does something you deem
88 * appropriate. If MALLOC is undefined, malloc will be invoked
89 * directly -- and assumed always to succeed.
90 */
91
92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$OpenBSD: strtod.c,v 1.15 2002/02/19 19:39:37 millert Exp $";
94#endif /* LIBC_SCCS and not lint */
95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
98 defined(__powerpc__) || defined(__m88k__) || defined(__hppa__)
99#include <sys/types.h>
100#if BYTE_ORDER == BIG_ENDIAN
101#define IEEE_BIG_ENDIAN
102#else
103#define IEEE_LITTLE_ENDIAN
104#endif
105#endif
106
107#ifdef __arm32__
108/*
109 * Although the CPU is little endian the FP has different
110 * byte and word endianness. The byte order is still little endian
111 * but the word order is big endian.
112 */
113#define IEEE_BIG_ENDIAN
114#endif
115
116#ifdef __vax__
117#define VAX
118#endif
119
120#define Long int32_t
121#define ULong u_int32_t
122
123#ifdef DEBUG
124#include "stdio.h"
125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
126#endif
127
128#ifdef __cplusplus
129#include "malloc.h"
130#include "memory.h"
131#else
132#ifndef KR_headers
133#include "stdlib.h"
134#include "string.h"
135#include "locale.h"
136#else
137#include "malloc.h"
138#include "memory.h"
139#endif
140#endif
141
142#ifdef MALLOC
143#ifdef KR_headers
144extern char *MALLOC();
145#else
146extern void *MALLOC(size_t);
147#endif
148#else
149#define MALLOC malloc
150#endif
151
152#include "ctype.h"
153#include "errno.h"
154
155#ifdef Bad_float_h
156#ifdef IEEE_BIG_ENDIAN
157#define IEEE_ARITHMETIC
158#endif
159#ifdef IEEE_LITTLE_ENDIAN
160#define IEEE_ARITHMETIC
161#endif
162
163#ifdef IEEE_ARITHMETIC
164#define DBL_DIG 15
165#define DBL_MAX_10_EXP 308
166#define DBL_MAX_EXP 1024
167#define FLT_RADIX 2
168#define FLT_ROUNDS 1
169#define DBL_MAX 1.7976931348623157e+308
170#endif
171
172#ifdef IBM
173#define DBL_DIG 16
174#define DBL_MAX_10_EXP 75
175#define DBL_MAX_EXP 63
176#define FLT_RADIX 16
177#define FLT_ROUNDS 0
178#define DBL_MAX 7.2370055773322621e+75
179#endif
180
181#ifdef VAX
182#define DBL_DIG 16
183#define DBL_MAX_10_EXP 38
184#define DBL_MAX_EXP 127
185#define FLT_RADIX 2
186#define FLT_ROUNDS 1
187#define DBL_MAX 1.7014118346046923e+38
188#endif
189
190#ifndef LONG_MAX
191#define LONG_MAX 2147483647
192#endif
193#else
194#include "float.h"
195#endif
196#ifndef __MATH_H__
197#include "math.h"
198#endif
199
200#ifdef __cplusplus
201extern "C" {
202#endif
203
204#ifndef CONST
205#ifdef KR_headers
206#define CONST /* blank */
207#else
208#define CONST const
209#endif
210#endif
211
212#ifdef Unsigned_Shifts
213#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
214#else
215#define Sign_Extend(a,b) /*no-op*/
216#endif
217
218#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
219 defined(IBM) != 1
220Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
221IBM should be defined.
222#endif
223
224typedef union {
225 double d;
226 ULong ul[2];
227} _double;
228#define value(x) ((x).d)
229#ifdef IEEE_LITTLE_ENDIAN
230#define word0(x) ((x).ul[1])
231#define word1(x) ((x).ul[0])
232#else
233#define word0(x) ((x).ul[0])
234#define word1(x) ((x).ul[1])
235#endif
236
237/* The following definition of Storeinc is appropriate for MIPS processors.
238 * An alternative that might be better on some machines is
239 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
240 */
241#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
242#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
243((unsigned short *)a)[0] = (unsigned short)c, a++)
244#else
245#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
246((unsigned short *)a)[1] = (unsigned short)c, a++)
247#endif
248
249/* #define P DBL_MANT_DIG */
250/* Ten_pmax = floor(P*log(2)/log(5)) */
251/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
252/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
253/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
254
255#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN)
256#define Exp_shift 20
257#define Exp_shift1 20
258#define Exp_msk1 0x100000
259#define Exp_msk11 0x100000
260#define Exp_mask 0x7ff00000
261#define P 53
262#define Bias 1023
263#define IEEE_Arith
264#define Emin (-1022)
265#define Exp_1 0x3ff00000
266#define Exp_11 0x3ff00000
267#define Ebits 11
268#define Frac_mask 0xfffff
269#define Frac_mask1 0xfffff
270#define Ten_pmax 22
271#define Bletch 0x10
272#define Bndry_mask 0xfffff
273#define Bndry_mask1 0xfffff
274#define LSB 1
275#define Sign_bit 0x80000000
276#define Log2P 1
277#define Tiny0 0
278#define Tiny1 1
279#define Quick_max 14
280#define Int_max 14
281#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
282#else
283#undef Sudden_Underflow
284#define Sudden_Underflow
285#ifdef IBM
286#define Exp_shift 24
287#define Exp_shift1 24
288#define Exp_msk1 0x1000000
289#define Exp_msk11 0x1000000
290#define Exp_mask 0x7f000000
291#define P 14
292#define Bias 65
293#define Exp_1 0x41000000
294#define Exp_11 0x41000000
295#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
296#define Frac_mask 0xffffff
297#define Frac_mask1 0xffffff
298#define Bletch 4
299#define Ten_pmax 22
300#define Bndry_mask 0xefffff
301#define Bndry_mask1 0xffffff
302#define LSB 1
303#define Sign_bit 0x80000000
304#define Log2P 4
305#define Tiny0 0x100000
306#define Tiny1 0
307#define Quick_max 14
308#define Int_max 15
309#else /* VAX */
310#define Exp_shift 23
311#define Exp_shift1 7
312#define Exp_msk1 0x80
313#define Exp_msk11 0x800000
314#define Exp_mask 0x7f80
315#define P 56
316#define Bias 129
317#define Exp_1 0x40800000
318#define Exp_11 0x4080
319#define Ebits 8
320#define Frac_mask 0x7fffff
321#define Frac_mask1 0xffff007f
322#define Ten_pmax 24
323#define Bletch 2
324#define Bndry_mask 0xffff007f
325#define Bndry_mask1 0xffff007f
326#define LSB 0x10000
327#define Sign_bit 0x8000
328#define Log2P 1
329#define Tiny0 0x80
330#define Tiny1 0
331#define Quick_max 15
332#define Int_max 15
333#endif
334#endif
335
336#ifndef IEEE_Arith
337#define ROUND_BIASED
338#endif
339
340#ifdef RND_PRODQUOT
341#define rounded_product(a,b) a = rnd_prod(a, b)
342#define rounded_quotient(a,b) a = rnd_quot(a, b)
343#ifdef KR_headers
344extern double rnd_prod(), rnd_quot();
345#else
346extern double rnd_prod(double, double), rnd_quot(double, double);
347#endif
348#else
349#define rounded_product(a,b) a *= b
350#define rounded_quotient(a,b) a /= b
351#endif
352
353#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
354#define Big1 0xffffffff
355
356#ifndef Just_16
357/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
358 * This makes some inner loops simpler and sometimes saves work
359 * during multiplications, but it often seems to make things slightly
360 * slower. Hence the default is now to store 32 bits per Long.
361 */
362#ifndef Pack_32
363#define Pack_32
364#endif
365#endif
366
367#define Kmax 15
368
369#ifdef __cplusplus
370extern "C" double strtod(const char *s00, char **se);
371extern "C" char *__dtoa(double d, int mode, int ndigits,
372 int *decpt, int *sign, char **rve);
373#endif
374
375 struct
376Bigint {
377 struct Bigint *next;
378 int k, maxwds, sign, wds;
379 ULong x[1];
380 };
381
382 typedef struct Bigint Bigint;
383
384 static Bigint *freelist[Kmax+1];
385
386 static Bigint *
387Balloc
388#ifdef KR_headers
389 (k) int k;
390#else
391 (int k)
392#endif
393{
394 int x;
395 Bigint *rv;
396
397 if ((rv = freelist[k])) {
398 freelist[k] = rv->next;
399 }
400 else {
401 x = 1 << k;
402 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
403 rv->k = k;
404 rv->maxwds = x;
405 }
406 rv->sign = rv->wds = 0;
407 return rv;
408 }
409
410 static void
411Bfree
412#ifdef KR_headers
413 (v) Bigint *v;
414#else
415 (Bigint *v)
416#endif
417{
418 if (v) {
419 v->next = freelist[v->k];
420 freelist[v->k] = v;
421 }
422 }
423
424#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
425y->wds*sizeof(Long) + 2*sizeof(int))
426
427 static Bigint *
428multadd
429#ifdef KR_headers
430 (b, m, a) Bigint *b; int m, a;
431#else
432 (Bigint *b, int m, int a) /* multiply by m and add a */
433#endif
434{
435 int i, wds;
436 ULong *x, y;
437#ifdef Pack_32
438 ULong xi, z;
439#endif
440 Bigint *b1;
441
442 wds = b->wds;
443 x = b->x;
444 i = 0;
445 do {
446#ifdef Pack_32
447 xi = *x;
448 y = (xi & 0xffff) * m + a;
449 z = (xi >> 16) * m + (y >> 16);
450 a = (int)(z >> 16);
451 *x++ = (z << 16) + (y & 0xffff);
452#else
453 y = *x * m + a;
454 a = (int)(y >> 16);
455 *x++ = y & 0xffff;
456#endif
457 }
458 while(++i < wds);
459 if (a) {
460 if (wds >= b->maxwds) {
461 b1 = Balloc(b->k+1);
462 Bcopy(b1, b);
463 Bfree(b);
464 b = b1;
465 }
466 b->x[wds++] = a;
467 b->wds = wds;
468 }
469 return b;
470 }
471
472 static Bigint *
473s2b
474#ifdef KR_headers
475 (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
476#else
477 (CONST char *s, int nd0, int nd, ULong y9)
478#endif
479{
480 Bigint *b;
481 int i, k;
482 Long x, y;
483
484 x = (nd + 8) / 9;
485 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
486#ifdef Pack_32
487 b = Balloc(k);
488 b->x[0] = y9;
489 b->wds = 1;
490#else
491 b = Balloc(k+1);
492 b->x[0] = y9 & 0xffff;
493 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
494#endif
495
496 i = 9;
497 if (9 < nd0) {
498 s += 9;
499 do b = multadd(b, 10, *s++ - '0');
500 while(++i < nd0);
501 s++;
502 }
503 else
504 s += 10;
505 for(; i < nd; i++)
506 b = multadd(b, 10, *s++ - '0');
507 return b;
508 }
509
510 static int
511hi0bits
512#ifdef KR_headers
513 (x) register ULong x;
514#else
515 (register ULong x)
516#endif
517{
518 register int k = 0;
519
520 if (!(x & 0xffff0000)) {
521 k = 16;
522 x <<= 16;
523 }
524 if (!(x & 0xff000000)) {
525 k += 8;
526 x <<= 8;
527 }
528 if (!(x & 0xf0000000)) {
529 k += 4;
530 x <<= 4;
531 }
532 if (!(x & 0xc0000000)) {
533 k += 2;
534 x <<= 2;
535 }
536 if (!(x & 0x80000000)) {
537 k++;
538 if (!(x & 0x40000000))
539 return 32;
540 }
541 return k;
542 }
543
544 static int
545lo0bits
546#ifdef KR_headers
547 (y) ULong *y;
548#else
549 (ULong *y)
550#endif
551{
552 register int k;
553 register ULong x = *y;
554
555 if (x & 7) {
556 if (x & 1)
557 return 0;
558 if (x & 2) {
559 *y = x >> 1;
560 return 1;
561 }
562 *y = x >> 2;
563 return 2;
564 }
565 k = 0;
566 if (!(x & 0xffff)) {
567 k = 16;
568 x >>= 16;
569 }
570 if (!(x & 0xff)) {
571 k += 8;
572 x >>= 8;
573 }
574 if (!(x & 0xf)) {
575 k += 4;
576 x >>= 4;
577 }
578 if (!(x & 0x3)) {
579 k += 2;
580 x >>= 2;
581 }
582 if (!(x & 1)) {
583 k++;
584 x >>= 1;
585 if (!x & 1)
586 return 32;
587 }
588 *y = x;
589 return k;
590 }
591
592 static Bigint *
593i2b
594#ifdef KR_headers
595 (i) int i;
596#else
597 (int i)
598#endif
599{
600 Bigint *b;
601
602 b = Balloc(1);
603 b->x[0] = i;
604 b->wds = 1;
605 return b;
606 }
607
608 static Bigint *
609mult
610#ifdef KR_headers
611 (a, b) Bigint *a, *b;
612#else
613 (Bigint *a, Bigint *b)
614#endif
615{
616 Bigint *c;
617 int k, wa, wb, wc;
618 ULong carry, y, z;
619 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
620#ifdef Pack_32
621 ULong z2;
622#endif
623
624 if (a->wds < b->wds) {
625 c = a;
626 a = b;
627 b = c;
628 }
629 k = a->k;
630 wa = a->wds;
631 wb = b->wds;
632 wc = wa + wb;
633 if (wc > a->maxwds)
634 k++;
635 c = Balloc(k);
636 for(x = c->x, xa = x + wc; x < xa; x++)
637 *x = 0;
638 xa = a->x;
639 xae = xa + wa;
640 xb = b->x;
641 xbe = xb + wb;
642 xc0 = c->x;
643#ifdef Pack_32
644 for(; xb < xbe; xb++, xc0++) {
645 if ((y = *xb & 0xffff)) {
646 x = xa;
647 xc = xc0;
648 carry = 0;
649 do {
650 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
651 carry = z >> 16;
652 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
653 carry = z2 >> 16;
654 Storeinc(xc, z2, z);
655 }
656 while(x < xae);
657 *xc = carry;
658 }
659 if ((y = *xb >> 16)) {
660 x = xa;
661 xc = xc0;
662 carry = 0;
663 z2 = *xc;
664 do {
665 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
666 carry = z >> 16;
667 Storeinc(xc, z, z2);
668 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
669 carry = z2 >> 16;
670 }
671 while(x < xae);
672 *xc = z2;
673 }
674 }
675#else
676 for(; xb < xbe; xc0++) {
677 if (y = *xb++) {
678 x = xa;
679 xc = xc0;
680 carry = 0;
681 do {
682 z = *x++ * y + *xc + carry;
683 carry = z >> 16;
684 *xc++ = z & 0xffff;
685 }
686 while(x < xae);
687 *xc = carry;
688 }
689 }
690#endif
691 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
692 c->wds = wc;
693 return c;
694 }
695
696 static Bigint *p5s;
697
698 static Bigint *
699pow5mult
700#ifdef KR_headers
701 (b, k) Bigint *b; int k;
702#else
703 (Bigint *b, int k)
704#endif
705{
706 Bigint *b1, *p5, *p51;
707 int i;
708 static int p05[3] = { 5, 25, 125 };
709
710 if ((i = k & 3))
711 b = multadd(b, p05[i-1], 0);
712
713 if (!(k >>= 2))
714 return b;
715 if (!(p5 = p5s)) {
716 /* first time */
717 p5 = p5s = i2b(625);
718 p5->next = 0;
719 }
720 for(;;) {
721 if (k & 1) {
722 b1 = mult(b, p5);
723 Bfree(b);
724 b = b1;
725 }
726 if (!(k >>= 1))
727 break;
728 if (!(p51 = p5->next)) {
729 p51 = p5->next = mult(p5,p5);
730 p51->next = 0;
731 }
732 p5 = p51;
733 }
734 return b;
735 }
736
737 static Bigint *
738lshift
739#ifdef KR_headers
740 (b, k) Bigint *b; int k;
741#else
742 (Bigint *b, int k)
743#endif
744{
745 int i, k1, n, n1;
746 Bigint *b1;
747 ULong *x, *x1, *xe, z;
748
749#ifdef Pack_32
750 n = k >> 5;
751#else
752 n = k >> 4;
753#endif
754 k1 = b->k;
755 n1 = n + b->wds + 1;
756 for(i = b->maxwds; n1 > i; i <<= 1)
757 k1++;
758 b1 = Balloc(k1);
759 x1 = b1->x;
760 for(i = 0; i < n; i++)
761 *x1++ = 0;
762 x = b->x;
763 xe = x + b->wds;
764#ifdef Pack_32
765 if (k &= 0x1f) {
766 k1 = 32 - k;
767 z = 0;
768 do {
769 *x1++ = *x << k | z;
770 z = *x++ >> k1;
771 }
772 while(x < xe);
773 if ((*x1 = z))
774 ++n1;
775 }
776#else
777 if (k &= 0xf) {
778 k1 = 16 - k;
779 z = 0;
780 do {
781 *x1++ = *x << k & 0xffff | z;
782 z = *x++ >> k1;
783 }
784 while(x < xe);
785 if (*x1 = z)
786 ++n1;
787 }
788#endif
789 else do
790 *x1++ = *x++;
791 while(x < xe);
792 b1->wds = n1 - 1;
793 Bfree(b);
794 return b1;
795 }
796
797 static int
798cmp
799#ifdef KR_headers
800 (a, b) Bigint *a, *b;
801#else
802 (Bigint *a, Bigint *b)
803#endif
804{
805 ULong *xa, *xa0, *xb, *xb0;
806 int i, j;
807
808 i = a->wds;
809 j = b->wds;
810#ifdef DEBUG
811 if (i > 1 && !a->x[i-1])
812 Bug("cmp called with a->x[a->wds-1] == 0");
813 if (j > 1 && !b->x[j-1])
814 Bug("cmp called with b->x[b->wds-1] == 0");
815#endif
816 if (i -= j)
817 return i;
818 xa0 = a->x;
819 xa = xa0 + j;
820 xb0 = b->x;
821 xb = xb0 + j;
822 for(;;) {
823 if (*--xa != *--xb)
824 return *xa < *xb ? -1 : 1;
825 if (xa <= xa0)
826 break;
827 }
828 return 0;
829 }
830
831 static Bigint *
832diff
833#ifdef KR_headers
834 (a, b) Bigint *a, *b;
835#else
836 (Bigint *a, Bigint *b)
837#endif
838{
839 Bigint *c;
840 int i, wa, wb;
841 Long borrow, y; /* We need signed shifts here. */
842 ULong *xa, *xae, *xb, *xbe, *xc;
843#ifdef Pack_32
844 Long z;
845#endif
846
847 i = cmp(a,b);
848 if (!i) {
849 c = Balloc(0);
850 c->wds = 1;
851 c->x[0] = 0;
852 return c;
853 }
854 if (i < 0) {
855 c = a;
856 a = b;
857 b = c;
858 i = 1;
859 }
860 else
861 i = 0;
862 c = Balloc(a->k);
863 c->sign = i;
864 wa = a->wds;
865 xa = a->x;
866 xae = xa + wa;
867 wb = b->wds;
868 xb = b->x;
869 xbe = xb + wb;
870 xc = c->x;
871 borrow = 0;
872#ifdef Pack_32
873 do {
874 y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
875 borrow = y >> 16;
876 Sign_Extend(borrow, y);
877 z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
878 borrow = z >> 16;
879 Sign_Extend(borrow, z);
880 Storeinc(xc, z, y);
881 }
882 while(xb < xbe);
883 while(xa < xae) {
884 y = (*xa & 0xffff) + borrow;
885 borrow = y >> 16;
886 Sign_Extend(borrow, y);
887 z = (*xa++ >> 16) + borrow;
888 borrow = z >> 16;
889 Sign_Extend(borrow, z);
890 Storeinc(xc, z, y);
891 }
892#else
893 do {
894 y = *xa++ - *xb++ + borrow;
895 borrow = y >> 16;
896 Sign_Extend(borrow, y);
897 *xc++ = y & 0xffff;
898 }
899 while(xb < xbe);
900 while(xa < xae) {
901 y = *xa++ + borrow;
902 borrow = y >> 16;
903 Sign_Extend(borrow, y);
904 *xc++ = y & 0xffff;
905 }
906#endif
907 while(!*--xc)
908 wa--;
909 c->wds = wa;
910 return c;
911 }
912
913 static double
914ulp
915#ifdef KR_headers
916 (_x) double _x;
917#else
918 (double _x)
919#endif
920{
921 _double x;
922 register Long L;
923 _double a;
924
925 value(x) = _x;
926 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
927#ifndef Sudden_Underflow
928 if (L > 0) {
929#endif
930#ifdef IBM
931 L |= Exp_msk1 >> 4;
932#endif
933 word0(a) = L;
934 word1(a) = 0;
935#ifndef Sudden_Underflow
936 }
937 else {
938 L = -L >> Exp_shift;
939 if (L < Exp_shift) {
940 word0(a) = 0x80000 >> L;
941 word1(a) = 0;
942 }
943 else {
944 word0(a) = 0;
945 L -= Exp_shift;
946 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
947 }
948 }
949#endif
950 return value(a);
951 }
952
953 static double
954b2d
955#ifdef KR_headers
956 (a, e) Bigint *a; int *e;
957#else
958 (Bigint *a, int *e)
959#endif
960{
961 ULong *xa, *xa0, w, y, z;
962 int k;
963 _double d;
964#ifdef VAX
965 ULong d0, d1;
966#else
967#define d0 word0(d)
968#define d1 word1(d)
969#endif
970
971 xa0 = a->x;
972 xa = xa0 + a->wds;
973 y = *--xa;
974#ifdef DEBUG
975 if (!y) Bug("zero y in b2d");
976#endif
977 k = hi0bits(y);
978 *e = 32 - k;
979#ifdef Pack_32
980 if (k < Ebits) {
981 d0 = Exp_1 | y >> Ebits - k;
982 w = xa > xa0 ? *--xa : 0;
983 d1 = y << (32-Ebits) + k | w >> Ebits - k;
984 goto ret_d;
985 }
986 z = xa > xa0 ? *--xa : 0;
987 if (k -= Ebits) {
988 d0 = Exp_1 | y << k | z >> 32 - k;
989 y = xa > xa0 ? *--xa : 0;
990 d1 = z << k | y >> 32 - k;
991 }
992 else {
993 d0 = Exp_1 | y;
994 d1 = z;
995 }
996#else
997 if (k < Ebits + 16) {
998 z = xa > xa0 ? *--xa : 0;
999 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1000 w = xa > xa0 ? *--xa : 0;
1001 y = xa > xa0 ? *--xa : 0;
1002 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1003 goto ret_d;
1004 }
1005 z = xa > xa0 ? *--xa : 0;
1006 w = xa > xa0 ? *--xa : 0;
1007 k -= Ebits + 16;
1008 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1009 y = xa > xa0 ? *--xa : 0;
1010 d1 = w << k + 16 | y << k;
1011#endif
1012 ret_d:
1013#ifdef VAX
1014 word0(d) = d0 >> 16 | d0 << 16;
1015 word1(d) = d1 >> 16 | d1 << 16;
1016#else
1017#undef d0
1018#undef d1
1019#endif
1020 return value(d);
1021 }
1022
1023 static Bigint *
1024d2b
1025#ifdef KR_headers
1026 (_d, e, bits) double d; int *e, *bits;
1027#else
1028 (double _d, int *e, int *bits)
1029#endif
1030{
1031 Bigint *b;
1032 int de, i, k;
1033 ULong *x, y, z;
1034 _double d;
1035#ifdef VAX
1036 ULong d0, d1;
1037#endif
1038
1039 value(d) = _d;
1040#ifdef VAX
1041 d0 = word0(d) >> 16 | word0(d) << 16;
1042 d1 = word1(d) >> 16 | word1(d) << 16;
1043#else
1044#define d0 word0(d)
1045#define d1 word1(d)
1046#endif
1047
1048#ifdef Pack_32
1049 b = Balloc(1);
1050#else
1051 b = Balloc(2);
1052#endif
1053 x = b->x;
1054
1055 z = d0 & Frac_mask;
1056 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
1057#ifdef Sudden_Underflow
1058 de = (int)(d0 >> Exp_shift);
1059#ifndef IBM
1060 z |= Exp_msk11;
1061#endif
1062#else
1063 if (de = (int)(d0 >> Exp_shift))
1064 z |= Exp_msk1;
1065#endif
1066#ifdef Pack_32
1067 if (y = d1) {
1068 if (k = lo0bits(&y)) {
1069 x[0] = y | z << 32 - k;
1070 z >>= k;
1071 }
1072 else
1073 x[0] = y;
1074 i = b->wds = (x[1] = z) ? 2 : 1;
1075 }
1076 else {
1077#ifdef DEBUG
1078 if (!z)
1079 Bug("Zero passed to d2b");
1080#endif
1081 k = lo0bits(&z);
1082 x[0] = z;
1083 i = b->wds = 1;
1084 k += 32;
1085 }
1086#else
1087 if (y = d1) {
1088 if (k = lo0bits(&y))
1089 if (k >= 16) {
1090 x[0] = y | z << 32 - k & 0xffff;
1091 x[1] = z >> k - 16 & 0xffff;
1092 x[2] = z >> k;
1093 i = 2;
1094 }
1095 else {
1096 x[0] = y & 0xffff;
1097 x[1] = y >> 16 | z << 16 - k & 0xffff;
1098 x[2] = z >> k & 0xffff;
1099 x[3] = z >> k+16;
1100 i = 3;
1101 }
1102 else {
1103 x[0] = y & 0xffff;
1104 x[1] = y >> 16;
1105 x[2] = z & 0xffff;
1106 x[3] = z >> 16;
1107 i = 3;
1108 }
1109 }
1110 else {
1111#ifdef DEBUG
1112 if (!z)
1113 Bug("Zero passed to d2b");
1114#endif
1115 k = lo0bits(&z);
1116 if (k >= 16) {
1117 x[0] = z;
1118 i = 0;
1119 }
1120 else {
1121 x[0] = z & 0xffff;
1122 x[1] = z >> 16;
1123 i = 1;
1124 }
1125 k += 32;
1126 }
1127 while(!x[i])
1128 --i;
1129 b->wds = i + 1;
1130#endif
1131#ifndef Sudden_Underflow
1132 if (de) {
1133#endif
1134#ifdef IBM
1135 *e = (de - Bias - (P-1) << 2) + k;
1136 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1137#else
1138 *e = de - Bias - (P-1) + k;
1139 *bits = P - k;
1140#endif
1141#ifndef Sudden_Underflow
1142 }
1143 else {
1144 *e = de - Bias - (P-1) + 1 + k;
1145#ifdef Pack_32
1146 *bits = 32*i - hi0bits(x[i-1]);
1147#else
1148 *bits = (i+2)*16 - hi0bits(x[i]);
1149#endif
1150 }
1151#endif
1152 return b;
1153 }
1154#undef d0
1155#undef d1
1156
1157 static double
1158ratio
1159#ifdef KR_headers
1160 (a, b) Bigint *a, *b;
1161#else
1162 (Bigint *a, Bigint *b)
1163#endif
1164{
1165 _double da, db;
1166 int k, ka, kb;
1167
1168 value(da) = b2d(a, &ka);
1169 value(db) = b2d(b, &kb);
1170#ifdef Pack_32
1171 k = ka - kb + 32*(a->wds - b->wds);
1172#else
1173 k = ka - kb + 16*(a->wds - b->wds);
1174#endif
1175#ifdef IBM
1176 if (k > 0) {
1177 word0(da) += (k >> 2)*Exp_msk1;
1178 if (k &= 3)
1179 da *= 1 << k;
1180 }
1181 else {
1182 k = -k;
1183 word0(db) += (k >> 2)*Exp_msk1;
1184 if (k &= 3)
1185 db *= 1 << k;
1186 }
1187#else
1188 if (k > 0)
1189 word0(da) += k*Exp_msk1;
1190 else {
1191 k = -k;
1192 word0(db) += k*Exp_msk1;
1193 }
1194#endif
1195 return value(da) / value(db);
1196 }
1197
1198static CONST double
1199tens[] = {
1200 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1201 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1202 1e20, 1e21, 1e22
1203#ifdef VAX
1204 , 1e23, 1e24
1205#endif
1206 };
1207
1208#ifdef IEEE_Arith
1209static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1210static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
1211#define n_bigtens 5
1212#else
1213#ifdef IBM
1214static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
1215static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1216#define n_bigtens 3
1217#else
1218static CONST double bigtens[] = { 1e16, 1e32 };
1219static CONST double tinytens[] = { 1e-16, 1e-32 };
1220#define n_bigtens 2
1221#endif
1222#endif
1223
1224 double
1225strtod
1226#ifdef KR_headers
1227 (s00, se) CONST char *s00; char **se;
1228#else
1229 (CONST char *s00, char **se)
1230#endif
1231{
1232 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1233 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1234 CONST char *s, *s0, *s1;
1235 double aadj, aadj1, adj;
1236 _double rv, rv0;
1237 Long L;
1238 ULong y, z;
1239 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1240
1241#ifndef KR_headers
1242 CONST char decimal_point = localeconv()->decimal_point[0];
1243#else
1244 CONST char decimal_point = '.';
1245#endif
1246
1247 sign = nz0 = nz = 0;
1248 value(rv) = 0.;
1249
1250
1251 for(s = s00; isspace((unsigned char) *s); s++)
1252 ;
1253
1254 if (*s == '-') {
1255 sign = 1;
1256 s++;
1257 } else if (*s == '+') {
1258 s++;
1259 }
1260
1261 if (*s == '\0') {
1262 s = s00;
1263 goto ret;
1264 }
1265
1266 if (*s == '0') {
1267 nz0 = 1;
1268 while(*++s == '0') ;
1269 if (!*s)
1270 goto ret;
1271 }
1272 s0 = s;
1273 y = z = 0;
1274 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
1275 if (nd < 9)
1276 y = 10*y + c - '0';
1277 else if (nd < 16)
1278 z = 10*z + c - '0';
1279 nd0 = nd;
1280 if (c == decimal_point) {
1281 c = *++s;
1282 if (!nd) {
1283 for(; c == '0'; c = *++s)
1284 nz++;
1285 if (c > '0' && c <= '9') {
1286 s0 = s;
1287 nf += nz;
1288 nz = 0;
1289 goto have_dig;
1290 }
1291 goto dig_done;
1292 }
1293 for(; c >= '0' && c <= '9'; c = *++s) {
1294 have_dig:
1295 nz++;
1296 if (c -= '0') {
1297 nf += nz;
1298 for(i = 1; i < nz; i++)
1299 if (nd++ < 9)
1300 y *= 10;
1301 else if (nd <= DBL_DIG + 1)
1302 z *= 10;
1303 if (nd++ < 9)
1304 y = 10*y + c;
1305 else if (nd <= DBL_DIG + 1)
1306 z = 10*z + c;
1307 nz = 0;
1308 }
1309 }
1310 }
1311 dig_done:
1312 e = 0;
1313 if (c == 'e' || c == 'E') {
1314 if (!nd && !nz && !nz0) {
1315 s = s00;
1316 goto ret;
1317 }
1318 s00 = s;
1319 esign = 0;
1320 switch(c = *++s) {
1321 case '-':
1322 esign = 1;
1323 case '+':
1324 c = *++s;
1325 }
1326 if (c >= '0' && c <= '9') {
1327 while(c == '0')
1328 c = *++s;
1329 if (c > '0' && c <= '9') {
1330 L = c - '0';
1331 s1 = s;
1332 while((c = *++s) >= '0' && c <= '9')
1333 L = 10*L + c - '0';
1334 if (s - s1 > 8 || L > 19999)
1335 /* Avoid confusion from exponents
1336 * so large that e might overflow.
1337 */
1338 e = 19999; /* safe for 16 bit ints */
1339 else
1340 e = (int)L;
1341 if (esign)
1342 e = -e;
1343 }
1344 else
1345 e = 0;
1346 }
1347 else
1348 s = s00;
1349 }
1350 if (!nd) {
1351 if (!nz && !nz0)
1352 s = s00;
1353 goto ret;
1354 }
1355 e1 = e -= nf;
1356
1357 /* Now we have nd0 digits, starting at s0, followed by a
1358 * decimal point, followed by nd-nd0 digits. The number we're
1359 * after is the integer represented by those digits times
1360 * 10**e */
1361
1362 if (!nd0)
1363 nd0 = nd;
1364 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1365 value(rv) = y;
1366 if (k > 9)
1367 value(rv) = tens[k - 9] * value(rv) + z;
1368 bd0 = 0;
1369 if (nd <= DBL_DIG
1370#ifndef RND_PRODQUOT
1371 && FLT_ROUNDS == 1
1372#endif
1373 ) {
1374 if (!e)
1375 goto ret;
1376 if (e > 0) {
1377 if (e <= Ten_pmax) {
1378#ifdef VAX
1379 goto vax_ovfl_check;
1380#else
1381 /* value(rv) = */ rounded_product(value(rv),
1382 tens[e]);
1383 goto ret;
1384#endif
1385 }
1386 i = DBL_DIG - nd;
1387 if (e <= Ten_pmax + i) {
1388 /* A fancier test would sometimes let us do
1389 * this for larger i values.
1390 */
1391 e -= i;
1392 value(rv) *= tens[i];
1393#ifdef VAX
1394 /* VAX exponent range is so narrow we must
1395 * worry about overflow here...
1396 */
1397 vax_ovfl_check:
1398 word0(rv) -= P*Exp_msk1;
1399 /* value(rv) = */ rounded_product(value(rv),
1400 tens[e]);
1401 if ((word0(rv) & Exp_mask)
1402 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1403 goto ovfl;
1404 word0(rv) += P*Exp_msk1;
1405#else
1406 /* value(rv) = */ rounded_product(value(rv),
1407 tens[e]);
1408#endif
1409 goto ret;
1410 }
1411 }
1412#ifndef Inaccurate_Divide
1413 else if (e >= -Ten_pmax) {
1414 /* value(rv) = */ rounded_quotient(value(rv),
1415 tens[-e]);
1416 goto ret;
1417 }
1418#endif
1419 }
1420 e1 += nd - k;
1421
1422 /* Get starting approximation = rv * 10**e1 */
1423
1424 if (e1 > 0) {
1425 if (i = e1 & 15)
1426 value(rv) *= tens[i];
1427 if (e1 &= ~15) {
1428 if (e1 > DBL_MAX_10_EXP) {
1429 ovfl:
1430 errno = ERANGE;
1431#ifndef Bad_float_h
1432 value(rv) = HUGE_VAL;
1433#else
1434 /* Can't trust HUGE_VAL */
1435#ifdef IEEE_Arith
1436 word0(rv) = Exp_mask;
1437 word1(rv) = 0;
1438#else
1439 word0(rv) = Big0;
1440 word1(rv) = Big1;
1441#endif
1442#endif
1443 if (bd0)
1444 goto retfree;
1445 goto ret;
1446 }
1447 if (e1 >>= 4) {
1448 for(j = 0; e1 > 1; j++, e1 >>= 1)
1449 if (e1 & 1)
1450 value(rv) *= bigtens[j];
1451 /* The last multiplication could overflow. */
1452 word0(rv) -= P*Exp_msk1;
1453 value(rv) *= bigtens[j];
1454 if ((z = word0(rv) & Exp_mask)
1455 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1456 goto ovfl;
1457 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1458 /* set to largest number */
1459 /* (Can't trust DBL_MAX) */
1460 word0(rv) = Big0;
1461 word1(rv) = Big1;
1462 }
1463 else
1464 word0(rv) += P*Exp_msk1;
1465 }
1466
1467 }
1468 }
1469 else if (e1 < 0) {
1470 e1 = -e1;
1471 if (i = e1 & 15)
1472 value(rv) /= tens[i];
1473 if (e1 &= ~15) {
1474 e1 >>= 4;
1475 if (e1 >= 1 << n_bigtens)
1476 goto undfl;
1477 for(j = 0; e1 > 1; j++, e1 >>= 1)
1478 if (e1 & 1)
1479 value(rv) *= tinytens[j];
1480 /* The last multiplication could underflow. */
1481 value(rv0) = value(rv);
1482 value(rv) *= tinytens[j];
1483 if (!value(rv)) {
1484 value(rv) = 2.*value(rv0);
1485 value(rv) *= tinytens[j];
1486 if (!value(rv)) {
1487 undfl:
1488 value(rv) = 0.;
1489 errno = ERANGE;
1490 if (bd0)
1491 goto retfree;
1492 goto ret;
1493 }
1494 word0(rv) = Tiny0;
1495 word1(rv) = Tiny1;
1496 /* The refinement below will clean
1497 * this approximation up.
1498 */
1499 }
1500 }
1501 }
1502
1503 /* Now the hard part -- adjusting rv to the correct value.*/
1504
1505 /* Put digits into bd: true value = bd * 10^e */
1506
1507 bd0 = s2b(s0, nd0, nd, y);
1508
1509 for(;;) {
1510 bd = Balloc(bd0->k);
1511 Bcopy(bd, bd0);
1512 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1513 bs = i2b(1);
1514
1515 if (e >= 0) {
1516 bb2 = bb5 = 0;
1517 bd2 = bd5 = e;
1518 }
1519 else {
1520 bb2 = bb5 = -e;
1521 bd2 = bd5 = 0;
1522 }
1523 if (bbe >= 0)
1524 bb2 += bbe;
1525 else
1526 bd2 -= bbe;
1527 bs2 = bb2;
1528#ifdef Sudden_Underflow
1529#ifdef IBM
1530 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
1531#else
1532 j = P + 1 - bbbits;
1533#endif
1534#else
1535 i = bbe + bbbits - 1; /* logb(rv) */
1536 if (i < Emin) /* denormal */
1537 j = bbe + (P-Emin);
1538 else
1539 j = P + 1 - bbbits;
1540#endif
1541 bb2 += j;
1542 bd2 += j;
1543 i = bb2 < bd2 ? bb2 : bd2;
1544 if (i > bs2)
1545 i = bs2;
1546 if (i > 0) {
1547 bb2 -= i;
1548 bd2 -= i;
1549 bs2 -= i;
1550 }
1551 if (bb5 > 0) {
1552 bs = pow5mult(bs, bb5);
1553 bb1 = mult(bs, bb);
1554 Bfree(bb);
1555 bb = bb1;
1556 }
1557 if (bb2 > 0)
1558 bb = lshift(bb, bb2);
1559 if (bd5 > 0)
1560 bd = pow5mult(bd, bd5);
1561 if (bd2 > 0)
1562 bd = lshift(bd, bd2);
1563 if (bs2 > 0)
1564 bs = lshift(bs, bs2);
1565 delta = diff(bb, bd);
1566 dsign = delta->sign;
1567 delta->sign = 0;
1568 i = cmp(delta, bs);
1569 if (i < 0) {
1570 /* Error is less than half an ulp -- check for
1571 * special case of mantissa a power of two.
1572 */
1573 if (dsign || word1(rv) || word0(rv) & Bndry_mask)
1574 break;
1575 delta = lshift(delta,Log2P);
1576 if (cmp(delta, bs) > 0)
1577 goto drop_down;
1578 break;
1579 }
1580 if (i == 0) {
1581 /* exactly half-way between */
1582 if (dsign) {
1583 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
1584 && word1(rv) == 0xffffffff) {
1585 /*boundary case -- increment exponent*/
1586 word0(rv) = (word0(rv) & Exp_mask)
1587 + Exp_msk1
1588#ifdef IBM
1589 | Exp_msk1 >> 4
1590#endif
1591 ;
1592 word1(rv) = 0;
1593 break;
1594 }
1595 }
1596 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
1597 drop_down:
1598 /* boundary case -- decrement exponent */
1599#ifdef Sudden_Underflow
1600 L = word0(rv) & Exp_mask;
1601#ifdef IBM
1602 if (L < Exp_msk1)
1603#else
1604 if (L <= Exp_msk1)
1605#endif
1606 goto undfl;
1607 L -= Exp_msk1;
1608#else
1609 L = (word0(rv) & Exp_mask) - Exp_msk1;
1610#endif
1611 word0(rv) = L | Bndry_mask1;
1612 word1(rv) = 0xffffffff;
1613#ifdef IBM
1614 goto cont;
1615#else
1616 break;
1617#endif
1618 }
1619#ifndef ROUND_BIASED
1620 if (!(word1(rv) & LSB))
1621 break;
1622#endif
1623 if (dsign)
1624 value(rv) += ulp(value(rv));
1625#ifndef ROUND_BIASED
1626 else {
1627 value(rv) -= ulp(value(rv));
1628#ifndef Sudden_Underflow
1629 if (!value(rv))
1630 goto undfl;
1631#endif
1632 }
1633#endif
1634 break;
1635 }
1636 if ((aadj = ratio(delta, bs)) <= 2.) {
1637 if (dsign)
1638 aadj = aadj1 = 1.;
1639 else if (word1(rv) || word0(rv) & Bndry_mask) {
1640#ifndef Sudden_Underflow
1641 if (word1(rv) == Tiny1 && !word0(rv))
1642 goto undfl;
1643#endif
1644 aadj = 1.;
1645 aadj1 = -1.;
1646 }
1647 else {
1648 /* special case -- power of FLT_RADIX to be */
1649 /* rounded down... */
1650
1651 if (aadj < 2./FLT_RADIX)
1652 aadj = 1./FLT_RADIX;
1653 else
1654 aadj *= 0.5;
1655 aadj1 = -aadj;
1656 }
1657 }
1658 else {
1659 aadj *= 0.5;
1660 aadj1 = dsign ? aadj : -aadj;
1661#ifdef Check_FLT_ROUNDS
1662 switch(FLT_ROUNDS) {
1663 case 2: /* towards +infinity */
1664 aadj1 -= 0.5;
1665 break;
1666 case 0: /* towards 0 */
1667 case 3: /* towards -infinity */
1668 aadj1 += 0.5;
1669 }
1670#else
1671 if (FLT_ROUNDS == 0)
1672 aadj1 += 0.5;
1673#endif
1674 }
1675 y = word0(rv) & Exp_mask;
1676
1677 /* Check for overflow */
1678
1679 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1680 value(rv0) = value(rv);
1681 word0(rv) -= P*Exp_msk1;
1682 adj = aadj1 * ulp(value(rv));
1683 value(rv) += adj;
1684 if ((word0(rv) & Exp_mask) >=
1685 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1686 if (word0(rv0) == Big0 && word1(rv0) == Big1)
1687 goto ovfl;
1688 word0(rv) = Big0;
1689 word1(rv) = Big1;
1690 goto cont;
1691 }
1692 else
1693 word0(rv) += P*Exp_msk1;
1694 }
1695 else {
1696#ifdef Sudden_Underflow
1697 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1698 value(rv0) = value(rv);
1699 word0(rv) += P*Exp_msk1;
1700 adj = aadj1 * ulp(value(rv));
1701 value(rv) += adj;
1702#ifdef IBM
1703 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1704#else
1705 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
1706#endif
1707 {
1708 if (word0(rv0) == Tiny0
1709 && word1(rv0) == Tiny1)
1710 goto undfl;
1711 word0(rv) = Tiny0;
1712 word1(rv) = Tiny1;
1713 goto cont;
1714 }
1715 else
1716 word0(rv) -= P*Exp_msk1;
1717 }
1718 else {
1719 adj = aadj1 * ulp(value(rv));
1720 value(rv) += adj;
1721 }
1722#else
1723 /* Compute adj so that the IEEE rounding rules will
1724 * correctly round rv + adj in some half-way cases.
1725 * If rv * ulp(rv) is denormalized (i.e.,
1726 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1727 * trouble from bits lost to denormalization;
1728 * example: 1.2e-307 .
1729 */
1730 if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
1731 aadj1 = (double)(int)(aadj + 0.5);
1732 if (!dsign)
1733 aadj1 = -aadj1;
1734 }
1735 adj = aadj1 * ulp(value(rv));
1736 value(rv) += adj;
1737#endif
1738 }
1739 z = word0(rv) & Exp_mask;
1740 if (y == z) {
1741 /* Can we stop now? */
1742 L = aadj;
1743 aadj -= L;
1744 /* The tolerances below are conservative. */
1745 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
1746 if (aadj < .4999999 || aadj > .5000001)
1747 break;
1748 }
1749 else if (aadj < .4999999/FLT_RADIX)
1750 break;
1751 }
1752 cont:
1753 Bfree(bb);
1754 Bfree(bd);
1755 Bfree(bs);
1756 Bfree(delta);
1757 }
1758 retfree:
1759 Bfree(bb);
1760 Bfree(bd);
1761 Bfree(bs);
1762 Bfree(bd0);
1763 Bfree(delta);
1764 ret:
1765 if (se)
1766 *se = (char *)s;
1767 return sign ? -value(rv) : value(rv);
1768 }
1769
1770 static int
1771quorem
1772#ifdef KR_headers
1773 (b, S) Bigint *b, *S;
1774#else
1775 (Bigint *b, Bigint *S)
1776#endif
1777{
1778 int n;
1779 Long borrow, y;
1780 ULong carry, q, ys;
1781 ULong *bx, *bxe, *sx, *sxe;
1782#ifdef Pack_32
1783 Long z;
1784 ULong si, zs;
1785#endif
1786
1787 n = S->wds;
1788#ifdef DEBUG
1789 /*debug*/ if (b->wds > n)
1790 /*debug*/ Bug("oversize b in quorem");
1791#endif
1792 if (b->wds < n)
1793 return 0;
1794 sx = S->x;
1795 sxe = sx + --n;
1796 bx = b->x;
1797 bxe = bx + n;
1798 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
1799#ifdef DEBUG
1800 /*debug*/ if (q > 9)
1801 /*debug*/ Bug("oversized quotient in quorem");
1802#endif
1803 if (q) {
1804 borrow = 0;
1805 carry = 0;
1806 do {
1807#ifdef Pack_32
1808 si = *sx++;
1809 ys = (si & 0xffff) * q + carry;
1810 zs = (si >> 16) * q + (ys >> 16);
1811 carry = zs >> 16;
1812 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1813 borrow = y >> 16;
1814 Sign_Extend(borrow, y);
1815 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1816 borrow = z >> 16;
1817 Sign_Extend(borrow, z);
1818 Storeinc(bx, z, y);
1819#else
1820 ys = *sx++ * q + carry;
1821 carry = ys >> 16;
1822 y = *bx - (ys & 0xffff) + borrow;
1823 borrow = y >> 16;
1824 Sign_Extend(borrow, y);
1825 *bx++ = y & 0xffff;
1826#endif
1827 }
1828 while(sx <= sxe);
1829 if (!*bxe) {
1830 bx = b->x;
1831 while(--bxe > bx && !*bxe)
1832 --n;
1833 b->wds = n;
1834 }
1835 }
1836 if (cmp(b, S) >= 0) {
1837 q++;
1838 borrow = 0;
1839 carry = 0;
1840 bx = b->x;
1841 sx = S->x;
1842 do {
1843#ifdef Pack_32
1844 si = *sx++;
1845 ys = (si & 0xffff) + carry;
1846 zs = (si >> 16) + (ys >> 16);
1847 carry = zs >> 16;
1848 y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
1849 borrow = y >> 16;
1850 Sign_Extend(borrow, y);
1851 z = (*bx >> 16) - (zs & 0xffff) + borrow;
1852 borrow = z >> 16;
1853 Sign_Extend(borrow, z);
1854 Storeinc(bx, z, y);
1855#else
1856 ys = *sx++ + carry;
1857 carry = ys >> 16;
1858 y = *bx - (ys & 0xffff) + borrow;
1859 borrow = y >> 16;
1860 Sign_Extend(borrow, y);
1861 *bx++ = y & 0xffff;
1862#endif
1863 }
1864 while(sx <= sxe);
1865 bx = b->x;
1866 bxe = bx + n;
1867 if (!*bxe) {
1868 while(--bxe > bx && !*bxe)
1869 --n;
1870 b->wds = n;
1871 }
1872 }
1873 return q;
1874 }
1875
1876/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
1877 *
1878 * Inspired by "How to Print Floating-Point Numbers Accurately" by
1879 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
1880 *
1881 * Modifications:
1882 * 1. Rather than iterating, we use a simple numeric overestimate
1883 * to determine k = floor(log10(d)). We scale relevant
1884 * quantities using O(log2(k)) rather than O(k) multiplications.
1885 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
1886 * try to generate digits strictly left to right. Instead, we
1887 * compute with fewer bits and propagate the carry if necessary
1888 * when rounding the final digit up. This is often faster.
1889 * 3. Under the assumption that input will be rounded nearest,
1890 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
1891 * That is, we allow equality in stopping tests when the
1892 * round-nearest rule will give the same floating-point value
1893 * as would satisfaction of the stopping test with strict
1894 * inequality.
1895 * 4. We remove common factors of powers of 2 from relevant
1896 * quantities.
1897 * 5. When converting floating-point integers less than 1e16,
1898 * we use floating-point arithmetic rather than resorting
1899 * to multiple-precision integers.
1900 * 6. When asked to produce fewer than 15 digits, we first try
1901 * to get by with floating-point arithmetic; we resort to
1902 * multiple-precision integer arithmetic only if we cannot
1903 * guarantee that the floating-point calculation has given
1904 * the correctly rounded result. For k requested digits and
1905 * "uniformly" distributed input, the probability is
1906 * something like 10^(k-15) that we must resort to the Long
1907 * calculation.
1908 */
1909
1910 char *
1911__dtoa
1912#ifdef KR_headers
1913 (_d, mode, ndigits, decpt, sign, rve)
1914 double _d; int mode, ndigits, *decpt, *sign; char **rve;
1915#else
1916 (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
1917#endif
1918{
1919 /* Arguments ndigits, decpt, sign are similar to those
1920 of ecvt and fcvt; trailing zeros are suppressed from
1921 the returned string. If not null, *rve is set to point
1922 to the end of the return value. If d is +-Infinity or NaN,
1923 then *decpt is set to 9999.
1924
1925 mode:
1926 0 ==> shortest string that yields d when read in
1927 and rounded to nearest.
1928 1 ==> like 0, but with Steele & White stopping rule;
1929 e.g. with IEEE P754 arithmetic , mode 0 gives
1930 1e23 whereas mode 1 gives 9.999999999999999e22.
1931 2 ==> max(1,ndigits) significant digits. This gives a
1932 return value similar to that of ecvt, except
1933 that trailing zeros are suppressed.
1934 3 ==> through ndigits past the decimal point. This
1935 gives a return value similar to that from fcvt,
1936 except that trailing zeros are suppressed, and
1937 ndigits can be negative.
1938 4-9 should give the same return values as 2-3, i.e.,
1939 4 <= mode <= 9 ==> same return as mode
1940 2 + (mode & 1). These modes are mainly for
1941 debugging; often they run slower but sometimes
1942 faster than modes 2-3.
1943 4,5,8,9 ==> left-to-right digit generation.
1944 6-9 ==> don't try fast floating-point estimate
1945 (if applicable).
1946
1947 Values of mode other than 0-9 are treated as mode 0.
1948
1949 Sufficient space is allocated to the return value
1950 to hold the suppressed trailing zeros.
1951 */
1952
1953 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
1954 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
1955 spec_case, try_quick;
1956 Long L;
1957#ifndef Sudden_Underflow
1958 int denorm;
1959 ULong x;
1960#endif
1961 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1962 double ds;
1963 char *s, *s0;
1964 static Bigint *result;
1965 static int result_k;
1966 _double d, d2, eps;
1967
1968 value(d) = _d;
1969 if (result) {
1970 result->k = result_k;
1971 result->maxwds = 1 << result_k;
1972 Bfree(result);
1973 result = 0;
1974 }
1975
1976 if (word0(d) & Sign_bit) {
1977 /* set sign for everything, including 0's and NaNs */
1978 *sign = 1;
1979 word0(d) &= ~Sign_bit; /* clear sign bit */
1980 }
1981 else
1982 *sign = 0;
1983
1984#if defined(IEEE_Arith) + defined(VAX)
1985#ifdef IEEE_Arith
1986 if ((word0(d) & Exp_mask) == Exp_mask)
1987#else
1988 if (word0(d) == 0x8000)
1989#endif
1990 {
1991 /* Infinity or NaN */
1992 *decpt = 9999;
1993 s =
1994#ifdef IEEE_Arith
1995 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
1996#endif
1997 "NaN";
1998 if (rve)
1999 *rve =
2000#ifdef IEEE_Arith
2001 s[3] ? s + 8 :
2002#endif
2003 s + 3;
2004 return s;
2005 }
2006#endif
2007#ifdef IBM
2008 value(d) += 0; /* normalize */
2009#endif
2010 if (!value(d)) {
2011 *decpt = 1;
2012 s = "0";
2013 if (rve)
2014 *rve = s + 1;
2015 return s;
2016 }
2017
2018 b = d2b(value(d), &be, &bbits);
2019#ifdef Sudden_Underflow
2020 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2021#else
2022 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
2023#endif
2024 value(d2) = value(d);
2025 word0(d2) &= Frac_mask1;
2026 word0(d2) |= Exp_11;
2027#ifdef IBM
2028 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2029 value(d2) /= 1 << j;
2030#endif
2031
2032 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2033 * log10(x) = log(x) / log(10)
2034 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2035 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2036 *
2037 * This suggests computing an approximation k to log10(d) by
2038 *
2039 * k = (i - Bias)*0.301029995663981
2040 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2041 *
2042 * We want k to be too large rather than too small.
2043 * The error in the first-order Taylor series approximation
2044 * is in our favor, so we just round up the constant enough
2045 * to compensate for any error in the multiplication of
2046 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2047 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2048 * adding 1e-13 to the constant term more than suffices.
2049 * Hence we adjust the constant term to 0.1760912590558.
2050 * (We could get a more accurate k by invoking log10,
2051 * but this is probably not worthwhile.)
2052 */
2053
2054 i -= Bias;
2055#ifdef IBM
2056 i <<= 2;
2057 i += j;
2058#endif
2059#ifndef Sudden_Underflow
2060 denorm = 0;
2061 }
2062 else {
2063 /* d is denormalized */
2064
2065 i = bbits + be + (Bias + (P-1) - 1);
2066 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2067 : word1(d) << 32 - i;
2068 value(d2) = x;
2069 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2070 i -= (Bias + (P-1) - 1) + 1;
2071 denorm = 1;
2072 }
2073#endif
2074 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2075 i*0.301029995663981;
2076 k = (int)ds;
2077 if (ds < 0. && ds != k)
2078 k--; /* want k = floor(ds) */
2079 k_check = 1;
2080 if (k >= 0 && k <= Ten_pmax) {
2081 if (value(d) < tens[k])
2082 k--;
2083 k_check = 0;
2084 }
2085 j = bbits - i - 1;
2086 if (j >= 0) {
2087 b2 = 0;
2088 s2 = j;
2089 }
2090 else {
2091 b2 = -j;
2092 s2 = 0;
2093 }
2094 if (k >= 0) {
2095 b5 = 0;
2096 s5 = k;
2097 s2 += k;
2098 }
2099 else {
2100 b2 -= k;
2101 b5 = -k;
2102 s5 = 0;
2103 }
2104 if (mode < 0 || mode > 9)
2105 mode = 0;
2106 try_quick = 1;
2107 if (mode > 5) {
2108 mode -= 4;
2109 try_quick = 0;
2110 }
2111 leftright = 1;
2112 switch(mode) {
2113 case 0:
2114 case 1:
2115 ilim = ilim1 = -1;
2116 i = 18;
2117 ndigits = 0;
2118 break;
2119 case 2:
2120 leftright = 0;
2121 /* no break */
2122 case 4:
2123 if (ndigits <= 0)
2124 ndigits = 1;
2125 ilim = ilim1 = i = ndigits;
2126 break;
2127 case 3:
2128 leftright = 0;
2129 /* no break */
2130 case 5:
2131 i = ndigits + k + 1;
2132 ilim = i;
2133 ilim1 = i - 1;
2134 if (i <= 0)
2135 i = 1;
2136 }
2137 j = sizeof(ULong);
2138 for(result_k = 0; sizeof(Bigint) - sizeof(ULong) + j <= i;
2139 j <<= 1) result_k++;
2140 result = Balloc(result_k);
2141 s = s0 = (char *)result;
2142
2143 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2144
2145 /* Try to get by with floating-point arithmetic. */
2146
2147 i = 0;
2148 value(d2) = value(d);
2149 k0 = k;
2150 ilim0 = ilim;
2151 ieps = 2; /* conservative */
2152 if (k > 0) {
2153 ds = tens[k&0xf];
2154 j = k >> 4;
2155 if (j & Bletch) {
2156 /* prevent overflows */
2157 j &= Bletch - 1;
2158 value(d) /= bigtens[n_bigtens-1];
2159 ieps++;
2160 }
2161 for(; j; j >>= 1, i++)
2162 if (j & 1) {
2163 ieps++;
2164 ds *= bigtens[i];
2165 }
2166 value(d) /= ds;
2167 }
2168 else if (j1 = -k) {
2169 value(d) *= tens[j1 & 0xf];
2170 for(j = j1 >> 4; j; j >>= 1, i++)
2171 if (j & 1) {
2172 ieps++;
2173 value(d) *= bigtens[i];
2174 }
2175 }
2176 if (k_check && value(d) < 1. && ilim > 0) {
2177 if (ilim1 <= 0)
2178 goto fast_failed;
2179 ilim = ilim1;
2180 k--;
2181 value(d) *= 10.;
2182 ieps++;
2183 }
2184 value(eps) = ieps*value(d) + 7.;
2185 word0(eps) -= (P-1)*Exp_msk1;
2186 if (ilim == 0) {
2187 S = mhi = 0;
2188 value(d) -= 5.;
2189 if (value(d) > value(eps))
2190 goto one_digit;
2191 if (value(d) < -value(eps))
2192 goto no_digits;
2193 goto fast_failed;
2194 }
2195#ifndef No_leftright
2196 if (leftright) {
2197 /* Use Steele & White method of only
2198 * generating digits needed.
2199 */
2200 value(eps) = 0.5/tens[ilim-1] - value(eps);
2201 for(i = 0;;) {
2202 L = value(d);
2203 value(d) -= L;
2204 *s++ = '0' + (int)L;
2205 if (value(d) < value(eps))
2206 goto ret1;
2207 if (1. - value(d) < value(eps))
2208 goto bump_up;
2209 if (++i >= ilim)
2210 break;
2211 value(eps) *= 10.;
2212 value(d) *= 10.;
2213 }
2214 }
2215 else {
2216#endif
2217 /* Generate ilim digits, then fix them up. */
2218 value(eps) *= tens[ilim-1];
2219 for(i = 1;; i++, value(d) *= 10.) {
2220 L = value(d);
2221 value(d) -= L;
2222 *s++ = '0' + (int)L;
2223 if (i == ilim) {
2224 if (value(d) > 0.5 + value(eps))
2225 goto bump_up;
2226 else if (value(d) < 0.5 - value(eps)) {
2227 while(*--s == '0');
2228 s++;
2229 goto ret1;
2230 }
2231 break;
2232 }
2233 }
2234#ifndef No_leftright
2235 }
2236#endif
2237 fast_failed:
2238 s = s0;
2239 value(d) = value(d2);
2240 k = k0;
2241 ilim = ilim0;
2242 }
2243
2244 /* Do we have a "small" integer? */
2245
2246 if (be >= 0 && k <= Int_max) {
2247 /* Yes. */
2248 ds = tens[k];
2249 if (ndigits < 0 && ilim <= 0) {
2250 S = mhi = 0;
2251 if (ilim < 0 || value(d) <= 5*ds)
2252 goto no_digits;
2253 goto one_digit;
2254 }
2255 for(i = 1;; i++) {
2256 L = value(d) / ds;
2257 value(d) -= L*ds;
2258#ifdef Check_FLT_ROUNDS
2259 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2260 if (value(d) < 0) {
2261 L--;
2262 value(d) += ds;
2263 }
2264#endif
2265 *s++ = '0' + (int)L;
2266 if (i == ilim) {
2267 value(d) += value(d);
2268 if (value(d) > ds || value(d) == ds && L & 1) {
2269 bump_up:
2270 while(*--s == '9')
2271 if (s == s0) {
2272 k++;
2273 *s = '0';
2274 break;
2275 }
2276 ++*s++;
2277 }
2278 break;
2279 }
2280 if (!(value(d) *= 10.))
2281 break;
2282 }
2283 goto ret1;
2284 }
2285
2286 m2 = b2;
2287 m5 = b5;
2288 mhi = mlo = 0;
2289 if (leftright) {
2290 if (mode < 2) {
2291 i =
2292#ifndef Sudden_Underflow
2293 denorm ? be + (Bias + (P-1) - 1 + 1) :
2294#endif
2295#ifdef IBM
2296 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
2297#else
2298 1 + P - bbits;
2299#endif
2300 }
2301 else {
2302 j = ilim - 1;
2303 if (m5 >= j)
2304 m5 -= j;
2305 else {
2306 s5 += j -= m5;
2307 b5 += j;
2308 m5 = 0;
2309 }
2310 if ((i = ilim) < 0) {
2311 m2 -= i;
2312 i = 0;
2313 }
2314 }
2315 b2 += i;
2316 s2 += i;
2317 mhi = i2b(1);
2318 }
2319 if (m2 > 0 && s2 > 0) {
2320 i = m2 < s2 ? m2 : s2;
2321 b2 -= i;
2322 m2 -= i;
2323 s2 -= i;
2324 }
2325 if (b5 > 0) {
2326 if (leftright) {
2327 if (m5 > 0) {
2328 mhi = pow5mult(mhi, m5);
2329 b1 = mult(mhi, b);
2330 Bfree(b);
2331 b = b1;
2332 }
2333 if (j = b5 - m5)
2334 b = pow5mult(b, j);
2335 }
2336 else
2337 b = pow5mult(b, b5);
2338 }
2339 S = i2b(1);
2340 if (s5 > 0)
2341 S = pow5mult(S, s5);
2342
2343 /* Check for special case that d is a normalized power of 2. */
2344
2345 if (mode < 2) {
2346 if (!word1(d) && !(word0(d) & Bndry_mask)
2347#ifndef Sudden_Underflow
2348 && word0(d) & Exp_mask
2349#endif
2350 ) {
2351 /* The special case */
2352 b2 += Log2P;
2353 s2 += Log2P;
2354 spec_case = 1;
2355 }
2356 else
2357 spec_case = 0;
2358 }
2359
2360 /* Arrange for convenient computation of quotients:
2361 * shift left if necessary so divisor has 4 leading 0 bits.
2362 *
2363 * Perhaps we should just compute leading 28 bits of S once
2364 * and for all and pass them and a shift to quorem, so it
2365 * can do shifts and ors to compute the numerator for q.
2366 */
2367#ifdef Pack_32
2368 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
2369 i = 32 - i;
2370#else
2371 if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
2372 i = 16 - i;
2373#endif
2374 if (i > 4) {
2375 i -= 4;
2376 b2 += i;
2377 m2 += i;
2378 s2 += i;
2379 }
2380 else if (i < 4) {
2381 i += 28;
2382 b2 += i;
2383 m2 += i;
2384 s2 += i;
2385 }
2386 if (b2 > 0)
2387 b = lshift(b, b2);
2388 if (s2 > 0)
2389 S = lshift(S, s2);
2390 if (k_check) {
2391 if (cmp(b,S) < 0) {
2392 k--;
2393 b = multadd(b, 10, 0); /* we botched the k estimate */
2394 if (leftright)
2395 mhi = multadd(mhi, 10, 0);
2396 ilim = ilim1;
2397 }
2398 }
2399 if (ilim <= 0 && mode > 2) {
2400 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
2401 /* no digits, fcvt style */
2402 no_digits:
2403 k = -1 - ndigits;
2404 goto ret;
2405 }
2406 one_digit:
2407 *s++ = '1';
2408 k++;
2409 goto ret;
2410 }
2411 if (leftright) {
2412 if (m2 > 0)
2413 mhi = lshift(mhi, m2);
2414
2415 /* Compute mlo -- check for special case
2416 * that d is a normalized power of 2.
2417 */
2418
2419 mlo = mhi;
2420 if (spec_case) {
2421 mhi = Balloc(mhi->k);
2422 Bcopy(mhi, mlo);
2423 mhi = lshift(mhi, Log2P);
2424 }
2425
2426 for(i = 1;;i++) {
2427 dig = quorem(b,S) + '0';
2428 /* Do we yet have the shortest decimal string
2429 * that will round to d?
2430 */
2431 j = cmp(b, mlo);
2432 delta = diff(S, mhi);
2433 j1 = delta->sign ? 1 : cmp(b, delta);
2434 Bfree(delta);
2435#ifndef ROUND_BIASED
2436 if (j1 == 0 && !mode && !(word1(d) & 1)) {
2437 if (dig == '9')
2438 goto round_9_up;
2439 if (j > 0)
2440 dig++;
2441 *s++ = dig;
2442 goto ret;
2443 }
2444#endif
2445 if (j < 0 || j == 0 && !mode
2446#ifndef ROUND_BIASED
2447 && !(word1(d) & 1)
2448#endif
2449 ) {
2450 if (j1 > 0) {
2451 b = lshift(b, 1);
2452 j1 = cmp(b, S);
2453 if ((j1 > 0 || j1 == 0 && dig & 1)
2454 && dig++ == '9')
2455 goto round_9_up;
2456 }
2457 *s++ = dig;
2458 goto ret;
2459 }
2460 if (j1 > 0) {
2461 if (dig == '9') { /* possible if i == 1 */
2462 round_9_up:
2463 *s++ = '9';
2464 goto roundoff;
2465 }
2466 *s++ = dig + 1;
2467 goto ret;
2468 }
2469 *s++ = dig;
2470 if (i == ilim)
2471 break;
2472 b = multadd(b, 10, 0);
2473 if (mlo == mhi)
2474 mlo = mhi = multadd(mhi, 10, 0);
2475 else {
2476 mlo = multadd(mlo, 10, 0);
2477 mhi = multadd(mhi, 10, 0);
2478 }
2479 }
2480 }
2481 else
2482 for(i = 1;; i++) {
2483 *s++ = dig = quorem(b,S) + '0';
2484 if (i >= ilim)
2485 break;
2486 b = multadd(b, 10, 0);
2487 }
2488
2489 /* Round off last digit */
2490
2491 b = lshift(b, 1);
2492 j = cmp(b, S);
2493 if (j > 0 || j == 0 && dig & 1) {
2494 roundoff:
2495 while(*--s == '9')
2496 if (s == s0) {
2497 k++;
2498 *s++ = '1';
2499 goto ret;
2500 }
2501 ++*s++;
2502 }
2503 else {
2504 while(*--s == '0');
2505 s++;
2506 }
2507 ret:
2508 Bfree(S);
2509 if (mhi) {
2510 if (mlo && mlo != mhi)
2511 Bfree(mlo);
2512 Bfree(mhi);
2513 }
2514 ret1:
2515 Bfree(b);
2516 if (s == s0) { /* don't return empty string */
2517 *s++ = '0';
2518 k = 0;
2519 }
2520 *s = 0;
2521 *decpt = k + 1;
2522 if (rve)
2523 *rve = s;
2524 return s0;
2525 }
2526#ifdef __cplusplus
2527}
2528#endif
diff --git a/src/lib/libc/stdlib/strtol.3 b/src/lib/libc/stdlib/strtol.3
new file mode 100644
index 0000000000..a5bdff0b81
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.3
@@ -0,0 +1,243 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtol.3,v 1.10 2002/06/29 00:20:11 millert Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOL 3
40.Os
41.Sh NAME
42.Nm strtol ,
43.Nm strtoll ,
44.Nm strtoq
45.Nd convert string value to a long or long long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Fd #include <limits.h>
49.Ft long
50.Fn strtol "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <stdlib.h>
53.Fd #include <limits.h>
54.Ft long long
55.Fn strtoll "const char *nptr" "char **endptr" "int base"
56.Pp
57.Fd #include <sys/types.h>
58.Fd #include <stdlib.h>
59.Fd #include <limits.h>
60.Ft quad_t
61.Fn strtoq "const char *nptr" "char **endptr" "int base"
62.Sh DESCRIPTION
63The
64.Fn strtol
65function converts the string in
66.Fa nptr
67to a
68.Li long
69value.
70The
71.Fn strtoll
72function converts the string in
73.Fa nptr
74to a
75.Li long long
76value.
77The
78.Fn strtoq
79function is a deprecated equivalent of
80.Fn strtoll
81and is provided for backwards compatibility with legacy programs.
82The conversion is done according to the given
83.Fa base ,
84which must be a number between 2 and 36 inclusive or the special value 0.
85.Pp
86The string may begin with an arbitrary amount of whitespace
87(as determined by
88.Xr isspace 3 )
89followed by a single optional
90.Ql +
91or
92.Ql -
93sign.
94If
95.Fa base
96is zero or 16, the string may then include a
97.Ql 0x
98prefix, and the number will be read in base 16; otherwise, a zero
99.Fa base
100is taken as 10 (decimal) unless the next character is
101.Ql 0 ,
102in which case it is taken as 8 (octal).
103.Pp
104The remainder of the string is converted to a
105.Li long
106value in the obvious manner,
107stopping at the first character which is not a valid digit
108in the given base.
109(In bases above 10, the letter
110.Ql A
111in either upper or lower case represents 10,
112.Ql B
113represents 11, and so forth, with
114.Ql Z
115representing 35.)
116.Pp
117If
118.Fa endptr
119is non-null,
120.Fn strtol
121stores the address of the first invalid character in
122.Fa *endptr .
123If there were no digits at all, however,
124.Fn strtol
125stores the original value of
126.Fa nptr
127in
128.Fa *endptr .
129(Thus, if
130.Fa *nptr
131is not
132.Ql \e0
133but
134.Fa **endptr
135is
136.Ql \e0
137on return, the entire string was valid.)
138.Sh RETURN VALUES
139The
140.Fn strtol
141function returns the result of the conversion,
142unless the value would underflow or overflow.
143If an underflow occurs,
144.Fn strtol
145returns
146.Dv LONG_MIN .
147If an overflow occurs,
148.Fn strtol
149returns
150.Dv LONG_MAX .
151In both cases,
152.Va errno
153is set to
154.Er ERANGE .
155.Pp
156The
157.Fn strtoll
158function has identical return values except that
159.Dv LLONG_MIN
160and
161.Dv LLONG_MAX
162are used to indicate underflow and overflow respectively.
163.Sh EXAMPLES
164Ensuring that a string is a valid number (i.e., in range and containing no
165trailing characters) requires clearing
166.Va errno
167beforehand explicitly since
168.Va errno
169is not changed on a successful call to
170.Fn strtol ,
171and the return value of
172.Fn strtol
173cannot be used unambiguously to signal an error:
174.Bd -literal -offset indent
175char *ep;
176long lval;
177
178\&...
179
180errno = 0;
181lval = strtol(buf, &ep, 10);
182if (buf[0] == '\e0' || *ep != '\e0')
183 goto not_a_number;
184if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
185 goto out_of_range;
186.Ed
187.Pp
188This example will accept
189.Dq 12
190but not
191.Dq 12foo
192or
193.Dq 12\en .
194If trailing whitespace is acceptable, further checks must be done on
195.Va *ep ;
196alternately, use
197.Xr sscanf 3 .
198.Pp
199If
200.Fn strtol
201is being used instead of
202.Xr atoi 3 ,
203error checking is further complicated because the desired return value is an
204.Li int
205rather than a
206.Li long ;
207however, on some architectures integers and long integers are the same size.
208Thus the following is necessary:
209.Bd -literal -offset indent
210char *ep;
211int ival;
212long lval;
213
214\&...
215
216errno = 0;
217lval = strtol(buf, &ep, 10);
218if (buf[0] == '\e0' || *ep != '\e0')
219 goto not_a_number;
220if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
221 (lval > INT_MAX || lval < INT_MIN))
222 goto out_of_range;
223ival = lval;
224.Ed
225.Sh ERRORS
226.Bl -tag -width Er
227.It Bq Er ERANGE
228The given string was out of range; the value converted has been clamped.
229.El
230.Sh SEE ALSO
231.Xr atof 3 ,
232.Xr atoi 3 ,
233.Xr atol 3 ,
234.Xr sscanf 3 ,
235.Xr strtod 3 ,
236.Xr strtoul 3
237.Sh STANDARDS
238The
239.Fn strtol
240function conforms to
241.St -ansiC .
242.Sh BUGS
243Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000000..e4ad557fd5
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.c
@@ -0,0 +1,150 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtol.c,v 1.4 1996/08/19 08:33:51 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43
44/*
45 * Convert a string to a long integer.
46 *
47 * Ignores `locale' stuff. Assumes that the upper and lower case
48 * alphabets and digits are each contiguous.
49 */
50long
51strtol(nptr, endptr, base)
52 const char *nptr;
53 char **endptr;
54 register int base;
55{
56 register const char *s;
57 register long acc, cutoff;
58 register int c;
59 register int neg, any, cutlim;
60
61 /*
62 * Skip white space and pick up leading +/- sign if any.
63 * If base is 0, allow 0x for hex and 0 for octal, else
64 * assume decimal; if base is already 16, allow 0x.
65 */
66 s = nptr;
67 do {
68 c = (unsigned char) *s++;
69 } while (isspace(c));
70 if (c == '-') {
71 neg = 1;
72 c = *s++;
73 } else {
74 neg = 0;
75 if (c == '+')
76 c = *s++;
77 }
78 if ((base == 0 || base == 16) &&
79 c == '0' && (*s == 'x' || *s == 'X')) {
80 c = s[1];
81 s += 2;
82 base = 16;
83 }
84 if (base == 0)
85 base = c == '0' ? 8 : 10;
86
87 /*
88 * Compute the cutoff value between legal numbers and illegal
89 * numbers. That is the largest legal value, divided by the
90 * base. An input number that is greater than this value, if
91 * followed by a legal input character, is too big. One that
92 * is equal to this value may be valid or not; the limit
93 * between valid and invalid numbers is then based on the last
94 * digit. For instance, if the range for longs is
95 * [-2147483648..2147483647] and the input base is 10,
96 * cutoff will be set to 214748364 and cutlim to either
97 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
98 * a value > 214748364, or equal but the next digit is > 7 (or 8),
99 * the number is too big, and we will return a range error.
100 *
101 * Set any if any `digits' consumed; make it negative to indicate
102 * overflow.
103 */
104 cutoff = neg ? LONG_MIN : LONG_MAX;
105 cutlim = cutoff % base;
106 cutoff /= base;
107 if (neg) {
108 if (cutlim > 0) {
109 cutlim -= base;
110 cutoff += 1;
111 }
112 cutlim = -cutlim;
113 }
114 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
115 if (isdigit(c))
116 c -= '0';
117 else if (isalpha(c))
118 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
119 else
120 break;
121 if (c >= base)
122 break;
123 if (any < 0)
124 continue;
125 if (neg) {
126 if (acc < cutoff || acc == cutoff && c > cutlim) {
127 any = -1;
128 acc = LONG_MIN;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc -= c;
134 }
135 } else {
136 if (acc > cutoff || acc == cutoff && c > cutlim) {
137 any = -1;
138 acc = LONG_MAX;
139 errno = ERANGE;
140 } else {
141 any = 1;
142 acc *= base;
143 acc += c;
144 }
145 }
146 }
147 if (endptr != 0)
148 *endptr = (char *) (any ? s - 1 : nptr);
149 return (acc);
150}
diff --git a/src/lib/libc/stdlib/strtoll.c b/src/lib/libc/stdlib/strtoll.c
new file mode 100644
index 0000000000..b0eb6d198c
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -0,0 +1,166 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static const char rcsid[] = "$OpenBSD: strtoll.c,v 1.1 2002/06/29 00:20:11 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to a long long.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51long long
52strtoll(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 int base;
56{
57 const char *s;
58 long long acc, cutoff;
59 int c;
60 int neg, any, cutlim;
61
62 /*
63 * Skip white space and pick up leading +/- sign if any.
64 * If base is 0, allow 0x for hex and 0 for octal, else
65 * assume decimal; if base is already 16, allow 0x.
66 */
67 s = nptr;
68 do {
69 c = (unsigned char) *s++;
70 } while (isspace(c));
71 if (c == '-') {
72 neg = 1;
73 c = *s++;
74 } else {
75 neg = 0;
76 if (c == '+')
77 c = *s++;
78 }
79 if ((base == 0 || base == 16) &&
80 c == '0' && (*s == 'x' || *s == 'X')) {
81 c = s[1];
82 s += 2;
83 base = 16;
84 }
85 if (base == 0)
86 base = c == '0' ? 8 : 10;
87
88 /*
89 * Compute the cutoff value between legal numbers and illegal
90 * numbers. That is the largest legal value, divided by the
91 * base. An input number that is greater than this value, if
92 * followed by a legal input character, is too big. One that
93 * is equal to this value may be valid or not; the limit
94 * between valid and invalid numbers is then based on the last
95 * digit. For instance, if the range for long longs is
96 * [-9223372036854775808..9223372036854775807] and the input base
97 * is 10, cutoff will be set to 922337203685477580 and cutlim to
98 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
99 * accumulated a value > 922337203685477580, or equal but the
100 * next digit is > 7 (or 8), the number is too big, and we will
101 * return a range error.
102 *
103 * Set any if any `digits' consumed; make it negative to indicate
104 * overflow.
105 */
106 cutoff = neg ? LLONG_MIN : LLONG_MAX;
107 cutlim = cutoff % base;
108 cutoff /= base;
109 if (neg) {
110 if (cutlim > 0) {
111 cutlim -= base;
112 cutoff += 1;
113 }
114 cutlim = -cutlim;
115 }
116 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
117 if (isdigit(c))
118 c -= '0';
119 else if (isalpha(c))
120 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
121 else
122 break;
123 if (c >= base)
124 break;
125 if (any < 0)
126 continue;
127 if (neg) {
128 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
129 any = -1;
130 acc = LLONG_MIN;
131 errno = ERANGE;
132 } else {
133 any = 1;
134 acc *= base;
135 acc -= c;
136 }
137 } else {
138 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
139 any = -1;
140 acc = LLONG_MAX;
141 errno = ERANGE;
142 } else {
143 any = 1;
144 acc *= base;
145 acc += c;
146 }
147 }
148 }
149 if (endptr != 0)
150 *endptr = (char *) (any ? s - 1 : nptr);
151 return (acc);
152}
153
154#ifdef __weak_alias
155__weak_alias(strtoq, strtoll);
156#else
157quad_t
158strtoq(nptr, endptr, base)
159 const char *nptr;
160 char **endptr;
161 int base;
162{
163
164 return ((quad_t)strtoll(nptr, endptr, base);
165}
166#endif
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000000..6d55de4d7a
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,225 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtoul.3,v 1.10 2002/06/29 00:20:11 millert Exp $
37.\"
38.Dd June 25, 1992
39.Dt STRTOUL 3
40.Os
41.Sh NAME
42.Nm strtoul ,
43.Nm strtoull ,
44.Nm strtouq
45.Nd convert a string to an unsigned long or unsigned long long integer
46.Sh SYNOPSIS
47.Fd #include <stdlib.h>
48.Fd #include <limits.h>
49.Ft unsigned long
50.Fn strtoul "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <stdlib.h>
53.Fd #include <limits.h>
54.Ft unsigned long long
55.Fn strtoull "const char *nptr" "char **endptr" "int base"
56.Pp
57.Fd #include <sys/types.h>
58.Fd #include <stdlib.h>
59.Fd #include <limits.h>
60.Ft u_quad_t
61.Fn strtouq "const char *nptr" "char **endptr" "int base"
62.Sh DESCRIPTION
63The
64.Fn strtoul
65function converts the string in
66.Fa nptr
67to an
68.Li unsigned long
69value.
70The
71.Fn strtoull
72function converts the string in
73.Fa nptr
74to an
75.Li unsigned long long
76value.
77The
78.Fn strtouq
79function is a deprecated equivalent of
80.Fn strtoull
81and is provided for backwards compatibility with legacy programs.
82The conversion is done according to the given
83.Fa base ,
84which must be a number between 2 and 36 inclusive
85or the special value 0.
86.Pp
87The string may begin with an arbitrary amount of whitespace
88(as determined by
89.Xr isspace 3 )
90followed by a single optional
91.Ql +
92or
93.Ql -
94sign.
95If
96.Fa base
97is zero or 16, the string may then include a
98.Ql 0x
99prefix, and the number will be read in base 16; otherwise, a zero
100.Fa base
101is taken as 10 (decimal) unless the next character is
102.Ql 0 ,
103in which case it is taken as 8 (octal).
104.Pp
105The remainder of the string is converted to an
106.Li unsigned long
107value in the obvious manner, stopping at the end of the string
108or at the first character that does not produce a valid digit
109in the given base.
110(In bases above 10, the letter
111.Ql A
112in either upper or lower case represents 10,
113.Ql B
114represents 11, and so forth, with
115.Ql Z
116representing 35.)
117.Pp
118If
119.Fa endptr
120is non-null,
121.Fn strtoul
122stores the address of the first invalid character in
123.Fa *endptr .
124If there were no digits at all, however,
125.Fn strtoul
126stores the original value of
127.Fa nptr
128in
129.Fa *endptr .
130(Thus, if
131.Fa *nptr
132is not
133.Ql \e0
134but
135.Fa **endptr
136is
137.Ql \e0
138on return, the entire string was valid.)
139.Sh RETURN VALUES
140The
141.Fn strtoul
142function returns the result of the conversion,
143unless the value would overflow, in which case
144.Dv ULONG_MAX
145is returned and
146.Va errno
147is set to
148.Er ERANGE .
149If there was a leading minus sign,
150.Fn strtoul
151returns the (unsigned) negation of the absolute value of the number, unless
152the absolute value would overflow.
153In this case,
154.Fn strtoul
155returns
156.Dv ULONG_MAX
157and sets the global variable
158.Va errno
159to
160.Er ERANGE .
161.Pp
162The
163.Fn strtoull
164function has identical return values except that
165.Dv ULLONG_MIN
166and
167.Dv ULLONG_MAX
168are used to indicate underflow and overflow respectively.
169.Pp
170There is no way to determine if
171.Fn strtoul
172has processed a negative number (and returned an unsigned value) short of
173examining the string in
174.Fa nptr
175directly.
176.Sh EXAMPLES
177Ensuring that a string is a valid number (i.e., in range and containing no
178trailing characters) requires clearing
179.Va errno
180beforehand explicitly since
181.Va errno
182is not changed on a successful call to
183.Fn strtoul ,
184and the return value of
185.Fn strtoul
186cannot be used unambiguously to signal an error:
187.Bd -literal -offset indent
188char *ep;
189unsigned long ulval;
190
191\&...
192
193errno = 0;
194ulval = strtoul(buf, &ep, 10);
195if (buf[0] == '\e0' || *ep != '\e0')
196 goto not_a_number;
197if (errno == ERANGE && ulval == ULONG_MAX)
198 goto out_of_range;
199.Ed
200.Pp
201This example will accept
202.Dq 12
203but not
204.Dq 12foo
205or
206.Dq 12\en .
207If trailing whitespace is acceptable, further checks must be done on
208.Va *ep ;
209alternately, use
210.Xr sscanf 3 .
211.Sh ERRORS
212.Bl -tag -width Er
213.It Bq Er ERANGE
214The given string was out of range; the value converted has been clamped.
215.El
216.Sh SEE ALSO
217.Xr sscanf 3 ,
218.Xr strtol 3
219.Sh STANDARDS
220The
221.Fn strtoul
222function conforms to
223.St -ansiC .
224.Sh BUGS
225Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
new file mode 100644
index 0000000000..d3b363fa04
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtoul.c,v 1.4 1996/08/19 08:33:52 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <ctype.h>
39#include <errno.h>
40#include <limits.h>
41#include <stdlib.h>
42
43/*
44 * Convert a string to an unsigned long integer.
45 *
46 * Ignores `locale' stuff. Assumes that the upper and lower case
47 * alphabets and digits are each contiguous.
48 */
49unsigned long
50strtoul(nptr, endptr, base)
51 const char *nptr;
52 char **endptr;
53 register int base;
54{
55 register const char *s;
56 register unsigned long acc, cutoff;
57 register int c;
58 register int neg, any, cutlim;
59
60 /*
61 * See strtol for comments as to the logic used.
62 */
63 s = nptr;
64 do {
65 c = (unsigned char) *s++;
66 } while (isspace(c));
67 if (c == '-') {
68 neg = 1;
69 c = *s++;
70 } else {
71 neg = 0;
72 if (c == '+')
73 c = *s++;
74 }
75 if ((base == 0 || base == 16) &&
76 c == '0' && (*s == 'x' || *s == 'X')) {
77 c = s[1];
78 s += 2;
79 base = 16;
80 }
81 if (base == 0)
82 base = c == '0' ? 8 : 10;
83
84 cutoff = ULONG_MAX / (unsigned long)base;
85 cutlim = ULONG_MAX % (unsigned long)base;
86 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
87 if (isdigit(c))
88 c -= '0';
89 else if (isalpha(c))
90 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
91 else
92 break;
93 if (c >= base)
94 break;
95 if (any < 0)
96 continue;
97 if (acc > cutoff || acc == cutoff && c > cutlim) {
98 any = -1;
99 acc = ULONG_MAX;
100 errno = ERANGE;
101 } else {
102 any = 1;
103 acc *= (unsigned long)base;
104 acc += c;
105 }
106 }
107 if (neg && any > 0)
108 acc = -acc;
109 if (endptr != 0)
110 *endptr = (char *) (any ? s - 1 : nptr);
111 return (acc);
112}
diff --git a/src/lib/libc/stdlib/strtoull.c b/src/lib/libc/stdlib/strtoull.c
new file mode 100644
index 0000000000..7b4dd56c01
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -0,0 +1,128 @@
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static const char rcsid[] = "$OpenBSD: strtoull.c,v 1.1 2002/06/29 00:20:11 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h>
44
45/*
46 * Convert a string to an unsigned long long.
47 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous.
50 */
51unsigned long long
52strtoull(nptr, endptr, base)
53 const char *nptr;
54 char **endptr;
55 int base;
56{
57 const char *s;
58 unsigned long long acc, cutoff;
59 int c;
60 int neg, any, cutlim;
61
62 /*
63 * See strtoq for comments as to the logic used.
64 */
65 s = nptr;
66 do {
67 c = (unsigned char) *s++;
68 } while (isspace(c));
69 if (c == '-') {
70 neg = 1;
71 c = *s++;
72 } else {
73 neg = 0;
74 if (c == '+')
75 c = *s++;
76 }
77 if ((base == 0 || base == 16) &&
78 c == '0' && (*s == 'x' || *s == 'X')) {
79 c = s[1];
80 s += 2;
81 base = 16;
82 }
83 if (base == 0)
84 base = c == '0' ? 8 : 10;
85
86 cutoff = ULLONG_MAX / (unsigned long long)base;
87 cutlim = ULLONG_MAX % (unsigned long long)base;
88 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
89 if (isdigit(c))
90 c -= '0';
91 else if (isalpha(c))
92 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
93 else
94 break;
95 if (c >= base)
96 break;
97 if (any < 0)
98 continue;
99 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
100 any = -1;
101 acc = ULLONG_MAX;
102 errno = ERANGE;
103 } else {
104 any = 1;
105 acc *= (unsigned long long)base;
106 acc += c;
107 }
108 }
109 if (neg && any > 0)
110 acc = -acc;
111 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc);
114}
115
116#ifdef __weak_alias
117__weak_alias(strtouq, strtoull);
118#else
119u_quad_t
120strtouq(nptr, endptr, base)
121 const char *nptr;
122 char **endptr;
123 int base;
124{
125
126 return ((u_quad_t)strtoull(nptr, endptr, base);
127}
128#endif
diff --git a/src/lib/libc/stdlib/system.3 b/src/lib/libc/stdlib/system.3
new file mode 100644
index 0000000000..83c6de80e3
--- /dev/null
+++ b/src/lib/libc/stdlib/system.3
@@ -0,0 +1,103 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: system.3,v 1.8 2000/10/06 04:17:51 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt SYSTEM 3
40.Os
41.Sh NAME
42.Nm system
43.Nd pass a command to the shell
44.Sh SYNOPSIS
45.Fd #include <stdlib.h>
46.Ft int
47.Fn system "const char *string"
48.Sh DESCRIPTION
49The
50.Fn system
51function hands the argument
52.Fa string
53to the command interpreter
54.Xr sh 1 .
55The calling process waits for the shell to finish executing the command,
56ignoring
57.Dv SIGINT
58and
59.Dv SIGQUIT ,
60and blocking
61.Dv SIGCHLD .
62.Pp
63If
64.Fa string
65is
66.Dv NULL ,
67.Fn system
68will return non-zero.
69Otherwise,
70.Fn system
71returns the termination status of the shell in the format specified by
72.Xr waitpid 2 .
73.Sh RETURN VALUES
74If a child process cannot be created, or the termination status of
75the shell cannot be obtained,
76.Fn system
77returns \-1 and sets
78.Va errno
79to indicate the error.
80If execution of the shell fails,
81.Fn system
82returns the termination status for a program that terminates with a call of
83.Fn exit 127 .
84.Sh SEE ALSO
85.Xr sh 1 ,
86.Xr execve 2 ,
87.Xr waitpid 2 ,
88.Xr popen 3
89.Sh STANDARDS
90The
91.Fn system
92function conforms to
93.St -ansiC
94and
95.St -p1003.2-92 .
96.Sh CAVEATS
97Never supply the
98.Fn system
99function with a command containing any part of an unsanitized user-supplied
100string.
101Shell meta-characters present will be honored by the
102.Xr sh 1
103command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
new file mode 100644
index 0000000000..636a9ebdff
--- /dev/null
+++ b/src/lib/libc/stdlib/system.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: system.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/wait.h>
40#include <signal.h>
41#include <stdlib.h>
42#include <unistd.h>
43#include <paths.h>
44
45extern char **environ;
46
47int
48system(command)
49 const char *command;
50{
51 pid_t pid;
52 sig_t intsave, quitsave;
53 sigset_t mask, omask;
54 int pstat;
55 char *argp[] = {"sh", "-c", NULL, NULL};
56
57 if (!command) /* just checking... */
58 return(1);
59
60 argp[2] = (char *)command;
61
62 sigemptyset(&mask);
63 sigaddset(&mask, SIGCHLD);
64 sigprocmask(SIG_BLOCK, &mask, &omask);
65 switch (pid = vfork()) {
66 case -1: /* error */
67 sigprocmask(SIG_SETMASK, &omask, NULL);
68 return(-1);
69 case 0: /* child */
70 sigprocmask(SIG_SETMASK, &omask, NULL);
71 execve(_PATH_BSHELL, argp, environ);
72 _exit(127);
73 }
74
75 intsave = signal(SIGINT, SIG_IGN);
76 quitsave = signal(SIGQUIT, SIG_IGN);
77 pid = waitpid(pid, (int *)&pstat, 0);
78 sigprocmask(SIG_SETMASK, &omask, NULL);
79 (void)signal(SIGINT, intsave);
80 (void)signal(SIGQUIT, quitsave);
81 return (pid == -1 ? -1 : pstat);
82}
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..5c3b8c17f5
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12#include <search.h>
13
14typedef struct node_t
15{
16 char *key;
17 struct node_t *llink, *rlink;
18} node;
19
20/* find a node, or return 0 */
21void *
22tfind(vkey, vrootp, compar)
23 const void *vkey; /* key to be found */
24 void *const *vrootp; /* address of the tree root */
25 int (*compar)(const void *, const void *);
26{
27 char *key = (char *)vkey;
28 node **rootp = (node **)vrootp;
29
30 if (rootp == (struct node_t **)0)
31 return ((struct node_t *)0);
32 while (*rootp != (struct node_t *)0) { /* T1: */
33 int r;
34 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
35 return (*rootp); /* key found */
36 rootp = (r < 0) ?
37 &(*rootp)->llink : /* T3: follow left branch */
38 &(*rootp)->rlink; /* T4: follow right branch */
39 }
40 return (node *)0;
41}
diff --git a/src/lib/libc/stdlib/tsearch.3 b/src/lib/libc/stdlib/tsearch.3
new file mode 100644
index 0000000000..b000a0a8b1
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,127 @@
1.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. The name of the author may not be used to endorse or promote products
13.\" derived from this software without specific prior written permission.
14.\"
15.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $OpenBSD: tsearch.3,v 1.9 2000/08/09 15:51:21 aaron Exp $
27.\"
28.Dd June 15, 1997
29.Dt TSEARCH 3
30.Os
31.Sh NAME
32.Nm tsearch ,
33.Nm tfind ,
34.Nm tdelete ,
35.Nm twalk
36.Nd manipulate binary search trees
37.Sh SYNOPSIS
38.Fd #include <search.h>
39.Ft void *
40.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
41.Ft void *
42.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
43.Ft void *
44.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
45.Ft void
46.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
47.Sh DESCRIPTION
48The
49.Fn tdelete ,
50.Fn tfind ,
51.Fn tsearch ,
52and
53.Fn twalk
54functions manage binary search trees based on algorithms T and D
55from Knuth (6.2.2).
56The comparison function passed in by
57the user has the same style of return values as
58.Xr strcmp 3 .
59.Pp
60.Fn tfind
61searches for the datum matched by the argument
62.Fa key
63in the binary tree rooted at
64.Fa rootp ,
65returning a pointer to the datum if it is found and
66.Dv NULL
67if it is not.
68.Pp
69.Fn tsearch
70is identical to
71.Fn tfind
72except that if no match is found,
73.Fa key
74is inserted into the tree and a pointer to it is returned.
75If
76.Fa rootp
77points to a null value a new binary search tree is created.
78.Pp
79.Fn tdelete
80deletes a node from the specified binary search tree and returns
81a pointer to the parent of the node to be deleted.
82It takes the same arguments as
83.Fn tfind
84and
85.Fn tsearch .
86If the node to be deleted is the root of the binary search tree,
87.Fa rootp
88will be adjusted.
89.Pp
90.Fn twalk
91walks the binary search tree rooted in
92.Fa root
93and calls the function
94.Fa action
95on each node.
96.Fa action
97is called with three arguments: a pointer to the current node,
98a value from the enum
99.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
100specifying the traversal type, and a node level (where level
101zero is the root of the tree).
102.Sh SEE ALSO
103.Xr bsearch 3 ,
104.Xr lsearch 3
105.Sh RETURN VALUES
106The
107.Fn tsearch
108function returns
109.Dv NULL
110if allocation of a new node fails (usually
111due to a lack of free memory).
112.Pp
113.Fn tfind ,
114.Fn tsearch ,
115and
116.Fn tdelete
117return
118.Dv NULL
119if
120.Fa rootp
121is
122.Dv NULL
123or the datum cannot be found.
124.Pp
125The
126.Fn twalk
127function returns no value.
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..0ad5866172
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,126 @@
1/*
2 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
3 * the AT&T man page says.
4 *
5 * The node_t structure is for internal use only, lint doesn't grok it.
6 *
7 * Written by reading the System V Interface Definition, not the code.
8 *
9 * Totally public domain.
10 */
11/*LINTLIBRARY*/
12
13#include <search.h>
14#include <stdlib.h>
15
16typedef struct node_t {
17 char *key;
18 struct node_t *left, *right;
19} node;
20
21/* find or insert datum into search tree */
22void *
23tsearch(vkey, vrootp, compar)
24 const void *vkey; /* key to be located */
25 void **vrootp; /* address of tree root */
26 int (*compar)(const void *, const void *);
27{
28 register node *q;
29 char *key = (char *)vkey;
30 node **rootp = (node **)vrootp;
31
32 if (rootp == (struct node_t **)0)
33 return ((void *)0);
34 while (*rootp != (struct node_t *)0) { /* Knuth's T1: */
35 int r;
36
37 if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
38 return ((void *)*rootp); /* we found it! */
39 rootp = (r < 0) ?
40 &(*rootp)->left : /* T3: follow left branch */
41 &(*rootp)->right; /* T4: follow right branch */
42 }
43 q = (node *) malloc(sizeof(node)); /* T5: key not found */
44 if (q != (struct node_t *)0) { /* make new node */
45 *rootp = q; /* link new node to old */
46 q->key = key; /* initialize new node */
47 q->left = q->right = (struct node_t *)0;
48 }
49 return ((void *)q);
50}
51
52/* delete node with given key */
53void *
54tdelete(vkey, vrootp, compar)
55 const void *vkey; /* key to be deleted */
56 void **vrootp; /* address of the root of tree */
57 int (*compar)(const void *, const void *);
58{
59 node **rootp = (node **)vrootp;
60 char *key = (char *)vkey;
61 node *p;
62 register node *q;
63 register node *r;
64 int cmp;
65
66 if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
67 return ((struct node_t *)0);
68 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
69 p = *rootp;
70 rootp = (cmp < 0) ?
71 &(*rootp)->left : /* follow left branch */
72 &(*rootp)->right; /* follow right branch */
73 if (*rootp == (struct node_t *)0)
74 return ((void *)0); /* key not found */
75 }
76 r = (*rootp)->right; /* D1: */
77 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
78 q = r;
79 else if (r != (struct node_t *)0) { /* Right link is null? */
80 if (r->left == (struct node_t *)0) { /* D2: Find successor */
81 r->left = q;
82 q = r;
83 } else { /* D3: Find (struct node_t *)0 link */
84 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
85 r = q;
86 r->left = q->right;
87 q->left = (*rootp)->left;
88 q->right = (*rootp)->right;
89 }
90 }
91 free((struct node_t *) *rootp); /* D4: Free node */
92 *rootp = q; /* link parent to new node */
93 return(p);
94}
95
96/* Walk the nodes of a tree */
97static void
98trecurse(root, action, level)
99 register node *root; /* Root of the tree to be walked */
100 register void (*action)(); /* Function to be called at each node */
101 register int level;
102{
103 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
104 (*action)(root, leaf, level);
105 else {
106 (*action)(root, preorder, level);
107 if (root->left != (struct node_t *)0)
108 trecurse(root->left, action, level + 1);
109 (*action)(root, postorder, level);
110 if (root->right != (struct node_t *)0)
111 trecurse(root->right, action, level + 1);
112 (*action)(root, endorder, level);
113 }
114}
115
116/* Walk the nodes of a tree */
117void
118twalk(vroot, action)
119 const void *vroot; /* Root of the tree to be walked */
120 void (*action)(const void *, VISIT, int);
121{
122 node *root = (node *)vroot;
123
124 if (root != (node *)0 && action != (void(*)())0)
125 trecurse(root, action, 0);
126}
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
new file mode 100644
index 0000000000..e7b81d0c43
--- /dev/null
+++ b/src/lib/libc/string/Makefile.inc
@@ -0,0 +1,151 @@
1# $OpenBSD: Makefile.inc,v 1.10 2001/09/05 16:27:01 mickey Exp $
2
3# string sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string ${LIBCSRCDIR}/string
5
6SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \
7 strlcat.c strmode.c strsignal.c strtok.c strxfrm.c \
8 __strerror.c __strsignal.c
9
10# machine-dependent net sources
11# m-d Makefile.inc must include sources for:
12# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset()
13# rindex() strcat() strcmp() strcpy() strcspn() strlen() strlcpy()
14# strncat() strncmp() strncpy() strpbrk() strsep()
15# strspn() strstr() swav()
16# m-d Makefile.inc may include sources for:
17# memcpy() memmove() strchr() strrchr()
18
19.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc"
20
21# if no machine specific memmove(3), build one out of bcopy(3).
22.if empty(SRCS:Mmemmove.S)
23OBJS+= memmove.o
24memmove.o: bcopy.c
25 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
26 @${LD} -x -r ${.TARGET}
27 @mv a.out ${.TARGET}
28
29memmove.go: bcopy.c
30 ${CC} -g -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
31 @${LD} -x -r ${.TARGET}
32 @mv a.out ${.TARGET}
33
34memmove.po: bcopy.c
35 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
36 @${LD} -X -r ${.TARGET}
37 @mv a.out ${.TARGET}
38
39memmove.so: bcopy.c
40 ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
41 -o ${.TARGET}
42.endif
43
44# if no machine specific memcpy(3), build one out of bcopy(3).
45# if there is a machine specific memmove(3), we'll assume it aliases
46# memcpy(3).
47.if empty(SRCS:Mmemcpy.S)
48.if empty(SRCS:Mmemmove.S)
49OBJS+= memcpy.o
50memcpy.o: bcopy.c
51 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
52 @${LD} -x -r ${.TARGET}
53 @mv a.out ${.TARGET}
54
55memcpy.go: bcopy.c
56 ${CC} -g -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
57 @${LD} -x -r ${.TARGET}
58 @mv a.out ${.TARGET}
59
60memcpy.po: bcopy.c
61 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
62 @${LD} -X -r ${.TARGET}
63 @mv a.out ${.TARGET}
64
65memcpy.so: bcopy.c
66 ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
67 -o ${.TARGET}
68.endif
69.endif
70
71# if no machine specific strchr(3), build one out of index(3).
72.if empty(SRCS:Mstrchr.S)
73OBJS+= strchr.o
74strchr.o: index.c
75 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
76 @${LD} -x -r ${.TARGET}
77 @mv a.out ${.TARGET}
78
79strchr.go: index.c
80 ${CC} -g -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
81 @${LD} -x -r ${.TARGET}
82 @mv a.out ${.TARGET}
83
84strchr.po: index.c
85 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
86 @${LD} -X -r ${.TARGET}
87 @mv a.out ${.TARGET}
88
89strchr.so: index.c
90 ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
91 -o ${.TARGET}
92.endif
93
94# if no machine specific strrchr(3), build one out of rindex(3).
95.if empty(SRCS:Mstrrchr.S)
96OBJS+= strrchr.o
97strrchr.o: rindex.c
98 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
99 @${LD} -x -r ${.TARGET}
100 @mv a.out ${.TARGET}
101
102strrchr.go: rindex.c
103 ${CC} -g -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
104 @${LD} -x -r ${.TARGET}
105 @mv a.out ${.TARGET}
106
107strrchr.po: rindex.c
108 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
109 @${LD} -X -r ${.TARGET}
110 @mv a.out ${.TARGET}
111
112strrchr.so: rindex.c
113 ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
114 -o ${.TARGET}
115.endif
116
117# build .ln files for memmove, memcpy, strchr and strrchr always from
118# bcopy, index, and rindex
119LOBJS+= memmove.ln memcpy.ln strchr.ln strrchr.ln
120
121memmove.ln: bcopy.c
122 lint ${LINTFLAGS} -DMEMMOVE ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
123 ${LIBCSRCDIR}/string/bcopy.c
124
125memcpy.ln: bcopy.c
126 lint ${LINTFLAGS} -DMEMCOPY ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
127 ${LIBCSRCDIR}/string/bcopy.c
128
129strchr.ln: index.c
130 lint ${LINTFLAGS} -DSTRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
131 ${LIBCSRCDIR}/string/index.c
132
133strrchr.ln: rindex.c
134 lint ${LINTFLAGS} -DSTRRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
135 ${LIBCSRCDIR}/string/rindex.c
136
137MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \
138 memcmp.3 memcpy.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \
139 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \
140 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
141 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3
142
143MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3
144MLINKS+=strchr.3 index.3
145MLINKS+=strrchr.3 rindex.3
146MLINKS+=strcasecmp.3 strncasecmp.3
147MLINKS+=strcat.3 strncat.3
148MLINKS+=strcmp.3 strncmp.3
149MLINKS+=strcpy.3 strncpy.3
150MLINKS+=strlcpy.3 strlcat.3
151MLINKS+=strtok.3 strtok_r.3
diff --git a/src/lib/libc/string/__strerror.c b/src/lib/libc/string/__strerror.c
new file mode 100644
index 0000000000..ae19ab3365
--- /dev/null
+++ b/src/lib/libc/string/__strerror.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: __strerror.c,v 1.8 2001/12/08 20:37:32 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifdef NLS
39#define catclose _catclose
40#define catgets _catgets
41#define catopen _catopen
42#include <nl_types.h>
43#endif
44
45#define sys_errlist _sys_errlist
46#define sys_nerr _sys_nerr
47
48#include <errno.h>
49#include <limits.h>
50#include <stdio.h>
51#include <string.h>
52
53static char *
54itoa(num)
55 int num;
56{
57 static char buffer[11];
58 char *p;
59
60 p = buffer + 4;
61 while (num >= 10) {
62 *--p = (num % 10) + '0';
63 num /= 10;
64 }
65 *p = (num % 10) + '0';
66 return p;
67}
68
69/*
70 * Since perror() is not allowed to change the contents of strerror()'s
71 * static buffer, both functions supply their own buffers to the
72 * internal function __strerror().
73 */
74
75char *
76__strerror(num, buf)
77 int num;
78 char *buf;
79{
80#define UPREFIX "Unknown error: "
81 register unsigned int errnum;
82#ifdef NLS
83 int save_errno;
84 nl_catd catd;
85
86 catd = catopen("libc", 0);
87#endif
88
89 errnum = num; /* convert to unsigned */
90 if (errnum < sys_nerr) {
91#ifdef NLS
92 strlcpy(buf, catgets(catd, 1, errnum,
93 (char *)sys_errlist[errnum]), NL_TEXTMAX);
94#else
95 return(sys_errlist[errnum]);
96#endif
97 } else {
98#ifdef NLS
99 strlcpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX);
100#else
101 strcpy(buf, UPREFIX);
102#endif
103 strncat(buf, itoa(errnum), NL_TEXTMAX-strlen(buf)-1);
104 errno = EINVAL;
105 }
106
107#ifdef NLS
108 save_errno = errno;
109 catclose(catd);
110 errno = save_errno;
111#endif
112
113 return buf;
114}
diff --git a/src/lib/libc/string/__strsignal.c b/src/lib/libc/string/__strsignal.c
new file mode 100644
index 0000000000..4ca5bad3c0
--- /dev/null
+++ b/src/lib/libc/string/__strsignal.c
@@ -0,0 +1,102 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: __strsignal.c,v 1.6 2001/06/27 00:58:56 lebel Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifdef NLS
39#define catclose _catclose
40#define catgets _catgets
41#define catopen _catopen
42#include <nl_types.h>
43#endif
44
45#define sys_siglist _sys_siglist
46
47#include <stdio.h>
48#include <limits.h>
49#include <signal.h>
50#include <string.h>
51
52static char *itoa(num)
53 int num;
54{
55 static char buffer[11];
56 char *p;
57
58 p = buffer + 4;
59 while (num >= 10) {
60 *--p = (num % 10) + '0';
61 num /= 10;
62 }
63 *p = (num % 10) + '0';
64 return p;
65}
66
67char *
68__strsignal(num, buf)
69 int num;
70 char *buf;
71{
72#define UPREFIX "Unknown signal: "
73 register unsigned int signum;
74
75#ifdef NLS
76 nl_catd catd ;
77 catd = catopen("libc", 0);
78#endif
79
80 signum = num; /* convert to unsigned */
81 if (signum < NSIG) {
82#ifdef NLS
83 strlcpy(buf, catgets(catd, 2, signum,
84 (char *)sys_siglist[signum]), NL_TEXTMAX);
85#else
86 return((char *)sys_siglist[signum]);
87#endif
88 } else {
89#ifdef NLS
90 strlcpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX);
91#else
92 strcpy(buf, UPREFIX);
93#endif
94 strncat(buf, itoa(signum), NL_TEXTMAX-strlen(buf)-1);
95 }
96
97#ifdef NLS
98 catclose(catd);
99#endif
100
101 return buf;
102}
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
new file mode 100644
index 0000000000..d880c1e6f0
--- /dev/null
+++ b/src/lib/libc/string/bcmp.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bcmp.3,v 1.5 2000/04/21 15:24:18 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt BCMP 3
38.Os
39.Sh NAME
40.Nm bcmp
41.Nd compare byte string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft int
45.Fn bcmp "const void *b1" "const void *b2" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn bcmp
49function compares byte string
50.Fa b1
51against byte string
52.Fa b2 ,
53returning zero if they are identical, non-zero otherwise.
54Both strings are assumed to be
55.Fa len
56bytes long.
57Zero-length strings are always identical.
58.Pp
59The strings may overlap.
60.Sh SEE ALSO
61.Xr memcmp 3 ,
62.Xr strcasecmp 3 ,
63.Xr strcmp 3 ,
64.Xr strcoll 3 ,
65.Xr strxfrm 3
66.Sh HISTORY
67A
68.Fn bcmp
69function first appeared in
70.Bx 4.2 .
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c
new file mode 100644
index 0000000000..4ed00975a4
--- /dev/null
+++ b/src/lib/libc/string/bcmp.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bcmp.c,v 1.4 1996/08/19 08:33:57 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44/*
45 * bcmp -- vax cmpc3 instruction
46 */
47int
48bcmp(b1, b2, length)
49 const void *b1, *b2;
50 register size_t length;
51{
52 register char *p1, *p2;
53
54 if (length == 0)
55 return(0);
56 p1 = (char *)b1;
57 p2 = (char *)b2;
58 do
59 if (*p1++ != *p2++)
60 break;
61 while (--length);
62 return(length);
63}
diff --git a/src/lib/libc/string/bcopy.3 b/src/lib/libc/string/bcopy.3
new file mode 100644
index 0000000000..b290418f4a
--- /dev/null
+++ b/src/lib/libc/string/bcopy.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: bcopy.3,v 1.5 2000/04/21 15:24:19 aaron Exp $
36.\"
37.Dd April 19, 1991
38.Dt BCOPY 3
39.Os
40.Sh NAME
41.Nm bcopy
42.Nd copy byte string
43.Sh SYNOPSIS
44.Fd #include <string.h>
45.Ft void
46.Fn bcopy "const void *src" "void *dst" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn bcopy
50function copies
51.Fa len
52bytes from string
53.Fa src
54to string
55.Fa dst .
56The two strings may overlap.
57If
58.Fa len
59is zero, no bytes are copied.
60.Sh SEE ALSO
61.Xr memccpy 3 ,
62.Xr memcpy 3 ,
63.Xr memmove 3 ,
64.Xr strcpy 3 ,
65.Xr strncpy 3
66.Sh HISTORY
67A
68.Fn bcopy
69function appeared in
70.Bx 4.2 .
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c
new file mode 100644
index 0000000000..023a3b2db2
--- /dev/null
+++ b/src/lib/libc/string/bcopy.c
@@ -0,0 +1,138 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: bcopy.c,v 1.2 1996/08/19 08:33:58 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * sizeof(word) MUST BE A POWER OF TWO
45 * SO THAT wmask BELOW IS ALL ONES
46 */
47typedef long word; /* "word" used for optimal copy speed */
48
49#define wsize sizeof(word)
50#define wmask (wsize - 1)
51
52/*
53 * Copy a block of memory, handling overlap.
54 * This is the routine that actually implements
55 * (the portable versions of) bcopy, memcpy, and memmove.
56 */
57#ifdef MEMCOPY
58void *
59memcpy(dst0, src0, length)
60#else
61#ifdef MEMMOVE
62void *
63memmove(dst0, src0, length)
64#else
65void
66bcopy(src0, dst0, length)
67#endif
68#endif
69 void *dst0;
70 const void *src0;
71 register size_t length;
72{
73 register char *dst = dst0;
74 register const char *src = src0;
75 register size_t t;
76
77 if (length == 0 || dst == src) /* nothing to do */
78 goto done;
79
80 /*
81 * Macros: loop-t-times; and loop-t-times, t>0
82 */
83#define TLOOP(s) if (t) TLOOP1(s)
84#define TLOOP1(s) do { s; } while (--t)
85
86 if ((unsigned long)dst < (unsigned long)src) {
87 /*
88 * Copy forward.
89 */
90 t = (long)src; /* only need low bits */
91 if ((t | (long)dst) & wmask) {
92 /*
93 * Try to align operands. This cannot be done
94 * unless the low bits match.
95 */
96 if ((t ^ (long)dst) & wmask || length < wsize)
97 t = length;
98 else
99 t = wsize - (t & wmask);
100 length -= t;
101 TLOOP1(*dst++ = *src++);
102 }
103 /*
104 * Copy whole words, then mop up any trailing bytes.
105 */
106 t = length / wsize;
107 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
108 t = length & wmask;
109 TLOOP(*dst++ = *src++);
110 } else {
111 /*
112 * Copy backwards. Otherwise essentially the same.
113 * Alignment works as before, except that it takes
114 * (t&wmask) bytes to align, not wsize-(t&wmask).
115 */
116 src += length;
117 dst += length;
118 t = (long)src;
119 if ((t | (long)dst) & wmask) {
120 if ((t ^ (long)dst) & wmask || length <= wsize)
121 t = length;
122 else
123 t &= wmask;
124 length -= t;
125 TLOOP1(*--dst = *--src);
126 }
127 t = length / wsize;
128 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
129 t = length & wmask;
130 TLOOP(*--dst = *--src);
131 }
132done:
133#if defined(MEMCOPY) || defined(MEMMOVE)
134 return (dst0);
135#else
136 return;
137#endif
138}
diff --git a/src/lib/libc/string/bm.3 b/src/lib/libc/string/bm.3
new file mode 100644
index 0000000000..7138ee4271
--- /dev/null
+++ b/src/lib/libc/string/bm.3
@@ -0,0 +1,115 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Andrew Hume of AT&T Bell Laboratories.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\" $OpenBSD: bm.3,v 1.6 2001/06/23 14:42:12 deraadt Exp $
36.\"
37.Dd June 29, 1999
38.Dt BM 3
39.Os
40.Sh NAME
41.Nm bm_comp ,
42.Nm bm_exec ,
43.Nm bm_free
44.Nd Boyer-Moore string search
45.Sh SYNOPSIS
46.Fd #include <sys/types.h>
47.Fd #include <bm.h>
48.Ft bm_pat *
49.Fn bm_comp "u_char *pattern" "size_t patlen" "u_char freq[256]"
50.Ft u_char *
51.Fn bm_exec "bm_pat *pdesc" "u_char *text" "size_t len"
52.Ft void
53.Fn bm_free "bm_pat *pdesc"
54.Sh DESCRIPTION
55These routines implement an efficient mechanism to find an
56occurrence of a byte string within another byte string.
57.Pp
58.Fn bm_comp
59evaluates
60.Fa patlen
61bytes starting at
62.Fa pattern
63and returns a pointer to a structure describing them.
64The bytes referenced by
65.Fa pattern
66may be of any value.
67.Pp
68The search takes advantage of the frequency distribution of the
69bytes in the text to be searched.
70If specified,
71.Ar freq
72should be an array of 256 values,
73with higher values indicating that the corresponding character occurs
74more frequently.
75(A less than optimal frequency distribution can only result in less
76than optimal performance, not incorrect results.)
77If
78.Ar freq
79is
80.Dv NULL ,
81a system default table is used.
82.Pp
83.Fn bm_exec
84returns a pointer to the leftmost occurrence of the string given to
85.Fn bm_comp
86within
87.Ar text ,
88or
89.Dv NULL
90if none occurs.
91The number of bytes in
92.Ar text
93must be specified by
94.Ar len .
95.Pp
96Space allocated for the returned description is discarded
97by calling
98.Fn bm_free
99with the returned description as an argument.
100.Pp
101The asymptotic speed of
102.Fn bm_exec
103is
104.Pf O Ns Pq len / patlen .
105.Sh SEE ALSO
106.Xr regexp 3 ,
107.Xr strstr 3
108.Rs
109.%R "Fast String Searching"
110.%A Andrew Hume
111.%A Daniel Sunday
112.%J "Software Practice and Experience"
113.%V Volume 21, 11 (November 1991)
114.%P 1221-48
115.Re
diff --git a/src/lib/libc/string/bm.c b/src/lib/libc/string/bm.c
new file mode 100644
index 0000000000..b191d340f6
--- /dev/null
+++ b/src/lib/libc/string/bm.c
@@ -0,0 +1,219 @@
1/*-
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Andrew Hume of AT&T Bell Laboratories.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: bm.c,v 1.3 1996/08/19 08:33:59 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <sys/types.h>
42
43#include <bm.h>
44#include <errno.h>
45#include <stdlib.h>
46#include <string.h>
47
48/*
49 * XXX
50 * The default frequency table starts at 99 and counts down. The default
51 * table should probably be oriented toward text, and will necessarily be
52 * locale specific. This one is for English. It was derived from the
53 * OSF/1 and 4.4BSD formatted and unformatted manual pages, and about 100Mb
54 * of email and random text. Change it if you can find something better.
55 */
56static u_char const freq_def[256] = {
57 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 77, 90, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0,
61 99, 28, 42, 27, 16, 14, 20, 51,
62 66, 65, 59, 24, 75, 76, 84, 56,
63 72, 74, 64, 55, 54, 47, 41, 37,
64 44, 61, 70, 43, 23, 53, 49, 22,
65 33, 58, 40, 46, 45, 57, 60, 26,
66 30, 63, 21, 12, 32, 50, 38, 39,
67 34, 11, 48, 67, 62, 35, 15, 29,
68 71, 18, 9, 17, 25, 13, 10, 52,
69 36, 95, 78, 86, 87, 98, 82, 80,
70 88, 94, 19, 68, 89, 83, 93, 96,
71 81, 7, 91, 92, 97, 85, 69, 73,
72 31, 79, 8, 5, 4, 6, 3, 0,
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0,
89};
90
91bm_pat *
92bm_comp(pb, len, freq)
93 u_char const *pb;
94 size_t len;
95 u_char const *freq;
96{
97 register u_char const *pe, *p;
98 register size_t *d, r;
99 register int j;
100 int sv_errno;
101 bm_pat *pat;
102
103 if (len == 0) {
104 errno = EINVAL;
105 return (NULL);
106 }
107 if ((pat = malloc(sizeof(*pat))) == NULL)
108 return (NULL);
109 pat->pat = NULL;
110 pat->delta = NULL;
111
112 pat->patlen = len; /* copy pattern */
113 if ((pat->pat = malloc(pat->patlen)) == NULL)
114 goto mem;
115 memcpy(pat->pat, pb, pat->patlen);
116 /* get skip delta */
117 if ((pat->delta = malloc(256 * sizeof(*d))) == NULL)
118 goto mem;
119 for (j = 0, d = pat->delta; j < 256; j++)
120 d[j] = pat->patlen;
121 for (pe = pb + pat->patlen - 1; pb <= pe; pb++)
122 d[*pb] = pe - pb;
123
124 if (freq == NULL) /* default freq table */
125 freq = freq_def;
126 r = 0; /* get guard */
127 for (pb = pat->pat, pe = pb + pat->patlen - 1; pb < pe; pb++)
128 if (freq[*pb] < freq[pat->pat[r]])
129 r = pb - pat->pat;
130 pat->rarec = pat->pat[r];
131 pat->rareoff = r - (pat->patlen - 1);
132
133 /* get md2 shift */
134 for (pe = pat->pat + pat->patlen - 1, p = pe - 1; p >= pat->pat; p--)
135 if (*p == *pe)
136 break;
137
138 /* *p is first leftward reoccurrence of *pe */
139 pat->md2 = pe - p;
140 return (pat);
141
142mem: sv_errno = errno;
143 bm_free(pat);
144 errno = sv_errno;
145 return (NULL);
146}
147
148void
149bm_free(pat)
150 bm_pat *pat;
151{
152 if (pat->pat != NULL)
153 free(pat->pat);
154 if (pat->delta != NULL)
155 free(pat->delta);
156 free(pat);
157}
158
159u_char *
160bm_exec(pat, base, n)
161 bm_pat *pat;
162 u_char *base;
163 size_t n;
164{
165 register u_char *e, *ep, *p, *q, *s;
166 register size_t *d0, k, md2, n1, ro;
167 register int rc;
168
169 if (n == 0)
170 return (NULL);
171
172 d0 = pat->delta;
173 n1 = pat->patlen - 1;
174 md2 = pat->md2;
175 ro = pat->rareoff;
176 rc = pat->rarec;
177 ep = pat->pat + pat->patlen - 1;
178 s = base + (pat->patlen - 1);
179
180 /* fast loop up to n - 3 * patlen */
181 e = base + n - 3 * pat->patlen;
182 while (s < e) {
183 k = d0[*s]; /* ufast skip loop */
184 while (k) {
185 k = d0[*(s += k)];
186 k = d0[*(s += k)];
187 }
188 if (s >= e)
189 break;
190 if (s[ro] != rc) /* guard test */
191 goto mismatch1;
192 /* fwd match */
193 for (p = pat->pat, q = s - n1; p < ep;)
194 if (*q++ != *p++)
195 goto mismatch1;
196 return (s - n1);
197
198mismatch1: s += md2; /* md2 shift */
199 }
200
201 /* slow loop up to end */
202 e = base + n;
203 while (s < e) {
204 s += d0[*s]; /* step */
205 if (s >= e)
206 break;
207 if (s[ro] != rc) /* guard test */
208 goto mismatch2;
209 /* fwd match */
210 for (p = pat->pat, q = s - n1; p <= ep;)
211 if (*q++ != *p++)
212 goto mismatch2;
213 return (s - n1);
214
215mismatch2: s += md2; /* md2 shift */
216 }
217
218 return (NULL);
219}
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3
new file mode 100644
index 0000000000..85283321c8
--- /dev/null
+++ b/src/lib/libc/string/bstring.3
@@ -0,0 +1,110 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bstring.3,v 1.4 2000/04/21 15:24:19 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt BSTRING 3
38.Os
39.Sh NAME
40.Nm bcmp ,
41.Nm bcopy ,
42.Nm bzero ,
43.Nm memccpy ,
44.Nm memchr ,
45.Nm memcmp ,
46.Nm memcpy ,
47.Nm memmove ,
48.Nm memset
49.Nd byte string operations
50.Sh SYNOPSIS
51.Fd #include <string.h>
52.Ft int
53.Fn bcmp "const void *b1" "const void *b2" "size_t len"
54.Ft void
55.Fn bcopy "const void *src" "void *dst" "size_t len"
56.Ft void
57.Fn bzero "void *b" "size_t len"
58.Ft void *
59.Fn memchr "const void *b" "int c" "size_t len"
60.Ft int
61.Fn memcmp "const void *b1" "const void *b2" "size_t len"
62.Ft void *
63.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
64.Ft void *
65.Fn memcpy "void *dst" "const void *src" "size_t len"
66.Ft void *
67.Fn memmove "void *dst" "const void *src" "size_t len"
68.Ft void *
69.Fn memset "void *b" "int c" "size_t len"
70.Sh DESCRIPTION
71These functions operate on variable length strings of bytes.
72They do not check for terminating null bytes as the routines
73listed in
74.Xr string 3
75do.
76.Pp
77See the specific manual pages for more information.
78.Sh SEE ALSO
79.Xr bcmp 3 ,
80.Xr bcopy 3 ,
81.Xr bzero 3 ,
82.Xr memccpy 3 ,
83.Xr memchr 3 ,
84.Xr memcmp 3 ,
85.Xr memcpy 3 ,
86.Xr memmove 3 ,
87.Xr memset 3
88.Sh STANDARDS
89The functions
90.Fn memchr ,
91.Fn memcmp ,
92.Fn memcpy ,
93.Fn memmove ,
94and
95.Fn memset
96conform to
97.St -ansiC .
98.Sh HISTORY
99The
100.Fn bzero
101and
102.Fn memccpy
103functions appeared in
104.Bx 4.3 .
105The
106.Fn bcmp
107and
108.Fn bcopy
109functions appeared in
110.Bx 4.2 .
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3
new file mode 100644
index 0000000000..a735d5ef3f
--- /dev/null
+++ b/src/lib/libc/string/bzero.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: bzero.3,v 1.5 2000/04/21 15:24:19 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt BZERO 3
38.Os
39.Sh NAME
40.Nm bzero
41.Nd write zeroes to a byte string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void
45.Fn bzero "void *b" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn bzero
49function writes
50.Fa len
51zero bytes to the string
52.Fa b .
53If
54.Fa len
55is zero,
56.Fn bzero
57does nothing.
58.Sh SEE ALSO
59.Xr memset 3 ,
60.Xr swab 3
61.Sh HISTORY
62A
63.Fn bzero
64function appeared in
65.Bx 4.3 .
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c
new file mode 100644
index 0000000000..3e660a307f
--- /dev/null
+++ b/src/lib/libc/string/bzero.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: bzero.c,v 1.3 1996/08/19 08:34:00 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44/*
45 * bzero -- vax movc5 instruction
46 */
47void
48bzero(b, length)
49 void *b;
50 register size_t length;
51{
52 register char *p;
53
54 for (p = b; length--;)
55 *p++ = '\0';
56}
diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3
new file mode 100644
index 0000000000..dc7a20741e
--- /dev/null
+++ b/src/lib/libc/string/ffs.3
@@ -0,0 +1,60 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: ffs.3,v 1.3 2000/04/21 15:24:19 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt FFS 3
38.Os
39.Sh NAME
40.Nm ffs
41.Nd find first bit set in a bit string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft int
45.Fn ffs "int value"
46.Sh DESCRIPTION
47The
48.Fn ffs
49function finds the first bit set in
50.Fa value
51and returns the index of that bit.
52Bits are numbered starting from 1, starting at the rightmost bit.
53A return value of 0 means that the argument was zero.
54.Sh SEE ALSO
55.Xr bitstring 3
56.Sh HISTORY
57The
58.Fn ffs
59function appeared in
60.Bx 4.3 .
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c
new file mode 100644
index 0000000000..887ce437d4
--- /dev/null
+++ b/src/lib/libc/string/ffs.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: ffs.c,v 1.5 2000/07/02 03:10:38 mickey Exp $ */
2
3/*
4 * Public domain.
5 * Written by Dale Rahn.
6 */
7
8#if defined(LIBC_SCCS) && !defined(lint)
9static char *rcsid = "$OpenBSD: ffs.c,v 1.5 2000/07/02 03:10:38 mickey Exp $";
10#endif /* LIBC_SCCS and not lint */
11
12#if !defined(_KERNEL) && !defined(_STANDALONE)
13#include <string.h>
14#else
15#include <lib/libkern/libkern.h>
16#endif
17
18/*
19 * ffs -- vax ffs instruction
20 */
21int
22ffs(mask)
23 register int mask;
24{
25 register int bit;
26 register unsigned int r = mask;
27 static const signed char t[16] = {
28 -28, 1, 2, 1,
29 3, 1, 2, 1,
30 4, 1, 2, 1,
31 3, 1, 2, 1
32 };
33
34 bit = 0;
35 if (!(r & 0xffff)) {
36 bit += 16;
37 r >>= 16;
38 }
39 if (!(r & 0xff)) {
40 bit += 8;
41 r >>= 8;
42 }
43 if (!(r & 0xf)) {
44 bit += 4;
45 r >>= 4;
46 }
47
48 return (bit + t[ r & 0xf ]);
49}
diff --git a/src/lib/libc/string/index.c b/src/lib/libc/string/index.c
new file mode 100644
index 0000000000..8e4b146493
--- /dev/null
+++ b/src/lib/libc/string/index.c
@@ -0,0 +1,54 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: index.c,v 1.3 2002/07/24 04:16:01 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41#ifdef STRCHR
42strchr(const char *p, int ch)
43#else
44index(const char *p, int ch)
45#endif
46{
47 for (;; ++p) {
48 if (*p == ch)
49 return((char *)p);
50 if (!*p)
51 return((char *)NULL);
52 }
53 /* NOTREACHED */
54}
diff --git a/src/lib/libc/string/memccpy.3 b/src/lib/libc/string/memccpy.3
new file mode 100644
index 0000000000..feedeff3a6
--- /dev/null
+++ b/src/lib/libc/string/memccpy.3
@@ -0,0 +1,76 @@
1.\" $OpenBSD: memccpy.3,v 1.6 2000/04/21 15:24:19 aaron Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt MEMCCPY 3
38.Os
39.Sh NAME
40.Nm memccpy
41.Nd copy string until character found
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void *
45.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
46.Sh DESCRIPTION
47The
48.Fn memccpy
49function copies bytes from string
50.Fa src
51to string
52.Fa dst .
53If the character
54.Fa c
55(as converted to an
56.Li unsigned char )
57occurs in the string
58.Fa src ,
59the copy stops and a pointer to the byte after the copy of
60.Fa c
61in the string
62.Fa dst
63is returned.
64Otherwise,
65.Fa len
66bytes are copied, and a null pointer is returned.
67.Sh SEE ALSO
68.Xr bcopy 3 ,
69.Xr memcpy 3 ,
70.Xr memmove 3 ,
71.Xr strcpy 3
72.Sh HISTORY
73The
74.Fn memccpy
75function first appeared in
76.Bx 4.4 .
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c
new file mode 100644
index 0000000000..020e6e5679
--- /dev/null
+++ b/src/lib/libc/string/memccpy.c
@@ -0,0 +1,64 @@
1/* $OpenBSD: memccpy.c,v 1.3 1997/08/20 04:09:39 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
39#else
40static char *rcsid = "$OpenBSD: memccpy.c,v 1.3 1997/08/20 04:09:39 millert Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <string.h>
45
46void *
47memccpy(t, f, c, n)
48 void *t;
49 const void *f;
50 int c;
51 register size_t n;
52{
53
54 if (n) {
55 register unsigned char *tp = t;
56 register const unsigned char *fp = f;
57 register unsigned char uc = c;
58 do {
59 if ((*tp++ = *fp++) == uc)
60 return (tp);
61 } while (--n != 0);
62 }
63 return (0);
64}
diff --git a/src/lib/libc/string/memchr.3 b/src/lib/libc/string/memchr.3
new file mode 100644
index 0000000000..632c440b5b
--- /dev/null
+++ b/src/lib/libc/string/memchr.3
@@ -0,0 +1,78 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memchr.3,v 1.5 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCHR 3
40.Os
41.Sh NAME
42.Nm memchr
43.Nd locate byte in byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memchr "const void *b" "int c" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memchr
51function locates the first occurrence of
52.Fa c
53(converted to an
54.Li unsigned char )
55in string
56.Fa b .
57.Sh RETURN VALUES
58The
59.Fn memchr
60function returns a pointer to the byte located, or
61.Dv NULL
62if no such byte exists within
63.Fa len
64bytes.
65.Sh SEE ALSO
66.Xr strchr 3 ,
67.Xr strcspn 3 ,
68.Xr strpbrk 3 ,
69.Xr strrchr 3 ,
70.Xr strsep 3 ,
71.Xr strspn 3 ,
72.Xr strstr 3 ,
73.Xr strtok 3
74.Sh STANDARDS
75The
76.Fn memchr
77function conforms to
78.St -ansiC .
diff --git a/src/lib/libc/string/memchr.c b/src/lib/libc/string/memchr.c
new file mode 100644
index 0000000000..d605d4734f
--- /dev/null
+++ b/src/lib/libc/string/memchr.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memchr.c,v 1.4 2001/09/07 08:09:31 espie Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43void *
44memchr(s, c, n)
45 const void *s;
46 int c;
47 size_t n;
48{
49 if (n != 0) {
50 const unsigned char *p = s;
51
52 do {
53 if (*p++ == (unsigned char)c)
54 return ((void *)(p - 1));
55 } while (--n != 0);
56 }
57 return (NULL);
58}
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3
new file mode 100644
index 0000000000..db4fef364b
--- /dev/null
+++ b/src/lib/libc/string/memcmp.3
@@ -0,0 +1,81 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memcmp.3,v 1.4 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCMP 3
40.Os
41.Sh NAME
42.Nm memcmp
43.Nd compare byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn memcmp "const void *b1" "const void *b2" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memcmp
51function compares byte string
52.Fa b1
53against byte string
54.Fa b2 .
55Both strings are assumed to be
56.Fa len
57bytes long.
58.Sh RETURN VALUES
59The
60.Fn memcmp
61function returns zero if the two strings are identical,
62otherwise returns the difference between the first two differing bytes
63(treated as
64.Li unsigned char
65values, so that
66.Sq Li \e200
67is greater than
68.Sq Li \&\e0 ,
69for example).
70Zero-length strings are always identical.
71.Sh SEE ALSO
72.Xr bcmp 3 ,
73.Xr strcasecmp 3 ,
74.Xr strcmp 3 ,
75.Xr strcoll 3 ,
76.Xr strxfrm 3
77.Sh STANDARDS
78The
79.Fn memcmp
80function conforms to
81.St -ansiC .
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c
new file mode 100644
index 0000000000..5ce33e2998
--- /dev/null
+++ b/src/lib/libc/string/memcmp.c
@@ -0,0 +1,60 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memcmp.c,v 1.2 1996/08/19 08:34:05 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Compare memory regions.
45 */
46int
47memcmp(s1, s2, n)
48 const void *s1, *s2;
49 size_t n;
50{
51 if (n != 0) {
52 register const unsigned char *p1 = s1, *p2 = s2;
53
54 do {
55 if (*p1++ != *p2++)
56 return (*--p1 - *--p2);
57 } while (--n != 0);
58 }
59 return (0);
60}
diff --git a/src/lib/libc/string/memcpy.3 b/src/lib/libc/string/memcpy.3
new file mode 100644
index 0000000000..030eadff20
--- /dev/null
+++ b/src/lib/libc/string/memcpy.3
@@ -0,0 +1,80 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memcpy.3,v 1.3 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMCPY 3
40.Os
41.Sh NAME
42.Nm memcpy
43.Nd copy byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memcpy "void *dst" "const void *src" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memcpy
51function copies
52.Fa len
53bytes from string
54.Fa src
55to string
56.Fa dst .
57.Sh RETURN VALUES
58The
59.Fn memcpy
60function returns the original value of
61.Fa dst .
62.Sh SEE ALSO
63.Xr bcopy 3 ,
64.Xr memccpy 3 ,
65.Xr memmove 3 ,
66.Xr strcpy 3
67.Sh STANDARDS
68The
69.Fn memcpy
70function conforms to
71.St -ansiC .
72.Sh BUGS
73In this implementation
74.Fn memcpy
75is implemented using
76.Xr bcopy 3 ,
77and therefore the strings may overlap.
78On other systems, copying overlapping strings may produce surprises.
79A simpler solution is to not use
80.Fn memcpy .
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3
new file mode 100644
index 0000000000..026dab0f9f
--- /dev/null
+++ b/src/lib/libc/string/memmove.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memmove.3,v 1.3 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMMOVE 3
40.Os
41.Sh NAME
42.Nm memmove
43.Nd copy byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memmove "void *dst" "const void *src" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memmove
51function copies
52.Fa len
53bytes from string
54.Fa src
55to string
56.Fa dst .
57The two strings may overlap;
58the copy is always done in a non-destructive manner.
59.Sh RETURN VALUES
60The
61.Fn memmove
62function returns the original value of
63.Fa dst .
64.Sh SEE ALSO
65.Xr bcopy 3 ,
66.Xr memccpy 3 ,
67.Xr memcpy 3 ,
68.Xr strcpy 3
69.Sh STANDARDS
70The
71.Fn memmove
72function conforms to
73.St -ansiC .
diff --git a/src/lib/libc/string/memset.3 b/src/lib/libc/string/memset.3
new file mode 100644
index 0000000000..9da14983c7
--- /dev/null
+++ b/src/lib/libc/string/memset.3
@@ -0,0 +1,71 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: memset.3,v 1.4 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt MEMSET 3
40.Os
41.Sh NAME
42.Nm memset
43.Nd write a byte to byte string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft void *
47.Fn memset "void *b" "int c" "size_t len"
48.Sh DESCRIPTION
49The
50.Fn memset
51function writes
52.Fa len
53bytes of value
54.Fa c
55(converted to an
56.Li unsigned char )
57to the string
58.Fa b .
59.Sh RETURN VALUES
60The
61.Fn memset
62function returns the original value of
63.Fa b .
64.Sh SEE ALSO
65.Xr bzero 3 ,
66.Xr swab 3
67.Sh STANDARDS
68The
69.Fn memset
70function conforms to
71.St -ansiC .
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c
new file mode 100644
index 0000000000..c3373a21a9
--- /dev/null
+++ b/src/lib/libc/string/memset.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: memset.c,v 1.2 1996/08/19 08:34:07 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43void *
44memset(dst, c, n)
45 void *dst;
46 register int c;
47 register size_t n;
48{
49
50 if (n != 0) {
51 register char *d = dst;
52
53 do
54 *d++ = c;
55 while (--n != 0);
56 }
57 return (dst);
58}
diff --git a/src/lib/libc/string/rindex.c b/src/lib/libc/string/rindex.c
new file mode 100644
index 0000000000..7c7c94ae81
--- /dev/null
+++ b/src/lib/libc/string/rindex.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: rindex.c,v 1.3 2002/07/24 04:16:01 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41#ifdef STRRCHR
42strrchr(const char *p, int ch)
43#else
44rindex(const char *p, int ch)
45#endif
46{
47 register char *save;
48
49 for (save = NULL;; ++p) {
50 if (*p == ch)
51 save = (char *)p;
52 if (!*p)
53 return(save);
54 }
55 /* NOTREACHED */
56}
diff --git a/src/lib/libc/string/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3
new file mode 100644
index 0000000000..3cfc76e36f
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.3
@@ -0,0 +1,88 @@
1.\" $OpenBSD: strcasecmp.3,v 1.6 2000/04/21 15:24:19 aaron Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
37.\"
38.Dd June 9, 1993
39.Dt STRCASECMP 3
40.Os
41.Sh NAME
42.Nm strcasecmp ,
43.Nm strncasecmp
44.Nd compare strings, ignoring case
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft int
48.Fn strcasecmp "const char *s1" "const char *s2"
49.Ft int
50.Fn strncasecmp "const char *s1" "const char *s2" "size_t len"
51.Sh DESCRIPTION
52The
53.Fn strcasecmp
54and
55.Fn strncasecmp
56functions compare the null-terminated strings
57.Fa s1
58and
59.Fa s2
60and return an integer greater than, equal to, or less than 0,
61according as
62.Fa s1
63is lexicographically greater than, equal to, or less than
64.Fa s2
65after translation of each corresponding character to lower-case.
66The strings themselves are not modified.
67The comparison is done using unsigned characters, so that
68.Sq Li \e200
69is greater than
70.Ql \e0 .
71.Pp
72.Fn strncasecmp
73compares at most
74.Fa len
75characters.
76.Sh SEE ALSO
77.Xr bcmp 3 ,
78.Xr memcmp 3 ,
79.Xr strcmp 3 ,
80.Xr strcoll 3 ,
81.Xr strxfrm 3
82.Sh HISTORY
83The
84.Fn strcasecmp
85and
86.Fn strncasecmp
87functions first appeared in
88.Bx 4.4 .
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000000..1f487524aa
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.c
@@ -0,0 +1,120 @@
1/* $OpenBSD: strcasecmp.c,v 1.3 1997/08/20 04:13:57 millert Exp $ */
2
3/*
4 * Copyright (c) 1987, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <string.h>
37
38#if defined(LIBC_SCCS) && !defined(lint)
39#if 0
40static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
41#else
42static char *rcsid = "$OpenBSD: strcasecmp.c,v 1.3 1997/08/20 04:13:57 millert Exp $";
43#endif
44#endif /* LIBC_SCCS and not lint */
45
46typedef unsigned char u_char;
47
48/*
49 * This array is designed for mapping upper and lower case letter
50 * together for a case independent comparison. The mappings are
51 * based upon ascii character sequences.
52 */
53static const u_char charmap[] = {
54 '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
55 '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
56 '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
57 '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
58 '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
59 '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
60 '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
61 '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
62 '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
63 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
64 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
65 '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
66 '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
67 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
68 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
69 '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
70 '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
71 '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
72 '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
73 '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
74 '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
75 '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
76 '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
77 '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
78 '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
79 '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
80 '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
81 '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
82 '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
83 '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
84 '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
85 '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
86};
87
88int
89strcasecmp(s1, s2)
90 const char *s1, *s2;
91{
92 register const u_char *cm = charmap,
93 *us1 = (const u_char *)s1,
94 *us2 = (const u_char *)s2;
95
96 while (cm[*us1] == cm[*us2++])
97 if (*us1++ == '\0')
98 return (0);
99 return (cm[*us1] - cm[*--us2]);
100}
101
102int
103strncasecmp(s1, s2, n)
104 const char *s1, *s2;
105 register size_t n;
106{
107 if (n != 0) {
108 register const u_char *cm = charmap,
109 *us1 = (const u_char *)s1,
110 *us2 = (const u_char *)s2;
111
112 do {
113 if (cm[*us1] != cm[*us2++])
114 return (cm[*us1] - cm[*--us2]);
115 if (*us1++ == '\0')
116 break;
117 } while (--n != 0);
118 }
119 return (0);
120}
diff --git a/src/lib/libc/string/strcat.3 b/src/lib/libc/string/strcat.3
new file mode 100644
index 0000000000..e9e5163bd3
--- /dev/null
+++ b/src/lib/libc/string/strcat.3
@@ -0,0 +1,135 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcat.3,v 1.8 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd July 8, 1997
39.Dt STRCAT 3
40.Os
41.Sh NAME
42.Nm strcat ,
43.Nm strncat
44.Nd concatenate strings
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strcat "char *s" "const char *append"
49.Ft char *
50.Fn strncat "char *s" "const char *append" "size_t count"
51.Sh DESCRIPTION
52The
53.Fn strcat
54and
55.Fn strncat
56functions append a copy of the null-terminated string
57.Fa append
58to the end of the null-terminated string
59.Fa s ,
60then add a terminating
61.Ql \e0 .
62The string
63.Fa s
64must have sufficient space to hold the result.
65.Pp
66The
67.Fn strncat
68function appends not more than
69.Fa count
70characters where space for the terminating
71.Ql \e0
72should not be included in
73.Fa count .
74.Sh RETURN VALUES
75The
76.Fn strcat
77and
78.Fn strncat
79functions return the pointer
80.Fa s .
81.Sh EXAMPLES
82The following appends
83.Dq Li abc
84to
85.Dq Li chararray :
86.Bd -literal -offset indent
87char *letters = "abcdefghi";
88
89(void)strncat(chararray, letters, 3);
90.Ed
91.Pp
92The following example shows how to use
93.Fn strncat
94safely in conjunction with
95.Xr strncpy 3 .
96.Bd -literal -offset indent
97char buf[BUFSIZ];
98char *input, *suffix;
99
100(void)strncpy(buf, input, sizeof(buf) - 1);
101buf[sizeof(buf) - 1] = '\e0';
102(void)strncat(buf, suffix, sizeof(buf) - 1 - strlen(buf));
103.Ed
104.Pp
105The above will copy as many characters from
106.Dq Li input
107to
108.Dq Li buf
109as will fit.
110It then appends as many characters from suffix as will fit (or none
111if there is no space).
112For operations like this, the
113.Xr strlcpy 3
114and
115.Xr strlcat 3
116functions are a better choice, as shown below.
117.Bd -literal -offset indent
118(void)strlcpy(buf, input, sizeof(buf));
119(void)strlcat(buf, suffix, sizeof(buf));
120.Ed
121.Sh SEE ALSO
122.Xr bcopy 3 ,
123.Xr memccpy 3 ,
124.Xr memcpy 3 ,
125.Xr memmove 3 ,
126.Xr strcpy 3 ,
127.Xr strlcat 3 ,
128.Xr strlcpy 3
129.Sh STANDARDS
130The
131.Fn strcat
132and
133.Fn strncat
134functions conform to
135.St -ansiC .
diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c
new file mode 100644
index 0000000000..374a2b7464
--- /dev/null
+++ b/src/lib/libc/string/strcat.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strcat.c,v 1.4 1996/08/19 08:34:10 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44char *
45strcat(s, append)
46 register char *s;
47 register const char *append;
48{
49 char *save = s;
50
51 for (; *s; ++s);
52 while ((*s++ = *append++) != '\0');
53 return(save);
54}
diff --git a/src/lib/libc/string/strchr.3 b/src/lib/libc/string/strchr.3
new file mode 100644
index 0000000000..1333a305d6
--- /dev/null
+++ b/src/lib/libc/string/strchr.3
@@ -0,0 +1,106 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strchr.3,v 1.7 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCHR 3
40.Os
41.Sh NAME
42.Nm strchr ,
43.Nm index
44.Nd locate first occurrence of a character in a string
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strchr "const char *s" "int c"
49.Ft char *
50.Fn index "const char *s" "int c"
51.Sh DESCRIPTION
52The
53.Fn strchr
54function locates the first occurrence of the character
55.Fa c
56in the string
57.Fa s .
58The terminating NUL character is considered part of the string.
59If
60.Fa c
61is
62.Ql \e0 ,
63.Fn strchr
64locates the terminating
65.Ql \e0 .
66.Pp
67The
68.Fn index
69function is an old synonym for
70.Fn strchr .
71.Sh RETURN VALUES
72The
73.Fn strchr
74function returns a pointer to the located character or
75.Dv NULL
76if the character does not appear in the string.
77.Sh EXAMPLES
78After the following call to
79.Fn strchr ,
80.Va p
81will point to the string
82.Qq oobar :
83.Bd -literal -offset indent
84char *p;
85char *s = "foobar";
86
87p = strchr(s, 'o');
88.Ed
89.Sh SEE ALSO
90.Xr memchr 3 ,
91.Xr strcspn 3 ,
92.Xr strpbrk 3 ,
93.Xr strrchr 3 ,
94.Xr strsep 3 ,
95.Xr strspn 3 ,
96.Xr strstr 3 ,
97.Xr strtok 3
98.Sh STANDARDS
99The
100.Fn strchr
101function conforms to
102.St -ansiC .
103.Pp
104The
105.Fn index
106function is deprecated and shouldn't be used in new code.
diff --git a/src/lib/libc/string/strcmp.3 b/src/lib/libc/string/strcmp.3
new file mode 100644
index 0000000000..c1173a423a
--- /dev/null
+++ b/src/lib/libc/string/strcmp.3
@@ -0,0 +1,91 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcmp.3,v 1.5 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCMP 3
40.Os
41.Sh NAME
42.Nm strcmp ,
43.Nm strncmp
44.Nd compare strings
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft int
48.Fn strcmp "const char *s1" "const char *s2"
49.Ft int
50.Fn strncmp "const char *s1" "const char *s2" "size_t len"
51.Sh DESCRIPTION
52The
53.Fn strcmp
54and
55.Fn strncmp
56functions lexicographically compare the null-terminated strings
57.Fa s1
58and
59.Fa s2 .
60.Sh RETURN VALUES
61The
62.Fn strcmp
63and
64.Fn strncmp
65return an integer greater than, equal to, or less than 0, according
66as the string
67.Fa s1
68is greater than, equal to, or less than the string
69.Fa s2 .
70The comparison is done using unsigned characters, so that
71.Ql \e200
72is greater than
73.Ql \e0 .
74.Pp
75.Fn strncmp
76compares at most
77.Fa len
78characters.
79.Sh SEE ALSO
80.Xr bcmp 3 ,
81.Xr memcmp 3 ,
82.Xr strcasecmp 3 ,
83.Xr strcoll 3 ,
84.Xr strxfrm 3
85.Sh STANDARDS
86The
87.Fn strcmp
88and
89.Fn strncmp
90functions conform to
91.St -ansiC .
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c
new file mode 100644
index 0000000000..9a5b208323
--- /dev/null
+++ b/src/lib/libc/string/strcmp.c
@@ -0,0 +1,58 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcmp.c,v 1.3 1996/08/19 08:34:12 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#ifndef _KERNEL
42#include <string.h>
43#else
44#include <lib/libkern/libkern.h>
45#endif
46
47/*
48 * Compare strings.
49 */
50int
51strcmp(s1, s2)
52 register const char *s1, *s2;
53{
54 while (*s1 == *s2++)
55 if (*s1++ == 0)
56 return (0);
57 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
58}
diff --git a/src/lib/libc/string/strcoll.3 b/src/lib/libc/string/strcoll.3
new file mode 100644
index 0000000000..5d3e44ee96
--- /dev/null
+++ b/src/lib/libc/string/strcoll.3
@@ -0,0 +1,72 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcoll.3,v 1.3 2000/04/21 15:24:19 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCOLL 3
40.Os
41.Sh NAME
42.Nm strcoll
43.Nd compare strings according to current collation
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft int
47.Fn strcoll "const char *s1" "const char *s2"
48.Sh DESCRIPTION
49The
50.Fn strcoll
51function lexicographically compares the null-terminated strings
52.Fa s1
53and
54.Fa s2
55according to the current locale collation
56and returns an integer greater than, equal to, or less than 0,
57according as
58.Fa s1
59is greater than, equal to, or less than
60.Fa s2 .
61.Sh SEE ALSO
62.Xr bcmp 3 ,
63.Xr memcmp 3 ,
64.Xr setlocale 3 ,
65.Xr strcasecmp 3 ,
66.Xr strcmp 3 ,
67.Xr strxfrm 3
68.Sh STANDARDS
69The
70.Fn strcoll
71function conforms to
72.St -ansiC .
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c
new file mode 100644
index 0000000000..dca0b10d25
--- /dev/null
+++ b/src/lib/libc/string/strcoll.c
@@ -0,0 +1,52 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcoll.c,v 1.2 1996/08/19 08:34:13 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Compare strings according to LC_COLLATE category of current locale.
45 */
46int
47strcoll(s1, s2)
48 const char *s1, *s2;
49{
50 /* LC_COLLATE is unimplemented, hence always "C" */
51 return (strcmp(s1, s2));
52}
diff --git a/src/lib/libc/string/strcpy.3 b/src/lib/libc/string/strcpy.3
new file mode 100644
index 0000000000..d3c095916b
--- /dev/null
+++ b/src/lib/libc/string/strcpy.3
@@ -0,0 +1,154 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcpy.3,v 1.11 2002/05/13 17:04:43 millert Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCPY 3
40.Os
41.Sh NAME
42.Nm strcpy ,
43.Nm strncpy
44.Nd copy strings
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strcpy "char *dst" "const char *src"
49.Ft char *
50.Fn strncpy "char *dst" "const char *src" "size_t len"
51.Sh DESCRIPTION
52The
53.Fn strcpy
54and
55.Fn strncpy
56functions copy the string
57.Fa src
58to
59.Fa dst
60(including the terminating
61.Ql \e0
62character).
63.Pp
64.Fn strncpy
65copies not more than
66.Fa len
67characters into
68.Fa dst ,
69appending
70.Ql \e0
71characters if
72.Fa src
73is less than
74.Fa len
75characters long, and
76.Em not
77terminating
78.Fa dst
79if the length of
80.Fa src
81is greater than or equal to
82.Fa len .
83.Sh RETURN VALUES
84The
85.Fn strcpy
86and
87.Fn strncpy
88functions return
89.Fa dst .
90.Sh EXAMPLES
91The following sets
92.Va chararray
93to
94.Dq abc\e0\e0\e0 :
95.Bd -literal -offset indent
96(void)strncpy(chararray, "abc", 6);
97.Ed
98.Pp
99The following sets
100.Va chararray
101to
102.Dq abcdef
103and does
104.Em not
105null terminate
106.Va chararray
107because the source string is >= the length parameter.
108.Fn strncpy
109.Em only
110null terminates the destination string when the length of the source
111string is less than the length parameter.
112.Bd -literal -offset indent
113(void)strncpy(chararray, "abcdefgh", 6);
114.Ed
115.Pp
116The following copies as many characters from
117.Va input
118to
119.Va buf
120as will fit and null terminates the result.
121Because
122.Fn strncpy
123does
124.Em not
125guarantee to null terminate the string itself, we must do this by hand.
126.Bd -literal -offset indent
127char buf[BUFSIZ];
128
129(void)strncpy(buf, input, sizeof(buf) - 1);
130buf[sizeof(buf) - 1] = '\e0';
131.Ed
132.Pp
133Note that
134.Xr strlcpy 3
135is a better choice for this kind of operation.
136The equivalent using
137.Xr strlcpy 3
138is simply:
139.Bd -literal -offset indent
140(void)strlcpy(buf, input, sizeof(buf));
141.Ed
142.Sh SEE ALSO
143.Xr bcopy 3 ,
144.Xr memccpy 3 ,
145.Xr memcpy 3 ,
146.Xr memmove 3 ,
147.Xr strlcpy 3
148.Sh STANDARDS
149The
150.Fn strcpy
151and
152.Fn strncpy
153functions conform to
154.St -ansiC .
diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c
new file mode 100644
index 0000000000..76b063fc10
--- /dev/null
+++ b/src/lib/libc/string/strcpy.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strcpy.c,v 1.4 1996/08/19 08:34:14 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44char *
45strcpy(to, from)
46 register char *to;
47 register const char *from;
48{
49 char *save = to;
50
51 for (; (*to = *from) != '\0'; ++from, ++to);
52 return(save);
53}
diff --git a/src/lib/libc/string/strcspn.3 b/src/lib/libc/string/strcspn.3
new file mode 100644
index 0000000000..37e8f163f1
--- /dev/null
+++ b/src/lib/libc/string/strcspn.3
@@ -0,0 +1,92 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strcspn.3,v 1.5 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRCSPN 3
40.Os
41.Sh NAME
42.Nm strcspn
43.Nd span the complement of a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strcspn "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strcspn
51function spans the initial part of the null-terminated string
52.Fa s
53as long as the characters from
54.Fa s
55do not occur in string
56.Fa charset
57(it spans the
58.Em complement
59of
60.Fa charset ) .
61.Sh RETURN VALUES
62The
63.Fn strcspn
64function returns the number of characters spanned.
65.Sh EXAMPLES
66The following call to
67.Fn strcspn
68will return 3, since the first three characters of string
69.Fa s
70do not occur in string
71.Fa charset :
72.Bd -literal -offset indent
73char *s = "foobar";
74char *charset = "bar";
75size_t span;
76
77span = strcspn(s, charset);
78.Ed
79.Sh SEE ALSO
80.Xr memchr 3 ,
81.Xr strchr 3 ,
82.Xr strpbrk 3 ,
83.Xr strrchr 3 ,
84.Xr strsep 3 ,
85.Xr strspn 3 ,
86.Xr strstr 3 ,
87.Xr strtok 3
88.Sh STANDARDS
89The
90.Fn strcspn
91function conforms to
92.St -ansiC .
diff --git a/src/lib/libc/string/strcspn.c b/src/lib/libc/string/strcspn.c
new file mode 100644
index 0000000000..f7261564a7
--- /dev/null
+++ b/src/lib/libc/string/strcspn.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strcspn.c,v 1.2 1996/08/19 08:34:15 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Span the complement of string s2.
45 */
46size_t
47strcspn(s1, s2)
48 const char *s1;
49 register const char *s2;
50{
51 register const char *p, *spanp;
52 register char c, sc;
53
54 /*
55 * Stop as soon as we find any character from s2. Note that there
56 * must be a NUL in s2; it suffices to stop when we find that, too.
57 */
58 for (p = s1;;) {
59 c = *p++;
60 spanp = s2;
61 do {
62 if ((sc = *spanp++) == c)
63 return (p - 1 - s1);
64 } while (sc != 0);
65 }
66 /* NOTREACHED */
67}
diff --git a/src/lib/libc/string/strdup.3 b/src/lib/libc/string/strdup.3
new file mode 100644
index 0000000000..9c154c7d70
--- /dev/null
+++ b/src/lib/libc/string/strdup.3
@@ -0,0 +1,87 @@
1.\" $OpenBSD: strdup.3,v 1.10 2000/04/21 15:32:15 aaron Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
35.\"
36.Dd June 9, 1993
37.Dt STRDUP 3
38.Os
39.Sh NAME
40.Nm strdup
41.Nd save a copy of a string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft char *
45.Fn strdup "const char *s"
46.Sh DESCRIPTION
47The
48.Fn strdup
49function allocates sufficient memory for a copy of the string
50.Fa s ,
51does the copy, and returns a pointer to it.
52The pointer may subsequently be used as an argument to the function
53.Xr free 3 .
54.Pp
55If insufficient memory is available,
56.Dv NULL
57is returned.
58.Sh EXAMPLES
59The following will point
60.Va p
61to an allocated area of memory containing the null-terminated string
62.Qq foobar :
63.Bd -literal -offset indent
64char *p;
65
66if ((p = strdup("foobar")) == NULL) {
67 fprintf(stderr, "Out of memory.\en");
68 exit(1);
69}
70.Ed
71.Sh ERRORS
72The
73.Fn strdup
74function may fail and set the external variable
75.Va errno
76for any of the errors specified for the library function
77.Xr malloc 3 .
78.Sh SEE ALSO
79.Xr free 3 ,
80.Xr malloc 3 ,
81.Xr strcpy 3 ,
82.Xr strlen 3
83.Sh HISTORY
84The
85.Fn strdup
86function first appeared in
87.Bx 4.4 .
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c
new file mode 100644
index 0000000000..be7f7ad094
--- /dev/null
+++ b/src/lib/libc/string/strdup.c
@@ -0,0 +1,62 @@
1/* $OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $ */
2
3/*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
39#else
40static char *rcsid = "$OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <sys/types.h>
45
46#include <stddef.h>
47#include <stdlib.h>
48#include <string.h>
49
50char *
51strdup(str)
52 const char *str;
53{
54 size_t siz;
55 char *copy;
56
57 siz = strlen(str) + 1;
58 if ((copy = malloc(siz)) == NULL)
59 return(NULL);
60 (void)memcpy(copy, str, siz);
61 return(copy);
62}
diff --git a/src/lib/libc/string/strerror.3 b/src/lib/libc/string/strerror.3
new file mode 100644
index 0000000000..11bacd313e
--- /dev/null
+++ b/src/lib/libc/string/strerror.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strerror.3,v 1.4 2000/10/23 19:14:41 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRERROR 3
40.Os
41.Sh NAME
42.Nm strerror
43.Nd get error message string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strerror "int errnum"
48.Sh DESCRIPTION
49The
50.Fn strerror
51function returns a pointer to the language-dependent error message
52string affiliated with the specified error number
53.Fa errnum .
54The returned string contains a maximum of
55.Dv NL_TEXTMAX
56characters, including the trailing NUL.
57.Pp
58The array pointed to is not to be modified by the program, but may be
59overwritten by subsequent calls to
60.Fn strerror .
61.Sh SEE ALSO
62.Xr intro 2 ,
63.Xr perror 3 ,
64.Xr setlocale 3
65.Sh STANDARDS
66The
67.Fn strerror
68function conforms to
69.St -ansiC .
diff --git a/src/lib/libc/string/strerror.c b/src/lib/libc/string/strerror.c
new file mode 100644
index 0000000000..b884a67df3
--- /dev/null
+++ b/src/lib/libc/string/strerror.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strerror.c,v 1.3 2002/02/16 21:27:24 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39#include <limits.h>
40
41/*
42 * Since perror() is not allowed to change the contents of strerror()'s
43 * static buffer, both functions supply their own buffers to the
44 * internal function __strerror().
45 */
46
47extern char *__strerror(int, char *);
48
49char *
50strerror(num)
51 int num;
52{
53 static char buf[NL_TEXTMAX];
54 return __strerror(num, buf);
55}
diff --git a/src/lib/libc/string/string.3 b/src/lib/libc/string/string.3
new file mode 100644
index 0000000000..7a67b96b53
--- /dev/null
+++ b/src/lib/libc/string/string.3
@@ -0,0 +1,161 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" $OpenBSD: string.3,v 1.8 2000/04/21 15:24:20 aaron Exp $
35.\"
36.Dd April 19, 1991
37.Dt STRING 3
38.Os
39.Sh NAME
40.Nm strcat ,
41.Nm strlcat ,
42.Nm strncat ,
43.Nm strchr ,
44.Nm strrchr ,
45.Nm strcmp ,
46.Nm strncmp ,
47.Nm strcasecmp ,
48.Nm strncasecmp ,
49.Nm strcpy ,
50.Nm strlcpy ,
51.Nm strncpy ,
52.Nm strerror ,
53.Nm strlen ,
54.Nm strpbrk ,
55.Nm strsep ,
56.Nm strspn ,
57.Nm strcspn ,
58.Nm strstr ,
59.Nm strtok ,
60.Nm index ,
61.Nm rindex
62.Nd string specific functions
63.Sh SYNOPSIS
64.Fd #include <string.h>
65.Ft char *
66.Fn strcat "char *s" "const char *append"
67.Ft char *
68.Fn strlcat "char *s" "const char *append" "size_t size"
69.Ft char *
70.Fn strncat "char *s" "const char *append" "size_t count"
71.Ft char *
72.Fn strchr "const char *s" "int c"
73.Ft char *
74.Fn strrchr "const char *s" "int c"
75.Ft int
76.Fn strcmp "const char *s1" "const char *s2"
77.Ft int
78.Fn strncmp "const char *s1" "const char *s2" "size_t count"
79.Ft int
80.Fn strcasecmp "const char *s1" "const char *s2"
81.Ft int
82.Fn strncasecmp "const char *s1" "const char *s2" "size_t count"
83.Ft char *
84.Fn strcpy "char *dst" "const char *src"
85.Ft char *
86.Fn strlcpy "char *dst" "const char *src" "size_t size"
87.Ft char *
88.Fn strncpy "char *dst" "const char *src" "size_t count"
89.Ft char *
90.Fn strerror "int errno"
91.Ft size_t
92.Fn strlen "const char *s"
93.Ft char *
94.Fn strpbrk "const char *s" "const char *charset"
95.Ft char *
96.Fn strsep "char **stringp" "const char *delim"
97.Ft size_t
98.Fn strspn "const char *s" "const char *charset"
99.Ft size_t
100.Fn strcspn "const char *s" "const char *charset"
101.Ft char *
102.Fn strstr "const char *big" "const char *little"
103.Ft char *
104.Fn strtok "char *s" "const char *delim"
105.Ft char *
106.Fn index "const char *s" "int c"
107.Ft char *
108.Fn rindex "const char *s" "int c"
109.Sh DESCRIPTION
110The string functions
111manipulate strings terminated by a
112null byte.
113.Pp
114See the specific manual pages for more information.
115For manipulating variable length generic objects as byte
116strings (without the null byte check), see
117.Xr bstring 3 .
118.Pp
119Except as noted in their specific manual pages,
120the string functions do not test the destination
121for size limitations.
122.Sh SEE ALSO
123.Xr bstring 3 ,
124.Xr index 3 ,
125.Xr rindex 3 ,
126.Xr strcasecmp 3 ,
127.Xr strcat 3 ,
128.Xr strchr 3 ,
129.Xr strcmp 3 ,
130.Xr strcpy 3 ,
131.Xr strcspn 3 ,
132.Xr strerror 3 ,
133.Xr strlcat 3 ,
134.Xr strlcpy 3 ,
135.Xr strlen 3 ,
136.Xr strpbrk 3 ,
137.Xr strrchr 3 ,
138.Xr strsep 3 ,
139.Xr strspn 3 ,
140.Xr strstr 3 ,
141.Xr strtok 3
142.Sh STANDARDS
143The
144.Fn strcat ,
145.Fn strncat ,
146.Fn strchr ,
147.Fn strrchr ,
148.Fn strcmp ,
149.Fn strncmp ,
150.Fn strcpy ,
151.Fn strncpy ,
152.Fn strerror ,
153.Fn strlen ,
154.Fn strpbrk ,
155.Fn strspn ,
156.Fn strcspn ,
157.Fn strstr ,
158and
159.Fn strtok
160functions conform to
161.St -ansiC .
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..b309648155
--- /dev/null
+++ b/src/lib/libc/string/strlcat.c
@@ -0,0 +1,73 @@
1/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Appends src to string dst of size siz (unlike strncat, siz is the
39 * full size of dst, not space left). At most siz-1 characters
40 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
41 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
42 * If retval >= siz, truncation occurred.
43 */
44size_t
45strlcat(dst, src, siz)
46 char *dst;
47 const char *src;
48 size_t siz;
49{
50 register char *d = dst;
51 register const char *s = src;
52 register size_t n = siz;
53 size_t dlen;
54
55 /* Find the end of dst and adjust bytes left but don't go past end */
56 while (n-- != 0 && *d != '\0')
57 d++;
58 dlen = d - dst;
59 n = siz - dlen;
60
61 if (n == 0)
62 return(dlen + strlen(s));
63 while (*s != '\0') {
64 if (n != 1) {
65 *d++ = *s;
66 n--;
67 }
68 s++;
69 }
70 *d = '\0';
71
72 return(dlen + (s - src)); /* count does not include NUL */
73}
diff --git a/src/lib/libc/string/strlcpy.3 b/src/lib/libc/string/strlcpy.3
new file mode 100644
index 0000000000..b103588b96
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,190 @@
1.\" $OpenBSD: strlcpy.3,v 1.14 2002/04/30 16:31:42 mpech Exp $
2.\"
3.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. The name of the author may not be used to endorse or promote products
15.\" derived from this software without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.\"
28.Dd June 22, 1998
29.Dt STRLCPY 3
30.Os
31.Sh NAME
32.Nm strlcpy ,
33.Nm strlcat
34.Nd size-bounded string copying and concatenation
35.Sh SYNOPSIS
36.Fd #include <string.h>
37.Ft size_t
38.Fn strlcpy "char *dst" "const char *src" "size_t size"
39.Ft size_t
40.Fn strlcat "char *dst" "const char *src" "size_t size"
41.Sh DESCRIPTION
42The
43.Fn strlcpy
44and
45.Fn strlcat
46functions copy and concatenate strings respectively.
47They are designed
48to be safer, more consistent, and less error prone replacements for
49.Xr strncpy 3
50and
51.Xr strncat 3 .
52Unlike those functions,
53.Fn strlcpy
54and
55.Fn strlcat
56take the full size of the buffer (not just the length) and guarantee to
57NUL-terminate the result (as long as
58.Fa size
59is larger than 0 or, in the case of
60.Fn strlcat ,
61as long as there is at least one byte free in
62.Fa dst ) .
63Note that you should include a byte for the NUL in
64.Fa size .
65Also note that
66.Fn strlcpy
67and
68.Fn strlcat
69only operate on true
70.Dq C
71strings.
72This means that for
73.Fn strlcpy
74.Fa src
75must be NUL-terminated and for
76.Fn strlcat
77both
78.Fa src
79and
80.Fa dst
81must be NUL-terminated.
82.Pp
83The
84.Fn strlcpy
85function copies up to
86.Fa size
87- 1 characters from the NUL-terminated string
88.Fa src
89to
90.Fa dst ,
91NUL-terminating the result.
92.Pp
93The
94.Fn strlcat
95function appends the NUL-terminated string
96.Fa src
97to the end of
98.Fa dst .
99It will append at most
100.Fa size
101- strlen(dst) - 1 bytes, NUL-terminating the result.
102.Sh RETURN VALUES
103The
104.Fn strlcpy
105and
106.Fn strlcat
107functions return the total length of the string they tried to create.
108For
109.Fn strlcpy
110that means the length of
111.Fa src .
112For
113.Fn strlcat
114that means the initial length of
115.Fa dst
116plus
117the length of
118.Fa src .
119While this may seem somewhat confusing it was done to make
120truncation detection simple.
121.Pp
122Note however, that if
123.Fn strlcat
124traverses
125.Fa size
126characters without finding a NUL, the length of the string is considered
127to be
128.Fa size
129and the destination string will not be NUL-terminated (since there was
130no space for the NUL).
131This keeps
132.Fn strlcat
133from running off the end of a string.
134In practice this should not happen (as it means that either
135.Fa size
136is incorrect or that
137.Fa dst
138is not a proper
139.Dq C
140string).
141The check exists to prevent potential security problems in incorrect code.
142.Sh EXAMPLES
143The following code fragment illustrates the simple case:
144.Bd -literal -offset indent
145char *s, *p, buf[BUFSIZ];
146
147\&...
148
149(void)strlcpy(buf, s, sizeof(buf));
150(void)strlcat(buf, p, sizeof(buf));
151.Ed
152.Pp
153To detect truncation, perhaps while building a pathname, something
154like the following might be used:
155.Bd -literal -offset indent
156char *dir, *file, pname[MAXPATHLEN];
157
158\&...
159
160if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
161 goto toolong;
162if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
163 goto toolong;
164.Ed
165.Pp
166Since we know how many characters we copied the first time, we can
167speed things up a bit by using a copy instead of an append:
168.Bd -literal -offset indent
169char *dir, *file, pname[MAXPATHLEN];
170size_t n;
171
172\&...
173
174n = strlcpy(pname, dir, sizeof(pname));
175if (n >= sizeof(pname))
176 goto toolong;
177if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
178 goto toolong;
179.Ed
180.Pp
181However, one may question the validity of such optimizations, as they
182defeat the whole purpose of
183.Fn strlcpy
184and
185.Fn strlcat .
186As a matter of fact, the first version of this manual page got it wrong.
187.Sh SEE ALSO
188.Xr snprintf 3 ,
189.Xr strncat 3 ,
190.Xr strncpy 3
diff --git a/src/lib/libc/string/strlcpy.c b/src/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000000..5f586964b7
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.c
@@ -0,0 +1,69 @@
1/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Copy src to string dst of size siz. At most siz-1 characters
39 * will be copied. Always NUL terminates (unless siz == 0).
40 * Returns strlen(src); if retval >= siz, truncation occurred.
41 */
42size_t
43strlcpy(dst, src, siz)
44 char *dst;
45 const char *src;
46 size_t siz;
47{
48 register char *d = dst;
49 register const char *s = src;
50 register size_t n = siz;
51
52 /* Copy as many bytes as will fit */
53 if (n != 0 && --n != 0) {
54 do {
55 if ((*d++ = *s++) == 0)
56 break;
57 } while (--n != 0);
58 }
59
60 /* Not enough room in dst, add NUL and traverse rest of src */
61 if (n == 0) {
62 if (siz != 0)
63 *d = '\0'; /* NUL-terminate dst */
64 while (*s++)
65 ;
66 }
67
68 return(s - src - 1); /* count does not include NUL */
69}
diff --git a/src/lib/libc/string/strlen.3 b/src/lib/libc/string/strlen.3
new file mode 100644
index 0000000000..759e724056
--- /dev/null
+++ b/src/lib/libc/string/strlen.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strlen.3,v 1.4 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRLEN 3
40.Os
41.Sh NAME
42.Nm strlen
43.Nd find length of a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strlen "const char *s"
48.Sh DESCRIPTION
49The
50.Fn strlen
51function computes the length of the string
52.Fa s .
53.Sh RETURN VALUES
54The
55.Fn strlen
56function returns the number of characters that precede the terminating
57.Tn NUL
58character.
59.Sh SEE ALSO
60.Xr string 3
61.Sh STANDARDS
62The
63.Fn strlen
64function conforms to
65.St -ansiC .
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c
new file mode 100644
index 0000000000..ab006e04c2
--- /dev/null
+++ b/src/lib/libc/string/strlen.c
@@ -0,0 +1,56 @@
1/* $OpenBSD: strlen.c,v 1.4 2001/07/29 21:15:23 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char *rcsid = "$OpenBSD: strlen.c,v 1.4 2001/07/29 21:15:23 millert Exp $";
38#endif /* LIBC_SCCS and not lint */
39
40#if !defined(_KERNEL) && !defined(_STANDALONE)
41#include <string.h>
42#else
43#include <lib/libkern/libkern.h>
44#endif
45
46size_t
47strlen(str)
48 const char *str;
49{
50 const char *s;
51
52 for (s = str; *s; ++s)
53 ;
54 return (s - str);
55}
56
diff --git a/src/lib/libc/string/strmode.3 b/src/lib/libc/string/strmode.3
new file mode 100644
index 0000000000..bf311f1f99
--- /dev/null
+++ b/src/lib/libc/string/strmode.3
@@ -0,0 +1,163 @@
1.\" $OpenBSD: strmode.3,v 1.8 2000/04/21 15:24:20 aaron Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
35.\"
36.Dd July 28, 1994
37.Dt STRMODE 3
38.Os
39.Sh NAME
40.Nm strmode
41.Nd convert inode status information into a symbolic string
42.Sh SYNOPSIS
43.Fd #include <string.h>
44.Ft void
45.Fn strmode "mode_t mode" "char *bp"
46.Sh DESCRIPTION
47The
48.Fn strmode
49function converts a file
50.Fa mode
51(the type and permission information associated with an inode, see
52.Xr stat 2 )
53into a symbolic string which is stored in the location referenced by
54.Fa bp .
55This stored string is eleven characters in length plus a trailing null byte.
56.Pp
57The first character is the inode type, and will be one of the following:
58.Pp
59.Bl -tag -width flag -offset indent -compact
60.It \-
61regular file
62.It b
63block special
64.It c
65character special
66.It d
67directory
68.It l
69symbolic link
70.It p
71fifo
72.It s
73socket
74.It w
75whiteout
76.It ?
77unknown inode type
78.El
79.Pp
80The next nine characters encode three sets of permissions, in three
81characters each.
82The first three characters are the permissions for the owner of the
83file, the second three for the group the file belongs to, and the
84third for the
85.Dq other ,
86or default, set of users.
87.Pp
88Permission checking is done as specifically as possible.
89If read permission is denied to the owner of a file in the first set
90of permissions, the owner of the file will not be able to read the file.
91This is true even if the owner is in the file's group and the group
92permissions allow reading or the
93.Dq other
94permissions allow reading.
95.Pp
96If the first character of the three character set is an
97.Sq r ,
98the file is readable for that set of users; if a dash
99.Pq Ql - ,
100it is not readable.
101.Pp
102If the second character of the three character set is a
103.Sq w ,
104the file is writable for that set of users; if a dash
105.Pq Ql - ,
106it is not writable.
107.Pp
108The third character is the first of the following characters that apply:
109.Bl -tag -width xxxx
110.It S
111If the character is part of the owner permissions and the file is not
112executable or the directory is not searchable by the owner, and the
113set-user-ID bit is set.
114.It S
115If the character is part of the group permissions and the file is not
116executable or the directory is not searchable by the group, and the
117set-group-ID bit is set.
118.It T
119If the character is part of the other permissions and the file is not
120executable or the directory is not searchable by others, and the
121.Dq sticky
122.Pq Dv S_ISVTX
123bit is set.
124.It s
125If the character is part of the owner permissions and the file is
126executable or the directory searchable by the owner, and the set-user-ID
127bit is set.
128.It s
129If the character is part of the group permissions and the file is
130executable or the directory searchable by the group, and the set-group-ID
131bit is set.
132.It t
133If the character is part of the other permissions and the file is
134executable or the directory searchable by others, and the
135.Dq sticky
136.Pq Dv S_ISVTX
137bit is set.
138.It x
139The file is executable or the directory is searchable.
140.It \-
141None of the above apply.
142.El
143.Pp
144The last character is a plus sign
145.Pq Ql +
146if there are any alternate
147or additional access control methods associated with the inode, otherwise
148it will be a space.
149.Sh RETURN VALUES
150The
151.Fn strmode
152function always returns 0.
153.Sh SEE ALSO
154.Xr chmod 1 ,
155.Xr find 1 ,
156.Xr stat 2 ,
157.Xr getmode 3 ,
158.Xr setmode 3
159.Sh HISTORY
160The
161.Fn strmode
162function first appeared in
163.Bx 4.4 .
diff --git a/src/lib/libc/string/strmode.c b/src/lib/libc/string/strmode.c
new file mode 100644
index 0000000000..5e7f15e857
--- /dev/null
+++ b/src/lib/libc/string/strmode.c
@@ -0,0 +1,152 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <string.h>
41
42void
43strmode(mode, p)
44 register mode_t mode;
45 register char *p;
46{
47 /* print type */
48 switch (mode & S_IFMT) {
49 case S_IFDIR: /* directory */
50 *p++ = 'd';
51 break;
52 case S_IFCHR: /* character special */
53 *p++ = 'c';
54 break;
55 case S_IFBLK: /* block special */
56 *p++ = 'b';
57 break;
58 case S_IFREG: /* regular */
59 *p++ = '-';
60 break;
61 case S_IFLNK: /* symbolic link */
62 *p++ = 'l';
63 break;
64 case S_IFSOCK: /* socket */
65 *p++ = 's';
66 break;
67#ifdef S_IFIFO
68 case S_IFIFO: /* fifo */
69 *p++ = 'p';
70 break;
71#endif
72#ifdef S_IFWHT
73 case S_IFWHT: /* whiteout */
74 *p++ = 'w';
75 break;
76#endif
77 default: /* unknown */
78 *p++ = '?';
79 break;
80 }
81 /* usr */
82 if (mode & S_IRUSR)
83 *p++ = 'r';
84 else
85 *p++ = '-';
86 if (mode & S_IWUSR)
87 *p++ = 'w';
88 else
89 *p++ = '-';
90 switch (mode & (S_IXUSR | S_ISUID)) {
91 case 0:
92 *p++ = '-';
93 break;
94 case S_IXUSR:
95 *p++ = 'x';
96 break;
97 case S_ISUID:
98 *p++ = 'S';
99 break;
100 case S_IXUSR | S_ISUID:
101 *p++ = 's';
102 break;
103 }
104 /* group */
105 if (mode & S_IRGRP)
106 *p++ = 'r';
107 else
108 *p++ = '-';
109 if (mode & S_IWGRP)
110 *p++ = 'w';
111 else
112 *p++ = '-';
113 switch (mode & (S_IXGRP | S_ISGID)) {
114 case 0:
115 *p++ = '-';
116 break;
117 case S_IXGRP:
118 *p++ = 'x';
119 break;
120 case S_ISGID:
121 *p++ = 'S';
122 break;
123 case S_IXGRP | S_ISGID:
124 *p++ = 's';
125 break;
126 }
127 /* other */
128 if (mode & S_IROTH)
129 *p++ = 'r';
130 else
131 *p++ = '-';
132 if (mode & S_IWOTH)
133 *p++ = 'w';
134 else
135 *p++ = '-';
136 switch (mode & (S_IXOTH | S_ISVTX)) {
137 case 0:
138 *p++ = '-';
139 break;
140 case S_IXOTH:
141 *p++ = 'x';
142 break;
143 case S_ISVTX:
144 *p++ = 'T';
145 break;
146 case S_IXOTH | S_ISVTX:
147 *p++ = 't';
148 break;
149 }
150 *p++ = ' '; /* will be a '+' if ACL's implemented */
151 *p = '\0';
152}
diff --git a/src/lib/libc/string/strncat.c b/src/lib/libc/string/strncat.c
new file mode 100644
index 0000000000..27ae2ba324
--- /dev/null
+++ b/src/lib/libc/string/strncat.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strncat.c,v 1.2 1996/08/19 08:34:21 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
45 * are written at dst (at most n+1 bytes being appended). Return dst.
46 */
47char *
48strncat(dst, src, n)
49 char *dst;
50 const char *src;
51 register size_t n;
52{
53 if (n != 0) {
54 register char *d = dst;
55 register const char *s = src;
56
57 while (*d != 0)
58 d++;
59 do {
60 if ((*d = *s++) == 0)
61 break;
62 d++;
63 } while (--n != 0);
64 *d = 0;
65 }
66 return (dst);
67}
diff --git a/src/lib/libc/string/strncmp.c b/src/lib/libc/string/strncmp.c
new file mode 100644
index 0000000000..0224957f8b
--- /dev/null
+++ b/src/lib/libc/string/strncmp.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strncmp.c,v 1.3 1996/08/19 08:34:21 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#ifndef _KERNEL
39#include <string.h>
40#else
41#include <lib/libkern/libkern.h>
42#endif
43
44int
45strncmp(s1, s2, n)
46 register const char *s1, *s2;
47 register size_t n;
48{
49
50 if (n == 0)
51 return (0);
52 do {
53 if (*s1 != *s2++)
54 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
55 if (*s1++ == 0)
56 break;
57 } while (--n != 0);
58 return (0);
59}
diff --git a/src/lib/libc/string/strncpy.c b/src/lib/libc/string/strncpy.c
new file mode 100644
index 0000000000..01bc8a872e
--- /dev/null
+++ b/src/lib/libc/string/strncpy.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strncpy.c,v 1.2 1996/08/19 08:34:22 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Copy src to dst, truncating or null-padding to always copy n bytes.
45 * Return dst.
46 */
47char *
48strncpy(dst, src, n)
49 char *dst;
50 const char *src;
51 register size_t n;
52{
53 if (n != 0) {
54 register char *d = dst;
55 register const char *s = src;
56
57 do {
58 if ((*d++ = *s++) == 0) {
59 /* NUL pad the remaining n-1 bytes */
60 while (--n != 0)
61 *d++ = 0;
62 break;
63 }
64 } while (--n != 0);
65 }
66 return (dst);
67}
diff --git a/src/lib/libc/string/strpbrk.3 b/src/lib/libc/string/strpbrk.3
new file mode 100644
index 0000000000..52bf13b924
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.3
@@ -0,0 +1,76 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strpbrk.3,v 1.5 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRPBRK 3
40.Os
41.Sh NAME
42.Nm strpbrk
43.Nd locate multiple characters in string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strpbrk "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strpbrk
51function locates in the null-terminated string
52.Fa s
53the first occurrence of any character in the string
54.Fa charset
55and returns a pointer to this character.
56If no characters from
57.Fa charset
58occur anywhere in
59.Fa s ,
60.Fn strpbrk
61returns
62.Dv NULL .
63.Sh SEE ALSO
64.Xr memchr 3 ,
65.Xr strchr 3 ,
66.Xr strcspn 3 ,
67.Xr strrchr 3 ,
68.Xr strsep 3 ,
69.Xr strspn 3 ,
70.Xr strstr 3 ,
71.Xr strtok 3
72.Sh STANDARDS
73The
74.Fn strpbrk
75function conforms to
76.St -ansiC .
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c
new file mode 100644
index 0000000000..748a3a8c94
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strpbrk.c,v 1.2 1996/08/19 08:34:23 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40/*
41 * Find the first occurrence in s1 of a character in s2 (excluding NUL).
42 */
43char *
44strpbrk(s1, s2)
45 register const char *s1, *s2;
46{
47 register const char *scanp;
48 register int c, sc;
49
50 while ((c = *s1++) != 0) {
51 for (scanp = s2; (sc = *scanp++) != 0;)
52 if (sc == c)
53 return ((char *)(s1 - 1));
54 }
55 return (NULL);
56}
diff --git a/src/lib/libc/string/strrchr.3 b/src/lib/libc/string/strrchr.3
new file mode 100644
index 0000000000..394fc2aad3
--- /dev/null
+++ b/src/lib/libc/string/strrchr.3
@@ -0,0 +1,108 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strrchr.3,v 1.6 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRRCHR 3
40.Os
41.Sh NAME
42.Nm strrchr ,
43.Nm rindex
44.Nd locate last occurrence of a character in a string
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strrchr "const char *s" "int c"
49.Ft char *
50.Fn rindex "const char *s" "int c"
51.Sh DESCRIPTION
52The
53.Fn strrchr
54function locates the last occurrence of the character
55.Fa c
56in the string
57.Fa s .
58The terminating
59.Tn NUL
60character is considered part of the string.
61If
62.Fa c
63is
64.Ql \e0 ,
65.Fn strrchr
66locates the terminating
67.Ql \e0 .
68.Pp
69The
70.Fn rindex
71function is an old synonym for
72.Fn strrchr .
73.Sh RETURN VALUES
74The
75.Fn strrchr
76function returns a pointer to the located character or
77.Dv NULL
78if the character does not appear in the string.
79.Sh EXAMPLES
80After the following call to
81.Fn strrchr ,
82.Va p
83will point to the string
84.Qq obar :
85.Bd -literal -offset indent
86char *p;
87char *s = "foobar";
88
89p = strrchr(s, 'o');
90.Ed
91.Sh SEE ALSO
92.Xr memchr 3 ,
93.Xr strchr 3 ,
94.Xr strcspn 3 ,
95.Xr strpbrk 3 ,
96.Xr strsep 3 ,
97.Xr strspn 3 ,
98.Xr strstr 3 ,
99.Xr strtok 3
100.Sh STANDARDS
101The
102.Fn strrchr
103function conforms to
104.St -ansiC .
105.Pp
106The
107.Fn rindex
108function is deprecated and shouldn't be used in new code.
diff --git a/src/lib/libc/string/strsep.3 b/src/lib/libc/string/strsep.3
new file mode 100644
index 0000000000..848dab1eb3
--- /dev/null
+++ b/src/lib/libc/string/strsep.3
@@ -0,0 +1,116 @@
1.\" $OpenBSD: strsep.3,v 1.10 2001/11/21 14:32:45 deraadt Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE.
36.\"
37.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
38.\"
39.Dd June 9, 1993
40.Dt STRSEP 3
41.Os
42.Sh NAME
43.Nm strsep
44.Nd separate strings
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strsep "char **stringp" "const char *delim"
49.Sh DESCRIPTION
50The
51.Fn strsep
52function locates, in the string referenced by
53.Fa *stringp ,
54the first occurrence of any character in the string
55.Fa delim
56(or the terminating
57.Ql \e0
58character) and replaces it with a
59.Ql \e0 .
60The location of the next character after the delimiter character
61(or
62.Dv NULL ,
63if the end of the string was reached) is stored in
64.Fa *stringp .
65The original value of
66.Fa *stringp
67is returned.
68.Pp
69An
70.Dq empty
71field, i.e., one caused by two adjacent delimiter characters,
72can be detected by comparing the location referenced by the pointer returned
73by
74.Fn strsep
75to
76.Ql \e0 .
77.Pp
78If
79.Fa *stringp
80is initially
81.Dv NULL ,
82.Fn strsep
83returns
84.Dv NULL .
85.Sh EXAMPLES
86The following uses
87.Fn strsep
88to parse a string, containing tokens delimited by whitespace, into an
89argument vector:
90.Bd -literal -offset indent
91char **ap, *argv[10], *inputstring;
92
93for (ap = argv; ap < &argv[9] &&
94 (*ap = strsep(&inputstring, " \et")) != NULL;) {
95 if (**ap != '\e0')
96 ap++;
97}
98*ap = NULL;
99.Ed
100.Sh HISTORY
101The
102.Fn strsep
103function is intended as a replacement for the
104.Fn strtok
105function.
106While the
107.Fn strtok
108function should be preferred for portability reasons (it conforms to
109.St -ansiC )
110it is unable to handle empty fields, i.e., detect fields delimited by
111two adjacent delimiter characters, or to be used for more than a single
112string at a time.
113The
114.Fn strsep
115function first appeared in
116.Bx 4.4 .
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c
new file mode 100644
index 0000000000..b69b715fc5
--- /dev/null
+++ b/src/lib/libc/string/strsep.c
@@ -0,0 +1,85 @@
1/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <string.h>
37#include <stdio.h>
38
39#if defined(LIBC_SCCS) && !defined(lint)
40#if 0
41static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
42#else
43static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $";
44#endif
45#endif /* LIBC_SCCS and not lint */
46
47/*
48 * Get next token from string *stringp, where tokens are possibly-empty
49 * strings separated by characters from delim.
50 *
51 * Writes NULs into the string at *stringp to end tokens.
52 * delim need not remain constant from call to call.
53 * On return, *stringp points past the last NUL written (if there might
54 * be further tokens), or is NULL (if there are definitely no more tokens).
55 *
56 * If *stringp is NULL, strsep returns NULL.
57 */
58char *
59strsep(stringp, delim)
60 register char **stringp;
61 register const char *delim;
62{
63 register char *s;
64 register const char *spanp;
65 register int c, sc;
66 char *tok;
67
68 if ((s = *stringp) == NULL)
69 return (NULL);
70 for (tok = s;;) {
71 c = *s++;
72 spanp = delim;
73 do {
74 if ((sc = *spanp++) == c) {
75 if (c == 0)
76 s = NULL;
77 else
78 s[-1] = 0;
79 *stringp = s;
80 return (tok);
81 }
82 } while (sc != 0);
83 }
84 /* NOTREACHED */
85}
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3
new file mode 100644
index 0000000000..83b3775f4e
--- /dev/null
+++ b/src/lib/libc/string/strsignal.3
@@ -0,0 +1,60 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strsignal.3,v 1.3 1999/05/23 14:11:03 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSIGNAL 3
40.Os
41.Sh NAME
42.Nm strsignal
43.Nd get signal description string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strsignal "int sig"
48.Sh DESCRIPTION
49The
50.Fn strsignal
51function returns a pointer to the language-dependent string describing
52a signal.
53.Pp
54The array pointed to is not to be modified by the program, but may be
55overwritten by subsequent calls to
56.Fn strsignal .
57.Sh SEE ALSO
58.Xr intro 2 ,
59.Xr psignal 3 ,
60.Xr setlocale 3
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c
new file mode 100644
index 0000000000..90118f70f9
--- /dev/null
+++ b/src/lib/libc/string/strsignal.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strsignal.c,v 1.3 2002/02/16 21:27:24 millert Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39#include <limits.h>
40
41extern char *__strsignal(int, char *);
42
43char *
44strsignal(sig)
45 int sig;
46{
47 static char buf[NL_TEXTMAX];
48 return __strsignal(sig, buf);
49}
diff --git a/src/lib/libc/string/strspn.3 b/src/lib/libc/string/strspn.3
new file mode 100644
index 0000000000..ca965aeb18
--- /dev/null
+++ b/src/lib/libc/string/strspn.3
@@ -0,0 +1,88 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strspn.3,v 1.6 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSPN 3
40.Os
41.Sh NAME
42.Nm strspn
43.Nd span a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strspn "const char *s" "const char *charset"
48.Sh DESCRIPTION
49The
50.Fn strspn
51function spans the initial part of the null-terminated string
52.Fa s
53as long as the characters from
54.Fa s
55occur in string
56.Fa charset .
57.Sh RETURN VALUES
58The
59.Fn strspn
60function returns the number of characters spanned.
61.Sh EXAMPLES
62The following call to
63.Fn strspn
64will return 3, since the first three characters of string
65.Fa s
66are part of string
67.Fa charset :
68.Bd -literal -offset indent
69char *s = "foobar";
70char *charset = "of";
71size_t span;
72
73span = strspn(s, charset);
74.Ed
75.Sh SEE ALSO
76.Xr memchr 3 ,
77.Xr strchr 3 ,
78.Xr strcspn 3 ,
79.Xr strpbrk 3 ,
80.Xr strrchr 3 ,
81.Xr strsep 3 ,
82.Xr strstr 3 ,
83.Xr strtok 3
84.Sh STANDARDS
85The
86.Fn strspn
87function conforms to
88.St -ansiC .
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c
new file mode 100644
index 0000000000..41940f9190
--- /dev/null
+++ b/src/lib/libc/string/strspn.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strspn.c,v 1.2 1996/08/19 08:34:26 tholo Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40/*
41 * Span the string s2 (skip characters that are in s2).
42 */
43size_t
44strspn(s1, s2)
45 const char *s1;
46 register const char *s2;
47{
48 register const char *p = s1, *spanp;
49 register char c, sc;
50
51 /*
52 * Skip any characters in s2, excluding the terminating \0.
53 */
54cont:
55 c = *p++;
56 for (spanp = s2; (sc = *spanp++) != 0;)
57 if (sc == c)
58 goto cont;
59 return (p - 1 - s1);
60}
diff --git a/src/lib/libc/string/strstr.3 b/src/lib/libc/string/strstr.3
new file mode 100644
index 0000000000..10beea42ca
--- /dev/null
+++ b/src/lib/libc/string/strstr.3
@@ -0,0 +1,85 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strstr.3,v 1.5 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRSTR 3
40.Os
41.Sh NAME
42.Nm strstr
43.Nd locate a substring in a string
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft char *
47.Fn strstr "const char *big" "const char *little"
48.Sh DESCRIPTION
49The
50.Fn strstr
51function locates the first occurrence of the null-terminated string
52.Fa little
53in the null-terminated string
54.Fa big .
55If
56.Fa little
57is the empty string,
58.Fn strstr
59returns
60.Fa big ;
61if
62.Fa little
63occurs nowhere in
64.Fa big ,
65.Fn strstr
66returns
67.Dv NULL ;
68otherwise
69.Fn strstr
70returns a pointer to the first character of the first occurrence of
71.Fa little .
72.Sh SEE ALSO
73.Xr memchr 3 ,
74.Xr strchr 3 ,
75.Xr strcspn 3 ,
76.Xr strpbrk 3 ,
77.Xr strrchr 3 ,
78.Xr strsep 3 ,
79.Xr strspn 3 ,
80.Xr strtok 3
81.Sh STANDARDS
82The
83.Fn strstr
84function conforms to
85.St -ansiC .
diff --git a/src/lib/libc/string/strstr.c b/src/lib/libc/string/strstr.c
new file mode 100644
index 0000000000..763c7e29d7
--- /dev/null
+++ b/src/lib/libc/string/strstr.c
@@ -0,0 +1,64 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strstr.c,v 1.2 1996/08/19 08:34:27 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Find the first occurrence of find in s.
45 */
46char *
47strstr(s, find)
48 register const char *s, *find;
49{
50 register char c, sc;
51 register size_t len;
52
53 if ((c = *find++) != 0) {
54 len = strlen(find);
55 do {
56 do {
57 if ((sc = *s++) == 0)
58 return (NULL);
59 } while (sc != c);
60 } while (strncmp(s, find, len) != 0);
61 s--;
62 }
63 return ((char *)s);
64}
diff --git a/src/lib/libc/string/strtok.3 b/src/lib/libc/string/strtok.3
new file mode 100644
index 0000000000..b8dad8eff0
--- /dev/null
+++ b/src/lib/libc/string/strtok.3
@@ -0,0 +1,156 @@
1.\" Copyright (c) 1988, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strtok.3,v 1.15 2001/08/06 10:42:26 mpech Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRTOK 3
40.Os
41.Sh NAME
42.Nm strtok ,
43.Nm strtok_r
44.Nd string token operations
45.Sh SYNOPSIS
46.Fd #include <string.h>
47.Ft char *
48.Fn strtok "char *str" "const char *sep"
49.Ft char *
50.Fn strtok_r "char *str" "const char *sep" "char **last"
51.Sh DESCRIPTION
52.Bf -symbolic
53This interface is obsoleted by
54.Xr strsep 3 .
55.Ef
56.Pp
57The
58.Fn strtok
59function is used to isolate sequential tokens in a null-terminated string,
60.Fa str .
61These tokens are separated in the string by at least one of the
62characters in
63.Fa sep .
64The first time that
65.Fn strtok
66is called,
67.Fa str
68should be specified; subsequent calls, wishing to obtain further tokens
69from the same string, should pass a null pointer instead.
70The separator string,
71.Fa sep ,
72must be supplied each time, and may change between calls.
73.Pp
74The
75.Fn strtok_r
76function is a version of
77.Fn strtok
78that takes an explicit context argument and is reentrant.
79.Pp
80The
81.Fn strtok
82and
83.Fn strtok_r
84functions return a pointer to the beginning of each subsequent token
85in the string, after replacing the separator character itself with an
86.Tn ASCII NUL
87character.
88When no more tokens remain, a null pointer is returned.
89.Pp
90Since
91.Fn strtok
92and
93.Fn strtok_r
94modify the string,
95.Fa str
96should not point to an area in the initialized data segment.
97.Sh EXAMPLES
98The following will construct an array of pointers to each individual word in
99the string
100.Va s :
101.Bd -literal -offset indent
102#define MAXTOKENS 128
103
104char s[512], *p, *tokens[MAXTOKENS];
105char *last;
106int i = 0;
107
108snprintf(s, sizeof(s), "cat dog horse cow");
109
110for ((p = strtok_r(s, " ", &last)); p;
111 (p = strtok_r(NULL, " ", &last)), i++) {
112 if (i < MAXTOKENS - 1)
113 tokens[i] = p;
114}
115tokens[i] = NULL;
116.Ed
117.Pp
118That is,
119.Li tokens[0]
120will point to
121.Qq cat ,
122.Li tokens[1]
123will point to
124.Qq dog ,
125.Li tokens[2]
126will point to
127.Qq horse ,
128and
129.Li tokens[3]
130will point to
131.Qq cow .
132.Sh SEE ALSO
133.Xr memchr 3 ,
134.Xr strchr 3 ,
135.Xr strcspn 3 ,
136.Xr strpbrk 3 ,
137.Xr strrchr 3 ,
138.Xr strsep 3 ,
139.Xr strspn 3 ,
140.Xr strstr 3
141.Sh STANDARDS
142The
143.Fn strtok
144function conforms to
145.St -ansiC .
146.Sh BUGS
147The System V
148.Fn strtok ,
149if handed a string containing only delimiter characters,
150will not alter the next starting point, so that a call to
151.Fn strtok
152with a different (or empty) delimiter string
153may return a non-null value.
154Since this implementation always alters the next starting point,
155such a sequence of calls would always return
156.Dv NULL .
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c
new file mode 100644
index 0000000000..d925dc75d0
--- /dev/null
+++ b/src/lib/libc/string/strtok.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static char *rcsid = "$OpenBSD: strtok.c,v 1.3 1999/11/09 11:19:46 art Exp $";
36#endif /* LIBC_SCCS and not lint */
37
38#include <string.h>
39
40char *
41strtok(s, delim)
42 register char *s;
43 register const char *delim;
44{
45 static char *last;
46
47 return strtok_r(s, delim, &last);
48}
49
50char *
51strtok_r(s, delim, last)
52 register char *s;
53 register const char *delim;
54 char **last;
55{
56 register char *spanp;
57 register int c, sc;
58 char *tok;
59
60
61 if (s == NULL && (s = *last) == NULL)
62 return (NULL);
63
64 /*
65 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
66 */
67cont:
68 c = *s++;
69 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
70 if (c == sc)
71 goto cont;
72 }
73
74 if (c == 0) { /* no non-delimiter characters */
75 *last = NULL;
76 return (NULL);
77 }
78 tok = s - 1;
79
80 /*
81 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
82 * Note that delim must have one NUL; we stop if we see that, too.
83 */
84 for (;;) {
85 c = *s++;
86 spanp = (char *)delim;
87 do {
88 if ((sc = *spanp++) == c) {
89 if (c == 0)
90 s = NULL;
91 else
92 s[-1] = 0;
93 *last = s;
94 return (tok);
95 }
96 } while (sc != 0);
97 }
98 /* NOTREACHED */
99}
diff --git a/src/lib/libc/string/strxfrm.3 b/src/lib/libc/string/strxfrm.3
new file mode 100644
index 0000000000..1e5338993a
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.3
@@ -0,0 +1,66 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" $OpenBSD: strxfrm.3,v 1.3 2000/04/21 15:24:20 aaron Exp $
37.\"
38.Dd June 29, 1991
39.Dt STRXFRM 3
40.Os
41.Sh NAME
42.Nm strxfrm
43.Nd transform a string under locale
44.Sh SYNOPSIS
45.Fd #include <string.h>
46.Ft size_t
47.Fn strxfrm "char *dst" "const char *src" "size_t n"
48.Sh DESCRIPTION
49The
50.Fn strxfrm
51function does something horrible (see
52.Tn ANSI
53standard).
54In this implementation it just copies.
55.Sh SEE ALSO
56.Xr bcmp 3 ,
57.Xr memcmp 3 ,
58.\" .Xr setlocale 3 ,
59.Xr strcasecmp 3 ,
60.Xr strcmp 3 ,
61.Xr strcoll 3
62.Sh STANDARDS
63The
64.Fn strxfrm
65function conforms to
66.St -ansiC .
diff --git a/src/lib/libc/string/strxfrm.c b/src/lib/libc/string/strxfrm.c
new file mode 100644
index 0000000000..6b258edecc
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.c
@@ -0,0 +1,73 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: strxfrm.c,v 1.2 1996/08/19 08:34:29 tholo Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <string.h>
42
43/*
44 * Transform src, storing the result in dst, such that
45 * strcmp() on transformed strings returns what strcoll()
46 * on the original untransformed strings would return.
47 */
48size_t
49strxfrm(dst, src, n)
50 register char *dst;
51 register const char *src;
52 register size_t n;
53{
54 register size_t r = 0;
55 register int c;
56
57 /*
58 * Since locales are unimplemented, this is just a copy.
59 */
60 if (n != 0) {
61 while ((c = *src++) != 0) {
62 r++;
63 if (--n == 0) {
64 while (*src++ != 0)
65 r++;
66 break;
67 }
68 *dst++ = c;
69 }
70 *dst = 0;
71 }
72 return (r);
73}
diff --git a/src/lib/libc/string/swab.3 b/src/lib/libc/string/swab.3
new file mode 100644
index 0000000000..628eb6b15f
--- /dev/null
+++ b/src/lib/libc/string/swab.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: swab.3,v 1.4 2000/01/03 22:52:59 aaron Exp $
33.\"
34.Dd May 1, 1991
35.Dt SWAB 3
36.Os
37.Sh NAME
38.Nm swab
39.Nd swap adjacent bytes
40.Sh SYNOPSIS
41.Fd #include <unistd.h>
42.Ft void
43.Fn swab "const void *src" "void *dst" "size_t len"
44.Sh DESCRIPTION
45The function
46.Fn swab
47copies
48.Fa len
49bytes from the location referenced by
50.Fa src
51to the location referenced by
52.Fa dst ,
53swapping adjacent bytes.
54.Pp
55The argument
56.Fa len
57must be an even number.
58.Sh SEE ALSO
59.Xr bzero 3 ,
60.Xr memset 3
61.Sh HISTORY
62A
63.Fn swab
64function appeared in
65.At v7 .
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c
new file mode 100644
index 0000000000..311cf13a53
--- /dev/null
+++ b/src/lib/libc/string/swab.c
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jeffrey Mogul.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char *rcsid = "$OpenBSD: swab.c,v 1.3 1998/02/10 02:19:48 deraadt Exp $";
39#endif /* LIBC_SCCS and not lint */
40
41#include <unistd.h>
42
43void
44swab(from, to, len)
45 const void *from;
46 void *to;
47 size_t len;
48{
49 register unsigned long temp;
50 register int n;
51 register char *fp, *tp;
52
53 n = (len >> 1) + 1;
54 fp = (char *)from;
55 tp = (char *)to;
56#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp
57 /* round to multiple of 8 */
58 while ((--n) & 07)
59 STEP;
60 n >>= 3;
61 while (--n >= 0) {
62 STEP; STEP; STEP; STEP;
63 STEP; STEP; STEP; STEP;
64 }
65}